Permalink
Browse files

Improvements to the Scala debugger

Improved display of all elements.
Added support for resume action.
Added 'this' in variable list.
Created tests for all improvements.
Added hack of logical structure support.
  • Loading branch information...
1 parent ae88091 commit ae022a416289fc51fd94224e13d2116f613afed0 @skyluc skyluc committed Mar 6, 2012
Showing with 1,201 additions and 62 deletions.
  1. +2 −0 org.scala-ide.sdt.debug.tests/.classpath
  2. +1 −0 org.scala-ide.sdt.debug.tests/.gitignore
  3. +2 −0 org.scala-ide.sdt.debug.tests/META-INF/MANIFEST.MF
  4. +5 −3 org.scala-ide.sdt.debug.tests/build.properties
  5. +26 −1 org.scala-ide.sdt.debug.tests/pom.xml
  6. +56 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugResumeTest.scala
  7. +13 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugRunningTest.scala
  8. +1 −9 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugSteppingTest.scala
  9. +15 −1 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugTestSession.scala
  10. +25 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugTests.scala
  11. +82 −0 ...ala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentationTest.scala
  12. +323 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaStackFrameTest.scala
  13. +73 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaThreadTest.scala
  14. +260 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaValueTest.scala
  15. +7 −0 org.scala-ide.sdt.debug/plugin.xml
  16. +32 −6 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/ScalaDebugger.scala
  17. +21 −8 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/ScalaSourceLocator.scala
  18. +28 −4 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentation.scala
  19. +1 −1 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaDebugTarget.scala
  20. +90 −0 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaLogicalStructureProvider.scala
  21. +66 −6 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaStackFrame.scala
  22. +37 −10 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaThread.scala
  23. +25 −12 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaValue.scala
  24. +10 −1 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaVariable.scala
