package com.sun.tools.javac.comp;
import org.jmlspecs.openjml.JmlTree;
import org.jmlspecs.openjml.JmlTreeCopier;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.util.Context;
public class JmlDeferredAttr extends DeferredAttr {
public static void preRegister(final Context context) {
context.put(deferredAttrKey, new Context.Factory<DeferredAttr>() {
public DeferredAttr make(Context context) {
return new JmlDeferredAttr(context); // Registers itself on construction
}
});
}
public static DeferredAttr instance(Context context) {
DeferredAttr instance = context.get(deferredAttrKey);
if (instance == null)
instance = new JmlDeferredAttr(context);
return instance;
}
Context context;
private JmlDeferredAttr(Context context) {
super(context);
this.context = context;
}
// Overridden to use a JmlDeferredChecker
@Override
boolean isDeferred(Env<AttrContext> env, JCExpression expr) {
DeferredChecker dc = new JmlDeferredChecker(env);
dc.scan(expr);
return dc.result.isPoly();
}
// Overridden to use a JML copier
protected TreeCopier<Void> makeCopier(TreeMaker make) {
return new JmlTreeCopier(context,JmlTree.Maker.instance(context));
}
class JmlDeferredChecker extends DeferredChecker {
public JmlDeferredChecker(Env<AttrContext> env) {
super(env);
}
// Overridden to handle JML function-like operators
@Override
public void visitApply(JCMethodInvocation tree) {
if (tree.meth != null) super.visitApply(tree);
else result = ArgumentExpressionKind.NO_POLY;
return;
}
// FIXME - motivate this override
protected boolean isSimpleReceiver(JCTree rec) {
if (rec.getTag() == null) return true;
return super.isSimpleReceiver(rec);
}
}
}