/*
* This file is part of the OpenJML project.
* Author: David R. Cok
*/
package org.jmlspecs.openjml.ext;
import org.jmlspecs.openjml.JmlTokenKind;
import org.jmlspecs.openjml.JmlTree.JmlMethodInvocation;
import com.sun.tools.javac.code.JmlTypes;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.JmlAttr;
import com.sun.tools.javac.parser.ExpressionExtension;
import com.sun.tools.javac.parser.JmlParser;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer;
/** This class handles expression extensions that take an argument list of JCExpressions.
* Even if there are constraints on the number of arguments, it
* is more robust to accept all of them and then issue an error in the typechecker
* if the number of arguments is wrong.
*
* @author David Cok
*
*/// TODO: This extension is inappropriately named at present. However, I expect that this
// extension will be broken into individual extensions when type checking and
// RAC and ESC translation are added.
public class Erasure extends ExpressionExtension {
protected JmlTypes jmltypes;
public Erasure(Context context) {
super(context);
this.jmltypes = JmlTypes.instance(context);
}
static public JmlTokenKind[] tokens() { return new JmlTokenKind[]{JmlTokenKind.BSERASURE}; }
@Override
public void checkParse(JmlParser parser, JmlMethodInvocation e) {
checkOneArg(parser,e);
}
public Type typecheck(JmlAttr attr, JCExpression expr, Env<AttrContext> localEnv) {
JmlMethodInvocation tree = (JmlMethodInvocation)expr;
JmlTokenKind token = tree.token;
// Expect one argument of any array type, result type is \TYPE
// The argument expression may contain JML constructs
int n = tree.args.size();
if (n != 1) {
error(tree.pos(),"jml.wrong.number.args",token.internedName(),1,n);
} else {
JCExpression e = tree.args.get(0);
if (e instanceof JmlMethodInvocation && ((JmlMethodInvocation)e).token == JmlTokenKind.BSTYPELC) {
((JmlMethodInvocation)e).javaType = true;
}
}
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
attr.attribArgs(tree.args, localEnv, argtypesBuf);
//attr.attribTypes(tree.typeargs, localEnv);
Type t = syms.errType;
if (n > 0) {
Type tt = tree.args.get(0).type;
if (tt == jmltypes.TYPE || tt == syms.classType) t = syms.classType;
}
return t;
}
}