@@ -3,8 +3,10 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/>
+ <classpathentry kind="var" path="JAVA_HOME/lib/tools.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="lib/mockito-all-1.8.5.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
@@ -1,2 +1,3 @@
.cache
target
+lib/*
@@ -9,3 +9,5 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Require-Bundle: org.scala-ide.scala.library,
org.eclipse.equinox.weaving.aspectj,
org.scala-ide.sdt.core
+Bundle-ClassPath: .,
+ lib/mockito-all-1.8.5.jar
@@ -1,6 +1,8 @@
source.. = src/
output.. = target/classes/
bin.includes = META-INF/,\
- test-workspace/,\
- lib/,\
- .
+ test-workspace/,\
+ lib/,\
+ .,\
+ lib/mockito-all-1.8.5.jar
+source.. = src/
@@ -140,7 +140,7 @@
<!-- </includes> -->
<argLine>${tycho.test.jvmArgs}</argLine>
<testSuite>${project.artifactId}</testSuite>
- <testClass>scala.tools.eclipse.debug.ScalaDebugSteppingTest</testClass>
+ <testClass>scala.tools.eclipse.debug.ScalaDebugTestSuite</testClass>
</configuration>
</plugin>
@@ -153,6 +153,31 @@
<pomDependencies>consider</pomDependencies>
</configuration>
</plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.5</version>
+ <outputDirectory>${basedir}/lib</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
@@ -0,0 +1,56 @@
+package scala.tools.eclipse.debug
+
+import scala.tools.eclipse.testsetup.TestProjectSetup
+import org.junit.Test
+import org.junit.Before
+import org.eclipse.core.resources.IncrementalProjectBuilder
+import org.junit.After
+import org.eclipse.core.runtime.NullProgressMonitor
+
+object ScalaDebugResumeTest extends TestProjectSetup("debug", bundleName= "org.scala-ide.sdt.debug.tests") with ScalaDebugRunningTest
+
+/**
+ * Test the resume action
+ */
+class ScalaDebugResumeTest {
+
+ import ScalaDebugSteppingTest._
+
+ var session: ScalaDebugTestSession = null
+
+ @Before
+ def setScalaDebugMode() {
+ ScalaDebugPlugin.plugin.getPreferenceStore.setValue(DebugPreferencePage.P_ENABLE, true)
+ }
+
+ @Before
+ def refreshBinaryFiles() {
+ project.underlying.build(IncrementalProjectBuilder.CLEAN_BUILD, new NullProgressMonitor)
+ project.underlying.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new NullProgressMonitor)
+ }
+
+ @After
+ def cleanDebugSession() {
+ if (session ne null) {
+ session.terminate()
+ session = null
+ }
+ }
+
+ @Test
+ def resumeToBreakpoindAndToCompletion() {
+
+ session = new ScalaDebugTestSession(file("ForComprehensionListString.launch"))
+
+ session.runToLine(TYPENAME_FC_LS + "$", 9)
+
+ session.checkStackFrame(TYPENAME_FC_LS + "$", "main([Ljava/lang/String;)V", 9)
+
+ session.runToLine(TYPENAME_FC_LS, 35)
+
+ session.checkStackFrame(TYPENAME_FC_LS, "bar()V", 35)
+
+ session.resumeToCompletion()
+ }
+
+}
@@ -0,0 +1,13 @@
+package scala.tools.eclipse.debug
+
+import scala.tools.eclipse.testsetup.TestProjectSetup
+
+trait ScalaDebugRunningTest {
+
+ val TYPENAME_FC_LS = "stepping.ForComprehensionListString"
+ val TYPENAME_FC_LS2 = "stepping.ForComprehensionListString2"
+ val TYPENAME_FC_LO = "stepping.ForComprehensionListObject"
+ val TYPENAME_FC_LI = "stepping.ForComprehensionListInt"
+ val TYPENAME_AF_LS = "stepping.AnonFunOnListString"
+
+}
@@ -5,15 +5,7 @@ import org.junit.{Test, Before, After}
import org.eclipse.core.resources.IncrementalProjectBuilder
import org.eclipse.core.runtime.NullProgressMonitor
-object ScalaDebugSteppingTest extends TestProjectSetup("debug", bundleName= "org.scala-ide.sdt.debug.tests") {
-
- val TYPENAME_FC_LS = "stepping.ForComprehensionListString"
- val TYPENAME_FC_LS2 = "stepping.ForComprehensionListString2"
- val TYPENAME_FC_LO = "stepping.ForComprehensionListObject"
- val TYPENAME_FC_LI = "stepping.ForComprehensionListInt"
- val TYPENAME_AF_LS = "stepping.AnonFunOnListString"
-
-}
+object ScalaDebugSteppingTest extends TestProjectSetup("debug", bundleName= "org.scala-ide.sdt.debug.tests") with ScalaDebugRunningTest
class ScalaDebugSteppingTest {
@@ -103,7 +103,7 @@ class ScalaDebugTestSession(launchConfigurationFile: IFile) extends IDebugEventS
if (state eq NOT_LAUNCHED) {
launch()
} else {
- currentStackFrame.resume
+ resume()
}
waitUntilSuspended
@@ -121,6 +121,16 @@ class ScalaDebugTestSession(launchConfigurationFile: IFile) extends IDebugEventS
assertEquals("Bad state after stepOver", SUSPENDED, state)
}
+
+ def resumeToCompletion() {
+ assertEquals("Bad state before resumeToCompletion", SUSPENDED, state)
+
+ resume
+
+ waitUntilSuspended
+
+ assertEquals("Bad state after resumeToCompletion", TERMINATED, state)
+ }
def terminate() {
if ((state ne NOT_LAUNCHED) && (state ne TERMINATED)) {
@@ -134,6 +144,10 @@ class ScalaDebugTestSession(launchConfigurationFile: IFile) extends IDebugEventS
val launchConfiguration = DebugPlugin.getDefault.getLaunchManager.getLaunchConfiguration(launchConfigurationFile)
launchConfiguration.launch(ILaunchManager.DEBUG_MODE, null).getDebugTarget.asInstanceOf[JDIDebugTarget]
}
+
+ private def resume() {
+ currentStackFrame.resume
+ }
// -----
@@ -0,0 +1,25 @@
+package scala.tools.eclipse.debug
+
+import junit.framework.TestSuite
+import org.junit.runners.Suite
+import org.junit.runner.RunWith
+import scala.tools.eclipse.debug.model.ScalaThreadTest
+import scala.tools.eclipse.debug.model.ScalaDebugModelPresentationTest
+import scala.tools.eclipse.debug.model.ScalaStackFrameTest
+import scala.tools.eclipse.debug.model.ScalaValueTest
+
+/**
+ * Junit test suite for the Scala debugger.
+ */
+
+@RunWith(classOf[Suite])
+@Suite.SuiteClasses(
+ Array(
+ classOf[ScalaDebugSteppingTest],
+ classOf[ScalaDebugResumeTest],
+ classOf[ScalaThreadTest],
+// classOf[ScalaDebugModelPresentationTest], // TODO: find where to put this test
+ classOf[ScalaStackFrameTest],
+ classOf[ScalaValueTest]))
+class ScalaDebugTestSuite {
+}
@@ -0,0 +1,82 @@
+package scala.tools.eclipse.debug.model
+
+import org.eclipse.debug.core.DebugPlugin
+import org.junit.Assert._
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito._
+import com.sun.jdi.ThreadReference
+import com.sun.jdi.ThreadGroupReference
+import com.sun.jdi.StackFrame
+import com.sun.jdi.Location
+import com.sun.jdi.Method
+import com.sun.jdi.ReferenceType
+
+class ScalaDebugModelPresentationTest {
+
+ val modelPres = new ScalaDebugModelPresentation
+
+ @Before
+ def initializeDebugPlugin() {
+ if (DebugPlugin.getDefault == null) {
+ new DebugPlugin
+ }
+ }
+
+ @Test
+ def scalaThreadName() {
+ val jdiThread = mock(classOf[ThreadReference])
+ when(jdiThread.name).thenReturn("thread name")
+ val jdiThreadGroup = mock(classOf[ThreadGroupReference])
+ when(jdiThread.threadGroup).thenReturn(jdiThreadGroup)
+ when(jdiThreadGroup.name).thenReturn("not system")
+
+ val scalaThread = new ScalaThread(null, jdiThread)
+
+ assertEquals("Bad display name for Scala thread", "Thread [thread name]", modelPres.getText(scalaThread))
+ }
+
+ @Test
+ def scalaThreadNameForSystemThread() {
+ val jdiThread = mock(classOf[ThreadReference])
+ when(jdiThread.name).thenReturn("system thread name")
+ val jdiThreadGroup = mock(classOf[ThreadGroupReference])
+ when(jdiThread.threadGroup).thenReturn(jdiThreadGroup)
+ when(jdiThreadGroup.name).thenReturn("system")
+
+ val scalaThread = new ScalaThread(null, jdiThread)
+
+ assertEquals("Bad display name for Scala system thread", "Deamon System Thread [system thread name]", modelPres.getText(scalaThread))
+ }
+
+ @Test
+ def scalaStackFrame() {
+ val scalaThread = mock(classOf[ScalaThread])
+
+ import ScalaStackFrameTest._
+
+ val jdiStackFrame = createJDIStackFrame("some.package.TypeName", "methodName", List(referenceType("a.b.ParamType1"), referenceType("a.b.ParamType2")))
+ val location= jdiStackFrame.location
+ when(location.lineNumber).thenReturn(42)
+
+ val scalaStackFrame = new ScalaStackFrame(scalaThread, jdiStackFrame)
+
+ assertEquals("Bad display name for Scala stack frame", "TypeName.methodName(ParamType1, ParamType2) line: 42", modelPres.getText(scalaStackFrame))
+ }
+
+ @Test
+ def scalaStackFrameLineNotAvailable() {
+ val scalaThread = mock(classOf[ScalaThread])
+
+ import ScalaStackFrameTest._
+
+ val jdiStackFrame = createJDIStackFrame("some.package.TypeName", "methodName", Nil)
+ val location= jdiStackFrame.location
+ when(location.lineNumber).thenReturn(-1)
+
+ val scalaStackFrame = new ScalaStackFrame(scalaThread, jdiStackFrame)
+
+ assertEquals("Bad display name for Scala stack frame", "TypeName.methodName() line: not available", modelPres.getText(scalaStackFrame))
+ }
+
+}
Oops, something went wrong. Retry.

0 comments on commit ae022a4

Please sign in to comment.