package edu.mit.ai.psg.jeva.examples;
import edu.mit.ai.psg.jeva.*;
import edu.mit.ai.psg.strings.*;
import java.util.*;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Modifier;
@author
public class TraceMethods {
public static void traceSource(PrintWriter iw, IJevaNode node,
Object evalHookdata) {
String nodeString = Indent.trimNewlines(node.printToString());
iw.println(Indent.unindent(Indent.leadingWhitespace(nodeString),
nodeString));
}
public static void traceFreeNames(PrintWriter iw, IJevaNode node,
Object evalHookData) {
Collection freeNames = FreeSimpleNamesCollector.collect(node);
if (freeNames.size() > 0) {
IEnv env = ((EvalMethods.EvalHookData)evalHookData).getEnv();
SortedMap map = new TreeMap();
for (Iterator iter = freeNames.iterator(); iter.hasNext(); ) {
JNName freeNameNode = (JNName) iter.next();
try{ map.put(freeNameNode.getSimpleName(),
resultString(freeNameNode.eval(env)));}
catch (Throwable e) {
map.put(freeNameNode.printToString(false), "?"); } }
iw.println(Prettify.string(map.toString()));
}
}
public static void traceApplications(PrintWriter pw, IJevaNode node,
Object preApplyData) {
if (preApplyData instanceof EvalMethods.PreApplyData) {
Object[] values = ((EvalMethods.PreApplyData)preApplyData).getValues();
StringWriter sw = new StringWriter();
PrintWriter bufw = new PrintWriter(sw);
int valNum = 0;
Token tok = node.getBeginToken();
printSubstitutingExpressions(bufw, node, tok, values, valNum);
bufw.flush(); sw.flush();
String nodeString = Indent.trimNewlines(sw.toString());
pw.println(Indent.unindent(Indent.leadingWhitespace(nodeString),
nodeString));
}
}
public static void tracePostData(PrintWriter pw, IJevaNode node,
Object evalHookPostData) {
if (evalHookPostData instanceof EvalMethods.ResultData) {
pw.println(resultString( ((EvalMethods.ResultData)
evalHookPostData).getResult() ));
} else if (evalHookPostData instanceof EvalMethods.ResultEnvData) {
pw.println();
} else if (evalHookPostData instanceof EvalMethods.ResultStoreData) {
IStore store =((EvalMethods.ResultStoreData)evalHookPostData).getStore();
pw.println(resultString(store));
} else if (evalHookPostData instanceof EvalMethods.AbruptData) {
AbruptCompletionException thrown =
((EvalMethods.AbruptData)evalHookPostData).getThrown();
if (thrown instanceof ReturnException) {
pw.print("return ");
PrintWriter iiw = new IndentWriter(pw, " ");
pw.println(Stringify.printToString
( ((ReturnException)thrown).getValue() ));
} else if (thrown instanceof ThrowException) {
pw.print("throw ");
PrintWriter iw = new IndentWriter(pw, " ");
iw.println(Stringify.printToString
( ((ThrowException)thrown).getThrown() ));
} else if (thrown instanceof BreakException) {
pw.println("break "+((BreakException)thrown).getLabel());
} else if (thrown instanceof ContinueException) {
pw.println("continue "+((ContinueException)thrown).getLabel());
} else {
pw.println("<<unrecogized AbruptCompletion>>");
}
} else pw.println();
}
{@link #collect(IJevaNode)}
public static class FreeSimpleNamesCollector extends JevaVisitorBase {
public static Collection collect(IJevaNode node) {
FreeSimpleNamesCollector collector = new FreeSimpleNamesCollector();
node.jjtAccept(collector, null);
return collector.freeNamesSet;
}
public static class NameEnv {
String name;
NameEnv next;
NameEnv(String name, NameEnv next) { this.name = name; this.next = next;}
static boolean isDefinedName(String name, NameEnv env) {
for (; env != null; env = env.next)
if (env.name.equals(name)) return true;
return false;
}
static String printToString(NameEnv env) {
StringBuffer buf = new StringBuffer("{");
for (; env != null; env = env.next)
buf.append(env.name + (env.next != null ? ", " : ""));
return buf+"}";
}
}
Set freeNamesSet = new HashSet();
FreeSimpleNamesCollector() {}
public Object visit(IJevaNode node, Object data) {
for (int i = 0; i < node.jjtGetNumChildren(); i++)
data = node.jnGetChild(i).jjtAccept(this, data);
return data;
}
public Object visit(IDeclarationNode node, Object data) {
return data;
}
public Object visit(IClassBodyDeclaration node, Object data) {
return data;
}
public Object visit(JNType node, Object data) {
return data;
}
public Object visit(JNName node, Object data) {
if (node.jjtGetNumChildren() == 0 &&
!(node.jjtGetParent() instanceof JNName)) {
String simpleName = node.getSimpleName();
if (! NameEnv.isDefinedName(simpleName, (NameEnv) data)) {
freeNamesSet.add(node);
}
return data;
} else return visit( (IJevaNode)node, data);
}
public Object visit(JNEMethodInvocationExpression node, Object data) {
IExpressionNode target = node.getTargetExpression();
if (target == null ||
Modifier.isStatic(node.getMethodSignature().getModifiers()))
return node.getArgumentExpressions().jjtAccept(this, data);
else return ((IJevaVisitor)this).visit( (IExpressionNode) node, data);
}
public Object visit(JNSVariableDeclarator node, Object data){
data = new NameEnv(node.getName(), (NameEnv) data);
if (node.getInitializer() != null)
return node.getInitializer().jjtAccept(this, data);
else return data;
}
public Object visit(JNSBlock node, Object data){
visit( (IJevaNode) node, data);
return data; }
}
public static int resultStringLengthLimit = 3;
public static int resultStringDepthLimit = 2;
public static String resultString(Object result) {
if (result instanceof IStore) {
String typeName = result.getClass().getName();
return "<"+typeName.substring(typeName.lastIndexOf('.')+1)+">";
} else {
return
Prettify.string(0, Stringify.printToString(resultStringLengthLimit,
result),
Prettify.widthLimit, resultStringDepthLimit,
resultStringLengthLimit, Prettify.shorterNotFaster,
Prettify.defaultSyntax);
}
}
public static int
printSubstitutingExpressions(PrintWriter pw, IJevaNode node,
Token fromToken, Object[] values, int valNum){
try {
if (node instanceof JNEAssignmentExpression) {
pw.print(resultString( (IStore) values[valNum++]));
pw.print(" = ");
pw.print(resultString(values[valNum++]));
String opTokenImage=(((JNEAssignmentExpression)node)
.getAssignmentOperatorNode()
.getBeginToken().image);
if (! "=".equals(opTokenImage)) {
pw.print(" "+opTokenImage.substring(0,1)+" ");
pw.print(resultString(values[valNum++]));
}
} else {
int firstChildNum = 0;
int lastChildNum = node.jjtGetNumChildren() - 1;
if (node instanceof JNEMethodInvocationExpression &&
null != ((JNEMethodInvocationExpression)
node).getTargetExpression() &&
Modifier.isStatic(((JNEMethodInvocationExpression) node)
.getMethodSignature().getModifiers()))
firstChildNum++;
for(int childNum= firstChildNum; childNum <= lastChildNum; childNum++){
IJevaNode child = node.jnGetChild(childNum);
if (child instanceof IExpressionNode) {
for(;fromToken != child.getBeginToken(); fromToken= fromToken.next)
JevaNode.printToken(fromToken, pw, true);
JevaNode.printSpecialTokens(fromToken, pw);
pw.print(resultString(values[valNum++]));
fromToken = child.getEndToken();
} else if (child instanceof JNEArguments) {
valNum = printSubstitutingExpressions(pw, child, fromToken, values,
valNum);
fromToken = child.getEndToken();
}
}
for (; fromToken != node.getEndToken(); fromToken = fromToken.next)
JevaNode.printToken(fromToken, pw, true);
}
} catch (Throwable t) { pw.println("<<"+t.getClass().getName()+">>"); }
return valNum;
}
}