package edu.mit.ai.psg.traveler.jevaHooks;
import edu.mit.ai.psg.jeva.*;
import edu.mit.ai.psg.traveler.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
@see@see@author
public class TraceCallsEvalHook extends JevaVisitorBase {
public TraceCallsEvalHook() {}
public Object visit(IJevaNode node, Object data) {
return null; }
{@link Trace#invoking}{@link Trace#returning}{@link Trace#throwing}{@link Trace#synchronizing}{@link #visit(JNSBlock, Object)}
public Object visit(JNEMethodInvocationExpression node, Object data) {
if (data instanceof EvalMethods.PreApplyData) {
Object[] values = ((EvalMethods.PreApplyData)data).getValues();
IMethod iMethodSignature = node.getMethodSignature();
Method methodSignature =
(iMethodSignature instanceof WrappedMethod ?
((WrappedMethod)iMethodSignature).getWrappedMethod() :
((InterpretedMethod)iMethodSignature).getProxyMethod());
if (Modifier.isStatic(methodSignature.getModifiers())) {
Trace.invokingStatic(methodSignature, values);
} else {
Object target = values[0];
Object[] argValues = new Object[values.length - 1];
System.arraycopy(values, 1, argValues, 0, argValues.length);
Trace.invoking(target, methodSignature, argValues);
if (target instanceof Thread &&
"start".equals(methodSignature.getName()) &&
0 == argValues.length) {
Trace.starting((Thread)target);
}
}
} else if (data instanceof EvalMethods.EvalHookPostData &&
Trace.getCurrentRecord() instanceof CallRecord) {
if (data instanceof EvalMethods.ResultData) {
CallRecord record = (CallRecord) Trace.getCurrentRecord();
if (record.getMember() instanceof Method &&
void.class.equals( ((Method)record.getMember()).getReturnType() ))
Trace.returningVoid(record);
else
Trace.returning(record, ((EvalMethods.ResultData)data).getResult());
} else if (data instanceof EvalMethods.AbruptData) {
Trace.throwing((CallRecord) Trace.getCurrentRecord(),
((EvalMethods.AbruptData)data).getThrown());
}
}
return null;
}
{@link Trace#invoking}{@link Trace#returning}{@link Trace#throwing}
public Object visit(JNEInstanceCreationExpression node, Object data) {
if (data instanceof EvalMethods.PreApplyData) {
Object[] values = ((EvalMethods.PreApplyData)data).getValues();
IConstructor iConstructor = node.getConstructor();
Constructor constructor =
(iConstructor instanceof WrappedConstructor ?
((WrappedConstructor)iConstructor).getWrappedConstructor() :
((InterpretedConstructor)iConstructor).getProxyConstructor());
Trace.invokingStatic(constructor, values);
} else if (data instanceof EvalMethods.EvalHookPostData &&
Trace.getCurrentRecord() instanceof CallRecord) {
if (data instanceof EvalMethods.ResultData) {
CallRecord record = (CallRecord) Trace.getCurrentRecord();
Trace.returning(record, ((EvalMethods.ResultData)data).getResult());
} else if (data instanceof EvalMethods.AbruptData) {
Trace.throwing((CallRecord) Trace.getCurrentRecord(),
((EvalMethods.AbruptData)data).getThrown());
}
}
return null;
}
@see
public Object visit(JNSSynchronizedStatement node, Object data) {
if (data instanceof EvalMethods.PreApplyData) {
Object[] values = ((EvalMethods.PreApplyData)data).getValues();
Node parent = node.jjtGetParent();
while (parent != null &&
! (parent instanceof JNDMethodDeclaration) &&
! (parent instanceof JNDConstructorDeclaration))
parent = parent.jjtGetParent();
Member member =
(parent instanceof JNDMethodDeclaration ?
(Member) ((JNDMethodDeclaration)parent).getMethod().getProxyMethod() :
parent instanceof JNDConstructorDeclaration ?
(Member) ((JNDConstructorDeclaration)
parent).getConstructor().getProxyConstructor() : null );
ActivityRecord record =
new SynchronizedRecordDefault(values[0], member);
Trace.entering(record);
} else if (data instanceof EvalMethods.EvalHookPostData) {
Trace.exiting(Trace.getCurrentRecord());
}
return null;
}
public Object visit(JNSBlock node, Object data) {
boolean parentIsSynchronized = false;
if (node.jjtGetParent() instanceof JNDMethodDeclaration) {
JNDMethodDeclaration methodDecl =
(JNDMethodDeclaration) node.jjtGetParent();
if (data instanceof EvalMethods.PreEvalData) {
InterpretedMethod method = methodDecl.getMethod();
if (Modifier.isSynchronized(method.getModifiers()))
parentIsSynchronized = true;
}
} else if (node.jjtGetParent() instanceof JNSSynchronizedStatement) {
parentIsSynchronized = true;
}
if (parentIsSynchronized) {
ActivityRecord record = Trace.getCurrentRecord();
if (record.isSynchronized())
Trace.synchronizing(record); }
return null;
}
@see
public static void main(String[] arguments) throws FileNotFoundException {
if (arguments.length == 0) {
System.err.println
("Use: java edu.mit.ai.psg.traveler.jeva.TraceCallsEvalHook "+
"ClassName [args]");
System.exit(1);
}
String className = arguments[0];
String[] programArguments = new String[arguments.length - 1];
System.arraycopy(arguments,1, programArguments,0, programArguments.length);
ActivityRecord record = Trace.entering(new StringRecord("TracingCalls"));
EvalMethods.setEvalHook(new TraceCallsEvalHook());
try { CompileUnit.setTempRoot(new File("./proxies")); Jeva.runClass(className, programArguments);
}
catch (ThrowException e) { } catch (ParseException e) { System.err.println(e); return; }
catch (ClassNotFoundException e) { System.err.println(e); return; }
catch (Throwable e) { e.printStackTrace(); return; }
TravelerOutliner.ensureInitialized();
java.awt.Window frame =
TravelerOutliner.makeFrame("Recording. (close this window to exit)",
TravelerOutliner.makeOutlineNode(record));
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0); }});
frame.show();
}
}