/* * This file is part of the OpenJML project. * Author: David R. Cok */ package org.jmlspecs.openjml.ext; import static org.jmlspecs.openjml.JmlTokenKind.ENDJMLCOMMENT; import org.jmlspecs.openjml.JmlTokenKind; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.TypeTag; 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.JmlParser; import com.sun.tools.javac.parser.StatementExtension; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.util.Context; /** 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 ReachableStatement extends StatementExtension { public ReachableStatement(Context context) { super(context); } public static void register(Context context) {} static public JmlTokenKind[] tokens() { return new JmlTokenKind[]{ JmlTokenKind.REACHABLE}; } // allowed forms: // reachable ; // reachable <expr> ; // reachable <expr> : <expr> ; // The first <epxr> is a String literal, used as a message or identifier // FIXME - string literal is not used public JCStatement parse(JmlParser parser) { init(parser); int pp = parser.pos(); int pe = parser.endPos(); JmlTokenKind jt = parser.jmlTokenKind(); int p = scanner.currentPos(); parser.nextToken(); if (parser.token().kind == TokenKind.SEMI) { return jmlF.at(p).JmlExpressionStatement(jt,null,jmlF.Literal(TypeTag.BOOLEAN,1)); } else { JCExpression opt = null; JCExpression e = parser.parseExpression(); if (e == null) return null; if (parser.token().kind == TokenKind.COLON) { opt = parser.parseExpression(); } if (parser.token().ikind == JmlTokenKind.ENDJMLCOMMENT) { parser.jmlwarning(p-2, "jml.missing.semi", jt); } else if (parser.token().kind != TokenKind.SEMI) { parser.jmlerror(p, "jml.missing.semi", jt); } return jmlF.at(p).JmlExpressionStatement(jt,null,e); } } @Override public Type typecheck(JmlAttr attr, JCExpression expr, Env<AttrContext> env) { // TODO Auto-generated method stub return null; } }