Skip to content

Commit

Permalink
add convenience methods for field access and modification handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jfager committed Jan 3, 2011
1 parent 215868e commit df13337
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 18 deletions.
36 changes: 19 additions & 17 deletions src/example/groovy/org/jdiscript/example/HelloWorldExample.groovy
Expand Up @@ -11,29 +11,31 @@ import com.sun.jdi.VirtualMachine;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.StepRequest

// The HelloWorld java example code prints out "Hello, <someone>" twice
// for 3 different values of <someone>. This scripts changes the second
// printout for each to "Hello, Groovy".

String OPTIONS = """
-cp ./target/classes/
-cp ../../../build/jdiscript.jar
"""
String MAIN = "org.jdiscript.example.HelloWorld"
VirtualMachine vm = new VMLauncher(OPTIONS, MAIN).start()

JDIScript j = new JDIScript(vm);
j.run({
j.classPrepareRequest({
def field = it.referenceType().fieldByName("helloTo")
j.accessWatchpointRequest(field, {
def obj = it.object()
j.stepRequest(it.thread(),
StepRequest.STEP_MIN,
StepRequest.STEP_OVER, {
StringReference alttobe = it.virtualMachine().mirrorOf("Groovy")
it.request().disable()
obj.setValue(field, alttobe)
} as OnStep).enable()
} as OnAccessWatchpoint).enable()
} as OnClassPrepare).addClassFilter("org.jdiscript.example.HelloWorld")
.enable()
} as OnVMStart)

j.onFieldAccess("org.jdiscript.example.HelloWorld", "helloTo", {
def obj = it.object()
def field = it.field()
j.stepRequest(it.thread(),
StepRequest.STEP_MIN,
StepRequest.STEP_OVER, {
StringReference alttobe = j.vm().mirrorOf("Groovy")
it.request().disable()
obj.setValue(field, alttobe)
} as OnStep).enable()
} as OnAccessWatchpoint)

j.run()



Expand Down
71 changes: 70 additions & 1 deletion src/main/java/org/jdiscript/JDIScript.java
Expand Up @@ -11,7 +11,7 @@
import org.jdiscript.requests.*;

import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

/**
Expand All @@ -33,6 +33,10 @@
* Runs the associated VM by setting up and starting the jdiscript
* {@link DebugEventDispatcher} and {@link EventThread}.
* </li>
* <li>
* Provides convenience methods for specifying handlers for field
* access and modification.
* </li>
* </ul>
*/
public class JDIScript {
Expand Down Expand Up @@ -539,4 +543,69 @@ public void printTrace(LocatableEvent event, String msg, PrintStream ps) {
"could not retrieve frames **");
}
}

/**
* Shortcut for the common pattern of responding to field accesses.
* <p>
* Builds a {@link ClassPrepareRequest}, filters it for the given
* class name, and adds an {@link OnClassPrepare} handler that
* creates an {@link AccessWatchpointRequest} for the given field name.
* Any field accesses are in turn handled by the given handler.
* <p>
* TODO: what should this return?
*
* @param className A class name suitable for use by
* {@link ClassPrepareRequest#addClassFilter(String)}
* @param fieldName A field name suitable for use by
* {@link ReferenceType#fieldByName(String)}. Must be
* a field belonging to all classes matched by className.
* @param handler The callback to execute when the field is accessed.
*/
public void onFieldAccess(final String className,
final String fieldName,
final OnAccessWatchpoint handler) {
classPrepareRequest()
.addClassFilter(className)
.addHandler(new OnClassPrepare() {
public void classPrepare(ClassPrepareEvent ev) {
Field field = ev.referenceType().fieldByName(fieldName);
accessWatchpointRequest(field, handler)
.enable();
}
})
.enable();
}

/**
* Shortcut for the common pattern of responding to field modifications.
* <p>
* Builds a {@link ClassPrepareRequest}, filters it for the given
* class name, and adds an {@link OnClassPrepare} handler that
* creates a {@link ModificationWatchpointRequest} for the given field name.
* Any field modifications are in turn handled by the given handler.
* <p>
* TODO: what should this return?
*
* @param className A class name suitable for use by
* {@link ClassPrepareRequest#addClassFilter(String)}
* @param fieldName A field name suitable for use by
* {@link ReferenceType#fieldByName(String)}. Must be
* a field belonging to all classes matched by className.
* @param handler The callback to execute when the field is modified.
*/
public void onFieldModification(final String className,
final String fieldName,
final OnModificationWatchpoint handler) {
classPrepareRequest()
.addClassFilter(className)
.addHandler(new OnClassPrepare() {
public void classPrepare(ClassPrepareEvent ev) {
Field field = ev.referenceType().fieldByName(fieldName);
modificationWatchpointRequest(field, handler)
.enable();
}
})
.enable();
}

}

0 comments on commit df13337

Please sign in to comment.