Browse files

Support for toString in detail pane

Improved the support for logical structure for collections
Changed the display name for array indexes
Added support for symbols in names

With tests
  • Loading branch information...
1 parent f6120e4 commit a1a4d8b5e48180bb6f10e6321494792a65936201 @skyluc skyluc committed Mar 15, 2012
Showing with 350 additions and 25 deletions.
  1. +76 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugComputeDetailTest.scala
  2. +1 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugRunningTest.scala
  3. +1 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugTestSession.scala
  4. +56 −0 ...ala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentationTest.scala
  5. +11 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaStackFrameTest.scala
  6. +14 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaValueTest.scala
  7. +26 −0 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaVariableTest.scala
  8. +1 −0 org.scala-ide.sdt.debug.tests/test-workspace/debug/.gitignore
  9. +11 −0 org.scala-ide.sdt.debug.tests/test-workspace/debug/Variables.launch
  10. +1 −1 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/{stepping → debug}/Helper.scala
  11. +18 −2 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/{stepping → debug}/Variables.scala
  12. +1 −1 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/stepping/AnonFunOnListString.scala
  13. +1 −1 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/stepping/ForComprehensionListInt.scala
  14. +1 −1 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/stepping/ForComprehensionListString2.scala
  15. +2 −2 org.scala-ide.sdt.debug/plugin.xml
  16. +5 −3 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/ScalaDebugger.scala
  17. +92 −2 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentation.scala
  18. +3 −5 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaLogicalStructureProvider.scala
  19. +8 −3 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaStackFrame.scala
  20. +17 −0 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaThread.scala
  21. +2 −2 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaValue.scala
  22. +2 −2 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaVariable.scala
View
76 ...scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugComputeDetailTest.scala
@@ -0,0 +1,76 @@
+package scala.tools.eclipse.debug
+
+import scala.tools.eclipse.testsetup.TestProjectSetup
+import org.junit.Before
+import org.eclipse.core.resources.IncrementalProjectBuilder
+import org.eclipse.core.runtime.NullProgressMonitor
+import org.junit.After
+import org.junit.Test
+import org.junit.Assert._
+import scala.tools.eclipse.debug.model.ScalaDebugModelPresentation
+
+object ScalaDebugComputeDetailTest extends TestProjectSetup("debug", bundleName= "org.scala-ide.sdt.debug.tests") with ScalaDebugRunningTest
+
+/**
+ * Test executing computeDetail for object references. This triggers a invocation of 'toString' on
+ * the target VM and is simpler to test without mocking.
+ */
+
+class ScalaDebugComputeDetailTest {
+
+ import ScalaDebugComputeDetailTest._
+
+ 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 for object reference
+ */
+ @Test
+ def computeDetailObject() {
+ session = new ScalaDebugTestSession(file("Variables.launch"))
+
+ session.runToLine(TYPENAME_VARIABLES + "$", 30)
+
+ session.checkStackFrame(TYPENAME_VARIABLES + "$", "main([Ljava/lang/String;)V", 30)
+
+ val detail= ScalaDebugModelPresentation.computeDetail(session.currentStackFrame.variables.find(_.getName == "j").get.getValue)
+
+ assertEquals("Bad detail for object", "List(4, 5, 6)", detail)
+ }
+
+ /**
+ * test for array reference containing object references
+ */
+ @Test
+ def computeDetailArrayOfMixedElements() {
+ session = new ScalaDebugTestSession(file("Variables.launch"))
+
+ session.runToLine(TYPENAME_VARIABLES + "$", 30)
+
+ session.checkStackFrame(TYPENAME_VARIABLES + "$", "main([Ljava/lang/String;)V", 30)
+
+ val detail= ScalaDebugModelPresentation.computeDetail(session.currentStackFrame.variables.find(_.getName == "k").get.getValue)
+
+ assertEquals("Bad detail for mixed elements array", "Array(one, 1, true)", detail)
+ }
+
+}
View
1 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugRunningTest.scala
@@ -9,5 +9,6 @@ trait ScalaDebugRunningTest {
val TYPENAME_FC_LO = "stepping.ForComprehensionListObject"
val TYPENAME_FC_LI = "stepping.ForComprehensionListInt"
val TYPENAME_AF_LS = "stepping.AnonFunOnListString"
+ val TYPENAME_VARIABLES = "debug.Variables"
}
View
1 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/ScalaDebugTestSession.scala
@@ -69,6 +69,7 @@ class ScalaDebugTestSession(launchConfigurationFile: IFile) extends IDebugEventS
def setSuspended(stackFrame: ScalaStackFrame) {
this.synchronized {
currentStackFrame = stackFrame
+ ScalaDebugger.currentThread = stackFrame.thread
state = SUSPENDED
this.notify
}
View
56 ...sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentationTest.scala
@@ -11,6 +11,12 @@ import com.sun.jdi.StackFrame
import com.sun.jdi.Location
import com.sun.jdi.Method
import com.sun.jdi.ReferenceType
+import com.sun.jdi.StringReference
+import com.sun.jdi.ArrayReference
+import com.sun.jdi.IntegerValue
+import com.sun.jdi.Value
+import com.sun.jdi.ObjectReference
+import com.sun.jdi.ClassType
class ScalaDebugModelPresentationTest {
@@ -78,5 +84,55 @@ class ScalaDebugModelPresentationTest {
assertEquals("Bad display name for Scala stack frame", "TypeName.methodName() line: not available", modelPres.getText(scalaStackFrame))
}
+
+ @Test
+ def computeDetailNull() {
+ val scalaValue = mock(classOf[ScalaNullValue])
+
+ val computedDetail= ScalaDebugModelPresentation.computeDetail(scalaValue)
+
+ assertEquals("Bad return value for computeDetail", "null", computedDetail)
+ }
+
+ @Test
+ def computeDetailPrimitiveNotString() {
+ val scalaValue = new ScalaPrimitiveValue(null, "a value", null)
+
+ val computedDetail= ScalaDebugModelPresentation.computeDetail(scalaValue)
+
+ assertEquals("Bad return value for computeDetail", "a value", computedDetail)
+ }
+
+ @Test
+ def computeDetailString() {
+ val stringReference = mock(classOf[StringReference])
+ when(stringReference.value).thenReturn("a string value")
+
+ val computedDetail= ScalaDebugModelPresentation.computeDetail(new ScalaStringReference(stringReference, null))
+
+ assertEquals("Bad return value for computeDetail", "a string value", computedDetail)
+ }
+
+ @Test
+ def computeDetailArrayOfPrimitive() {
+ val arrayReference= mock(classOf[ArrayReference])
+ import scala.collection.JavaConverters._
+ val values= List(createIntValue(1), createIntValue(2), createIntValue(4)).asJava
+ when(arrayReference.getValues).thenReturn(values)
+
+ val computedDetail= ScalaDebugModelPresentation.computeDetail(new ScalaArrayReference(arrayReference, null))
+
+ assertEquals("Bad return value for computeDetail", "Array(1, 2, 4)", computedDetail)
+ }
+
+ // TODO: test for array of object reference
+
+ // -----
+ def createIntValue(i: Int): Value = {
+ val value= mock(classOf[IntegerValue])
+ when(value.value).thenReturn(i)
+ value
+ }
+
}
View
11 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaStackFrameTest.scala
@@ -270,6 +270,17 @@ class ScalaStackFrameTest {
}
@Test
+ def getFullMethodNameWithEncoding() {
+ val scalaThread = mock(classOf[ScalaThread])
+
+ val jdiStackFrame = createJDIStackFrame("package.name.TypeName", "$colon$plus$minus$qmark")
+
+ val scalaStackFrame = new ScalaStackFrame(scalaThread, jdiStackFrame)
+
+ assertEquals("Bad full method name", "TypeName.:+-?()", scalaStackFrame.getMethodFullName)
+ }
+
+ @Test
def getVariableNonStaticMethod() {
import scala.collection.JavaConverters._
View
14 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaValueTest.scala
@@ -222,6 +222,20 @@ class ScalaValueTest {
}
@Test
+ def objectReferenceValueWithEncodedName() {
+ val jdiValue = mock(classOf[ObjectReference])
+ when(jdiValue.uniqueID).thenReturn(666)
+ val jdiReferenceType = mock(classOf[ClassType])
+ when(jdiValue.referenceType).thenReturn(jdiReferenceType)
+ when(jdiReferenceType.name).thenReturn("scala.collection.immutable.$colon$colon")
+
+ val scalaValue = ScalaValue(jdiValue, null)
+
+ assertEquals("Bad type", "scala.collection.immutable.$colon$colon", scalaValue.getReferenceTypeName)
+ assertEquals("Bad value", ":: (id=666)", scalaValue.getValueString)
+ }
+
+ @Test
def arrayReferenecValue() {
val jdiValue = mock(classOf[ArrayReference])
when(jdiValue.length).thenReturn(3)
View
26 org.scala-ide.sdt.debug.tests/src/scala/tools/eclipse/debug/model/ScalaVariableTest.scala
@@ -0,0 +1,26 @@
+package scala.tools.eclipse.debug.model
+
+import org.junit.Test
+import org.junit.Assert._
+
+class ScalaVariableTest {
+
+ /**
+ * Check the format of the name returned by a scalaArrayElementVariable
+ */
+ @Test
+ def scalaArrayElementVariableName() {
+
+ val arrayReference= new ScalaArrayReference(null, null)
+
+ val arrayElementVariable= new ScalaArrayElementVariable(0, arrayReference)
+
+ assertEquals("Bad variable name", "(0)", arrayElementVariable.getName)
+
+ val arrayElementVariable2= new ScalaArrayElementVariable(12, arrayReference)
+
+ assertEquals("Bad variable name", "(12)", arrayElementVariable2.getName)
+
+ }
+
+}
View
1 org.scala-ide.sdt.debug.tests/test-workspace/debug/.gitignore
@@ -0,0 +1 @@
+bin/
View
11 org.scala-ide.sdt.debug.tests/test-workspace/debug/Variables.launch
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="scala.application">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/debug/src/debug/Variables.scala"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="debug.Variables"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="debug"/>
+</launchConfiguration>
View
2 ...workspace/debug/src/stepping/Helper.scala → ...st-workspace/debug/src/debug/Helper.scala
@@ -1,4 +1,4 @@
-package stepping
+package debug
object Helper {
View
20 ...kspace/debug/src/stepping/Variables.scala → ...workspace/debug/src/debug/Variables.scala
@@ -1,6 +1,6 @@
-package stepping
+package debug
-import Helper._
+import Helper.noop
object Variables {
@@ -15,7 +15,23 @@ object Variables {
val h = "test"
val i = Array(1, 2, 3)
val j = List(4, 5, 6)
+ val k = Array(One("one"), 1, true)
+
+
+
+
+
+
+
+
+
+
+
noop(None)
}
+}
+
+case class One(s: String) {
+ override def toString() = s
}
View
2 org.scala-ide.sdt.debug.tests/test-workspace/debug/src/stepping/AnonFunOnListString.scala
@@ -1,6 +1,6 @@
package stepping
-import Helper._
+import debug.Helper._
object AnonFunOnListString {
View
2 ...scala-ide.sdt.debug.tests/test-workspace/debug/src/stepping/ForComprehensionListInt.scala
@@ -1,6 +1,6 @@
package stepping
-import Helper._
+import debug.Helper._
object ForComprehensionListInt {
View
2 ...a-ide.sdt.debug.tests/test-workspace/debug/src/stepping/ForComprehensionListString2.scala
@@ -1,6 +1,6 @@
package stepping
-import Helper._
+import debug.Helper._
object ForComprehensionListString2 {
View
4 org.scala-ide.sdt.debug/plugin.xml
@@ -29,11 +29,11 @@
class="scala.tools.eclipse.debug.ScalaDebugPlugin">
</startup>
</extension>
-<!-- <extension
+ <extension
point="org.eclipse.debug.core.logicalStructureProviders">
<logicalStructureProvider
class="scala.tools.eclipse.debug.model.ScalaLogicalStructureProvider"
modelIdentifier="org.scala-ide.sdt.debug">
</logicalStructureProvider>
- </extension> -->
+ </extension>
</plugin>
View
8 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/ScalaDebugger.scala
@@ -11,6 +11,7 @@ import org.eclipse.ui.ISelectionListener
import model.ScalaThread
import org.eclipse.jface.viewers.IStructuredSelection
import model.ScalaStackFrame
+import scala.tools.eclipse.ScalaPlugin
object ScalaDebugger extends IDebugEventSetListener with ISelectionListener {
@@ -82,9 +83,10 @@ object ScalaDebugger extends IDebugEventSetListener with ISelectionListener {
def init() {
DebugPlugin.getDefault.addDebugEventListener(this)
- // TODO: really ugly. Need to keep track of current selection per window.
- // TODO: disable during headless tests
- //WorkbenchPlugin.getDefault.getWorkbench.getWorkbenchWindows.apply(0).getSelectionService.addSelectionListener("org.eclipse.debug.ui.DebugView", this)
+ if (!ScalaPlugin.plugin.headlessMode) {
+ // TODO: really ugly. Need to keep track of current selection per window.
+ WorkbenchPlugin.getDefault.getWorkbench.getWorkbenchWindows.apply(0).getSelectionService.addSelectionListener("org.eclipse.debug.ui.DebugView", this)
+ }
}
private def javaDebugTargetCreated(target: JDIDebugTarget) {
View
94 ...scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaDebugModelPresentation.scala
@@ -6,6 +6,91 @@ import org.eclipse.debug.ui.{ IValueDetailListener, IDebugUIConstants, IDebugMod
import org.eclipse.ui.ide.IDE
import org.eclipse.ui.part.FileEditorInput
import org.eclipse.ui.{ IFileEditorInput, IEditorInput }
+import com.sun.jdi.Value
+import com.sun.jdi.ArrayReference
+import com.sun.jdi.BooleanValue
+import com.sun.jdi.ByteValue
+import com.sun.jdi.CharValue
+import com.sun.jdi.DoubleValue
+import com.sun.jdi.FloatValue
+import com.sun.jdi.IntegerValue
+import com.sun.jdi.LongValue
+import com.sun.jdi.ShortValue
+import com.sun.jdi.StringReference
+import com.sun.jdi.ObjectReference
+import com.sun.jdi.VoidValue
+import com.sun.jdi.ClassType
+import scala.tools.eclipse.debug.ScalaDebugger
+import org.eclipse.core.runtime.jobs.Job
+import org.eclipse.core.runtime.IProgressMonitor
+import org.eclipse.core.runtime.IStatus
+import org.eclipse.core.runtime.Status
+import scala.tools.eclipse.debug.ScalaDebugPlugin
+
+object ScalaDebugModelPresentation {
+ def computeDetail(value: IValue): String = {
+ value match {
+ case v: ScalaPrimitiveValue =>
+ v.getValueString
+ case v: ScalaStringReference =>
+ v.stringReference.value
+ case v: ScalaNullValue =>
+ "null"
+ case arrayReference: ScalaArrayReference =>
+ computeDetail(arrayReference.arrayReference)
+ case objecReference: ScalaObjectReference =>
+ computeDetail(objecReference.objectReference)
+ case _ =>
+ ???
+ }
+ }
+
+ def computeDetail(arrayReference: ArrayReference): String = {
+ import scala.collection.JavaConverters._
+ arrayReference.getValues.asScala.map(computeDetail(_)).mkString("Array(", ", ", ")")
+ }
+
+ def computeDetail(objectReference: ObjectReference): String = {
+ val method= objectReference.referenceType.asInstanceOf[ClassType].concreteMethodByName("toString", "()Ljava/lang/String;")
+ // TODO: check toString() return null
+ ScalaDebugger.currentThread.invokeMethod(objectReference, method).asInstanceOf[StringReference].value
+ }
+
+ def computeDetail(value: Value): String = {
+ // TODO: some of this is duplicate of ScalaValue#apply()
+ value match {
+ case arrayReference: ArrayReference =>
+ computeDetail(arrayReference)
+ case booleanValue: BooleanValue =>
+ booleanValue.value.toString
+ case byteValue: ByteValue =>
+ byteValue.value.toString
+ case charValue: CharValue =>
+ charValue.value.toString
+ case doubleValue: DoubleValue =>
+ doubleValue.value.toString
+ case floatValue: FloatValue =>
+ floatValue.value.toString
+ case integerValue: IntegerValue =>
+ integerValue.value.toString
+ case longValue: LongValue =>
+ longValue.value.toString
+ case shortValue: ShortValue =>
+ shortValue.value.toString
+ case stringReference: StringReference =>
+ stringReference.value
+ case objectReference: ObjectReference => // include ClassLoaderReference, ClassObjectReference, ThreadGroupReference, ThreadReference
+ computeDetail(objectReference)
+ case null =>
+ // TODO : cache
+ "null"
+ case voidValue: VoidValue =>
+ ??? // TODO: in what cases do we get this value ?
+ case _ =>
+ ???
+ }
+ }
+}
class ScalaDebugModelPresentation extends IDebugModelPresentation {
@@ -19,8 +104,13 @@ class ScalaDebugModelPresentation extends IDebugModelPresentation {
// Members declared in org.eclipse.debug.ui.IDebugModelPresentation
def computeDetail(value: IValue, listener: IValueDetailListener): Unit = {
- // TODO: the real work
- listener.detailComputed(value, null)
+ new Job("Computing Scala debug details") {
+ override def run(progressMonitor: IProgressMonitor): IStatus = {
+ // TODO: support error cases
+ listener.detailComputed(value, ScalaDebugModelPresentation.computeDetail(value))
+ Status.OK_STATUS
+ }
+ }.schedule
}
def getImage(element: Any): org.eclipse.swt.graphics.Image = {
View
8 ...ala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaLogicalStructureProvider.scala
@@ -69,17 +69,15 @@ object ScalaCollectionLogicalStructureType extends ILogicalStructureType {
val manifestObjectEntity = objectReference.virtualMachine.classesByName("scala/reflect/Manifest$").get(0).asInstanceOf[ClassType]
val manifestObjectField = manifestObjectEntity.fieldByName("MODULE$")
val manifestObject = manifestObjectEntity.getValue(manifestObjectField).asInstanceOf[ObjectReference]
- val manifestMethod = manifestObjectEntity.concreteMethodByName("Int", "()Lscala/reflect/AnyValManifest;")
+ val manifestMethod = manifestObjectEntity.concreteMethodByName("Any", "()Lscala/reflect/Manifest;")
- val thread= ScalaDebugger.currentThread.thread
-
- val anyValManifestObject= manifestObject.invokeMethod(thread, manifestMethod, new ArrayList(), 0)
+ val anyValManifestObject= ScalaDebugger.currentThread.invokeMethod(manifestObject, manifestMethod)
val toArrayMethod = objectReference.referenceType.asInstanceOf[ClassType].concreteMethodByName("toArray", "(Lscala/reflect/ClassManifest;)Ljava/lang/Object;")
import scala.collection.JavaConverters._
- ScalaValue(objectReference.invokeMethod(thread, toArrayMethod, List(anyValManifestObject).asJava, 0), scalaValue.getScalaDebugTarget)
+ ScalaValue(ScalaDebugger.currentThread.invokeMethod(objectReference, toArrayMethod, anyValManifestObject), scalaValue.getScalaDebugTarget)
}
def providesLogicalStructure(value: IValue): Boolean = true // TODO: check that as it is created by the provider, it is never used with other values
View
11 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaStackFrame.scala
@@ -16,6 +16,7 @@ import com.sun.jdi.FloatType
import com.sun.jdi.LongType
import com.sun.jdi.ShortType
import com.sun.jdi.ArrayType
+import scala.reflect.NameTransformer
object ScalaStackFrame {
@@ -40,7 +41,7 @@ object ScalaStackFrame {
case arrayType: ArrayType =>
"Array[%s]".format(getSimpleName(arrayType.componentType))
case refType: ReferenceType =>
- refType.name.split('.').last
+ NameTransformer.decode(refType.name.split('.').last)
case _ =>
???
}
@@ -50,12 +51,12 @@ object ScalaStackFrame {
import scala.collection.JavaConverters._
"%s.%s(%s)".format(
getSimpleName(method.declaringType),
- method.name,
+ NameTransformer.decode(method.name),
method.argumentTypes.asScala.map(getSimpleName(_)).mkString(", "))
}
}
-class ScalaStackFrame(val thread: ScalaThread, val stackFrame: StackFrame) extends ScalaDebugElement(thread.getScalaDebugTarget) with IStackFrame {
+class ScalaStackFrame(val thread: ScalaThread, var stackFrame: StackFrame) extends ScalaDebugElement(thread.getScalaDebugTarget) with IStackFrame {
import ScalaStackFrame._
// Members declared in org.eclipse.debug.core.model.IStackFrame
@@ -111,5 +112,9 @@ class ScalaStackFrame(val thread: ScalaThread, val stackFrame: StackFrame) exten
def getMethodFullName(): String = {
getFullName(stackFrame.location.method)
}
+
+ def rebind(newStackFrame: StackFrame) {
+ stackFrame= newStackFrame
+ }
}
View
17 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaThread.scala
@@ -7,6 +7,9 @@ import com.sun.jdi.ThreadReference
import com.sun.jdi.VMDisconnectedException
import com.sun.jdi.ObjectCollectedException
import org.eclipse.debug.core.DebugEvent
+import com.sun.jdi.Value
+import com.sun.jdi.ObjectReference
+import com.sun.jdi.Method
class ScalaThread(target: ScalaDebugTarget, val thread: ThreadReference) extends ScalaDebugElement(target) with IThread {
@@ -99,7 +102,21 @@ class ScalaThread(target: ScalaDebugTarget, val thread: ThreadReference) extends
fireResumeEvent(eventDetail)
}
+ def updateStackFramesAfterInvocation() {
+ import scala.collection.JavaConverters._
+ thread.frames.asScala.iterator.zip(stackFrames.iterator).foreach(
+ v => v._2.rebind(v._1)
+ )
+ }
+
// ----
+ def invokeMethod(objectReference: ObjectReference, method: Method, args: Value*): Value = {
+ import scala.collection.JavaConverters._
+ val result= objectReference.invokeMethod(thread, method, args.asJava, 0)
+ updateStackFramesAfterInvocation()
+ result
+ }
+
}
View
4 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaValue.scala
@@ -60,7 +60,7 @@ class ScalaArrayReference(val arrayReference: ArrayReference, target: ScalaDebug
def getReferenceTypeName(): String = "scala.Array"
def getValueString(): String = "%s(%d) (id=%d)".format(ScalaStackFrame.getSimpleName(arrayReference.referenceType), arrayReference.length, arrayReference.uniqueID) // TODO: need real value
def getVariables(): Array[org.eclipse.debug.core.model.IVariable] = {
- (0 until arrayReference.length).map(new ScalaArrayVariable(_, this)).toArray
+ (0 until arrayReference.length).map(new ScalaArrayElementVariable(_, this)).toArray
}
def hasVariables(): Boolean = arrayReference.length > 0
}
@@ -76,7 +76,7 @@ class ScalaPrimitiveValue(typeName: String, value: String, target: ScalaDebugTar
}
-class ScalaStringReference(stringReference: StringReference, target: ScalaDebugTarget) extends ScalaObjectReference(stringReference, target) {
+class ScalaStringReference(val stringReference: StringReference, target: ScalaDebugTarget) extends ScalaObjectReference(stringReference, target) {
override def getReferenceTypeName() = "java.lang.String"
override def getValueString(): String = """"%s" (id=%d)""".format(stringReference.value, stringReference.uniqueID)
View
4 org.scala-ide.sdt.debug/src/scala/tools/eclipse/debug/model/ScalaVariable.scala
@@ -37,11 +37,11 @@ class ScalaLocalVariable(variable: LocalVariable, stackFrame: ScalaStackFrame) e
def getValue(): org.eclipse.debug.core.model.IValue = ScalaValue(stackFrame.stackFrame.getValue(variable), getScalaDebugTarget)
}
-class ScalaArrayVariable(index: Int, arrayReference: ScalaArrayReference) extends ScalaVariable(arrayReference.getScalaDebugTarget) {
+class ScalaArrayElementVariable(index: Int, arrayReference: ScalaArrayReference) extends ScalaVariable(arrayReference.getScalaDebugTarget) {
// Members declared in org.eclipse.debug.core.model.IVariable
- def getName(): String = index.toString
+ def getName(): String = "(%s)".format(index)
def getReferenceTypeName(): String = arrayReference.arrayReference.referenceType.asInstanceOf[ArrayType].componentTypeName
def getValue(): org.eclipse.debug.core.model.IValue = ScalaValue(arrayReference.arrayReference.getValue(index), getScalaDebugTarget)

0 comments on commit a1a4d8b

Please sign in to comment.