Fri, 12 Sep 2008 23:32:51 -0700
Merge
1.1 --- a/src/share/classes/com/sun/source/util/Trees.java Fri Sep 12 14:35:51 2008 -0700 1.2 +++ b/src/share/classes/com/sun/source/util/Trees.java Fri Sep 12 23:32:51 2008 -0700 1.3 @@ -33,6 +33,7 @@ 1.4 import javax.lang.model.element.ExecutableElement; 1.5 import javax.lang.model.element.TypeElement; 1.6 import javax.lang.model.type.DeclaredType; 1.7 +import javax.lang.model.type.ErrorType; 1.8 import javax.lang.model.type.TypeMirror; 1.9 import javax.tools.JavaCompiler.CompilationTask; 1.10 1.11 @@ -177,4 +178,11 @@ 1.12 * @return true if {@code member} is accessible in {@code type} 1.13 */ 1.14 public abstract boolean isAccessible(Scope scope, Element member, DeclaredType type); 1.15 + 1.16 + /** 1.17 + * Gets the original type from the ErrorType object. 1.18 + * @param errorType The errorType for which we want to get the original type. 1.19 + * @returns javax.lang.model.type.TypeMirror corresponding to the original type, replaced by the ErrorType. 1.20 + */ 1.21 + public abstract TypeMirror getOriginalType(ErrorType errorType); 1.22 }
2.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Sep 12 14:35:51 2008 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Sep 12 23:32:51 2008 -0700 2.3 @@ -27,6 +27,7 @@ 2.4 2.5 import java.io.File; 2.6 import java.io.IOException; 2.7 +import java.nio.CharBuffer; 2.8 import java.util.*; 2.9 import java.util.concurrent.atomic.AtomicBoolean; 2.10 2.11 @@ -45,7 +46,7 @@ 2.12 import com.sun.tools.javac.main.*; 2.13 import com.sun.tools.javac.model.*; 2.14 import com.sun.tools.javac.parser.Parser; 2.15 -import com.sun.tools.javac.parser.Scanner; 2.16 +import com.sun.tools.javac.parser.ParserFactory; 2.17 import com.sun.tools.javac.tree.*; 2.18 import com.sun.tools.javac.tree.JCTree.*; 2.19 import com.sun.tools.javac.util.*; 2.20 @@ -93,6 +94,9 @@ 2.21 args.getClass(); 2.22 context.getClass(); 2.23 fileObjects.getClass(); 2.24 + 2.25 + // force the use of the scanner that captures Javadoc comments 2.26 + com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context); 2.27 } 2.28 2.29 JavacTaskImpl(JavacTool tool, 2.30 @@ -166,8 +170,6 @@ 2.31 if (!filenames.isEmpty()) 2.32 throw new IllegalArgumentException("Malformed arguments " + filenames.toString(" ")); 2.33 compiler = JavaCompiler.instance(context); 2.34 - // force the use of the scanner that captures Javadoc comments 2.35 - com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context); 2.36 compiler.keepComments = true; 2.37 compiler.genEndPos = true; 2.38 // NOTE: this value will be updated after annotation processing 2.39 @@ -519,14 +521,12 @@ 2.40 throw new IllegalArgumentException(); 2.41 compiler = JavaCompiler.instance(context); 2.42 JavaFileObject prev = compiler.log.useSource(null); 2.43 - Scanner.Factory scannerFactory = Scanner.Factory.instance(context); 2.44 - Parser.Factory parserFactory = Parser.Factory.instance(context); 2.45 + ParserFactory parserFactory = ParserFactory.instance(context); 2.46 Attr attr = Attr.instance(context); 2.47 try { 2.48 - Scanner scanner = scannerFactory.newScanner((expr+"\u0000").toCharArray(), 2.49 - expr.length()); 2.50 - Parser parser = parserFactory.newParser(scanner, false, false); 2.51 - JCTree tree = parser.type(); 2.52 + CharBuffer buf = CharBuffer.wrap((expr+"\u0000").toCharArray(), 0, expr.length()); 2.53 + Parser parser = parserFactory.newParser(buf, false, false, false); 2.54 + JCTree tree = parser.parseType(); 2.55 return attr.attribType(tree, (Symbol.TypeSymbol)scope); 2.56 } finally { 2.57 compiler.log.useSource(prev);
3.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Sep 12 14:35:51 2008 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Sep 12 23:32:51 2008 -0700 3.3 @@ -322,4 +322,18 @@ 3.4 return t2; 3.5 } 3.6 } 3.7 + 3.8 + /** 3.9 + * Gets the original type from the ErrorType object. 3.10 + * @param errorType The errorType for which we want to get the original type. 3.11 + * @returns TypeMirror corresponding to the original type, replaced by the ErrorType. 3.12 + * noType (type.tag == NONE) is returned if there is no original type. 3.13 + */ 3.14 + public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) { 3.15 + if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) { 3.16 + return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType(); 3.17 + } 3.18 + 3.19 + return com.sun.tools.javac.code.Type.noType; 3.20 + } 3.21 }
4.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 12 14:35:51 2008 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 12 23:32:51 2008 -0700 4.3 @@ -776,7 +776,7 @@ 4.4 } catch (CompletionFailure ex) { 4.5 // quiet error recovery 4.6 flags_field |= (PUBLIC|STATIC); 4.7 - this.type = new ErrorType(this); 4.8 + this.type = new ErrorType(this, Type.noType); 4.9 throw ex; 4.10 } 4.11 }
5.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Sep 12 14:35:51 2008 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Sep 12 23:32:51 2008 -0700 5.3 @@ -93,8 +93,7 @@ 5.4 */ 5.5 public final ClassSymbol errSymbol; 5.6 5.7 - /** An instance of the error type. 5.8 - */ 5.9 + /** A value for the errType, with a originalType of noType */ 5.10 public final Type errType; 5.11 5.12 /** A value for the unknown type. */ 5.13 @@ -348,7 +347,7 @@ 5.14 5.15 // create the error symbols 5.16 errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); 5.17 - errType = new ErrorType(errSymbol); 5.18 + errType = new ErrorType(errSymbol, Type.noType); 5.19 5.20 // initialize builtin types 5.21 initType(byteType, "byte", "Byte"); 5.22 @@ -389,6 +388,9 @@ 5.23 scope.enter(booleanType.tsym); 5.24 scope.enter(errType.tsym); 5.25 5.26 + // Enter symbol for the errSymbol 5.27 + scope.enter(errSymbol); 5.28 + 5.29 classes.put(predefClass.fullname, predefClass); 5.30 5.31 reader = ClassReader.instance(context);
6.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java Fri Sep 12 14:35:51 2008 -0700 6.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Fri Sep 12 23:32:51 2008 -0700 6.3 @@ -1194,21 +1194,24 @@ 6.4 public static class ErrorType extends ClassType 6.5 implements javax.lang.model.type.ErrorType { 6.6 6.7 - public ErrorType() { 6.8 + private Type originalType = null; 6.9 + 6.10 + public ErrorType(Type originalType, TypeSymbol tsym) { 6.11 super(noType, List.<Type>nil(), null); 6.12 tag = ERROR; 6.13 + this.tsym = tsym; 6.14 + this.originalType = (originalType == null ? noType : originalType); 6.15 } 6.16 6.17 - public ErrorType(ClassSymbol c) { 6.18 - this(); 6.19 - tsym = c; 6.20 + public ErrorType(ClassSymbol c, Type originalType) { 6.21 + this(originalType, c); 6.22 c.type = this; 6.23 c.kind = ERR; 6.24 c.members_field = new Scope.ErrorScope(c); 6.25 } 6.26 6.27 - public ErrorType(Name name, TypeSymbol container) { 6.28 - this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container)); 6.29 + public ErrorType(Name name, TypeSymbol container, Type originalType) { 6.30 + this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType); 6.31 } 6.32 6.33 @Override 6.34 @@ -1234,6 +1237,10 @@ 6.35 return TypeKind.ERROR; 6.36 } 6.37 6.38 + public Type getOriginalType() { 6.39 + return originalType; 6.40 + } 6.41 + 6.42 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 6.43 return v.visitError(this, p); 6.44 }
7.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 12 14:35:51 2008 -0700 7.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 12 23:32:51 2008 -0700 7.3 @@ -2187,6 +2187,20 @@ 7.4 }; 7.5 // </editor-fold> 7.6 7.7 + // <editor-fold defaultstate="collapsed" desc="createErrorType"> 7.8 + public Type createErrorType(Type originalType) { 7.9 + return new ErrorType(originalType, syms.errSymbol); 7.10 + } 7.11 + 7.12 + public Type createErrorType(ClassSymbol c, Type originalType) { 7.13 + return new ErrorType(c, originalType); 7.14 + } 7.15 + 7.16 + public Type createErrorType(Name name, TypeSymbol container, Type originalType) { 7.17 + return new ErrorType(name, container, originalType); 7.18 + } 7.19 + // </editor-fold> 7.20 + 7.21 // <editor-fold defaultstate="collapsed" desc="rank"> 7.22 /** 7.23 * The rank of a class is the length of the longest path between 7.24 @@ -2604,7 +2618,7 @@ 7.25 if (!bound.isInterface()) 7.26 classCount++; 7.27 if (classCount > 1) 7.28 - return syms.errType; 7.29 + return createErrorType(t); 7.30 } 7.31 return makeCompoundType(bounds); 7.32 }
8.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 12 14:35:51 2008 -0700 8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 12 23:32:51 2008 -0700 8.3 @@ -159,7 +159,7 @@ 8.4 * If check succeeds, store type in tree and return it. 8.5 * If check fails, store errType in tree and return it. 8.6 * No checks are performed if the prototype is a method type. 8.7 - * Its not necessary in this case since we know that kind and type 8.8 + * It is not necessary in this case since we know that kind and type 8.9 * are correct. 8.10 * 8.11 * @param tree The tree whose kind and type is checked 8.12 @@ -176,7 +176,7 @@ 8.13 log.error(tree.pos(), "unexpected.type", 8.14 kindNames(pkind), 8.15 kindName(ownkind)); 8.16 - owntype = syms.errType; 8.17 + owntype = types.createErrorType(owntype); 8.18 } 8.19 } 8.20 tree.type = owntype; 8.21 @@ -524,7 +524,7 @@ 8.22 // check that type variable is already visible 8.23 if (t.getUpperBound() == null) { 8.24 log.error(tree.pos(), "illegal.forward.ref"); 8.25 - return syms.errType; 8.26 + return types.createErrorType(t); 8.27 } 8.28 } else { 8.29 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); 8.30 @@ -533,12 +533,12 @@ 8.31 log.error(tree.pos(), "intf.expected.here"); 8.32 // return errType is necessary since otherwise there might 8.33 // be undetected cycles which cause attribution to loop 8.34 - return syms.errType; 8.35 + return types.createErrorType(t); 8.36 } else if (checkExtensible && 8.37 classExpected && 8.38 (t.tsym.flags() & INTERFACE) != 0) { 8.39 log.error(tree.pos(), "no.intf.expected.here"); 8.40 - return syms.errType; 8.41 + return types.createErrorType(t); 8.42 } 8.43 if (checkExtensible && 8.44 ((t.tsym.flags() & FINAL) != 0)) { 8.45 @@ -804,7 +804,7 @@ 8.46 Type base = types.asSuper(exprType, syms.iterableType.tsym); 8.47 if (base == null) { 8.48 log.error(tree.expr.pos(), "foreach.not.applicable.to.type"); 8.49 - elemtype = syms.errType; 8.50 + elemtype = types.createErrorType(exprType); 8.51 } else { 8.52 List<Type> iterableParams = base.allparams(); 8.53 elemtype = iterableParams.isEmpty() 8.54 @@ -1219,7 +1219,7 @@ 8.55 if (methName == names._super) { 8.56 if (site == syms.objectType) { 8.57 log.error(tree.meth.pos(), "no.superclass", site); 8.58 - site = syms.errType; 8.59 + site = types.createErrorType(syms.objectType); 8.60 } else { 8.61 site = types.supertype(site); 8.62 } 8.63 @@ -1351,7 +1351,7 @@ 8.64 } 8.65 8.66 public void visitNewClass(JCNewClass tree) { 8.67 - Type owntype = syms.errType; 8.68 + Type owntype = types.createErrorType(tree.type); 8.69 8.70 // The local environment of a class creation is 8.71 // a new environment nested in the current one. 8.72 @@ -1551,7 +1551,7 @@ 8.73 } 8.74 8.75 public void visitNewArray(JCNewArray tree) { 8.76 - Type owntype = syms.errType; 8.77 + Type owntype = types.createErrorType(tree.type); 8.78 Type elemtype; 8.79 if (tree.elemtype != null) { 8.80 elemtype = attribType(tree.elemtype, env); 8.81 @@ -1571,7 +1571,7 @@ 8.82 log.error(tree.pos(), "illegal.initializer.for.type", 8.83 pt); 8.84 } 8.85 - elemtype = syms.errType; 8.86 + elemtype = types.createErrorType(pt); 8.87 } 8.88 } 8.89 if (tree.elems != null) { 8.90 @@ -1631,7 +1631,7 @@ 8.91 Symbol operator = tree.operator = 8.92 rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype); 8.93 8.94 - Type owntype = syms.errType; 8.95 + Type owntype = types.createErrorType(tree.type); 8.96 if (operator.kind == MTH) { 8.97 owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) 8.98 ? tree.arg.type 8.99 @@ -1667,7 +1667,7 @@ 8.100 Symbol operator = tree.operator = 8.101 rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right); 8.102 8.103 - Type owntype = syms.errType; 8.104 + Type owntype = types.createErrorType(tree.type); 8.105 if (operator.kind == MTH) { 8.106 owntype = operator.type.getReturnType(); 8.107 int opc = chk.checkOperator(tree.lhs.pos(), 8.108 @@ -1728,7 +1728,7 @@ 8.109 } 8.110 8.111 public void visitIndexed(JCArrayAccess tree) { 8.112 - Type owntype = syms.errType; 8.113 + Type owntype = types.createErrorType(tree.type); 8.114 Type atype = attribExpr(tree.indexed, env); 8.115 attribExpr(tree.index, env, syms.intType); 8.116 if (types.isArray(atype)) 8.117 @@ -1849,7 +1849,7 @@ 8.118 elt = ((ArrayType)elt).elemtype; 8.119 if (elt.tag == TYPEVAR) { 8.120 log.error(tree.pos(), "type.var.cant.be.deref"); 8.121 - result = syms.errType; 8.122 + result = types.createErrorType(tree.type); 8.123 return; 8.124 } 8.125 } 8.126 @@ -2009,7 +2009,7 @@ 8.127 } 8.128 case ERROR: 8.129 // preserve identifier names through errors 8.130 - return new ErrorType(name, site.tsym).tsym; 8.131 + return types.createErrorType(name, site.tsym, site).tsym; 8.132 default: 8.133 // The qualifier expression is of a primitive type -- only 8.134 // .class is allowed for these. 8.135 @@ -2059,7 +2059,7 @@ 8.136 int pkind, 8.137 Type pt, 8.138 boolean useVarargs) { 8.139 - if (pt.isErroneous()) return syms.errType; 8.140 + if (pt.isErroneous()) return types.createErrorType(site); 8.141 Type owntype; // The computed type of this identifier occurrence. 8.142 switch (sym.kind) { 8.143 case TYP: 8.144 @@ -2129,7 +2129,7 @@ 8.145 for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail) 8.146 if (!owntype.contains(l.head)) { 8.147 log.error(tree.pos(), "undetermined.type", owntype1); 8.148 - owntype1 = syms.errType; 8.149 + owntype1 = types.createErrorType(owntype1); 8.150 } 8.151 owntype = owntype1; 8.152 } 8.153 @@ -2332,7 +2332,7 @@ 8.154 "internal.error.cant.instantiate", 8.155 sym, site, 8.156 Type.toString(pt.getParameterTypes())); 8.157 - owntype = syms.errType; 8.158 + owntype = types.createErrorType(site); 8.159 } else { 8.160 // System.out.println("call : " + env.tree); 8.161 // System.out.println("method : " + owntype); 8.162 @@ -2454,7 +2454,7 @@ 8.163 * before supertype structure is completely known 8.164 */ 8.165 public void visitTypeApply(JCTypeApply tree) { 8.166 - Type owntype = syms.errType; 8.167 + Type owntype = types.createErrorType(tree.type); 8.168 8.169 // Attribute functor part of application and make sure it's a class. 8.170 Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env)); 8.171 @@ -2498,7 +2498,7 @@ 8.172 } else { 8.173 log.error(tree.pos(), "type.doesnt.take.params", clazztype.tsym); 8.174 } 8.175 - owntype = syms.errType; 8.176 + owntype = types.createErrorType(tree.type); 8.177 } 8.178 } 8.179 result = check(tree, owntype, TYP, pkind, pt);
9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 12 14:35:51 2008 -0700 9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 12 23:32:51 2008 -0700 9.3 @@ -192,12 +192,12 @@ 9.4 Type typeError(DiagnosticPosition pos, Object problem, Type found, Type req) { 9.5 log.error(pos, "prob.found.req", 9.6 problem, found, req); 9.7 - return syms.errType; 9.8 + return types.createErrorType(found); 9.9 } 9.10 9.11 Type typeError(DiagnosticPosition pos, String problem, Type found, Type req, Object explanation) { 9.12 log.error(pos, "prob.found.req.1", problem, found, req, explanation); 9.13 - return syms.errType; 9.14 + return types.createErrorType(found); 9.15 } 9.16 9.17 /** Report an error that wrong type tag was found. 9.18 @@ -208,7 +208,7 @@ 9.19 */ 9.20 Type typeTagError(DiagnosticPosition pos, Object required, Object found) { 9.21 log.error(pos, "type.found.req", found, required); 9.22 - return syms.errType; 9.23 + return types.createErrorType(found instanceof Type ? (Type)found : syms.errType); 9.24 } 9.25 9.26 /** Report an error that symbol cannot be referenced before super 9.27 @@ -348,11 +348,11 @@ 9.28 return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req); 9.29 if (found.isSuperBound()) { 9.30 log.error(pos, "assignment.from.super-bound", found); 9.31 - return syms.errType; 9.32 + return types.createErrorType(found); 9.33 } 9.34 if (req.isExtendsBound()) { 9.35 log.error(pos, "assignment.to.extends-bound", req); 9.36 - return syms.errType; 9.37 + return types.createErrorType(found); 9.38 } 9.39 return typeError(pos, diags.fragment("incompatible.types"), found, req); 9.40 } 9.41 @@ -378,7 +378,7 @@ 9.42 log.error(pos, 9.43 "undetermined.type" + (d!=null ? ".1" : ""), 9.44 t, d); 9.45 - return syms.errType; 9.46 + return types.createErrorType(pt); 9.47 } else { 9.48 JCDiagnostic d = ex.getDiagnostic(); 9.49 return typeError(pos, 9.50 @@ -469,7 +469,7 @@ 9.51 Type checkNonVoid(DiagnosticPosition pos, Type t) { 9.52 if (t.tag == VOID) { 9.53 log.error(pos, "void.not.allowed.here"); 9.54 - return syms.errType; 9.55 + return types.createErrorType(t); 9.56 } else { 9.57 return t; 9.58 } 9.59 @@ -521,7 +521,7 @@ 9.60 t); 9.61 } else if (!types.isReifiable(t)) { 9.62 log.error(pos, "illegal.generic.type.for.instof"); 9.63 - return syms.errType; 9.64 + return types.createErrorType(t); 9.65 } else { 9.66 return t; 9.67 } 9.68 @@ -1542,7 +1542,7 @@ 9.69 return; 9.70 if (seen.contains(t)) { 9.71 tv = (TypeVar)t; 9.72 - tv.bound = new ErrorType(); 9.73 + tv.bound = types.createErrorType(t); 9.74 log.error(pos, "cyclic.inheritance", t); 9.75 } else if (t.tag == TYPEVAR) { 9.76 tv = (TypeVar)t; 9.77 @@ -1597,11 +1597,11 @@ 9.78 private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) { 9.79 log.error(pos, "cyclic.inheritance", c); 9.80 for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail) 9.81 - l.head = new ErrorType((ClassSymbol)l.head.tsym); 9.82 + l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType); 9.83 Type st = types.supertype(c.type); 9.84 if (st.tag == CLASS) 9.85 - ((ClassType)c.type).supertype_field = new ErrorType((ClassSymbol)st.tsym); 9.86 - c.type = new ErrorType(c); 9.87 + ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType); 9.88 + c.type = types.createErrorType(c, c.type); 9.89 c.flags_field |= ACYCLIC; 9.90 } 9.91
10.1 --- a/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Sep 12 14:35:51 2008 -0700 10.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Sep 12 23:32:51 2008 -0700 10.3 @@ -98,6 +98,7 @@ 10.4 ClassReader reader; 10.5 Annotate annotate; 10.6 MemberEnter memberEnter; 10.7 + Types types; 10.8 Lint lint; 10.9 JavaFileManager fileManager; 10.10 10.11 @@ -119,6 +120,7 @@ 10.12 syms = Symtab.instance(context); 10.13 chk = Check.instance(context); 10.14 memberEnter = MemberEnter.instance(context); 10.15 + types = Types.instance(context); 10.16 annotate = Annotate.instance(context); 10.17 lint = Lint.instance(context); 10.18 10.19 @@ -355,7 +357,7 @@ 10.20 // Enter class into `compiled' table and enclosing scope. 10.21 if (chk.compiled.get(c.flatname) != null) { 10.22 duplicateClass(tree.pos(), c); 10.23 - result = new ErrorType(tree.name, (TypeSymbol)owner); 10.24 + result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType); 10.25 tree.sym = (ClassSymbol)result.tsym; 10.26 return; 10.27 }
11.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 12 14:35:51 2008 -0700 11.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 12 23:32:51 2008 -0700 11.3 @@ -204,7 +204,7 @@ 11.4 return true; 11.5 } 11.6 11.7 - /** Instaniate undetermined type variable to the lub of all its lower bounds. 11.8 + /** Instantiate undetermined type variable to the lub of all its lower bounds. 11.9 * Throw a NoInstanceException if this not possible. 11.10 */ 11.11 void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException { 11.12 @@ -216,7 +216,7 @@ 11.13 else { 11.14 that.inst = types.lub(that.lobounds); 11.15 } 11.16 - if (that.inst == null || that.inst == syms.errType) 11.17 + if (that.inst == null || that.inst.tag == ERROR) 11.18 throw ambiguousNoInstanceException 11.19 .setMessage("no.unique.minimal.instance.exists", 11.20 that.qtype, that.lobounds);
12.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 12 14:35:51 2008 -0700 12.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 12 23:32:51 2008 -0700 12.3 @@ -656,7 +656,7 @@ 12.4 return new AmbiguityError(m1, m2); 12.5 // both abstract, neither overridden; merge throws clause and result type 12.6 Symbol result; 12.7 - Type result2 = mt2.getReturnType();; 12.8 + Type result2 = mt2.getReturnType(); 12.9 if (mt2.tag == FORALL) 12.10 result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); 12.11 if (types.isSubtype(mt1.getReturnType(), result2)) { 12.12 @@ -1099,7 +1099,7 @@ 12.13 if (sym == syms.errSymbol // preserve the symbol name through errors 12.14 || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned 12.15 && (sym.kind & TYP) != 0)) 12.16 - sym = new ErrorType(name, qualified?site.tsym:syms.noSymbol).tsym; 12.17 + sym = types.createErrorType(name, qualified ? site.tsym : syms.noSymbol, sym.type).tsym; 12.18 } 12.19 return sym; 12.20 }
13.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Sep 12 14:35:51 2008 -0700 13.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Sep 12 23:32:51 2008 -0700 13.3 @@ -276,7 +276,7 @@ 13.4 13.5 /** Factory for parsers. 13.6 */ 13.7 - protected Parser.Factory parserFactory; 13.8 + protected ParserFactory parserFactory; 13.9 13.10 /** Optional listener for progress events 13.11 */ 13.12 @@ -320,7 +320,7 @@ 13.13 todo = Todo.instance(context); 13.14 13.15 fileManager = context.get(JavaFileManager.class); 13.16 - parserFactory = Parser.Factory.instance(context); 13.17 + parserFactory = ParserFactory.instance(context); 13.18 13.19 try { 13.20 // catch completion problems with predefineds 13.21 @@ -510,10 +510,6 @@ 13.22 return parseErrors; 13.23 } 13.24 13.25 - protected Scanner.Factory getScannerFactory() { 13.26 - return Scanner.Factory.instance(context); 13.27 - } 13.28 - 13.29 /** Try to open input stream with given name. 13.30 * Report an error if this fails. 13.31 * @param filename The file name of the input stream to be opened. 13.32 @@ -545,13 +541,9 @@ 13.33 taskListener.started(e); 13.34 } 13.35 int initialErrorCount = log.nerrors; 13.36 - Scanner scanner = getScannerFactory().newScanner(content); 13.37 - Parser parser = parserFactory.newParser(scanner, keepComments(), genEndPos); 13.38 - tree = parser.compilationUnit(); 13.39 + Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo); 13.40 + tree = parser.parseCompilationUnit(); 13.41 parseErrors |= (log.nerrors > initialErrorCount); 13.42 - if (lineDebugInfo) { 13.43 - tree.lineMap = scanner.getLineMap(); 13.44 - } 13.45 if (verbose) { 13.46 printVerbose("parsing.done", Long.toString(elapsed(msec))); 13.47 }
14.1 --- a/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java Fri Sep 12 14:35:51 2008 -0700 14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java Fri Sep 12 23:32:51 2008 -0700 14.3 @@ -41,10 +41,10 @@ 14.4 * This code and its internal interfaces are subject to change or 14.5 * deletion without notice.</b></p> 14.6 */ 14.7 -public class EndPosParser extends Parser { 14.8 +public class EndPosParser extends JavacParser { 14.9 14.10 - public EndPosParser(Factory fac, Lexer S, boolean keepDocComments) { 14.11 - super(fac, S, keepDocComments); 14.12 + public EndPosParser(ParserFactory fac, Lexer S, boolean keepDocComments, boolean keepLineMap) { 14.13 + super(fac, S, keepDocComments, keepLineMap); 14.14 this.S = S; 14.15 endPositions = new HashMap<JCTree,Integer>(); 14.16 } 14.17 @@ -79,8 +79,8 @@ 14.18 } 14.19 14.20 @Override 14.21 - public JCCompilationUnit compilationUnit() { 14.22 - JCCompilationUnit t = super.compilationUnit(); 14.23 + public JCCompilationUnit parseCompilationUnit() { 14.24 + JCCompilationUnit t = super.parseCompilationUnit(); 14.25 t.endPositions = endPositions; 14.26 return t; 14.27 }
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Sep 12 23:32:51 2008 -0700 15.3 @@ -0,0 +1,2819 @@ 15.4 +/* 15.5 + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. 15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.7 + * 15.8 + * This code is free software; you can redistribute it and/or modify it 15.9 + * under the terms of the GNU General Public License version 2 only, as 15.10 + * published by the Free Software Foundation. Sun designates this 15.11 + * particular file as subject to the "Classpath" exception as provided 15.12 + * by Sun in the LICENSE file that accompanied this code. 15.13 + * 15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.17 + * version 2 for more details (a copy is included in the LICENSE file that 15.18 + * accompanied this code). 15.19 + * 15.20 + * You should have received a copy of the GNU General Public License version 15.21 + * 2 along with this work; if not, write to the Free Software Foundation, 15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.23 + * 15.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 15.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 15.26 + * have any questions. 15.27 + */ 15.28 + 15.29 +package com.sun.tools.javac.parser; 15.30 + 15.31 +import java.util.*; 15.32 + 15.33 +import com.sun.tools.javac.tree.*; 15.34 +import com.sun.tools.javac.code.*; 15.35 +import com.sun.tools.javac.util.*; 15.36 +import com.sun.tools.javac.util.List; 15.37 +import static com.sun.tools.javac.util.ListBuffer.lb; 15.38 + 15.39 +import com.sun.tools.javac.tree.JCTree.*; 15.40 + 15.41 +import static com.sun.tools.javac.parser.Token.*; 15.42 + 15.43 +/** The parser maps a token sequence into an abstract syntax 15.44 + * tree. It operates by recursive descent, with code derived 15.45 + * systematically from an LL(1) grammar. For efficiency reasons, an 15.46 + * operator precedence scheme is used for parsing binary operation 15.47 + * expressions. 15.48 + * 15.49 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 15.50 + * you write code that depends on this, you do so at your own risk. 15.51 + * This code and its internal interfaces are subject to change or 15.52 + * deletion without notice.</b> 15.53 + */ 15.54 +public class JavacParser implements Parser { 15.55 + 15.56 + /** The number of precedence levels of infix operators. 15.57 + */ 15.58 + private static final int infixPrecedenceLevels = 10; 15.59 + 15.60 + /** The scanner used for lexical analysis. 15.61 + */ 15.62 + private Lexer S; 15.63 + 15.64 + /** The factory to be used for abstract syntax tree construction. 15.65 + */ 15.66 + protected TreeMaker F; 15.67 + 15.68 + /** The log to be used for error diagnostics. 15.69 + */ 15.70 + private Log log; 15.71 + 15.72 + /** The keyword table. */ 15.73 + private Keywords keywords; 15.74 + 15.75 + /** The Source language setting. */ 15.76 + private Source source; 15.77 + 15.78 + /** The name table. */ 15.79 + private Name.Table names; 15.80 + 15.81 + /** Construct a parser from a given scanner, tree factory and log. 15.82 + */ 15.83 + protected JavacParser(ParserFactory fac, 15.84 + Lexer S, 15.85 + boolean keepDocComments, 15.86 + boolean keepLineMap) { 15.87 + this.S = S; 15.88 + S.nextToken(); // prime the pump 15.89 + this.F = fac.F; 15.90 + this.log = fac.log; 15.91 + this.names = fac.names; 15.92 + this.keywords = fac.keywords; 15.93 + this.source = fac.source; 15.94 + this.allowGenerics = source.allowGenerics(); 15.95 + this.allowVarargs = source.allowVarargs(); 15.96 + this.allowAsserts = source.allowAsserts(); 15.97 + this.allowEnums = source.allowEnums(); 15.98 + this.allowForeach = source.allowForeach(); 15.99 + this.allowStaticImport = source.allowStaticImport(); 15.100 + this.allowAnnotations = source.allowAnnotations(); 15.101 + this.keepDocComments = keepDocComments; 15.102 + if (keepDocComments) 15.103 + docComments = new HashMap<JCTree,String>(); 15.104 + this.keepLineMap = keepLineMap; 15.105 + this.errorTree = F.Erroneous(); 15.106 + } 15.107 + 15.108 + /** Switch: Should generics be recognized? 15.109 + */ 15.110 + boolean allowGenerics; 15.111 + 15.112 + /** Switch: Should varargs be recognized? 15.113 + */ 15.114 + boolean allowVarargs; 15.115 + 15.116 + /** Switch: should we recognize assert statements, or just give a warning? 15.117 + */ 15.118 + boolean allowAsserts; 15.119 + 15.120 + /** Switch: should we recognize enums, or just give a warning? 15.121 + */ 15.122 + boolean allowEnums; 15.123 + 15.124 + /** Switch: should we recognize foreach? 15.125 + */ 15.126 + boolean allowForeach; 15.127 + 15.128 + /** Switch: should we recognize foreach? 15.129 + */ 15.130 + boolean allowStaticImport; 15.131 + 15.132 + /** Switch: should we recognize annotations? 15.133 + */ 15.134 + boolean allowAnnotations; 15.135 + 15.136 + /** Switch: should we keep docComments? 15.137 + */ 15.138 + boolean keepDocComments; 15.139 + 15.140 + /** Switch: should we keep line table? 15.141 + */ 15.142 + boolean keepLineMap; 15.143 + 15.144 + /** When terms are parsed, the mode determines which is expected: 15.145 + * mode = EXPR : an expression 15.146 + * mode = TYPE : a type 15.147 + * mode = NOPARAMS : no parameters allowed for type 15.148 + * mode = TYPEARG : type argument 15.149 + */ 15.150 + static final int EXPR = 1; 15.151 + static final int TYPE = 2; 15.152 + static final int NOPARAMS = 4; 15.153 + static final int TYPEARG = 8; 15.154 + 15.155 + /** The current mode. 15.156 + */ 15.157 + private int mode = 0; 15.158 + 15.159 + /** The mode of the term that was parsed last. 15.160 + */ 15.161 + private int lastmode = 0; 15.162 + 15.163 +/* ---------- error recovery -------------- */ 15.164 + 15.165 + private JCErroneous errorTree; 15.166 + 15.167 + /** Skip forward until a suitable stop token is found. 15.168 + */ 15.169 + private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 15.170 + while (true) { 15.171 + switch (S.token()) { 15.172 + case SEMI: 15.173 + S.nextToken(); 15.174 + return; 15.175 + case PUBLIC: 15.176 + case FINAL: 15.177 + case ABSTRACT: 15.178 + case MONKEYS_AT: 15.179 + case EOF: 15.180 + case CLASS: 15.181 + case INTERFACE: 15.182 + case ENUM: 15.183 + return; 15.184 + case IMPORT: 15.185 + if (stopAtImport) 15.186 + return; 15.187 + break; 15.188 + case LBRACE: 15.189 + case RBRACE: 15.190 + case PRIVATE: 15.191 + case PROTECTED: 15.192 + case STATIC: 15.193 + case TRANSIENT: 15.194 + case NATIVE: 15.195 + case VOLATILE: 15.196 + case SYNCHRONIZED: 15.197 + case STRICTFP: 15.198 + case LT: 15.199 + case BYTE: 15.200 + case SHORT: 15.201 + case CHAR: 15.202 + case INT: 15.203 + case LONG: 15.204 + case FLOAT: 15.205 + case DOUBLE: 15.206 + case BOOLEAN: 15.207 + case VOID: 15.208 + if (stopAtMemberDecl) 15.209 + return; 15.210 + break; 15.211 + case IDENTIFIER: 15.212 + if (stopAtIdentifier) 15.213 + return; 15.214 + break; 15.215 + case CASE: 15.216 + case DEFAULT: 15.217 + case IF: 15.218 + case FOR: 15.219 + case WHILE: 15.220 + case DO: 15.221 + case TRY: 15.222 + case SWITCH: 15.223 + case RETURN: 15.224 + case THROW: 15.225 + case BREAK: 15.226 + case CONTINUE: 15.227 + case ELSE: 15.228 + case FINALLY: 15.229 + case CATCH: 15.230 + if (stopAtStatement) 15.231 + return; 15.232 + break; 15.233 + } 15.234 + S.nextToken(); 15.235 + } 15.236 + } 15.237 + 15.238 + private JCErroneous syntaxError(int pos, String key, Token... args) { 15.239 + return syntaxError(pos, null, key, args); 15.240 + } 15.241 + 15.242 + private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) { 15.243 + setErrorEndPos(pos); 15.244 + reportSyntaxError(pos, key, (Object[])args); 15.245 + return toP(F.at(pos).Erroneous(errs)); 15.246 + } 15.247 + 15.248 + private int errorPos = Position.NOPOS; 15.249 + /** 15.250 + * Report a syntax error at given position using the given 15.251 + * argument unless one was already reported at the same position. 15.252 + */ 15.253 + private void reportSyntaxError(int pos, String key, Object... args) { 15.254 + if (pos > S.errPos() || pos == Position.NOPOS) { 15.255 + if (S.token() == EOF) 15.256 + log.error(pos, "premature.eof"); 15.257 + else 15.258 + log.error(pos, key, args); 15.259 + } 15.260 + S.errPos(pos); 15.261 + if (S.pos() == errorPos) 15.262 + S.nextToken(); // guarantee progress 15.263 + errorPos = S.pos(); 15.264 + } 15.265 + 15.266 + 15.267 + /** Generate a syntax error at current position unless one was already 15.268 + * reported at the same position. 15.269 + */ 15.270 + private JCErroneous syntaxError(String key) { 15.271 + return syntaxError(S.pos(), key); 15.272 + } 15.273 + 15.274 + /** Generate a syntax error at current position unless one was 15.275 + * already reported at the same position. 15.276 + */ 15.277 + private JCErroneous syntaxError(String key, Token arg) { 15.278 + return syntaxError(S.pos(), key, arg); 15.279 + } 15.280 + 15.281 + /** If next input token matches given token, skip it, otherwise report 15.282 + * an error. 15.283 + */ 15.284 + public void accept(Token token) { 15.285 + if (S.token() == token) { 15.286 + S.nextToken(); 15.287 + } else { 15.288 + setErrorEndPos(S.pos()); 15.289 + reportSyntaxError(S.prevEndPos(), "expected", token); 15.290 + } 15.291 + } 15.292 + 15.293 + /** Report an illegal start of expression/type error at given position. 15.294 + */ 15.295 + JCExpression illegal(int pos) { 15.296 + setErrorEndPos(S.pos()); 15.297 + if ((mode & EXPR) != 0) 15.298 + return syntaxError(pos, "illegal.start.of.expr"); 15.299 + else 15.300 + return syntaxError(pos, "illegal.start.of.type"); 15.301 + 15.302 + } 15.303 + 15.304 + /** Report an illegal start of expression/type error at current position. 15.305 + */ 15.306 + JCExpression illegal() { 15.307 + return illegal(S.pos()); 15.308 + } 15.309 + 15.310 + /** Diagnose a modifier flag from the set, if any. */ 15.311 + void checkNoMods(long mods) { 15.312 + if (mods != 0) { 15.313 + long lowestMod = mods & -mods; 15.314 + log.error(S.pos(), "mod.not.allowed.here", 15.315 + Flags.asFlagSet(lowestMod)); 15.316 + } 15.317 + } 15.318 + 15.319 +/* ---------- doc comments --------- */ 15.320 + 15.321 + /** A hashtable to store all documentation comments 15.322 + * indexed by the tree nodes they refer to. 15.323 + * defined only if option flag keepDocComment is set. 15.324 + */ 15.325 + Map<JCTree, String> docComments; 15.326 + 15.327 + /** Make an entry into docComments hashtable, 15.328 + * provided flag keepDocComments is set and given doc comment is non-null. 15.329 + * @param tree The tree to be used as index in the hashtable 15.330 + * @param dc The doc comment to associate with the tree, or null. 15.331 + */ 15.332 + void attach(JCTree tree, String dc) { 15.333 + if (keepDocComments && dc != null) { 15.334 +// System.out.println("doc comment = ");System.out.println(dc);//DEBUG 15.335 + docComments.put(tree, dc); 15.336 + } 15.337 + } 15.338 + 15.339 +/* -------- source positions ------- */ 15.340 + 15.341 + private int errorEndPos = -1; 15.342 + 15.343 + private void setErrorEndPos(int errPos) { 15.344 + if (errPos > errorEndPos) 15.345 + errorEndPos = errPos; 15.346 + } 15.347 + 15.348 + protected int getErrorEndPos() { 15.349 + return errorEndPos; 15.350 + } 15.351 + 15.352 + /** 15.353 + * Store ending position for a tree. 15.354 + * @param tree The tree. 15.355 + * @param endpos The ending position to associate with the tree. 15.356 + */ 15.357 + protected void storeEnd(JCTree tree, int endpos) {} 15.358 + 15.359 + /** 15.360 + * Store ending position for a tree. The ending position should 15.361 + * be the ending position of the current token. 15.362 + * @param t The tree. 15.363 + */ 15.364 + protected <T extends JCTree> T to(T t) { return t; } 15.365 + 15.366 + /** 15.367 + * Store ending position for a tree. The ending position should 15.368 + * be greater of the ending position of the previous token and errorEndPos. 15.369 + * @param t The tree. 15.370 + */ 15.371 + protected <T extends JCTree> T toP(T t) { return t; } 15.372 + 15.373 + /** Get the start position for a tree node. The start position is 15.374 + * defined to be the position of the first character of the first 15.375 + * token of the node's source text. 15.376 + * @param tree The tree node 15.377 + */ 15.378 + public int getStartPos(JCTree tree) { 15.379 + return TreeInfo.getStartPos(tree); 15.380 + } 15.381 + 15.382 + /** 15.383 + * Get the end position for a tree node. The end position is 15.384 + * defined to be the position of the last character of the last 15.385 + * token of the node's source text. Returns Position.NOPOS if end 15.386 + * positions are not generated or the position is otherwise not 15.387 + * found. 15.388 + * @param tree The tree node 15.389 + */ 15.390 + public int getEndPos(JCTree tree) { 15.391 + return Position.NOPOS; 15.392 + } 15.393 + 15.394 + 15.395 + 15.396 +/* ---------- parsing -------------- */ 15.397 + 15.398 + /** 15.399 + * Ident = IDENTIFIER 15.400 + */ 15.401 + Name ident() { 15.402 + if (S.token() == IDENTIFIER) { 15.403 + Name name = S.name(); 15.404 + S.nextToken(); 15.405 + return name; 15.406 + } else if (S.token() == ASSERT) { 15.407 + if (allowAsserts) { 15.408 + log.error(S.pos(), "assert.as.identifier"); 15.409 + S.nextToken(); 15.410 + return names.error; 15.411 + } else { 15.412 + log.warning(S.pos(), "assert.as.identifier"); 15.413 + Name name = S.name(); 15.414 + S.nextToken(); 15.415 + return name; 15.416 + } 15.417 + } else if (S.token() == ENUM) { 15.418 + if (allowEnums) { 15.419 + log.error(S.pos(), "enum.as.identifier"); 15.420 + S.nextToken(); 15.421 + return names.error; 15.422 + } else { 15.423 + log.warning(S.pos(), "enum.as.identifier"); 15.424 + Name name = S.name(); 15.425 + S.nextToken(); 15.426 + return name; 15.427 + } 15.428 + } else { 15.429 + accept(IDENTIFIER); 15.430 + return names.error; 15.431 + } 15.432 +} 15.433 + 15.434 + /** 15.435 + * Qualident = Ident { DOT Ident } 15.436 + */ 15.437 + public JCExpression qualident() { 15.438 + JCExpression t = toP(F.at(S.pos()).Ident(ident())); 15.439 + while (S.token() == DOT) { 15.440 + int pos = S.pos(); 15.441 + S.nextToken(); 15.442 + t = toP(F.at(pos).Select(t, ident())); 15.443 + } 15.444 + return t; 15.445 + } 15.446 + 15.447 + /** 15.448 + * Literal = 15.449 + * INTLITERAL 15.450 + * | LONGLITERAL 15.451 + * | FLOATLITERAL 15.452 + * | DOUBLELITERAL 15.453 + * | CHARLITERAL 15.454 + * | STRINGLITERAL 15.455 + * | TRUE 15.456 + * | FALSE 15.457 + * | NULL 15.458 + */ 15.459 + JCExpression literal(Name prefix) { 15.460 + int pos = S.pos(); 15.461 + JCExpression t = errorTree; 15.462 + switch (S.token()) { 15.463 + case INTLITERAL: 15.464 + try { 15.465 + t = F.at(pos).Literal( 15.466 + TypeTags.INT, 15.467 + Convert.string2int(strval(prefix), S.radix())); 15.468 + } catch (NumberFormatException ex) { 15.469 + log.error(S.pos(), "int.number.too.large", strval(prefix)); 15.470 + } 15.471 + break; 15.472 + case LONGLITERAL: 15.473 + try { 15.474 + t = F.at(pos).Literal( 15.475 + TypeTags.LONG, 15.476 + new Long(Convert.string2long(strval(prefix), S.radix()))); 15.477 + } catch (NumberFormatException ex) { 15.478 + log.error(S.pos(), "int.number.too.large", strval(prefix)); 15.479 + } 15.480 + break; 15.481 + case FLOATLITERAL: { 15.482 + String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 15.483 + Float n; 15.484 + try { 15.485 + n = Float.valueOf(proper); 15.486 + } catch (NumberFormatException ex) { 15.487 + // error already repoted in scanner 15.488 + n = Float.NaN; 15.489 + } 15.490 + if (n.floatValue() == 0.0f && !isZero(proper)) 15.491 + log.error(S.pos(), "fp.number.too.small"); 15.492 + else if (n.floatValue() == Float.POSITIVE_INFINITY) 15.493 + log.error(S.pos(), "fp.number.too.large"); 15.494 + else 15.495 + t = F.at(pos).Literal(TypeTags.FLOAT, n); 15.496 + break; 15.497 + } 15.498 + case DOUBLELITERAL: { 15.499 + String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 15.500 + Double n; 15.501 + try { 15.502 + n = Double.valueOf(proper); 15.503 + } catch (NumberFormatException ex) { 15.504 + // error already reported in scanner 15.505 + n = Double.NaN; 15.506 + } 15.507 + if (n.doubleValue() == 0.0d && !isZero(proper)) 15.508 + log.error(S.pos(), "fp.number.too.small"); 15.509 + else if (n.doubleValue() == Double.POSITIVE_INFINITY) 15.510 + log.error(S.pos(), "fp.number.too.large"); 15.511 + else 15.512 + t = F.at(pos).Literal(TypeTags.DOUBLE, n); 15.513 + break; 15.514 + } 15.515 + case CHARLITERAL: 15.516 + t = F.at(pos).Literal( 15.517 + TypeTags.CHAR, 15.518 + S.stringVal().charAt(0) + 0); 15.519 + break; 15.520 + case STRINGLITERAL: 15.521 + t = F.at(pos).Literal( 15.522 + TypeTags.CLASS, 15.523 + S.stringVal()); 15.524 + break; 15.525 + case TRUE: case FALSE: 15.526 + t = F.at(pos).Literal( 15.527 + TypeTags.BOOLEAN, 15.528 + (S.token() == TRUE ? 1 : 0)); 15.529 + break; 15.530 + case NULL: 15.531 + t = F.at(pos).Literal( 15.532 + TypeTags.BOT, 15.533 + null); 15.534 + break; 15.535 + default: 15.536 + assert false; 15.537 + } 15.538 + if (t == errorTree) 15.539 + t = F.at(pos).Erroneous(); 15.540 + storeEnd(t, S.endPos()); 15.541 + S.nextToken(); 15.542 + return t; 15.543 + } 15.544 +//where 15.545 + boolean isZero(String s) { 15.546 + char[] cs = s.toCharArray(); 15.547 + int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10); 15.548 + int i = ((base==16) ? 2 : 0); 15.549 + while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++; 15.550 + return !(i < cs.length && (Character.digit(cs[i], base) > 0)); 15.551 + } 15.552 + 15.553 + String strval(Name prefix) { 15.554 + String s = S.stringVal(); 15.555 + return (prefix.len == 0) ? s : prefix + s; 15.556 + } 15.557 + 15.558 + /** terms can be either expressions or types. 15.559 + */ 15.560 + public JCExpression parseExpression() { 15.561 + return term(EXPR); 15.562 + } 15.563 + 15.564 + public JCExpression parseType() { 15.565 + return term(TYPE); 15.566 + } 15.567 + 15.568 + JCExpression term(int newmode) { 15.569 + int prevmode = mode; 15.570 + mode = newmode; 15.571 + JCExpression t = term(); 15.572 + lastmode = mode; 15.573 + mode = prevmode; 15.574 + return t; 15.575 + } 15.576 + 15.577 + /** 15.578 + * Expression = Expression1 [ExpressionRest] 15.579 + * ExpressionRest = [AssignmentOperator Expression1] 15.580 + * AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | 15.581 + * "&=" | "|=" | "^=" | 15.582 + * "%=" | "<<=" | ">>=" | ">>>=" 15.583 + * Type = Type1 15.584 + * TypeNoParams = TypeNoParams1 15.585 + * StatementExpression = Expression 15.586 + * ConstantExpression = Expression 15.587 + */ 15.588 + JCExpression term() { 15.589 + JCExpression t = term1(); 15.590 + if ((mode & EXPR) != 0 && 15.591 + S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0) 15.592 + return termRest(t); 15.593 + else 15.594 + return t; 15.595 + } 15.596 + 15.597 + JCExpression termRest(JCExpression t) { 15.598 + switch (S.token()) { 15.599 + case EQ: { 15.600 + int pos = S.pos(); 15.601 + S.nextToken(); 15.602 + mode = EXPR; 15.603 + JCExpression t1 = term(); 15.604 + return toP(F.at(pos).Assign(t, t1)); 15.605 + } 15.606 + case PLUSEQ: 15.607 + case SUBEQ: 15.608 + case STAREQ: 15.609 + case SLASHEQ: 15.610 + case PERCENTEQ: 15.611 + case AMPEQ: 15.612 + case BAREQ: 15.613 + case CARETEQ: 15.614 + case LTLTEQ: 15.615 + case GTGTEQ: 15.616 + case GTGTGTEQ: 15.617 + int pos = S.pos(); 15.618 + Token token = S.token(); 15.619 + S.nextToken(); 15.620 + mode = EXPR; 15.621 + JCExpression t1 = term(); 15.622 + return F.at(pos).Assignop(optag(token), t, t1); 15.623 + default: 15.624 + return t; 15.625 + } 15.626 + } 15.627 + 15.628 + /** Expression1 = Expression2 [Expression1Rest] 15.629 + * Type1 = Type2 15.630 + * TypeNoParams1 = TypeNoParams2 15.631 + */ 15.632 + JCExpression term1() { 15.633 + JCExpression t = term2(); 15.634 + if ((mode & EXPR) != 0 && S.token() == QUES) { 15.635 + mode = EXPR; 15.636 + return term1Rest(t); 15.637 + } else { 15.638 + return t; 15.639 + } 15.640 + } 15.641 + 15.642 + /** Expression1Rest = ["?" Expression ":" Expression1] 15.643 + */ 15.644 + JCExpression term1Rest(JCExpression t) { 15.645 + if (S.token() == QUES) { 15.646 + int pos = S.pos(); 15.647 + S.nextToken(); 15.648 + JCExpression t1 = term(); 15.649 + accept(COLON); 15.650 + JCExpression t2 = term1(); 15.651 + return F.at(pos).Conditional(t, t1, t2); 15.652 + } else { 15.653 + return t; 15.654 + } 15.655 + } 15.656 + 15.657 + /** Expression2 = Expression3 [Expression2Rest] 15.658 + * Type2 = Type3 15.659 + * TypeNoParams2 = TypeNoParams3 15.660 + */ 15.661 + JCExpression term2() { 15.662 + JCExpression t = term3(); 15.663 + if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) { 15.664 + mode = EXPR; 15.665 + return term2Rest(t, TreeInfo.orPrec); 15.666 + } else { 15.667 + return t; 15.668 + } 15.669 + } 15.670 + 15.671 + /* Expression2Rest = {infixop Expression3} 15.672 + * | Expression3 instanceof Type 15.673 + * infixop = "||" 15.674 + * | "&&" 15.675 + * | "|" 15.676 + * | "^" 15.677 + * | "&" 15.678 + * | "==" | "!=" 15.679 + * | "<" | ">" | "<=" | ">=" 15.680 + * | "<<" | ">>" | ">>>" 15.681 + * | "+" | "-" 15.682 + * | "*" | "/" | "%" 15.683 + */ 15.684 + JCExpression term2Rest(JCExpression t, int minprec) { 15.685 + List<JCExpression[]> savedOd = odStackSupply.elems; 15.686 + JCExpression[] odStack = newOdStack(); 15.687 + List<Token[]> savedOp = opStackSupply.elems; 15.688 + Token[] opStack = newOpStack(); 15.689 + // optimization, was odStack = new Tree[...]; opStack = new Tree[...]; 15.690 + int top = 0; 15.691 + odStack[0] = t; 15.692 + int startPos = S.pos(); 15.693 + Token topOp = ERROR; 15.694 + while (prec(S.token()) >= minprec) { 15.695 + opStack[top] = topOp; 15.696 + top++; 15.697 + topOp = S.token(); 15.698 + int pos = S.pos(); 15.699 + S.nextToken(); 15.700 + odStack[top] = topOp == INSTANCEOF ? parseType() : term3(); 15.701 + while (top > 0 && prec(topOp) >= prec(S.token())) { 15.702 + odStack[top-1] = makeOp(pos, topOp, odStack[top-1], 15.703 + odStack[top]); 15.704 + top--; 15.705 + topOp = opStack[top]; 15.706 + } 15.707 + } 15.708 + assert top == 0; 15.709 + t = odStack[0]; 15.710 + 15.711 + if (t.getTag() == JCTree.PLUS) { 15.712 + StringBuffer buf = foldStrings(t); 15.713 + if (buf != null) { 15.714 + t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString())); 15.715 + } 15.716 + } 15.717 + 15.718 + odStackSupply.elems = savedOd; // optimization 15.719 + opStackSupply.elems = savedOp; // optimization 15.720 + return t; 15.721 + } 15.722 +//where 15.723 + /** Construct a binary or type test node. 15.724 + */ 15.725 + private JCExpression makeOp(int pos, 15.726 + Token topOp, 15.727 + JCExpression od1, 15.728 + JCExpression od2) 15.729 + { 15.730 + if (topOp == INSTANCEOF) { 15.731 + return F.at(pos).TypeTest(od1, od2); 15.732 + } else { 15.733 + return F.at(pos).Binary(optag(topOp), od1, od2); 15.734 + } 15.735 + } 15.736 + /** If tree is a concatenation of string literals, replace it 15.737 + * by a single literal representing the concatenated string. 15.738 + */ 15.739 + protected StringBuffer foldStrings(JCTree tree) { 15.740 + List<String> buf = List.nil(); 15.741 + while (true) { 15.742 + if (tree.getTag() == JCTree.LITERAL) { 15.743 + JCLiteral lit = (JCLiteral) tree; 15.744 + if (lit.typetag == TypeTags.CLASS) { 15.745 + StringBuffer sbuf = 15.746 + new StringBuffer((String)lit.value); 15.747 + while (buf.nonEmpty()) { 15.748 + sbuf.append(buf.head); 15.749 + buf = buf.tail; 15.750 + } 15.751 + return sbuf; 15.752 + } 15.753 + } else if (tree.getTag() == JCTree.PLUS) { 15.754 + JCBinary op = (JCBinary)tree; 15.755 + if (op.rhs.getTag() == JCTree.LITERAL) { 15.756 + JCLiteral lit = (JCLiteral) op.rhs; 15.757 + if (lit.typetag == TypeTags.CLASS) { 15.758 + buf = buf.prepend((String) lit.value); 15.759 + tree = op.lhs; 15.760 + continue; 15.761 + } 15.762 + } 15.763 + } 15.764 + return null; 15.765 + } 15.766 + } 15.767 + 15.768 + /** optimization: To save allocating a new operand/operator stack 15.769 + * for every binary operation, we use supplys. 15.770 + */ 15.771 + ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>(); 15.772 + ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>(); 15.773 + 15.774 + private JCExpression[] newOdStack() { 15.775 + if (odStackSupply.elems == odStackSupply.last) 15.776 + odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]); 15.777 + JCExpression[] odStack = odStackSupply.elems.head; 15.778 + odStackSupply.elems = odStackSupply.elems.tail; 15.779 + return odStack; 15.780 + } 15.781 + 15.782 + private Token[] newOpStack() { 15.783 + if (opStackSupply.elems == opStackSupply.last) 15.784 + opStackSupply.append(new Token[infixPrecedenceLevels + 1]); 15.785 + Token[] opStack = opStackSupply.elems.head; 15.786 + opStackSupply.elems = opStackSupply.elems.tail; 15.787 + return opStack; 15.788 + } 15.789 + 15.790 + /** Expression3 = PrefixOp Expression3 15.791 + * | "(" Expr | TypeNoParams ")" Expression3 15.792 + * | Primary {Selector} {PostfixOp} 15.793 + * Primary = "(" Expression ")" 15.794 + * | Literal 15.795 + * | [TypeArguments] THIS [Arguments] 15.796 + * | [TypeArguments] SUPER SuperSuffix 15.797 + * | NEW [TypeArguments] Creator 15.798 + * | Ident { "." Ident } 15.799 + * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 15.800 + * | Arguments 15.801 + * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 15.802 + * ] 15.803 + * | BasicType BracketsOpt "." CLASS 15.804 + * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" 15.805 + * PostfixOp = "++" | "--" 15.806 + * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt 15.807 + * | BasicType 15.808 + * TypeNoParams3 = Ident { "." Ident } BracketsOpt 15.809 + * Selector = "." [TypeArguments] Ident [Arguments] 15.810 + * | "." THIS 15.811 + * | "." [TypeArguments] SUPER SuperSuffix 15.812 + * | "." NEW [TypeArguments] InnerCreator 15.813 + * | "[" Expression "]" 15.814 + * TypeSelector = "." Ident [TypeArguments] 15.815 + * SuperSuffix = Arguments | "." Ident [Arguments] 15.816 + */ 15.817 + protected JCExpression term3() { 15.818 + int pos = S.pos(); 15.819 + JCExpression t; 15.820 + List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); 15.821 + switch (S.token()) { 15.822 + case QUES: 15.823 + if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { 15.824 + mode = TYPE; 15.825 + return typeArgument(); 15.826 + } else 15.827 + return illegal(); 15.828 + case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: 15.829 + if (typeArgs == null && (mode & EXPR) != 0) { 15.830 + Token token = S.token(); 15.831 + S.nextToken(); 15.832 + mode = EXPR; 15.833 + if (token == SUB && 15.834 + (S.token() == INTLITERAL || S.token() == LONGLITERAL) && 15.835 + S.radix() == 10) { 15.836 + mode = EXPR; 15.837 + t = literal(names.hyphen); 15.838 + } else { 15.839 + t = term3(); 15.840 + return F.at(pos).Unary(unoptag(token), t); 15.841 + } 15.842 + } else return illegal(); 15.843 + break; 15.844 + case LPAREN: 15.845 + if (typeArgs == null && (mode & EXPR) != 0) { 15.846 + S.nextToken(); 15.847 + mode = EXPR | TYPE | NOPARAMS; 15.848 + t = term3(); 15.849 + if ((mode & TYPE) != 0 && S.token() == LT) { 15.850 + // Could be a cast to a parameterized type 15.851 + int op = JCTree.LT; 15.852 + int pos1 = S.pos(); 15.853 + S.nextToken(); 15.854 + mode &= (EXPR | TYPE); 15.855 + mode |= TYPEARG; 15.856 + JCExpression t1 = term3(); 15.857 + if ((mode & TYPE) != 0 && 15.858 + (S.token() == COMMA || S.token() == GT)) { 15.859 + mode = TYPE; 15.860 + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 15.861 + args.append(t1); 15.862 + while (S.token() == COMMA) { 15.863 + S.nextToken(); 15.864 + args.append(typeArgument()); 15.865 + } 15.866 + accept(GT); 15.867 + t = F.at(pos1).TypeApply(t, args.toList()); 15.868 + checkGenerics(); 15.869 + t = bracketsOpt(toP(t)); 15.870 + } else if ((mode & EXPR) != 0) { 15.871 + mode = EXPR; 15.872 + t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec)); 15.873 + t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 15.874 + } else { 15.875 + accept(GT); 15.876 + } 15.877 + } else { 15.878 + t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 15.879 + } 15.880 + accept(RPAREN); 15.881 + lastmode = mode; 15.882 + mode = EXPR; 15.883 + if ((lastmode & EXPR) == 0) { 15.884 + JCExpression t1 = term3(); 15.885 + return F.at(pos).TypeCast(t, t1); 15.886 + } else if ((lastmode & TYPE) != 0) { 15.887 + switch (S.token()) { 15.888 + /*case PLUSPLUS: case SUBSUB: */ 15.889 + case BANG: case TILDE: 15.890 + case LPAREN: case THIS: case SUPER: 15.891 + case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 15.892 + case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 15.893 + case TRUE: case FALSE: case NULL: 15.894 + case NEW: case IDENTIFIER: case ASSERT: case ENUM: 15.895 + case BYTE: case SHORT: case CHAR: case INT: 15.896 + case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 15.897 + JCExpression t1 = term3(); 15.898 + return F.at(pos).TypeCast(t, t1); 15.899 + } 15.900 + } 15.901 + } else return illegal(); 15.902 + t = toP(F.at(pos).Parens(t)); 15.903 + break; 15.904 + case THIS: 15.905 + if ((mode & EXPR) != 0) { 15.906 + mode = EXPR; 15.907 + t = to(F.at(pos).Ident(names._this)); 15.908 + S.nextToken(); 15.909 + if (typeArgs == null) 15.910 + t = argumentsOpt(null, t); 15.911 + else 15.912 + t = arguments(typeArgs, t); 15.913 + typeArgs = null; 15.914 + } else return illegal(); 15.915 + break; 15.916 + case SUPER: 15.917 + if ((mode & EXPR) != 0) { 15.918 + mode = EXPR; 15.919 + t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super))); 15.920 + typeArgs = null; 15.921 + } else return illegal(); 15.922 + break; 15.923 + case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: 15.924 + case CHARLITERAL: case STRINGLITERAL: 15.925 + case TRUE: case FALSE: case NULL: 15.926 + if (typeArgs == null && (mode & EXPR) != 0) { 15.927 + mode = EXPR; 15.928 + t = literal(names.empty); 15.929 + } else return illegal(); 15.930 + break; 15.931 + case NEW: 15.932 + if (typeArgs != null) return illegal(); 15.933 + if ((mode & EXPR) != 0) { 15.934 + mode = EXPR; 15.935 + S.nextToken(); 15.936 + if (S.token() == LT) typeArgs = typeArguments(); 15.937 + t = creator(pos, typeArgs); 15.938 + typeArgs = null; 15.939 + } else return illegal(); 15.940 + break; 15.941 + case IDENTIFIER: case ASSERT: case ENUM: 15.942 + if (typeArgs != null) return illegal(); 15.943 + t = toP(F.at(S.pos()).Ident(ident())); 15.944 + loop: while (true) { 15.945 + pos = S.pos(); 15.946 + switch (S.token()) { 15.947 + case LBRACKET: 15.948 + S.nextToken(); 15.949 + if (S.token() == RBRACKET) { 15.950 + S.nextToken(); 15.951 + t = bracketsOpt(t); 15.952 + t = toP(F.at(pos).TypeArray(t)); 15.953 + t = bracketsSuffix(t); 15.954 + } else { 15.955 + if ((mode & EXPR) != 0) { 15.956 + mode = EXPR; 15.957 + JCExpression t1 = term(); 15.958 + t = to(F.at(pos).Indexed(t, t1)); 15.959 + } 15.960 + accept(RBRACKET); 15.961 + } 15.962 + break loop; 15.963 + case LPAREN: 15.964 + if ((mode & EXPR) != 0) { 15.965 + mode = EXPR; 15.966 + t = arguments(typeArgs, t); 15.967 + typeArgs = null; 15.968 + } 15.969 + break loop; 15.970 + case DOT: 15.971 + S.nextToken(); 15.972 + int oldmode = mode; 15.973 + mode &= ~NOPARAMS; 15.974 + typeArgs = typeArgumentsOpt(EXPR); 15.975 + mode = oldmode; 15.976 + if ((mode & EXPR) != 0) { 15.977 + switch (S.token()) { 15.978 + case CLASS: 15.979 + if (typeArgs != null) return illegal(); 15.980 + mode = EXPR; 15.981 + t = to(F.at(pos).Select(t, names._class)); 15.982 + S.nextToken(); 15.983 + break loop; 15.984 + case THIS: 15.985 + if (typeArgs != null) return illegal(); 15.986 + mode = EXPR; 15.987 + t = to(F.at(pos).Select(t, names._this)); 15.988 + S.nextToken(); 15.989 + break loop; 15.990 + case SUPER: 15.991 + mode = EXPR; 15.992 + t = to(F.at(pos).Select(t, names._super)); 15.993 + t = superSuffix(typeArgs, t); 15.994 + typeArgs = null; 15.995 + break loop; 15.996 + case NEW: 15.997 + if (typeArgs != null) return illegal(); 15.998 + mode = EXPR; 15.999 + int pos1 = S.pos(); 15.1000 + S.nextToken(); 15.1001 + if (S.token() == LT) typeArgs = typeArguments(); 15.1002 + t = innerCreator(pos1, typeArgs, t); 15.1003 + typeArgs = null; 15.1004 + break loop; 15.1005 + } 15.1006 + } 15.1007 + // typeArgs saved for next loop iteration. 15.1008 + t = toP(F.at(pos).Select(t, ident())); 15.1009 + break; 15.1010 + default: 15.1011 + break loop; 15.1012 + } 15.1013 + } 15.1014 + if (typeArgs != null) illegal(); 15.1015 + t = typeArgumentsOpt(t); 15.1016 + break; 15.1017 + case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 15.1018 + case DOUBLE: case BOOLEAN: 15.1019 + if (typeArgs != null) illegal(); 15.1020 + t = bracketsSuffix(bracketsOpt(basicType())); 15.1021 + break; 15.1022 + case VOID: 15.1023 + if (typeArgs != null) illegal(); 15.1024 + if ((mode & EXPR) != 0) { 15.1025 + S.nextToken(); 15.1026 + if (S.token() == DOT) { 15.1027 + JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); 15.1028 + t = bracketsSuffix(ti); 15.1029 + } else { 15.1030 + return illegal(pos); 15.1031 + } 15.1032 + } else { 15.1033 + return illegal(); 15.1034 + } 15.1035 + break; 15.1036 + default: 15.1037 + return illegal(); 15.1038 + } 15.1039 + if (typeArgs != null) illegal(); 15.1040 + while (true) { 15.1041 + int pos1 = S.pos(); 15.1042 + if (S.token() == LBRACKET) { 15.1043 + S.nextToken(); 15.1044 + if ((mode & TYPE) != 0) { 15.1045 + int oldmode = mode; 15.1046 + mode = TYPE; 15.1047 + if (S.token() == RBRACKET) { 15.1048 + S.nextToken(); 15.1049 + t = bracketsOpt(t); 15.1050 + t = toP(F.at(pos1).TypeArray(t)); 15.1051 + return t; 15.1052 + } 15.1053 + mode = oldmode; 15.1054 + } 15.1055 + if ((mode & EXPR) != 0) { 15.1056 + mode = EXPR; 15.1057 + JCExpression t1 = term(); 15.1058 + t = to(F.at(pos1).Indexed(t, t1)); 15.1059 + } 15.1060 + accept(RBRACKET); 15.1061 + } else if (S.token() == DOT) { 15.1062 + S.nextToken(); 15.1063 + typeArgs = typeArgumentsOpt(EXPR); 15.1064 + if (S.token() == SUPER && (mode & EXPR) != 0) { 15.1065 + mode = EXPR; 15.1066 + t = to(F.at(pos1).Select(t, names._super)); 15.1067 + S.nextToken(); 15.1068 + t = arguments(typeArgs, t); 15.1069 + typeArgs = null; 15.1070 + } else if (S.token() == NEW && (mode & EXPR) != 0) { 15.1071 + if (typeArgs != null) return illegal(); 15.1072 + mode = EXPR; 15.1073 + int pos2 = S.pos(); 15.1074 + S.nextToken(); 15.1075 + if (S.token() == LT) typeArgs = typeArguments(); 15.1076 + t = innerCreator(pos2, typeArgs, t); 15.1077 + typeArgs = null; 15.1078 + } else { 15.1079 + t = toP(F.at(pos1).Select(t, ident())); 15.1080 + t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 15.1081 + typeArgs = null; 15.1082 + } 15.1083 + } else { 15.1084 + break; 15.1085 + } 15.1086 + } 15.1087 + while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 15.1088 + mode = EXPR; 15.1089 + t = to(F.at(S.pos()).Unary( 15.1090 + S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 15.1091 + S.nextToken(); 15.1092 + } 15.1093 + return toP(t); 15.1094 + } 15.1095 + 15.1096 + /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 15.1097 + */ 15.1098 + JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 15.1099 + S.nextToken(); 15.1100 + if (S.token() == LPAREN || typeArgs != null) { 15.1101 + t = arguments(typeArgs, t); 15.1102 + } else { 15.1103 + int pos = S.pos(); 15.1104 + accept(DOT); 15.1105 + typeArgs = (S.token() == LT) ? typeArguments() : null; 15.1106 + t = toP(F.at(pos).Select(t, ident())); 15.1107 + t = argumentsOpt(typeArgs, t); 15.1108 + } 15.1109 + return t; 15.1110 + } 15.1111 + 15.1112 + /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 15.1113 + */ 15.1114 + JCPrimitiveTypeTree basicType() { 15.1115 + JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token()))); 15.1116 + S.nextToken(); 15.1117 + return t; 15.1118 + } 15.1119 + 15.1120 + /** ArgumentsOpt = [ Arguments ] 15.1121 + */ 15.1122 + JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 15.1123 + if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) { 15.1124 + mode = EXPR; 15.1125 + return arguments(typeArgs, t); 15.1126 + } else { 15.1127 + return t; 15.1128 + } 15.1129 + } 15.1130 + 15.1131 + /** Arguments = "(" [Expression { COMMA Expression }] ")" 15.1132 + */ 15.1133 + List<JCExpression> arguments() { 15.1134 + ListBuffer<JCExpression> args = lb(); 15.1135 + if (S.token() == LPAREN) { 15.1136 + S.nextToken(); 15.1137 + if (S.token() != RPAREN) { 15.1138 + args.append(parseExpression()); 15.1139 + while (S.token() == COMMA) { 15.1140 + S.nextToken(); 15.1141 + args.append(parseExpression()); 15.1142 + } 15.1143 + } 15.1144 + accept(RPAREN); 15.1145 + } else { 15.1146 + syntaxError(S.pos(), "expected", LPAREN); 15.1147 + } 15.1148 + return args.toList(); 15.1149 + } 15.1150 + 15.1151 + JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 15.1152 + int pos = S.pos(); 15.1153 + List<JCExpression> args = arguments(); 15.1154 + return toP(F.at(pos).Apply(typeArgs, t, args)); 15.1155 + } 15.1156 + 15.1157 + /** TypeArgumentsOpt = [ TypeArguments ] 15.1158 + */ 15.1159 + JCExpression typeArgumentsOpt(JCExpression t) { 15.1160 + if (S.token() == LT && 15.1161 + (mode & TYPE) != 0 && 15.1162 + (mode & NOPARAMS) == 0) { 15.1163 + mode = TYPE; 15.1164 + checkGenerics(); 15.1165 + return typeArguments(t); 15.1166 + } else { 15.1167 + return t; 15.1168 + } 15.1169 + } 15.1170 + List<JCExpression> typeArgumentsOpt() { 15.1171 + return typeArgumentsOpt(TYPE); 15.1172 + } 15.1173 + 15.1174 + List<JCExpression> typeArgumentsOpt(int useMode) { 15.1175 + if (S.token() == LT) { 15.1176 + checkGenerics(); 15.1177 + if ((mode & useMode) == 0 || 15.1178 + (mode & NOPARAMS) != 0) { 15.1179 + illegal(); 15.1180 + } 15.1181 + mode = useMode; 15.1182 + return typeArguments(); 15.1183 + } 15.1184 + return null; 15.1185 + } 15.1186 + 15.1187 + /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 15.1188 + */ 15.1189 + List<JCExpression> typeArguments() { 15.1190 + ListBuffer<JCExpression> args = lb(); 15.1191 + if (S.token() == LT) { 15.1192 + S.nextToken(); 15.1193 + args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 15.1194 + while (S.token() == COMMA) { 15.1195 + S.nextToken(); 15.1196 + args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 15.1197 + } 15.1198 + switch (S.token()) { 15.1199 + case GTGTGTEQ: 15.1200 + S.token(GTGTEQ); 15.1201 + break; 15.1202 + case GTGTEQ: 15.1203 + S.token(GTEQ); 15.1204 + break; 15.1205 + case GTEQ: 15.1206 + S.token(EQ); 15.1207 + break; 15.1208 + case GTGTGT: 15.1209 + S.token(GTGT); 15.1210 + break; 15.1211 + case GTGT: 15.1212 + S.token(GT); 15.1213 + break; 15.1214 + default: 15.1215 + accept(GT); 15.1216 + break; 15.1217 + } 15.1218 + } else { 15.1219 + syntaxError(S.pos(), "expected", LT); 15.1220 + } 15.1221 + return args.toList(); 15.1222 + } 15.1223 + 15.1224 + /** TypeArgument = Type 15.1225 + * | "?" 15.1226 + * | "?" EXTENDS Type {"&" Type} 15.1227 + * | "?" SUPER Type 15.1228 + */ 15.1229 + JCExpression typeArgument() { 15.1230 + if (S.token() != QUES) return parseType(); 15.1231 + int pos = S.pos(); 15.1232 + S.nextToken(); 15.1233 + if (S.token() == EXTENDS) { 15.1234 + TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS)); 15.1235 + S.nextToken(); 15.1236 + return F.at(pos).Wildcard(t, parseType()); 15.1237 + } else if (S.token() == SUPER) { 15.1238 + TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER)); 15.1239 + S.nextToken(); 15.1240 + return F.at(pos).Wildcard(t, parseType()); 15.1241 + } else if (S.token() == IDENTIFIER) { 15.1242 + //error recovery 15.1243 + reportSyntaxError(S.prevEndPos(), "expected3", 15.1244 + GT, EXTENDS, SUPER); 15.1245 + TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 15.1246 + JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 15.1247 + JCIdent id = toP(F.at(S.pos()).Ident(ident())); 15.1248 + return F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 15.1249 + } else { 15.1250 + TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 15.1251 + return toP(F.at(pos).Wildcard(t, null)); 15.1252 + } 15.1253 + } 15.1254 + 15.1255 + JCTypeApply typeArguments(JCExpression t) { 15.1256 + int pos = S.pos(); 15.1257 + List<JCExpression> args = typeArguments(); 15.1258 + return toP(F.at(pos).TypeApply(t, args)); 15.1259 + } 15.1260 + 15.1261 + /** BracketsOpt = {"[" "]"} 15.1262 + */ 15.1263 + private JCExpression bracketsOpt(JCExpression t) { 15.1264 + if (S.token() == LBRACKET) { 15.1265 + int pos = S.pos(); 15.1266 + S.nextToken(); 15.1267 + t = bracketsOptCont(t, pos); 15.1268 + F.at(pos); 15.1269 + } 15.1270 + return t; 15.1271 + } 15.1272 + 15.1273 + private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) { 15.1274 + accept(RBRACKET); 15.1275 + t = bracketsOpt(t); 15.1276 + return toP(F.at(pos).TypeArray(t)); 15.1277 + } 15.1278 + 15.1279 + /** BracketsSuffixExpr = "." CLASS 15.1280 + * BracketsSuffixType = 15.1281 + */ 15.1282 + JCExpression bracketsSuffix(JCExpression t) { 15.1283 + if ((mode & EXPR) != 0 && S.token() == DOT) { 15.1284 + mode = EXPR; 15.1285 + int pos = S.pos(); 15.1286 + S.nextToken(); 15.1287 + accept(CLASS); 15.1288 + if (S.pos() == errorEndPos) { 15.1289 + // error recovery 15.1290 + Name name = null; 15.1291 + if (S.token() == IDENTIFIER) { 15.1292 + name = S.name(); 15.1293 + S.nextToken(); 15.1294 + } else { 15.1295 + name = names.error; 15.1296 + } 15.1297 + t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name)))); 15.1298 + } else { 15.1299 + t = toP(F.at(pos).Select(t, names._class)); 15.1300 + } 15.1301 + } else if ((mode & TYPE) != 0) { 15.1302 + mode = TYPE; 15.1303 + } else { 15.1304 + syntaxError(S.pos(), "dot.class.expected"); 15.1305 + } 15.1306 + return t; 15.1307 + } 15.1308 + 15.1309 + /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 15.1310 + */ 15.1311 + JCExpression creator(int newpos, List<JCExpression> typeArgs) { 15.1312 + switch (S.token()) { 15.1313 + case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 15.1314 + case DOUBLE: case BOOLEAN: 15.1315 + if (typeArgs == null) 15.1316 + return arrayCreatorRest(newpos, basicType()); 15.1317 + break; 15.1318 + default: 15.1319 + } 15.1320 + JCExpression t = qualident(); 15.1321 + int oldmode = mode; 15.1322 + mode = TYPE; 15.1323 + if (S.token() == LT) { 15.1324 + checkGenerics(); 15.1325 + t = typeArguments(t); 15.1326 + } 15.1327 + while (S.token() == DOT) { 15.1328 + int pos = S.pos(); 15.1329 + S.nextToken(); 15.1330 + t = toP(F.at(pos).Select(t, ident())); 15.1331 + if (S.token() == LT) { 15.1332 + checkGenerics(); 15.1333 + t = typeArguments(t); 15.1334 + } 15.1335 + } 15.1336 + mode = oldmode; 15.1337 + if (S.token() == LBRACKET) { 15.1338 + JCExpression e = arrayCreatorRest(newpos, t); 15.1339 + if (typeArgs != null) { 15.1340 + int pos = newpos; 15.1341 + if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 15.1342 + // note: this should always happen but we should 15.1343 + // not rely on this as the parser is continuously 15.1344 + // modified to improve error recovery. 15.1345 + pos = typeArgs.head.pos; 15.1346 + } 15.1347 + setErrorEndPos(S.prevEndPos()); 15.1348 + reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 15.1349 + return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 15.1350 + } 15.1351 + return e; 15.1352 + } else if (S.token() == LPAREN) { 15.1353 + return classCreatorRest(newpos, null, typeArgs, t); 15.1354 + } else { 15.1355 + reportSyntaxError(S.pos(), "expected2", 15.1356 + LPAREN, LBRACKET); 15.1357 + t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 15.1358 + return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 15.1359 + } 15.1360 + } 15.1361 + 15.1362 + /** InnerCreator = Ident [TypeArguments] ClassCreatorRest 15.1363 + */ 15.1364 + JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 15.1365 + JCExpression t = toP(F.at(S.pos()).Ident(ident())); 15.1366 + if (S.token() == LT) { 15.1367 + checkGenerics(); 15.1368 + t = typeArguments(t); 15.1369 + } 15.1370 + return classCreatorRest(newpos, encl, typeArgs, t); 15.1371 + } 15.1372 + 15.1373 + /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer 15.1374 + * | Expression "]" {"[" Expression "]"} BracketsOpt ) 15.1375 + */ 15.1376 + JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 15.1377 + accept(LBRACKET); 15.1378 + if (S.token() == RBRACKET) { 15.1379 + accept(RBRACKET); 15.1380 + elemtype = bracketsOpt(elemtype); 15.1381 + if (S.token() == LBRACE) { 15.1382 + return arrayInitializer(newpos, elemtype); 15.1383 + } else { 15.1384 + return syntaxError(S.pos(), "array.dimension.missing"); 15.1385 + } 15.1386 + } else { 15.1387 + ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 15.1388 + dims.append(parseExpression()); 15.1389 + accept(RBRACKET); 15.1390 + while (S.token() == LBRACKET) { 15.1391 + int pos = S.pos(); 15.1392 + S.nextToken(); 15.1393 + if (S.token() == RBRACKET) { 15.1394 + elemtype = bracketsOptCont(elemtype, pos); 15.1395 + } else { 15.1396 + dims.append(parseExpression()); 15.1397 + accept(RBRACKET); 15.1398 + } 15.1399 + } 15.1400 + return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); 15.1401 + } 15.1402 + } 15.1403 + 15.1404 + /** ClassCreatorRest = Arguments [ClassBody] 15.1405 + */ 15.1406 + JCExpression classCreatorRest(int newpos, 15.1407 + JCExpression encl, 15.1408 + List<JCExpression> typeArgs, 15.1409 + JCExpression t) 15.1410 + { 15.1411 + List<JCExpression> args = arguments(); 15.1412 + JCClassDecl body = null; 15.1413 + if (S.token() == LBRACE) { 15.1414 + int pos = S.pos(); 15.1415 + List<JCTree> defs = classOrInterfaceBody(names.empty, false); 15.1416 + JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 15.1417 + body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 15.1418 + } 15.1419 + return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); 15.1420 + } 15.1421 + 15.1422 + /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}" 15.1423 + */ 15.1424 + JCExpression arrayInitializer(int newpos, JCExpression t) { 15.1425 + accept(LBRACE); 15.1426 + ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 15.1427 + if (S.token() == COMMA) { 15.1428 + S.nextToken(); 15.1429 + } else if (S.token() != RBRACE) { 15.1430 + elems.append(variableInitializer()); 15.1431 + while (S.token() == COMMA) { 15.1432 + S.nextToken(); 15.1433 + if (S.token() == RBRACE) break; 15.1434 + elems.append(variableInitializer()); 15.1435 + } 15.1436 + } 15.1437 + accept(RBRACE); 15.1438 + return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList())); 15.1439 + } 15.1440 + 15.1441 + /** VariableInitializer = ArrayInitializer | Expression 15.1442 + */ 15.1443 + public JCExpression variableInitializer() { 15.1444 + return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression(); 15.1445 + } 15.1446 + 15.1447 + /** ParExpression = "(" Expression ")" 15.1448 + */ 15.1449 + JCExpression parExpression() { 15.1450 + accept(LPAREN); 15.1451 + JCExpression t = parseExpression(); 15.1452 + accept(RPAREN); 15.1453 + return t; 15.1454 + } 15.1455 + 15.1456 + /** Block = "{" BlockStatements "}" 15.1457 + */ 15.1458 + JCBlock block(int pos, long flags) { 15.1459 + accept(LBRACE); 15.1460 + List<JCStatement> stats = blockStatements(); 15.1461 + JCBlock t = F.at(pos).Block(flags, stats); 15.1462 + while (S.token() == CASE || S.token() == DEFAULT) { 15.1463 + syntaxError("orphaned", S.token()); 15.1464 + switchBlockStatementGroups(); 15.1465 + } 15.1466 + // the Block node has a field "endpos" for first char of last token, which is 15.1467 + // usually but not necessarily the last char of the last token. 15.1468 + t.endpos = S.pos(); 15.1469 + accept(RBRACE); 15.1470 + return toP(t); 15.1471 + } 15.1472 + 15.1473 + public JCBlock block() { 15.1474 + return block(S.pos(), 0); 15.1475 + } 15.1476 + 15.1477 + /** BlockStatements = { BlockStatement } 15.1478 + * BlockStatement = LocalVariableDeclarationStatement 15.1479 + * | ClassOrInterfaceOrEnumDeclaration 15.1480 + * | [Ident ":"] Statement 15.1481 + * LocalVariableDeclarationStatement 15.1482 + * = { FINAL | '@' Annotation } Type VariableDeclarators ";" 15.1483 + */ 15.1484 + @SuppressWarnings("fallthrough") 15.1485 + List<JCStatement> blockStatements() { 15.1486 +//todo: skip to anchor on error(?) 15.1487 + int lastErrPos = -1; 15.1488 + ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 15.1489 + while (true) { 15.1490 + int pos = S.pos(); 15.1491 + switch (S.token()) { 15.1492 + case RBRACE: case CASE: case DEFAULT: case EOF: 15.1493 + return stats.toList(); 15.1494 + case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 15.1495 + case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 15.1496 + case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 15.1497 + stats.append(parseStatement()); 15.1498 + break; 15.1499 + case MONKEYS_AT: 15.1500 + case FINAL: { 15.1501 + String dc = S.docComment(); 15.1502 + JCModifiers mods = modifiersOpt(); 15.1503 + if (S.token() == INTERFACE || 15.1504 + S.token() == CLASS || 15.1505 + allowEnums && S.token() == ENUM) { 15.1506 + stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 15.1507 + } else { 15.1508 + JCExpression t = parseType(); 15.1509 + stats.appendList(variableDeclarators(mods, t, 15.1510 + new ListBuffer<JCStatement>())); 15.1511 + // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 15.1512 + storeEnd(stats.elems.last(), S.endPos()); 15.1513 + accept(SEMI); 15.1514 + } 15.1515 + break; 15.1516 + } 15.1517 + case ABSTRACT: case STRICTFP: { 15.1518 + String dc = S.docComment(); 15.1519 + JCModifiers mods = modifiersOpt(); 15.1520 + stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 15.1521 + break; 15.1522 + } 15.1523 + case INTERFACE: 15.1524 + case CLASS: 15.1525 + stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 15.1526 + S.docComment())); 15.1527 + break; 15.1528 + case ENUM: 15.1529 + case ASSERT: 15.1530 + if (allowEnums && S.token() == ENUM) { 15.1531 + log.error(S.pos(), "local.enum"); 15.1532 + stats. 15.1533 + append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 15.1534 + S.docComment())); 15.1535 + break; 15.1536 + } else if (allowAsserts && S.token() == ASSERT) { 15.1537 + stats.append(parseStatement()); 15.1538 + break; 15.1539 + } 15.1540 + /* fall through to default */ 15.1541 + default: 15.1542 + Name name = S.name(); 15.1543 + JCExpression t = term(EXPR | TYPE); 15.1544 + if (S.token() == COLON && t.getTag() == JCTree.IDENT) { 15.1545 + S.nextToken(); 15.1546 + JCStatement stat = parseStatement(); 15.1547 + stats.append(F.at(pos).Labelled(name, stat)); 15.1548 + } else if ((lastmode & TYPE) != 0 && 15.1549 + (S.token() == IDENTIFIER || 15.1550 + S.token() == ASSERT || 15.1551 + S.token() == ENUM)) { 15.1552 + pos = S.pos(); 15.1553 + JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 15.1554 + F.at(pos); 15.1555 + stats.appendList(variableDeclarators(mods, t, 15.1556 + new ListBuffer<JCStatement>())); 15.1557 + // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 15.1558 + storeEnd(stats.elems.last(), S.endPos()); 15.1559 + accept(SEMI); 15.1560 + } else { 15.1561 + // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 15.1562 + stats.append(to(F.at(pos).Exec(checkExprStat(t)))); 15.1563 + accept(SEMI); 15.1564 + } 15.1565 + } 15.1566 + 15.1567 + // error recovery 15.1568 + if (S.pos() == lastErrPos) 15.1569 + return stats.toList(); 15.1570 + if (S.pos() <= errorEndPos) { 15.1571 + skip(false, true, true, true); 15.1572 + lastErrPos = S.pos(); 15.1573 + } 15.1574 + 15.1575 + // ensure no dangling /** @deprecated */ active 15.1576 + S.resetDeprecatedFlag(); 15.1577 + } 15.1578 + } 15.1579 + 15.1580 + /** Statement = 15.1581 + * Block 15.1582 + * | IF ParExpression Statement [ELSE Statement] 15.1583 + * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement 15.1584 + * | FOR "(" FormalParameter : Expression ")" Statement 15.1585 + * | WHILE ParExpression Statement 15.1586 + * | DO Statement WHILE ParExpression ";" 15.1587 + * | TRY Block ( Catches | [Catches] FinallyPart ) 15.1588 + * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" 15.1589 + * | SYNCHRONIZED ParExpression Block 15.1590 + * | RETURN [Expression] ";" 15.1591 + * | THROW Expression ";" 15.1592 + * | BREAK [Ident] ";" 15.1593 + * | CONTINUE [Ident] ";" 15.1594 + * | ASSERT Expression [ ":" Expression ] ";" 15.1595 + * | ";" 15.1596 + * | ExpressionStatement 15.1597 + * | Ident ":" Statement 15.1598 + */ 15.1599 + @SuppressWarnings("fallthrough") 15.1600 + public JCStatement parseStatement() { 15.1601 + int pos = S.pos(); 15.1602 + switch (S.token()) { 15.1603 + case LBRACE: 15.1604 + return block(); 15.1605 + case IF: { 15.1606 + S.nextToken(); 15.1607 + JCExpression cond = parExpression(); 15.1608 + JCStatement thenpart = parseStatement(); 15.1609 + JCStatement elsepart = null; 15.1610 + if (S.token() == ELSE) { 15.1611 + S.nextToken(); 15.1612 + elsepart = parseStatement(); 15.1613 + } 15.1614 + return F.at(pos).If(cond, thenpart, elsepart); 15.1615 + } 15.1616 + case FOR: { 15.1617 + S.nextToken(); 15.1618 + accept(LPAREN); 15.1619 + List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); 15.1620 + if (inits.length() == 1 && 15.1621 + inits.head.getTag() == JCTree.VARDEF && 15.1622 + ((JCVariableDecl) inits.head).init == null && 15.1623 + S.token() == COLON) { 15.1624 + checkForeach(); 15.1625 + JCVariableDecl var = (JCVariableDecl)inits.head; 15.1626 + accept(COLON); 15.1627 + JCExpression expr = parseExpression(); 15.1628 + accept(RPAREN); 15.1629 + JCStatement body = parseStatement(); 15.1630 + return F.at(pos).ForeachLoop(var, expr, body); 15.1631 + } else { 15.1632 + accept(SEMI); 15.1633 + JCExpression cond = S.token() == SEMI ? null : parseExpression(); 15.1634 + accept(SEMI); 15.1635 + List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 15.1636 + accept(RPAREN); 15.1637 + JCStatement body = parseStatement(); 15.1638 + return F.at(pos).ForLoop(inits, cond, steps, body); 15.1639 + } 15.1640 + } 15.1641 + case WHILE: { 15.1642 + S.nextToken(); 15.1643 + JCExpression cond = parExpression(); 15.1644 + JCStatement body = parseStatement(); 15.1645 + return F.at(pos).WhileLoop(cond, body); 15.1646 + } 15.1647 + case DO: { 15.1648 + S.nextToken(); 15.1649 + JCStatement body = parseStatement(); 15.1650 + accept(WHILE); 15.1651 + JCExpression cond = parExpression(); 15.1652 + JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond)); 15.1653 + accept(SEMI); 15.1654 + return t; 15.1655 + } 15.1656 + case TRY: { 15.1657 + S.nextToken(); 15.1658 + JCBlock body = block(); 15.1659 + ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); 15.1660 + JCBlock finalizer = null; 15.1661 + if (S.token() == CATCH || S.token() == FINALLY) { 15.1662 + while (S.token() == CATCH) catchers.append(catchClause()); 15.1663 + if (S.token() == FINALLY) { 15.1664 + S.nextToken(); 15.1665 + finalizer = block(); 15.1666 + } 15.1667 + } else { 15.1668 + log.error(pos, "try.without.catch.or.finally"); 15.1669 + } 15.1670 + return F.at(pos).Try(body, catchers.toList(), finalizer); 15.1671 + } 15.1672 + case SWITCH: { 15.1673 + S.nextToken(); 15.1674 + JCExpression selector = parExpression(); 15.1675 + accept(LBRACE); 15.1676 + List<JCCase> cases = switchBlockStatementGroups(); 15.1677 + JCSwitch t = to(F.at(pos).Switch(selector, cases)); 15.1678 + accept(RBRACE); 15.1679 + return t; 15.1680 + } 15.1681 + case SYNCHRONIZED: { 15.1682 + S.nextToken(); 15.1683 + JCExpression lock = parExpression(); 15.1684 + JCBlock body = block(); 15.1685 + return F.at(pos).Synchronized(lock, body); 15.1686 + } 15.1687 + case RETURN: { 15.1688 + S.nextToken(); 15.1689 + JCExpression result = S.token() == SEMI ? null : parseExpression(); 15.1690 + JCReturn t = to(F.at(pos).Return(result)); 15.1691 + accept(SEMI); 15.1692 + return t; 15.1693 + } 15.1694 + case THROW: { 15.1695 + S.nextToken(); 15.1696 + JCExpression exc = parseExpression(); 15.1697 + JCThrow t = to(F.at(pos).Throw(exc)); 15.1698 + accept(SEMI); 15.1699 + return t; 15.1700 + } 15.1701 + case BREAK: { 15.1702 + S.nextToken(); 15.1703 + Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 15.1704 + JCBreak t = to(F.at(pos).Break(label)); 15.1705 + accept(SEMI); 15.1706 + return t; 15.1707 + } 15.1708 + case CONTINUE: { 15.1709 + S.nextToken(); 15.1710 + Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 15.1711 + JCContinue t = to(F.at(pos).Continue(label)); 15.1712 + accept(SEMI); 15.1713 + return t; 15.1714 + } 15.1715 + case SEMI: 15.1716 + S.nextToken(); 15.1717 + return toP(F.at(pos).Skip()); 15.1718 + case ELSE: 15.1719 + return toP(F.Exec(syntaxError("else.without.if"))); 15.1720 + case FINALLY: 15.1721 + return toP(F.Exec(syntaxError("finally.without.try"))); 15.1722 + case CATCH: 15.1723 + return toP(F.Exec(syntaxError("catch.without.try"))); 15.1724 + case ASSERT: { 15.1725 + if (allowAsserts && S.token() == ASSERT) { 15.1726 + S.nextToken(); 15.1727 + JCExpression assertion = parseExpression(); 15.1728 + JCExpression message = null; 15.1729 + if (S.token() == COLON) { 15.1730 + S.nextToken(); 15.1731 + message = parseExpression(); 15.1732 + } 15.1733 + JCAssert t = to(F.at(pos).Assert(assertion, message)); 15.1734 + accept(SEMI); 15.1735 + return t; 15.1736 + } 15.1737 + /* else fall through to default case */ 15.1738 + } 15.1739 + case ENUM: 15.1740 + default: 15.1741 + Name name = S.name(); 15.1742 + JCExpression expr = parseExpression(); 15.1743 + if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { 15.1744 + S.nextToken(); 15.1745 + JCStatement stat = parseStatement(); 15.1746 + return F.at(pos).Labelled(name, stat); 15.1747 + } else { 15.1748 + // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 15.1749 + JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); 15.1750 + accept(SEMI); 15.1751 + return stat; 15.1752 + } 15.1753 + } 15.1754 + } 15.1755 + 15.1756 + /** CatchClause = CATCH "(" FormalParameter ")" Block 15.1757 + */ 15.1758 + JCCatch catchClause() { 15.1759 + int pos = S.pos(); 15.1760 + accept(CATCH); 15.1761 + accept(LPAREN); 15.1762 + JCVariableDecl formal = 15.1763 + variableDeclaratorId(optFinal(Flags.PARAMETER), 15.1764 + qualident()); 15.1765 + accept(RPAREN); 15.1766 + JCBlock body = block(); 15.1767 + return F.at(pos).Catch(formal, body); 15.1768 + } 15.1769 + 15.1770 + /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 15.1771 + * SwitchBlockStatementGroup = SwitchLabel BlockStatements 15.1772 + * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 15.1773 + */ 15.1774 + List<JCCase> switchBlockStatementGroups() { 15.1775 + ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); 15.1776 + while (true) { 15.1777 + int pos = S.pos(); 15.1778 + switch (S.token()) { 15.1779 + case CASE: { 15.1780 + S.nextToken(); 15.1781 + JCExpression pat = parseExpression(); 15.1782 + accept(COLON); 15.1783 + List<JCStatement> stats = blockStatements(); 15.1784 + JCCase c = F.at(pos).Case(pat, stats); 15.1785 + if (stats.isEmpty()) 15.1786 + storeEnd(c, S.prevEndPos()); 15.1787 + cases.append(c); 15.1788 + break; 15.1789 + } 15.1790 + case DEFAULT: { 15.1791 + S.nextToken(); 15.1792 + accept(COLON); 15.1793 + List<JCStatement> stats = blockStatements(); 15.1794 + JCCase c = F.at(pos).Case(null, stats); 15.1795 + if (stats.isEmpty()) 15.1796 + storeEnd(c, S.prevEndPos()); 15.1797 + cases.append(c); 15.1798 + break; 15.1799 + } 15.1800 + case RBRACE: case EOF: 15.1801 + return cases.toList(); 15.1802 + default: 15.1803 + S.nextToken(); // to ensure progress 15.1804 + syntaxError(pos, "expected3", 15.1805 + CASE, DEFAULT, RBRACE); 15.1806 + } 15.1807 + } 15.1808 + } 15.1809 + 15.1810 + /** MoreStatementExpressions = { COMMA StatementExpression } 15.1811 + */ 15.1812 + <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos, 15.1813 + JCExpression first, 15.1814 + T stats) { 15.1815 + // This Exec is a "StatementExpression"; it subsumes no terminating token 15.1816 + stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 15.1817 + while (S.token() == COMMA) { 15.1818 + S.nextToken(); 15.1819 + pos = S.pos(); 15.1820 + JCExpression t = parseExpression(); 15.1821 + // This Exec is a "StatementExpression"; it subsumes no terminating token 15.1822 + stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 15.1823 + } 15.1824 + return stats; 15.1825 + } 15.1826 + 15.1827 + /** ForInit = StatementExpression MoreStatementExpressions 15.1828 + * | { FINAL | '@' Annotation } Type VariableDeclarators 15.1829 + */ 15.1830 + List<JCStatement> forInit() { 15.1831 + ListBuffer<JCStatement> stats = lb(); 15.1832 + int pos = S.pos(); 15.1833 + if (S.token() == FINAL || S.token() == MONKEYS_AT) { 15.1834 + return variableDeclarators(optFinal(0), parseType(), stats).toList(); 15.1835 + } else { 15.1836 + JCExpression t = term(EXPR | TYPE); 15.1837 + if ((lastmode & TYPE) != 0 && 15.1838 + (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) 15.1839 + return variableDeclarators(modifiersOpt(), t, stats).toList(); 15.1840 + else 15.1841 + return moreStatementExpressions(pos, t, stats).toList(); 15.1842 + } 15.1843 + } 15.1844 + 15.1845 + /** ForUpdate = StatementExpression MoreStatementExpressions 15.1846 + */ 15.1847 + List<JCExpressionStatement> forUpdate() { 15.1848 + return moreStatementExpressions(S.pos(), 15.1849 + parseExpression(), 15.1850 + new ListBuffer<JCExpressionStatement>()).toList(); 15.1851 + } 15.1852 + 15.1853 + /** AnnotationsOpt = { '@' Annotation } 15.1854 + */ 15.1855 + List<JCAnnotation> annotationsOpt() { 15.1856 + if (S.token() != MONKEYS_AT) return List.nil(); // optimization 15.1857 + ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 15.1858 + while (S.token() == MONKEYS_AT) { 15.1859 + int pos = S.pos(); 15.1860 + S.nextToken(); 15.1861 + buf.append(annotation(pos)); 15.1862 + } 15.1863 + return buf.toList(); 15.1864 + } 15.1865 + 15.1866 + /** ModifiersOpt = { Modifier } 15.1867 + * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 15.1868 + * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 15.1869 + * | "@" Annotation 15.1870 + */ 15.1871 + JCModifiers modifiersOpt() { 15.1872 + return modifiersOpt(null); 15.1873 + } 15.1874 + JCModifiers modifiersOpt(JCModifiers partial) { 15.1875 + long flags = (partial == null) ? 0 : partial.flags; 15.1876 + if (S.deprecatedFlag()) { 15.1877 + flags |= Flags.DEPRECATED; 15.1878 + S.resetDeprecatedFlag(); 15.1879 + } 15.1880 + ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>(); 15.1881 + if (partial != null) annotations.appendList(partial.annotations); 15.1882 + int pos = S.pos(); 15.1883 + int lastPos = Position.NOPOS; 15.1884 + loop: 15.1885 + while (true) { 15.1886 + long flag; 15.1887 + switch (S.token()) { 15.1888 + case PRIVATE : flag = Flags.PRIVATE; break; 15.1889 + case PROTECTED : flag = Flags.PROTECTED; break; 15.1890 + case PUBLIC : flag = Flags.PUBLIC; break; 15.1891 + case STATIC : flag = Flags.STATIC; break; 15.1892 + case TRANSIENT : flag = Flags.TRANSIENT; break; 15.1893 + case FINAL : flag = Flags.FINAL; break; 15.1894 + case ABSTRACT : flag = Flags.ABSTRACT; break; 15.1895 + case NATIVE : flag = Flags.NATIVE; break; 15.1896 + case VOLATILE : flag = Flags.VOLATILE; break; 15.1897 + case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 15.1898 + case STRICTFP : flag = Flags.STRICTFP; break; 15.1899 + case MONKEYS_AT : flag = Flags.ANNOTATION; break; 15.1900 + default: break loop; 15.1901 + } 15.1902 + if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier"); 15.1903 + lastPos = S.pos(); 15.1904 + S.nextToken(); 15.1905 + if (flag == Flags.ANNOTATION) { 15.1906 + checkAnnotations(); 15.1907 + if (S.token() != INTERFACE) { 15.1908 + JCAnnotation ann = annotation(lastPos); 15.1909 + // if first modifier is an annotation, set pos to annotation's. 15.1910 + if (flags == 0 && annotations.isEmpty()) 15.1911 + pos = ann.pos; 15.1912 + annotations.append(ann); 15.1913 + lastPos = ann.pos; 15.1914 + flag = 0; 15.1915 + } 15.1916 + } 15.1917 + flags |= flag; 15.1918 + } 15.1919 + switch (S.token()) { 15.1920 + case ENUM: flags |= Flags.ENUM; break; 15.1921 + case INTERFACE: flags |= Flags.INTERFACE; break; 15.1922 + default: break; 15.1923 + } 15.1924 + 15.1925 + /* A modifiers tree with no modifier tokens or annotations 15.1926 + * has no text position. */ 15.1927 + if (flags == 0 && annotations.isEmpty()) 15.1928 + pos = Position.NOPOS; 15.1929 + 15.1930 + JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 15.1931 + if (pos != Position.NOPOS) 15.1932 + storeEnd(mods, S.prevEndPos()); 15.1933 + return mods; 15.1934 + } 15.1935 + 15.1936 + /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 15.1937 + * @param pos position of "@" token 15.1938 + */ 15.1939 + JCAnnotation annotation(int pos) { 15.1940 + // accept(AT); // AT consumed by caller 15.1941 + checkAnnotations(); 15.1942 + JCTree ident = qualident(); 15.1943 + List<JCExpression> fieldValues = annotationFieldValuesOpt(); 15.1944 + JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); 15.1945 + storeEnd(ann, S.prevEndPos()); 15.1946 + return ann; 15.1947 + } 15.1948 + 15.1949 + List<JCExpression> annotationFieldValuesOpt() { 15.1950 + return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 15.1951 + } 15.1952 + 15.1953 + /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 15.1954 + List<JCExpression> annotationFieldValues() { 15.1955 + accept(LPAREN); 15.1956 + ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 15.1957 + if (S.token() != RPAREN) { 15.1958 + buf.append(annotationFieldValue()); 15.1959 + while (S.token() == COMMA) { 15.1960 + S.nextToken(); 15.1961 + buf.append(annotationFieldValue()); 15.1962 + } 15.1963 + } 15.1964 + accept(RPAREN); 15.1965 + return buf.toList(); 15.1966 + } 15.1967 + 15.1968 + /** AnnotationFieldValue = AnnotationValue 15.1969 + * | Identifier "=" AnnotationValue 15.1970 + */ 15.1971 + JCExpression annotationFieldValue() { 15.1972 + if (S.token() == IDENTIFIER) { 15.1973 + mode = EXPR; 15.1974 + JCExpression t1 = term1(); 15.1975 + if (t1.getTag() == JCTree.IDENT && S.token() == EQ) { 15.1976 + int pos = S.pos(); 15.1977 + accept(EQ); 15.1978 + return toP(F.at(pos).Assign(t1, annotationValue())); 15.1979 + } else { 15.1980 + return t1; 15.1981 + } 15.1982 + } 15.1983 + return annotationValue(); 15.1984 + } 15.1985 + 15.1986 + /* AnnotationValue = ConditionalExpression 15.1987 + * | Annotation 15.1988 + * | "{" [ AnnotationValue { "," AnnotationValue } ] "}" 15.1989 + */ 15.1990 + JCExpression annotationValue() { 15.1991 + int pos; 15.1992 + switch (S.token()) { 15.1993 + case MONKEYS_AT: 15.1994 + pos = S.pos(); 15.1995 + S.nextToken(); 15.1996 + return annotation(pos); 15.1997 + case LBRACE: 15.1998 + pos = S.pos(); 15.1999 + accept(LBRACE); 15.2000 + ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 15.2001 + if (S.token() != RBRACE) { 15.2002 + buf.append(annotationValue()); 15.2003 + while (S.token() == COMMA) { 15.2004 + S.nextToken(); 15.2005 + if (S.token() == RPAREN) break; 15.2006 + buf.append(annotationValue()); 15.2007 + } 15.2008 + } 15.2009 + accept(RBRACE); 15.2010 + return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList())); 15.2011 + default: 15.2012 + mode = EXPR; 15.2013 + return term1(); 15.2014 + } 15.2015 + } 15.2016 + 15.2017 + /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator } 15.2018 + */ 15.2019 + public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods, 15.2020 + JCExpression type, 15.2021 + T vdefs) 15.2022 + { 15.2023 + return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs); 15.2024 + } 15.2025 + 15.2026 + /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 15.2027 + * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator } 15.2028 + * 15.2029 + * @param reqInit Is an initializer always required? 15.2030 + * @param dc The documentation comment for the variable declarations, or null. 15.2031 + */ 15.2032 + <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos, 15.2033 + JCModifiers mods, 15.2034 + JCExpression type, 15.2035 + Name name, 15.2036 + boolean reqInit, 15.2037 + String dc, 15.2038 + T vdefs) 15.2039 + { 15.2040 + vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc)); 15.2041 + while (S.token() == COMMA) { 15.2042 + // All but last of multiple declarators subsume a comma 15.2043 + storeEnd((JCTree)vdefs.elems.last(), S.endPos()); 15.2044 + S.nextToken(); 15.2045 + vdefs.append(variableDeclarator(mods, type, reqInit, dc)); 15.2046 + } 15.2047 + return vdefs; 15.2048 + } 15.2049 + 15.2050 + /** VariableDeclarator = Ident VariableDeclaratorRest 15.2051 + * ConstantDeclarator = Ident ConstantDeclaratorRest 15.2052 + */ 15.2053 + JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) { 15.2054 + return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc); 15.2055 + } 15.2056 + 15.2057 + /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 15.2058 + * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer 15.2059 + * 15.2060 + * @param reqInit Is an initializer always required? 15.2061 + * @param dc The documentation comment for the variable declarations, or null. 15.2062 + */ 15.2063 + JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, 15.2064 + boolean reqInit, String dc) { 15.2065 + type = bracketsOpt(type); 15.2066 + JCExpression init = null; 15.2067 + if (S.token() == EQ) { 15.2068 + S.nextToken(); 15.2069 + init = variableInitializer(); 15.2070 + } 15.2071 + else if (reqInit) syntaxError(S.pos(), "expected", EQ); 15.2072 + JCVariableDecl result = 15.2073 + toP(F.at(pos).VarDef(mods, name, type, init)); 15.2074 + attach(result, dc); 15.2075 + return result; 15.2076 + } 15.2077 + 15.2078 + /** VariableDeclaratorId = Ident BracketsOpt 15.2079 + */ 15.2080 + JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 15.2081 + int pos = S.pos(); 15.2082 + Name name = ident(); 15.2083 + if ((mods.flags & Flags.VARARGS) == 0) 15.2084 + type = bracketsOpt(type); 15.2085 + return toP(F.at(pos).VarDef(mods, name, type, null)); 15.2086 + } 15.2087 + 15.2088 + /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 15.2089 + */ 15.2090 + public JCTree.JCCompilationUnit parseCompilationUnit() { 15.2091 + int pos = S.pos(); 15.2092 + JCExpression pid = null; 15.2093 + String dc = S.docComment(); 15.2094 + JCModifiers mods = null; 15.2095 + List<JCAnnotation> packageAnnotations = List.nil(); 15.2096 + if (S.token() == MONKEYS_AT) 15.2097 + mods = modifiersOpt(); 15.2098 + 15.2099 + if (S.token() == PACKAGE) { 15.2100 + if (mods != null) { 15.2101 + checkNoMods(mods.flags); 15.2102 + packageAnnotations = mods.annotations; 15.2103 + mods = null; 15.2104 + } 15.2105 + S.nextToken(); 15.2106 + pid = qualident(); 15.2107 + accept(SEMI); 15.2108 + } 15.2109 + ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 15.2110 + boolean checkForImports = true; 15.2111 + while (S.token() != EOF) { 15.2112 + if (S.pos() <= errorEndPos) { 15.2113 + // error recovery 15.2114 + skip(checkForImports, false, false, false); 15.2115 + if (S.token() == EOF) 15.2116 + break; 15.2117 + } 15.2118 + if (checkForImports && mods == null && S.token() == IMPORT) { 15.2119 + defs.append(importDeclaration()); 15.2120 + } else { 15.2121 + JCTree def = typeDeclaration(mods); 15.2122 + if (def instanceof JCExpressionStatement) 15.2123 + def = ((JCExpressionStatement)def).expr; 15.2124 + defs.append(def); 15.2125 + if (def instanceof JCClassDecl) 15.2126 + checkForImports = false; 15.2127 + mods = null; 15.2128 + } 15.2129 + } 15.2130 + JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList()); 15.2131 + attach(toplevel, dc); 15.2132 + if (defs.elems.isEmpty()) 15.2133 + storeEnd(toplevel, S.prevEndPos()); 15.2134 + if (keepDocComments) 15.2135 + toplevel.docComments = docComments; 15.2136 + if (keepLineMap) 15.2137 + toplevel.lineMap = S.getLineMap(); 15.2138 + return toplevel; 15.2139 + } 15.2140 + 15.2141 + /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 15.2142 + */ 15.2143 + JCTree importDeclaration() { 15.2144 + int pos = S.pos(); 15.2145 + S.nextToken(); 15.2146 + boolean importStatic = false; 15.2147 + if (S.token() == STATIC) { 15.2148 + checkStaticImports(); 15.2149 + importStatic = true; 15.2150 + S.nextToken(); 15.2151 + } 15.2152 + JCExpression pid = toP(F.at(S.pos()).Ident(ident())); 15.2153 + do { 15.2154 + int pos1 = S.pos(); 15.2155 + accept(DOT); 15.2156 + if (S.token() == STAR) { 15.2157 + pid = to(F.at(pos1).Select(pid, names.asterisk)); 15.2158 + S.nextToken(); 15.2159 + break; 15.2160 + } else { 15.2161 + pid = toP(F.at(pos1).Select(pid, ident())); 15.2162 + } 15.2163 + } while (S.token() == DOT); 15.2164 + accept(SEMI); 15.2165 + return toP(F.at(pos).Import(pid, importStatic)); 15.2166 + } 15.2167 + 15.2168 + /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 15.2169 + * | ";" 15.2170 + */ 15.2171 + JCTree typeDeclaration(JCModifiers mods) { 15.2172 + int pos = S.pos(); 15.2173 + if (mods == null && S.token() == SEMI) { 15.2174 + S.nextToken(); 15.2175 + return toP(F.at(pos).Skip()); 15.2176 + } else { 15.2177 + String dc = S.docComment(); 15.2178 + return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc); 15.2179 + } 15.2180 + } 15.2181 + 15.2182 + /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt 15.2183 + * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) 15.2184 + * @param mods Any modifiers starting the class or interface declaration 15.2185 + * @param dc The documentation comment for the class, or null. 15.2186 + */ 15.2187 + JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) { 15.2188 + if (S.token() == CLASS) { 15.2189 + return classDeclaration(mods, dc); 15.2190 + } else if (S.token() == INTERFACE) { 15.2191 + return interfaceDeclaration(mods, dc); 15.2192 + } else if (allowEnums) { 15.2193 + if (S.token() == ENUM) { 15.2194 + return enumDeclaration(mods, dc); 15.2195 + } else { 15.2196 + int pos = S.pos(); 15.2197 + List<JCTree> errs; 15.2198 + if (S.token() == IDENTIFIER) { 15.2199 + errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 15.2200 + setErrorEndPos(S.pos()); 15.2201 + } else { 15.2202 + errs = List.<JCTree>of(mods); 15.2203 + } 15.2204 + return toP(F.Exec(syntaxError(pos, errs, "expected3", 15.2205 + CLASS, INTERFACE, ENUM))); 15.2206 + } 15.2207 + } else { 15.2208 + if (S.token() == ENUM) { 15.2209 + log.error(S.pos(), "enums.not.supported.in.source", source.name); 15.2210 + allowEnums = true; 15.2211 + return enumDeclaration(mods, dc); 15.2212 + } 15.2213 + int pos = S.pos(); 15.2214 + List<JCTree> errs; 15.2215 + if (S.token() == IDENTIFIER) { 15.2216 + errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 15.2217 + setErrorEndPos(S.pos()); 15.2218 + } else { 15.2219 + errs = List.<JCTree>of(mods); 15.2220 + } 15.2221 + return toP(F.Exec(syntaxError(pos, errs, "expected2", 15.2222 + CLASS, INTERFACE))); 15.2223 + } 15.2224 + } 15.2225 + 15.2226 + /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type] 15.2227 + * [IMPLEMENTS TypeList] ClassBody 15.2228 + * @param mods The modifiers starting the class declaration 15.2229 + * @param dc The documentation comment for the class, or null. 15.2230 + */ 15.2231 + JCClassDecl classDeclaration(JCModifiers mods, String dc) { 15.2232 + int pos = S.pos(); 15.2233 + accept(CLASS); 15.2234 + Name name = ident(); 15.2235 + 15.2236 + List<JCTypeParameter> typarams = typeParametersOpt(); 15.2237 + 15.2238 + JCTree extending = null; 15.2239 + if (S.token() == EXTENDS) { 15.2240 + S.nextToken(); 15.2241 + extending = parseType(); 15.2242 + } 15.2243 + List<JCExpression> implementing = List.nil(); 15.2244 + if (S.token() == IMPLEMENTS) { 15.2245 + S.nextToken(); 15.2246 + implementing = typeList(); 15.2247 + } 15.2248 + List<JCTree> defs = classOrInterfaceBody(name, false); 15.2249 + JCClassDecl result = toP(F.at(pos).ClassDef( 15.2250 + mods, name, typarams, extending, implementing, defs)); 15.2251 + attach(result, dc); 15.2252 + return result; 15.2253 + } 15.2254 + 15.2255 + /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt 15.2256 + * [EXTENDS TypeList] InterfaceBody 15.2257 + * @param mods The modifiers starting the interface declaration 15.2258 + * @param dc The documentation comment for the interface, or null. 15.2259 + */ 15.2260 + JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 15.2261 + int pos = S.pos(); 15.2262 + accept(INTERFACE); 15.2263 + Name name = ident(); 15.2264 + 15.2265 + List<JCTypeParameter> typarams = typeParametersOpt(); 15.2266 + 15.2267 + List<JCExpression> extending = List.nil(); 15.2268 + if (S.token() == EXTENDS) { 15.2269 + S.nextToken(); 15.2270 + extending = typeList(); 15.2271 + } 15.2272 + List<JCTree> defs = classOrInterfaceBody(name, true); 15.2273 + JCClassDecl result = toP(F.at(pos).ClassDef( 15.2274 + mods, name, typarams, null, extending, defs)); 15.2275 + attach(result, dc); 15.2276 + return result; 15.2277 + } 15.2278 + 15.2279 + /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody 15.2280 + * @param mods The modifiers starting the enum declaration 15.2281 + * @param dc The documentation comment for the enum, or null. 15.2282 + */ 15.2283 + JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 15.2284 + int pos = S.pos(); 15.2285 + accept(ENUM); 15.2286 + Name name = ident(); 15.2287 + 15.2288 + List<JCExpression> implementing = List.nil(); 15.2289 + if (S.token() == IMPLEMENTS) { 15.2290 + S.nextToken(); 15.2291 + implementing = typeList(); 15.2292 + } 15.2293 + 15.2294 + List<JCTree> defs = enumBody(name); 15.2295 + JCModifiers newMods = 15.2296 + F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations); 15.2297 + JCClassDecl result = toP(F.at(pos). 15.2298 + ClassDef(newMods, name, List.<JCTypeParameter>nil(), 15.2299 + null, implementing, defs)); 15.2300 + attach(result, dc); 15.2301 + return result; 15.2302 + } 15.2303 + 15.2304 + /** EnumBody = "{" { EnumeratorDeclarationList } [","] 15.2305 + * [ ";" {ClassBodyDeclaration} ] "}" 15.2306 + */ 15.2307 + List<JCTree> enumBody(Name enumName) { 15.2308 + accept(LBRACE); 15.2309 + ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 15.2310 + if (S.token() == COMMA) { 15.2311 + S.nextToken(); 15.2312 + } else if (S.token() != RBRACE && S.token() != SEMI) { 15.2313 + defs.append(enumeratorDeclaration(enumName)); 15.2314 + while (S.token() == COMMA) { 15.2315 + S.nextToken(); 15.2316 + if (S.token() == RBRACE || S.token() == SEMI) break; 15.2317 + defs.append(enumeratorDeclaration(enumName)); 15.2318 + } 15.2319 + if (S.token() != SEMI && S.token() != RBRACE) { 15.2320 + defs.append(syntaxError(S.pos(), "expected3", 15.2321 + COMMA, RBRACE, SEMI)); 15.2322 + S.nextToken(); 15.2323 + } 15.2324 + } 15.2325 + if (S.token() == SEMI) { 15.2326 + S.nextToken(); 15.2327 + while (S.token() != RBRACE && S.token() != EOF) { 15.2328 + defs.appendList(classOrInterfaceBodyDeclaration(enumName, 15.2329 + false)); 15.2330 + if (S.pos() <= errorEndPos) { 15.2331 + // error recovery 15.2332 + skip(false, true, true, false); 15.2333 + } 15.2334 + } 15.2335 + } 15.2336 + accept(RBRACE); 15.2337 + return defs.toList(); 15.2338 + } 15.2339 + 15.2340 + /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 15.2341 + */ 15.2342 + JCTree enumeratorDeclaration(Name enumName) { 15.2343 + String dc = S.docComment(); 15.2344 + int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 15.2345 + if (S.deprecatedFlag()) { 15.2346 + flags |= Flags.DEPRECATED; 15.2347 + S.resetDeprecatedFlag(); 15.2348 + } 15.2349 + int pos = S.pos(); 15.2350 + List<JCAnnotation> annotations = annotationsOpt(); 15.2351 + JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 15.2352 + List<JCExpression> typeArgs = typeArgumentsOpt(); 15.2353 + int identPos = S.pos(); 15.2354 + Name name = ident(); 15.2355 + int createPos = S.pos(); 15.2356 + List<JCExpression> args = (S.token() == LPAREN) 15.2357 + ? arguments() : List.<JCExpression>nil(); 15.2358 + JCClassDecl body = null; 15.2359 + if (S.token() == LBRACE) { 15.2360 + JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC); 15.2361 + List<JCTree> defs = classOrInterfaceBody(names.empty, false); 15.2362 + body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 15.2363 + } 15.2364 + if (args.isEmpty() && body == null) 15.2365 + createPos = Position.NOPOS; 15.2366 + JCIdent ident = F.at(Position.NOPOS).Ident(enumName); 15.2367 + JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 15.2368 + if (createPos != Position.NOPOS) 15.2369 + storeEnd(create, S.prevEndPos()); 15.2370 + ident = F.at(Position.NOPOS).Ident(enumName); 15.2371 + JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 15.2372 + attach(result, dc); 15.2373 + return result; 15.2374 + } 15.2375 + 15.2376 + /** TypeList = Type {"," Type} 15.2377 + */ 15.2378 + List<JCExpression> typeList() { 15.2379 + ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 15.2380 + ts.append(parseType()); 15.2381 + while (S.token() == COMMA) { 15.2382 + S.nextToken(); 15.2383 + ts.append(parseType()); 15.2384 + } 15.2385 + return ts.toList(); 15.2386 + } 15.2387 + 15.2388 + /** ClassBody = "{" {ClassBodyDeclaration} "}" 15.2389 + * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 15.2390 + */ 15.2391 + List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 15.2392 + accept(LBRACE); 15.2393 + if (S.pos() <= errorEndPos) { 15.2394 + // error recovery 15.2395 + skip(false, true, false, false); 15.2396 + if (S.token() == LBRACE) 15.2397 + S.nextToken(); 15.2398 + } 15.2399 + ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 15.2400 + while (S.token() != RBRACE && S.token() != EOF) { 15.2401 + defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 15.2402 + if (S.pos() <= errorEndPos) { 15.2403 + // error recovery 15.2404 + skip(false, true, true, false); 15.2405 + } 15.2406 + } 15.2407 + accept(RBRACE); 15.2408 + return defs.toList(); 15.2409 + } 15.2410 + 15.2411 + /** ClassBodyDeclaration = 15.2412 + * ";" 15.2413 + * | [STATIC] Block 15.2414 + * | ModifiersOpt 15.2415 + * ( Type Ident 15.2416 + * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) 15.2417 + * | VOID Ident MethodDeclaratorRest 15.2418 + * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest 15.2419 + * | Ident ConstructorDeclaratorRest 15.2420 + * | TypeParameters Ident ConstructorDeclaratorRest 15.2421 + * | ClassOrInterfaceOrEnumDeclaration 15.2422 + * ) 15.2423 + * InterfaceBodyDeclaration = 15.2424 + * ";" 15.2425 + * | ModifiersOpt Type Ident 15.2426 + * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 15.2427 + */ 15.2428 + List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 15.2429 + if (S.token() == SEMI) { 15.2430 + S.nextToken(); 15.2431 + return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil())); 15.2432 + } else { 15.2433 + String dc = S.docComment(); 15.2434 + int pos = S.pos(); 15.2435 + JCModifiers mods = modifiersOpt(); 15.2436 + if (S.token() == CLASS || 15.2437 + S.token() == INTERFACE || 15.2438 + allowEnums && S.token() == ENUM) { 15.2439 + return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc)); 15.2440 + } else if (S.token() == LBRACE && !isInterface && 15.2441 + (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 15.2442 + mods.annotations.isEmpty()) { 15.2443 + return List.<JCTree>of(block(pos, mods.flags)); 15.2444 + } else { 15.2445 + pos = S.pos(); 15.2446 + List<JCTypeParameter> typarams = typeParametersOpt(); 15.2447 + // Hack alert: if there are type arguments but no Modifiers, the start 15.2448 + // position will be lost unless we set the Modifiers position. There 15.2449 + // should be an AST node for type parameters (BugId 5005090). 15.2450 + if (typarams.length() > 0 && mods.pos == Position.NOPOS) { 15.2451 + mods.pos = pos; 15.2452 + } 15.2453 + Token token = S.token(); 15.2454 + Name name = S.name(); 15.2455 + pos = S.pos(); 15.2456 + JCExpression type; 15.2457 + boolean isVoid = S.token() == VOID; 15.2458 + if (isVoid) { 15.2459 + type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 15.2460 + S.nextToken(); 15.2461 + } else { 15.2462 + type = parseType(); 15.2463 + } 15.2464 + if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 15.2465 + if (isInterface || name != className) 15.2466 + log.error(pos, "invalid.meth.decl.ret.type.req"); 15.2467 + return List.of(methodDeclaratorRest( 15.2468 + pos, mods, null, names.init, typarams, 15.2469 + isInterface, true, dc)); 15.2470 + } else { 15.2471 + pos = S.pos(); 15.2472 + name = ident(); 15.2473 + if (S.token() == LPAREN) { 15.2474 + return List.of(methodDeclaratorRest( 15.2475 + pos, mods, type, name, typarams, 15.2476 + isInterface, isVoid, dc)); 15.2477 + } else if (!isVoid && typarams.isEmpty()) { 15.2478 + List<JCTree> defs = 15.2479 + variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 15.2480 + new ListBuffer<JCTree>()).toList(); 15.2481 + storeEnd(defs.last(), S.endPos()); 15.2482 + accept(SEMI); 15.2483 + return defs; 15.2484 + } else { 15.2485 + pos = S.pos(); 15.2486 + List<JCTree> err = isVoid 15.2487 + ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 15.2488 + List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null))) 15.2489 + : null; 15.2490 + return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN)); 15.2491 + } 15.2492 + } 15.2493 + } 15.2494 + } 15.2495 + } 15.2496 + 15.2497 + /** MethodDeclaratorRest = 15.2498 + * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 15.2499 + * VoidMethodDeclaratorRest = 15.2500 + * FormalParameters [Throws TypeList] ( MethodBody | ";") 15.2501 + * InterfaceMethodDeclaratorRest = 15.2502 + * FormalParameters BracketsOpt [THROWS TypeList] ";" 15.2503 + * VoidInterfaceMethodDeclaratorRest = 15.2504 + * FormalParameters [THROWS TypeList] ";" 15.2505 + * ConstructorDeclaratorRest = 15.2506 + * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody 15.2507 + */ 15.2508 + JCTree methodDeclaratorRest(int pos, 15.2509 + JCModifiers mods, 15.2510 + JCExpression type, 15.2511 + Name name, 15.2512 + List<JCTypeParameter> typarams, 15.2513 + boolean isInterface, boolean isVoid, 15.2514 + String dc) { 15.2515 + List<JCVariableDecl> params = formalParameters(); 15.2516 + if (!isVoid) type = bracketsOpt(type); 15.2517 + List<JCExpression> thrown = List.nil(); 15.2518 + if (S.token() == THROWS) { 15.2519 + S.nextToken(); 15.2520 + thrown = qualidentList(); 15.2521 + } 15.2522 + JCBlock body = null; 15.2523 + JCExpression defaultValue; 15.2524 + if (S.token() == LBRACE) { 15.2525 + body = block(); 15.2526 + defaultValue = null; 15.2527 + } else { 15.2528 + if (S.token() == DEFAULT) { 15.2529 + accept(DEFAULT); 15.2530 + defaultValue = annotationValue(); 15.2531 + } else { 15.2532 + defaultValue = null; 15.2533 + } 15.2534 + accept(SEMI); 15.2535 + if (S.pos() <= errorEndPos) { 15.2536 + // error recovery 15.2537 + skip(false, true, false, false); 15.2538 + if (S.token() == LBRACE) { 15.2539 + body = block(); 15.2540 + } 15.2541 + } 15.2542 + } 15.2543 + JCMethodDecl result = 15.2544 + toP(F.at(pos).MethodDef(mods, name, type, typarams, 15.2545 + params, thrown, 15.2546 + body, defaultValue)); 15.2547 + attach(result, dc); 15.2548 + return result; 15.2549 + } 15.2550 + 15.2551 + /** QualidentList = Qualident {"," Qualident} 15.2552 + */ 15.2553 + List<JCExpression> qualidentList() { 15.2554 + ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 15.2555 + ts.append(qualident()); 15.2556 + while (S.token() == COMMA) { 15.2557 + S.nextToken(); 15.2558 + ts.append(qualident()); 15.2559 + } 15.2560 + return ts.toList(); 15.2561 + } 15.2562 + 15.2563 + /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 15.2564 + */ 15.2565 + List<JCTypeParameter> typeParametersOpt() { 15.2566 + if (S.token() == LT) { 15.2567 + checkGenerics(); 15.2568 + ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>(); 15.2569 + S.nextToken(); 15.2570 + typarams.append(typeParameter()); 15.2571 + while (S.token() == COMMA) { 15.2572 + S.nextToken(); 15.2573 + typarams.append(typeParameter()); 15.2574 + } 15.2575 + accept(GT); 15.2576 + return typarams.toList(); 15.2577 + } else { 15.2578 + return List.nil(); 15.2579 + } 15.2580 + } 15.2581 + 15.2582 + /** TypeParameter = TypeVariable [TypeParameterBound] 15.2583 + * TypeParameterBound = EXTENDS Type {"&" Type} 15.2584 + * TypeVariable = Ident 15.2585 + */ 15.2586 + JCTypeParameter typeParameter() { 15.2587 + int pos = S.pos(); 15.2588 + Name name = ident(); 15.2589 + ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 15.2590 + if (S.token() == EXTENDS) { 15.2591 + S.nextToken(); 15.2592 + bounds.append(parseType()); 15.2593 + while (S.token() == AMP) { 15.2594 + S.nextToken(); 15.2595 + bounds.append(parseType()); 15.2596 + } 15.2597 + } 15.2598 + return toP(F.at(pos).TypeParameter(name, bounds.toList())); 15.2599 + } 15.2600 + 15.2601 + /** FormalParameters = "(" [ FormalParameterList ] ")" 15.2602 + * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 15.2603 + * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 15.2604 + */ 15.2605 + List<JCVariableDecl> formalParameters() { 15.2606 + ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 15.2607 + JCVariableDecl lastParam = null; 15.2608 + accept(LPAREN); 15.2609 + if (S.token() != RPAREN) { 15.2610 + params.append(lastParam = formalParameter()); 15.2611 + while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) { 15.2612 + S.nextToken(); 15.2613 + params.append(lastParam = formalParameter()); 15.2614 + } 15.2615 + } 15.2616 + accept(RPAREN); 15.2617 + return params.toList(); 15.2618 + } 15.2619 + 15.2620 + JCModifiers optFinal(long flags) { 15.2621 + JCModifiers mods = modifiersOpt(); 15.2622 + checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 15.2623 + mods.flags |= flags; 15.2624 + return mods; 15.2625 + } 15.2626 + 15.2627 + /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 15.2628 + * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 15.2629 + */ 15.2630 + JCVariableDecl formalParameter() { 15.2631 + JCModifiers mods = optFinal(Flags.PARAMETER); 15.2632 + JCExpression type = parseType(); 15.2633 + if (S.token() == ELLIPSIS) { 15.2634 + checkVarargs(); 15.2635 + mods.flags |= Flags.VARARGS; 15.2636 + type = to(F.at(S.pos()).TypeArray(type)); 15.2637 + S.nextToken(); 15.2638 + } 15.2639 + return variableDeclaratorId(mods, type); 15.2640 + } 15.2641 + 15.2642 +/* ---------- auxiliary methods -------------- */ 15.2643 + 15.2644 + /** Check that given tree is a legal expression statement. 15.2645 + */ 15.2646 + protected JCExpression checkExprStat(JCExpression t) { 15.2647 + switch(t.getTag()) { 15.2648 + case JCTree.PREINC: case JCTree.PREDEC: 15.2649 + case JCTree.POSTINC: case JCTree.POSTDEC: 15.2650 + case JCTree.ASSIGN: 15.2651 + case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG: 15.2652 + case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG: 15.2653 + case JCTree.PLUS_ASG: case JCTree.MINUS_ASG: 15.2654 + case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG: 15.2655 + case JCTree.APPLY: case JCTree.NEWCLASS: 15.2656 + case JCTree.ERRONEOUS: 15.2657 + return t; 15.2658 + default: 15.2659 + log.error(t.pos, "not.stmt"); 15.2660 + return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 15.2661 + } 15.2662 + } 15.2663 + 15.2664 + /** Return precedence of operator represented by token, 15.2665 + * -1 if token is not a binary operator. @see TreeInfo.opPrec 15.2666 + */ 15.2667 + static int prec(Token token) { 15.2668 + int oc = optag(token); 15.2669 + return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 15.2670 + } 15.2671 + 15.2672 + /** Return operation tag of binary operator represented by token, 15.2673 + * -1 if token is not a binary operator. 15.2674 + */ 15.2675 + static int optag(Token token) { 15.2676 + switch (token) { 15.2677 + case BARBAR: 15.2678 + return JCTree.OR; 15.2679 + case AMPAMP: 15.2680 + return JCTree.AND; 15.2681 + case BAR: 15.2682 + return JCTree.BITOR; 15.2683 + case BAREQ: 15.2684 + return JCTree.BITOR_ASG; 15.2685 + case CARET: 15.2686 + return JCTree.BITXOR; 15.2687 + case CARETEQ: 15.2688 + return JCTree.BITXOR_ASG; 15.2689 + case AMP: 15.2690 + return JCTree.BITAND; 15.2691 + case AMPEQ: 15.2692 + return JCTree.BITAND_ASG; 15.2693 + case EQEQ: 15.2694 + return JCTree.EQ; 15.2695 + case BANGEQ: 15.2696 + return JCTree.NE; 15.2697 + case LT: 15.2698 + return JCTree.LT; 15.2699 + case GT: 15.2700 + return JCTree.GT; 15.2701 + case LTEQ: 15.2702 + return JCTree.LE; 15.2703 + case GTEQ: 15.2704 + return JCTree.GE; 15.2705 + case LTLT: 15.2706 + return JCTree.SL; 15.2707 + case LTLTEQ: 15.2708 + return JCTree.SL_ASG; 15.2709 + case GTGT: 15.2710 + return JCTree.SR; 15.2711 + case GTGTEQ: 15.2712 + return JCTree.SR_ASG; 15.2713 + case GTGTGT: 15.2714 + return JCTree.USR; 15.2715 + case GTGTGTEQ: 15.2716 + return JCTree.USR_ASG; 15.2717 + case PLUS: 15.2718 + return JCTree.PLUS; 15.2719 + case PLUSEQ: 15.2720 + return JCTree.PLUS_ASG; 15.2721 + case SUB: 15.2722 + return JCTree.MINUS; 15.2723 + case SUBEQ: 15.2724 + return JCTree.MINUS_ASG; 15.2725 + case STAR: 15.2726 + return JCTree.MUL; 15.2727 + case STAREQ: 15.2728 + return JCTree.MUL_ASG; 15.2729 + case SLASH: 15.2730 + return JCTree.DIV; 15.2731 + case SLASHEQ: 15.2732 + return JCTree.DIV_ASG; 15.2733 + case PERCENT: 15.2734 + return JCTree.MOD; 15.2735 + case PERCENTEQ: 15.2736 + return JCTree.MOD_ASG; 15.2737 + case INSTANCEOF: 15.2738 + return JCTree.TYPETEST; 15.2739 + default: 15.2740 + return -1; 15.2741 + } 15.2742 + } 15.2743 + 15.2744 + /** Return operation tag of unary operator represented by token, 15.2745 + * -1 if token is not a binary operator. 15.2746 + */ 15.2747 + static int unoptag(Token token) { 15.2748 + switch (token) { 15.2749 + case PLUS: 15.2750 + return JCTree.POS; 15.2751 + case SUB: 15.2752 + return JCTree.NEG; 15.2753 + case BANG: 15.2754 + return JCTree.NOT; 15.2755 + case TILDE: 15.2756 + return JCTree.COMPL; 15.2757 + case PLUSPLUS: 15.2758 + return JCTree.PREINC; 15.2759 + case SUBSUB: 15.2760 + return JCTree.PREDEC; 15.2761 + default: 15.2762 + return -1; 15.2763 + } 15.2764 + } 15.2765 + 15.2766 + /** Return type tag of basic type represented by token, 15.2767 + * -1 if token is not a basic type identifier. 15.2768 + */ 15.2769 + static int typetag(Token token) { 15.2770 + switch (token) { 15.2771 + case BYTE: 15.2772 + return TypeTags.BYTE; 15.2773 + case CHAR: 15.2774 + return TypeTags.CHAR; 15.2775 + case SHORT: 15.2776 + return TypeTags.SHORT; 15.2777 + case INT: 15.2778 + return TypeTags.INT; 15.2779 + case LONG: 15.2780 + return TypeTags.LONG; 15.2781 + case FLOAT: 15.2782 + return TypeTags.FLOAT; 15.2783 + case DOUBLE: 15.2784 + return TypeTags.DOUBLE; 15.2785 + case BOOLEAN: 15.2786 + return TypeTags.BOOLEAN; 15.2787 + default: 15.2788 + return -1; 15.2789 + } 15.2790 + } 15.2791 + 15.2792 + void checkGenerics() { 15.2793 + if (!allowGenerics) { 15.2794 + log.error(S.pos(), "generics.not.supported.in.source", source.name); 15.2795 + allowGenerics = true; 15.2796 + } 15.2797 + } 15.2798 + void checkVarargs() { 15.2799 + if (!allowVarargs) { 15.2800 + log.error(S.pos(), "varargs.not.supported.in.source", source.name); 15.2801 + allowVarargs = true; 15.2802 + } 15.2803 + } 15.2804 + void checkForeach() { 15.2805 + if (!allowForeach) { 15.2806 + log.error(S.pos(), "foreach.not.supported.in.source", source.name); 15.2807 + allowForeach = true; 15.2808 + } 15.2809 + } 15.2810 + void checkStaticImports() { 15.2811 + if (!allowStaticImport) { 15.2812 + log.error(S.pos(), "static.import.not.supported.in.source", source.name); 15.2813 + allowStaticImport = true; 15.2814 + } 15.2815 + } 15.2816 + void checkAnnotations() { 15.2817 + if (!allowAnnotations) { 15.2818 + log.error(S.pos(), "annotations.not.supported.in.source", source.name); 15.2819 + allowAnnotations = true; 15.2820 + } 15.2821 + } 15.2822 +}
16.1 --- a/src/share/classes/com/sun/tools/javac/parser/Parser.java Fri Sep 12 14:35:51 2008 -0700 16.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Parser.java Fri Sep 12 23:32:51 2008 -0700 16.3 @@ -23,2834 +23,44 @@ 16.4 * have any questions. 16.5 */ 16.6 16.7 + 16.8 package com.sun.tools.javac.parser; 16.9 16.10 -import java.util.*; 16.11 +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 16.12 +import com.sun.tools.javac.tree.JCTree.JCExpression; 16.13 +import com.sun.tools.javac.tree.JCTree.JCStatement; 16.14 16.15 -import com.sun.tools.javac.tree.*; 16.16 -import com.sun.tools.javac.code.*; 16.17 -import com.sun.tools.javac.util.*; 16.18 -import com.sun.tools.javac.util.List; 16.19 -import static com.sun.tools.javac.util.ListBuffer.lb; 16.20 - 16.21 -import com.sun.tools.javac.tree.JCTree.*; 16.22 - 16.23 -import static com.sun.tools.javac.parser.Token.*; 16.24 - 16.25 -/** The parser maps a token sequence into an abstract syntax 16.26 - * tree. It operates by recursive descent, with code derived 16.27 - * systematically from an LL(1) grammar. For efficiency reasons, an 16.28 - * operator precedence scheme is used for parsing binary operation 16.29 - * expressions. 16.30 +/** 16.31 + * Reads syntactic units from source code. 16.32 + * Parsers are normally created from a ParserFactory. 16.33 * 16.34 - * <p><b>This is NOT part of any API supported by Sun Microsystems. If 16.35 - * you write code that depends on this, you do so at your own risk. 16.36 - * This code and its internal interfaces are subject to change or 16.37 - * deletion without notice.</b> 16.38 + * <p><b>This is NOT part of any API supported by Sun Microsystems. 16.39 + * If you write code that depends on this, you do so at your own risk. 16.40 + * This code and its internal interfaces are subject to change or 16.41 + * deletion without notice.</b> 16.42 */ 16.43 -public class Parser { 16.44 - 16.45 - /** A factory for creating parsers. */ 16.46 - public static class Factory { 16.47 - /** The context key for the parser factory. */ 16.48 - protected static final Context.Key<Parser.Factory> parserFactoryKey = 16.49 - new Context.Key<Parser.Factory>(); 16.50 - 16.51 - /** Get the Factory instance for this context. */ 16.52 - public static Factory instance(Context context) { 16.53 - Factory instance = context.get(parserFactoryKey); 16.54 - if (instance == null) 16.55 - instance = new Factory(context); 16.56 - return instance; 16.57 - } 16.58 - 16.59 - final TreeMaker F; 16.60 - final Log log; 16.61 - final Keywords keywords; 16.62 - final Source source; 16.63 - final Name.Table names; 16.64 - final Options options; 16.65 - 16.66 - /** Create a new parser factory. */ 16.67 - protected Factory(Context context) { 16.68 - context.put(parserFactoryKey, this); 16.69 - this.F = TreeMaker.instance(context); 16.70 - this.log = Log.instance(context); 16.71 - this.names = Name.Table.instance(context); 16.72 - this.keywords = Keywords.instance(context); 16.73 - this.source = Source.instance(context); 16.74 - this.options = Options.instance(context); 16.75 - } 16.76 - 16.77 - /** 16.78 - * Create a new Parser. 16.79 - * @param S Lexer for getting tokens while parsing 16.80 - * @param keepDocComments true if javadoc comments should be kept 16.81 - * @param genEndPos true if end positions should be generated 16.82 - */ 16.83 - public Parser newParser(Lexer S, boolean keepDocComments, boolean genEndPos) { 16.84 - if (!genEndPos) 16.85 - return new Parser(this, S, keepDocComments); 16.86 - else 16.87 - return new EndPosParser(this, S, keepDocComments); 16.88 - } 16.89 - } 16.90 - 16.91 - /** The number of precedence levels of infix operators. 16.92 +public interface Parser { 16.93 + /** 16.94 + * Parse a compilation unit. 16.95 + * @return a compilation unit 16.96 */ 16.97 - private static final int infixPrecedenceLevels = 10; 16.98 - 16.99 - /** The scanner used for lexical analysis. 16.100 - */ 16.101 - private Lexer S; 16.102 - 16.103 - /** The factory to be used for abstract syntax tree construction. 16.104 - */ 16.105 - protected TreeMaker F; 16.106 - 16.107 - /** The log to be used for error diagnostics. 16.108 - */ 16.109 - private Log log; 16.110 - 16.111 - /** The keyword table. */ 16.112 - private Keywords keywords; 16.113 - 16.114 - /** The Source language setting. */ 16.115 - private Source source; 16.116 - 16.117 - /** The name table. */ 16.118 - private Name.Table names; 16.119 - 16.120 - /** Construct a parser from a given scanner, tree factory and log. 16.121 - */ 16.122 - protected Parser(Factory fac, 16.123 - Lexer S, 16.124 - boolean keepDocComments) { 16.125 - this.S = S; 16.126 - S.nextToken(); // prime the pump 16.127 - this.F = fac.F; 16.128 - this.log = fac.log; 16.129 - this.names = fac.names; 16.130 - this.keywords = fac.keywords; 16.131 - this.source = fac.source; 16.132 - Options options = fac.options; 16.133 - this.allowGenerics = source.allowGenerics(); 16.134 - this.allowVarargs = source.allowVarargs(); 16.135 - this.allowAsserts = source.allowAsserts(); 16.136 - this.allowEnums = source.allowEnums(); 16.137 - this.allowForeach = source.allowForeach(); 16.138 - this.allowStaticImport = source.allowStaticImport(); 16.139 - this.allowAnnotations = source.allowAnnotations(); 16.140 - this.keepDocComments = keepDocComments; 16.141 - if (keepDocComments) docComments = new HashMap<JCTree,String>(); 16.142 - this.errorTree = F.Erroneous(); 16.143 - } 16.144 - 16.145 - /** Switch: Should generics be recognized? 16.146 - */ 16.147 - boolean allowGenerics; 16.148 - 16.149 - /** Switch: Should varargs be recognized? 16.150 - */ 16.151 - boolean allowVarargs; 16.152 - 16.153 - /** Switch: should we recognize assert statements, or just give a warning? 16.154 - */ 16.155 - boolean allowAsserts; 16.156 - 16.157 - /** Switch: should we recognize enums, or just give a warning? 16.158 - */ 16.159 - boolean allowEnums; 16.160 - 16.161 - /** Switch: should we recognize foreach? 16.162 - */ 16.163 - boolean allowForeach; 16.164 - 16.165 - /** Switch: should we recognize foreach? 16.166 - */ 16.167 - boolean allowStaticImport; 16.168 - 16.169 - /** Switch: should we recognize annotations? 16.170 - */ 16.171 - boolean allowAnnotations; 16.172 - 16.173 - /** Switch: should we keep docComments? 16.174 - */ 16.175 - boolean keepDocComments; 16.176 - 16.177 - /** When terms are parsed, the mode determines which is expected: 16.178 - * mode = EXPR : an expression 16.179 - * mode = TYPE : a type 16.180 - * mode = NOPARAMS : no parameters allowed for type 16.181 - * mode = TYPEARG : type argument 16.182 - */ 16.183 - static final int EXPR = 1; 16.184 - static final int TYPE = 2; 16.185 - static final int NOPARAMS = 4; 16.186 - static final int TYPEARG = 8; 16.187 - 16.188 - /** The current mode. 16.189 - */ 16.190 - private int mode = 0; 16.191 - 16.192 - /** The mode of the term that was parsed last. 16.193 - */ 16.194 - private int lastmode = 0; 16.195 - 16.196 -/* ---------- error recovery -------------- */ 16.197 - 16.198 - private JCErroneous errorTree; 16.199 - 16.200 - /** Skip forward until a suitable stop token is found. 16.201 - */ 16.202 - private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 16.203 - while (true) { 16.204 - switch (S.token()) { 16.205 - case SEMI: 16.206 - S.nextToken(); 16.207 - return; 16.208 - case PUBLIC: 16.209 - case FINAL: 16.210 - case ABSTRACT: 16.211 - case MONKEYS_AT: 16.212 - case EOF: 16.213 - case CLASS: 16.214 - case INTERFACE: 16.215 - case ENUM: 16.216 - return; 16.217 - case IMPORT: 16.218 - if (stopAtImport) 16.219 - return; 16.220 - break; 16.221 - case LBRACE: 16.222 - case RBRACE: 16.223 - case PRIVATE: 16.224 - case PROTECTED: 16.225 - case STATIC: 16.226 - case TRANSIENT: 16.227 - case NATIVE: 16.228 - case VOLATILE: 16.229 - case SYNCHRONIZED: 16.230 - case STRICTFP: 16.231 - case LT: 16.232 - case BYTE: 16.233 - case SHORT: 16.234 - case CHAR: 16.235 - case INT: 16.236 - case LONG: 16.237 - case FLOAT: 16.238 - case DOUBLE: 16.239 - case BOOLEAN: 16.240 - case VOID: 16.241 - if (stopAtMemberDecl) 16.242 - return; 16.243 - break; 16.244 - case IDENTIFIER: 16.245 - if (stopAtIdentifier) 16.246 - return; 16.247 - break; 16.248 - case CASE: 16.249 - case DEFAULT: 16.250 - case IF: 16.251 - case FOR: 16.252 - case WHILE: 16.253 - case DO: 16.254 - case TRY: 16.255 - case SWITCH: 16.256 - case RETURN: 16.257 - case THROW: 16.258 - case BREAK: 16.259 - case CONTINUE: 16.260 - case ELSE: 16.261 - case FINALLY: 16.262 - case CATCH: 16.263 - if (stopAtStatement) 16.264 - return; 16.265 - break; 16.266 - } 16.267 - S.nextToken(); 16.268 - } 16.269 - } 16.270 - 16.271 - private JCErroneous syntaxError(int pos, String key, Token... args) { 16.272 - return syntaxError(pos, null, key, args); 16.273 - } 16.274 - 16.275 - private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) { 16.276 - setErrorEndPos(pos); 16.277 - reportSyntaxError(pos, key, (Object[])args); 16.278 - return toP(F.at(pos).Erroneous(errs)); 16.279 - } 16.280 - 16.281 - private int errorPos = Position.NOPOS; 16.282 - /** 16.283 - * Report a syntax error at given position using the given 16.284 - * argument unless one was already reported at the same position. 16.285 - */ 16.286 - private void reportSyntaxError(int pos, String key, Object... args) { 16.287 - if (pos > S.errPos() || pos == Position.NOPOS) { 16.288 - if (S.token() == EOF) 16.289 - log.error(pos, "premature.eof"); 16.290 - else 16.291 - log.error(pos, key, args); 16.292 - } 16.293 - S.errPos(pos); 16.294 - if (S.pos() == errorPos) 16.295 - S.nextToken(); // guarantee progress 16.296 - errorPos = S.pos(); 16.297 - } 16.298 - 16.299 - 16.300 - /** Generate a syntax error at current position unless one was already 16.301 - * reported at the same position. 16.302 - */ 16.303 - private JCErroneous syntaxError(String key) { 16.304 - return syntaxError(S.pos(), key); 16.305 - } 16.306 - 16.307 - /** Generate a syntax error at current position unless one was 16.308 - * already reported at the same position. 16.309 - */ 16.310 - private JCErroneous syntaxError(String key, Token arg) { 16.311 - return syntaxError(S.pos(), key, arg); 16.312 - } 16.313 - 16.314 - /** If next input token matches given token, skip it, otherwise report 16.315 - * an error. 16.316 - */ 16.317 - public void accept(Token token) { 16.318 - if (S.token() == token) { 16.319 - S.nextToken(); 16.320 - } else { 16.321 - setErrorEndPos(S.pos()); 16.322 - reportSyntaxError(S.prevEndPos(), "expected", token); 16.323 - } 16.324 - } 16.325 - 16.326 - /** Report an illegal start of expression/type error at given position. 16.327 - */ 16.328 - JCExpression illegal(int pos) { 16.329 - setErrorEndPos(S.pos()); 16.330 - if ((mode & EXPR) != 0) 16.331 - return syntaxError(pos, "illegal.start.of.expr"); 16.332 - else 16.333 - return syntaxError(pos, "illegal.start.of.type"); 16.334 - 16.335 - } 16.336 - 16.337 - /** Report an illegal start of expression/type error at current position. 16.338 - */ 16.339 - JCExpression illegal() { 16.340 - return illegal(S.pos()); 16.341 - } 16.342 - 16.343 - /** Diagnose a modifier flag from the set, if any. */ 16.344 - void checkNoMods(long mods) { 16.345 - if (mods != 0) { 16.346 - long lowestMod = mods & -mods; 16.347 - log.error(S.pos(), "mod.not.allowed.here", 16.348 - Flags.asFlagSet(lowestMod)); 16.349 - } 16.350 - } 16.351 - 16.352 -/* ---------- doc comments --------- */ 16.353 - 16.354 - /** A hashtable to store all documentation comments 16.355 - * indexed by the tree nodes they refer to. 16.356 - * defined only if option flag keepDocComment is set. 16.357 - */ 16.358 - Map<JCTree, String> docComments; 16.359 - 16.360 - /** Make an entry into docComments hashtable, 16.361 - * provided flag keepDocComments is set and given doc comment is non-null. 16.362 - * @param tree The tree to be used as index in the hashtable 16.363 - * @param dc The doc comment to associate with the tree, or null. 16.364 - */ 16.365 - void attach(JCTree tree, String dc) { 16.366 - if (keepDocComments && dc != null) { 16.367 -// System.out.println("doc comment = ");System.out.println(dc);//DEBUG 16.368 - docComments.put(tree, dc); 16.369 - } 16.370 - } 16.371 - 16.372 -/* -------- source positions ------- */ 16.373 - 16.374 - private int errorEndPos = -1; 16.375 - 16.376 - private void setErrorEndPos(int errPos) { 16.377 - if (errPos > errorEndPos) 16.378 - errorEndPos = errPos; 16.379 - } 16.380 - 16.381 - protected int getErrorEndPos() { 16.382 - return errorEndPos; 16.383 - } 16.384 + JCCompilationUnit parseCompilationUnit(); 16.385 16.386 /** 16.387 - * Store ending position for a tree. 16.388 - * @param tree The tree. 16.389 - * @param endpos The ending position to associate with the tree. 16.390 + * Parse an expression. 16.391 + * @return an expression 16.392 */ 16.393 - protected void storeEnd(JCTree tree, int endpos) {} 16.394 + JCExpression parseExpression(); 16.395 16.396 /** 16.397 - * Store ending position for a tree. The ending position should 16.398 - * be the ending position of the current token. 16.399 - * @param t The tree. 16.400 + * Parse a statement. 16.401 + * @return an expression 16.402 */ 16.403 - protected <T extends JCTree> T to(T t) { return t; } 16.404 + JCStatement parseStatement(); 16.405 16.406 /** 16.407 - * Store ending position for a tree. The ending position should 16.408 - * be greater of the ending position of the previous token and errorEndPos. 16.409 - * @param t The tree. 16.410 + * Parse a type. 16.411 + * @return an expression for a type 16.412 */ 16.413 - protected <T extends JCTree> T toP(T t) { return t; } 16.414 - 16.415 - /** Get the start position for a tree node. The start position is 16.416 - * defined to be the position of the first character of the first 16.417 - * token of the node's source text. 16.418 - * @param tree The tree node 16.419 - */ 16.420 - public int getStartPos(JCTree tree) { 16.421 - return TreeInfo.getStartPos(tree); 16.422 - } 16.423 - 16.424 - /** 16.425 - * Get the end position for a tree node. The end position is 16.426 - * defined to be the position of the last character of the last 16.427 - * token of the node's source text. Returns Position.NOPOS if end 16.428 - * positions are not generated or the position is otherwise not 16.429 - * found. 16.430 - * @param tree The tree node 16.431 - */ 16.432 - public int getEndPos(JCTree tree) { 16.433 - return Position.NOPOS; 16.434 - } 16.435 - 16.436 - 16.437 - 16.438 -/* ---------- parsing -------------- */ 16.439 - 16.440 - /** 16.441 - * Ident = IDENTIFIER 16.442 - */ 16.443 - Name ident() { 16.444 - if (S.token() == IDENTIFIER) { 16.445 - Name name = S.name(); 16.446 - S.nextToken(); 16.447 - return name; 16.448 - } else if (S.token() == ASSERT) { 16.449 - if (allowAsserts) { 16.450 - log.error(S.pos(), "assert.as.identifier"); 16.451 - S.nextToken(); 16.452 - return names.error; 16.453 - } else { 16.454 - log.warning(S.pos(), "assert.as.identifier"); 16.455 - Name name = S.name(); 16.456 - S.nextToken(); 16.457 - return name; 16.458 - } 16.459 - } else if (S.token() == ENUM) { 16.460 - if (allowEnums) { 16.461 - log.error(S.pos(), "enum.as.identifier"); 16.462 - S.nextToken(); 16.463 - return names.error; 16.464 - } else { 16.465 - log.warning(S.pos(), "enum.as.identifier"); 16.466 - Name name = S.name(); 16.467 - S.nextToken(); 16.468 - return name; 16.469 - } 16.470 - } else { 16.471 - accept(IDENTIFIER); 16.472 - return names.error; 16.473 - } 16.474 + JCExpression parseType(); 16.475 } 16.476 - 16.477 - /** 16.478 - * Qualident = Ident { DOT Ident } 16.479 - */ 16.480 - public JCExpression qualident() { 16.481 - JCExpression t = toP(F.at(S.pos()).Ident(ident())); 16.482 - while (S.token() == DOT) { 16.483 - int pos = S.pos(); 16.484 - S.nextToken(); 16.485 - t = toP(F.at(pos).Select(t, ident())); 16.486 - } 16.487 - return t; 16.488 - } 16.489 - 16.490 - /** 16.491 - * Literal = 16.492 - * INTLITERAL 16.493 - * | LONGLITERAL 16.494 - * | FLOATLITERAL 16.495 - * | DOUBLELITERAL 16.496 - * | CHARLITERAL 16.497 - * | STRINGLITERAL 16.498 - * | TRUE 16.499 - * | FALSE 16.500 - * | NULL 16.501 - */ 16.502 - JCExpression literal(Name prefix) { 16.503 - int pos = S.pos(); 16.504 - JCExpression t = errorTree; 16.505 - switch (S.token()) { 16.506 - case INTLITERAL: 16.507 - try { 16.508 - t = F.at(pos).Literal( 16.509 - TypeTags.INT, 16.510 - Convert.string2int(strval(prefix), S.radix())); 16.511 - } catch (NumberFormatException ex) { 16.512 - log.error(S.pos(), "int.number.too.large", strval(prefix)); 16.513 - } 16.514 - break; 16.515 - case LONGLITERAL: 16.516 - try { 16.517 - t = F.at(pos).Literal( 16.518 - TypeTags.LONG, 16.519 - new Long(Convert.string2long(strval(prefix), S.radix()))); 16.520 - } catch (NumberFormatException ex) { 16.521 - log.error(S.pos(), "int.number.too.large", strval(prefix)); 16.522 - } 16.523 - break; 16.524 - case FLOATLITERAL: { 16.525 - String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 16.526 - Float n; 16.527 - try { 16.528 - n = Float.valueOf(proper); 16.529 - } catch (NumberFormatException ex) { 16.530 - // error already repoted in scanner 16.531 - n = Float.NaN; 16.532 - } 16.533 - if (n.floatValue() == 0.0f && !isZero(proper)) 16.534 - log.error(S.pos(), "fp.number.too.small"); 16.535 - else if (n.floatValue() == Float.POSITIVE_INFINITY) 16.536 - log.error(S.pos(), "fp.number.too.large"); 16.537 - else 16.538 - t = F.at(pos).Literal(TypeTags.FLOAT, n); 16.539 - break; 16.540 - } 16.541 - case DOUBLELITERAL: { 16.542 - String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 16.543 - Double n; 16.544 - try { 16.545 - n = Double.valueOf(proper); 16.546 - } catch (NumberFormatException ex) { 16.547 - // error already reported in scanner 16.548 - n = Double.NaN; 16.549 - } 16.550 - if (n.doubleValue() == 0.0d && !isZero(proper)) 16.551 - log.error(S.pos(), "fp.number.too.small"); 16.552 - else if (n.doubleValue() == Double.POSITIVE_INFINITY) 16.553 - log.error(S.pos(), "fp.number.too.large"); 16.554 - else 16.555 - t = F.at(pos).Literal(TypeTags.DOUBLE, n); 16.556 - break; 16.557 - } 16.558 - case CHARLITERAL: 16.559 - t = F.at(pos).Literal( 16.560 - TypeTags.CHAR, 16.561 - S.stringVal().charAt(0) + 0); 16.562 - break; 16.563 - case STRINGLITERAL: 16.564 - t = F.at(pos).Literal( 16.565 - TypeTags.CLASS, 16.566 - S.stringVal()); 16.567 - break; 16.568 - case TRUE: case FALSE: 16.569 - t = F.at(pos).Literal( 16.570 - TypeTags.BOOLEAN, 16.571 - (S.token() == TRUE ? 1 : 0)); 16.572 - break; 16.573 - case NULL: 16.574 - t = F.at(pos).Literal( 16.575 - TypeTags.BOT, 16.576 - null); 16.577 - break; 16.578 - default: 16.579 - assert false; 16.580 - } 16.581 - if (t == errorTree) 16.582 - t = F.at(pos).Erroneous(); 16.583 - storeEnd(t, S.endPos()); 16.584 - S.nextToken(); 16.585 - return t; 16.586 - } 16.587 -//where 16.588 - boolean isZero(String s) { 16.589 - char[] cs = s.toCharArray(); 16.590 - int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10); 16.591 - int i = ((base==16) ? 2 : 0); 16.592 - while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++; 16.593 - return !(i < cs.length && (Character.digit(cs[i], base) > 0)); 16.594 - } 16.595 - 16.596 - String strval(Name prefix) { 16.597 - String s = S.stringVal(); 16.598 - return (prefix.len == 0) ? s : prefix + s; 16.599 - } 16.600 - 16.601 - /** terms can be either expressions or types. 16.602 - */ 16.603 - public JCExpression expression() { 16.604 - return term(EXPR); 16.605 - } 16.606 - 16.607 - public JCExpression type() { 16.608 - return term(TYPE); 16.609 - } 16.610 - 16.611 - JCExpression term(int newmode) { 16.612 - int prevmode = mode; 16.613 - mode = newmode; 16.614 - JCExpression t = term(); 16.615 - lastmode = mode; 16.616 - mode = prevmode; 16.617 - return t; 16.618 - } 16.619 - 16.620 - /** 16.621 - * Expression = Expression1 [ExpressionRest] 16.622 - * ExpressionRest = [AssignmentOperator Expression1] 16.623 - * AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | 16.624 - * "&=" | "|=" | "^=" | 16.625 - * "%=" | "<<=" | ">>=" | ">>>=" 16.626 - * Type = Type1 16.627 - * TypeNoParams = TypeNoParams1 16.628 - * StatementExpression = Expression 16.629 - * ConstantExpression = Expression 16.630 - */ 16.631 - JCExpression term() { 16.632 - JCExpression t = term1(); 16.633 - if ((mode & EXPR) != 0 && 16.634 - S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0) 16.635 - return termRest(t); 16.636 - else 16.637 - return t; 16.638 - } 16.639 - 16.640 - JCExpression termRest(JCExpression t) { 16.641 - switch (S.token()) { 16.642 - case EQ: { 16.643 - int pos = S.pos(); 16.644 - S.nextToken(); 16.645 - mode = EXPR; 16.646 - JCExpression t1 = term(); 16.647 - return toP(F.at(pos).Assign(t, t1)); 16.648 - } 16.649 - case PLUSEQ: 16.650 - case SUBEQ: 16.651 - case STAREQ: 16.652 - case SLASHEQ: 16.653 - case PERCENTEQ: 16.654 - case AMPEQ: 16.655 - case BAREQ: 16.656 - case CARETEQ: 16.657 - case LTLTEQ: 16.658 - case GTGTEQ: 16.659 - case GTGTGTEQ: 16.660 - int pos = S.pos(); 16.661 - Token token = S.token(); 16.662 - S.nextToken(); 16.663 - mode = EXPR; 16.664 - JCExpression t1 = term(); 16.665 - return F.at(pos).Assignop(optag(token), t, t1); 16.666 - default: 16.667 - return t; 16.668 - } 16.669 - } 16.670 - 16.671 - /** Expression1 = Expression2 [Expression1Rest] 16.672 - * Type1 = Type2 16.673 - * TypeNoParams1 = TypeNoParams2 16.674 - */ 16.675 - JCExpression term1() { 16.676 - JCExpression t = term2(); 16.677 - if ((mode & EXPR) != 0 && S.token() == QUES) { 16.678 - mode = EXPR; 16.679 - return term1Rest(t); 16.680 - } else { 16.681 - return t; 16.682 - } 16.683 - } 16.684 - 16.685 - /** Expression1Rest = ["?" Expression ":" Expression1] 16.686 - */ 16.687 - JCExpression term1Rest(JCExpression t) { 16.688 - if (S.token() == QUES) { 16.689 - int pos = S.pos(); 16.690 - S.nextToken(); 16.691 - JCExpression t1 = term(); 16.692 - accept(COLON); 16.693 - JCExpression t2 = term1(); 16.694 - return F.at(pos).Conditional(t, t1, t2); 16.695 - } else { 16.696 - return t; 16.697 - } 16.698 - } 16.699 - 16.700 - /** Expression2 = Expression3 [Expression2Rest] 16.701 - * Type2 = Type3 16.702 - * TypeNoParams2 = TypeNoParams3 16.703 - */ 16.704 - JCExpression term2() { 16.705 - JCExpression t = term3(); 16.706 - if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) { 16.707 - mode = EXPR; 16.708 - return term2Rest(t, TreeInfo.orPrec); 16.709 - } else { 16.710 - return t; 16.711 - } 16.712 - } 16.713 - 16.714 - /* Expression2Rest = {infixop Expression3} 16.715 - * | Expression3 instanceof Type 16.716 - * infixop = "||" 16.717 - * | "&&" 16.718 - * | "|" 16.719 - * | "^" 16.720 - * | "&" 16.721 - * | "==" | "!=" 16.722 - * | "<" | ">" | "<=" | ">=" 16.723 - * | "<<" | ">>" | ">>>" 16.724 - * | "+" | "-" 16.725 - * | "*" | "/" | "%" 16.726 - */ 16.727 - JCExpression term2Rest(JCExpression t, int minprec) { 16.728 - List<JCExpression[]> savedOd = odStackSupply.elems; 16.729 - JCExpression[] odStack = newOdStack(); 16.730 - List<Token[]> savedOp = opStackSupply.elems; 16.731 - Token[] opStack = newOpStack(); 16.732 - // optimization, was odStack = new Tree[...]; opStack = new Tree[...]; 16.733 - int top = 0; 16.734 - odStack[0] = t; 16.735 - int startPos = S.pos(); 16.736 - Token topOp = ERROR; 16.737 - while (prec(S.token()) >= minprec) { 16.738 - opStack[top] = topOp; 16.739 - top++; 16.740 - topOp = S.token(); 16.741 - int pos = S.pos(); 16.742 - S.nextToken(); 16.743 - odStack[top] = topOp == INSTANCEOF ? type() : term3(); 16.744 - while (top > 0 && prec(topOp) >= prec(S.token())) { 16.745 - odStack[top-1] = makeOp(pos, topOp, odStack[top-1], 16.746 - odStack[top]); 16.747 - top--; 16.748 - topOp = opStack[top]; 16.749 - } 16.750 - } 16.751 - assert top == 0; 16.752 - t = odStack[0]; 16.753 - 16.754 - if (t.getTag() == JCTree.PLUS) { 16.755 - StringBuffer buf = foldStrings(t); 16.756 - if (buf != null) { 16.757 - t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString())); 16.758 - } 16.759 - } 16.760 - 16.761 - odStackSupply.elems = savedOd; // optimization 16.762 - opStackSupply.elems = savedOp; // optimization 16.763 - return t; 16.764 - } 16.765 -//where 16.766 - /** Construct a binary or type test node. 16.767 - */ 16.768 - private JCExpression makeOp(int pos, 16.769 - Token topOp, 16.770 - JCExpression od1, 16.771 - JCExpression od2) 16.772 - { 16.773 - if (topOp == INSTANCEOF) { 16.774 - return F.at(pos).TypeTest(od1, od2); 16.775 - } else { 16.776 - return F.at(pos).Binary(optag(topOp), od1, od2); 16.777 - } 16.778 - } 16.779 - /** If tree is a concatenation of string literals, replace it 16.780 - * by a single literal representing the concatenated string. 16.781 - */ 16.782 - protected StringBuffer foldStrings(JCTree tree) { 16.783 - List<String> buf = List.nil(); 16.784 - while (true) { 16.785 - if (tree.getTag() == JCTree.LITERAL) { 16.786 - JCLiteral lit = (JCLiteral) tree; 16.787 - if (lit.typetag == TypeTags.CLASS) { 16.788 - StringBuffer sbuf = 16.789 - new StringBuffer((String)lit.value); 16.790 - while (buf.nonEmpty()) { 16.791 - sbuf.append(buf.head); 16.792 - buf = buf.tail; 16.793 - } 16.794 - return sbuf; 16.795 - } 16.796 - } else if (tree.getTag() == JCTree.PLUS) { 16.797 - JCBinary op = (JCBinary)tree; 16.798 - if (op.rhs.getTag() == JCTree.LITERAL) { 16.799 - JCLiteral lit = (JCLiteral) op.rhs; 16.800 - if (lit.typetag == TypeTags.CLASS) { 16.801 - buf = buf.prepend((String) lit.value); 16.802 - tree = op.lhs; 16.803 - continue; 16.804 - } 16.805 - } 16.806 - } 16.807 - return null; 16.808 - } 16.809 - } 16.810 - 16.811 - /** optimization: To save allocating a new operand/operator stack 16.812 - * for every binary operation, we use supplys. 16.813 - */ 16.814 - ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>(); 16.815 - ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>(); 16.816 - 16.817 - private JCExpression[] newOdStack() { 16.818 - if (odStackSupply.elems == odStackSupply.last) 16.819 - odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]); 16.820 - JCExpression[] odStack = odStackSupply.elems.head; 16.821 - odStackSupply.elems = odStackSupply.elems.tail; 16.822 - return odStack; 16.823 - } 16.824 - 16.825 - private Token[] newOpStack() { 16.826 - if (opStackSupply.elems == opStackSupply.last) 16.827 - opStackSupply.append(new Token[infixPrecedenceLevels + 1]); 16.828 - Token[] opStack = opStackSupply.elems.head; 16.829 - opStackSupply.elems = opStackSupply.elems.tail; 16.830 - return opStack; 16.831 - } 16.832 - 16.833 - /** Expression3 = PrefixOp Expression3 16.834 - * | "(" Expr | TypeNoParams ")" Expression3 16.835 - * | Primary {Selector} {PostfixOp} 16.836 - * Primary = "(" Expression ")" 16.837 - * | Literal 16.838 - * | [TypeArguments] THIS [Arguments] 16.839 - * | [TypeArguments] SUPER SuperSuffix 16.840 - * | NEW [TypeArguments] Creator 16.841 - * | Ident { "." Ident } 16.842 - * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 16.843 - * | Arguments 16.844 - * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 16.845 - * ] 16.846 - * | BasicType BracketsOpt "." CLASS 16.847 - * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" 16.848 - * PostfixOp = "++" | "--" 16.849 - * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt 16.850 - * | BasicType 16.851 - * TypeNoParams3 = Ident { "." Ident } BracketsOpt 16.852 - * Selector = "." [TypeArguments] Ident [Arguments] 16.853 - * | "." THIS 16.854 - * | "." [TypeArguments] SUPER SuperSuffix 16.855 - * | "." NEW [TypeArguments] InnerCreator 16.856 - * | "[" Expression "]" 16.857 - * TypeSelector = "." Ident [TypeArguments] 16.858 - * SuperSuffix = Arguments | "." Ident [Arguments] 16.859 - */ 16.860 - protected JCExpression term3() { 16.861 - int pos = S.pos(); 16.862 - JCExpression t; 16.863 - List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); 16.864 - switch (S.token()) { 16.865 - case QUES: 16.866 - if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { 16.867 - mode = TYPE; 16.868 - return typeArgument(); 16.869 - } else 16.870 - return illegal(); 16.871 - case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: 16.872 - if (typeArgs == null && (mode & EXPR) != 0) { 16.873 - Token token = S.token(); 16.874 - S.nextToken(); 16.875 - mode = EXPR; 16.876 - if (token == SUB && 16.877 - (S.token() == INTLITERAL || S.token() == LONGLITERAL) && 16.878 - S.radix() == 10) { 16.879 - mode = EXPR; 16.880 - t = literal(names.hyphen); 16.881 - } else { 16.882 - t = term3(); 16.883 - return F.at(pos).Unary(unoptag(token), t); 16.884 - } 16.885 - } else return illegal(); 16.886 - break; 16.887 - case LPAREN: 16.888 - if (typeArgs == null && (mode & EXPR) != 0) { 16.889 - S.nextToken(); 16.890 - mode = EXPR | TYPE | NOPARAMS; 16.891 - t = term3(); 16.892 - if ((mode & TYPE) != 0 && S.token() == LT) { 16.893 - // Could be a cast to a parameterized type 16.894 - int op = JCTree.LT; 16.895 - int pos1 = S.pos(); 16.896 - S.nextToken(); 16.897 - mode &= (EXPR | TYPE); 16.898 - mode |= TYPEARG; 16.899 - JCExpression t1 = term3(); 16.900 - if ((mode & TYPE) != 0 && 16.901 - (S.token() == COMMA || S.token() == GT)) { 16.902 - mode = TYPE; 16.903 - ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 16.904 - args.append(t1); 16.905 - while (S.token() == COMMA) { 16.906 - S.nextToken(); 16.907 - args.append(typeArgument()); 16.908 - } 16.909 - accept(GT); 16.910 - t = F.at(pos1).TypeApply(t, args.toList()); 16.911 - checkGenerics(); 16.912 - t = bracketsOpt(toP(t)); 16.913 - } else if ((mode & EXPR) != 0) { 16.914 - mode = EXPR; 16.915 - t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec)); 16.916 - t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 16.917 - } else { 16.918 - accept(GT); 16.919 - } 16.920 - } else { 16.921 - t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 16.922 - } 16.923 - accept(RPAREN); 16.924 - lastmode = mode; 16.925 - mode = EXPR; 16.926 - if ((lastmode & EXPR) == 0) { 16.927 - JCExpression t1 = term3(); 16.928 - return F.at(pos).TypeCast(t, t1); 16.929 - } else if ((lastmode & TYPE) != 0) { 16.930 - switch (S.token()) { 16.931 - /*case PLUSPLUS: case SUBSUB: */ 16.932 - case BANG: case TILDE: 16.933 - case LPAREN: case THIS: case SUPER: 16.934 - case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 16.935 - case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 16.936 - case TRUE: case FALSE: case NULL: 16.937 - case NEW: case IDENTIFIER: case ASSERT: case ENUM: 16.938 - case BYTE: case SHORT: case CHAR: case INT: 16.939 - case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 16.940 - JCExpression t1 = term3(); 16.941 - return F.at(pos).TypeCast(t, t1); 16.942 - } 16.943 - } 16.944 - } else return illegal(); 16.945 - t = toP(F.at(pos).Parens(t)); 16.946 - break; 16.947 - case THIS: 16.948 - if ((mode & EXPR) != 0) { 16.949 - mode = EXPR; 16.950 - t = to(F.at(pos).Ident(names._this)); 16.951 - S.nextToken(); 16.952 - if (typeArgs == null) 16.953 - t = argumentsOpt(null, t); 16.954 - else 16.955 - t = arguments(typeArgs, t); 16.956 - typeArgs = null; 16.957 - } else return illegal(); 16.958 - break; 16.959 - case SUPER: 16.960 - if ((mode & EXPR) != 0) { 16.961 - mode = EXPR; 16.962 - t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super))); 16.963 - typeArgs = null; 16.964 - } else return illegal(); 16.965 - break; 16.966 - case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: 16.967 - case CHARLITERAL: case STRINGLITERAL: 16.968 - case TRUE: case FALSE: case NULL: 16.969 - if (typeArgs == null && (mode & EXPR) != 0) { 16.970 - mode = EXPR; 16.971 - t = literal(names.empty); 16.972 - } else return illegal(); 16.973 - break; 16.974 - case NEW: 16.975 - if (typeArgs != null) return illegal(); 16.976 - if ((mode & EXPR) != 0) { 16.977 - mode = EXPR; 16.978 - S.nextToken(); 16.979 - if (S.token() == LT) typeArgs = typeArguments(); 16.980 - t = creator(pos, typeArgs); 16.981 - typeArgs = null; 16.982 - } else return illegal(); 16.983 - break; 16.984 - case IDENTIFIER: case ASSERT: case ENUM: 16.985 - if (typeArgs != null) return illegal(); 16.986 - t = toP(F.at(S.pos()).Ident(ident())); 16.987 - loop: while (true) { 16.988 - pos = S.pos(); 16.989 - switch (S.token()) { 16.990 - case LBRACKET: 16.991 - S.nextToken(); 16.992 - if (S.token() == RBRACKET) { 16.993 - S.nextToken(); 16.994 - t = bracketsOpt(t); 16.995 - t = toP(F.at(pos).TypeArray(t)); 16.996 - t = bracketsSuffix(t); 16.997 - } else { 16.998 - if ((mode & EXPR) != 0) { 16.999 - mode = EXPR; 16.1000 - JCExpression t1 = term(); 16.1001 - t = to(F.at(pos).Indexed(t, t1)); 16.1002 - } 16.1003 - accept(RBRACKET); 16.1004 - } 16.1005 - break loop; 16.1006 - case LPAREN: 16.1007 - if ((mode & EXPR) != 0) { 16.1008 - mode = EXPR; 16.1009 - t = arguments(typeArgs, t); 16.1010 - typeArgs = null; 16.1011 - } 16.1012 - break loop; 16.1013 - case DOT: 16.1014 - S.nextToken(); 16.1015 - int oldmode = mode; 16.1016 - mode &= ~NOPARAMS; 16.1017 - typeArgs = typeArgumentsOpt(EXPR); 16.1018 - mode = oldmode; 16.1019 - if ((mode & EXPR) != 0) { 16.1020 - switch (S.token()) { 16.1021 - case CLASS: 16.1022 - if (typeArgs != null) return illegal(); 16.1023 - mode = EXPR; 16.1024 - t = to(F.at(pos).Select(t, names._class)); 16.1025 - S.nextToken(); 16.1026 - break loop; 16.1027 - case THIS: 16.1028 - if (typeArgs != null) return illegal(); 16.1029 - mode = EXPR; 16.1030 - t = to(F.at(pos).Select(t, names._this)); 16.1031 - S.nextToken(); 16.1032 - break loop; 16.1033 - case SUPER: 16.1034 - mode = EXPR; 16.1035 - t = to(F.at(pos).Select(t, names._super)); 16.1036 - t = superSuffix(typeArgs, t); 16.1037 - typeArgs = null; 16.1038 - break loop; 16.1039 - case NEW: 16.1040 - if (typeArgs != null) return illegal(); 16.1041 - mode = EXPR; 16.1042 - int pos1 = S.pos(); 16.1043 - S.nextToken(); 16.1044 - if (S.token() == LT) typeArgs = typeArguments(); 16.1045 - t = innerCreator(pos1, typeArgs, t); 16.1046 - typeArgs = null; 16.1047 - break loop; 16.1048 - } 16.1049 - } 16.1050 - // typeArgs saved for next loop iteration. 16.1051 - t = toP(F.at(pos).Select(t, ident())); 16.1052 - break; 16.1053 - default: 16.1054 - break loop; 16.1055 - } 16.1056 - } 16.1057 - if (typeArgs != null) illegal(); 16.1058 - t = typeArgumentsOpt(t); 16.1059 - break; 16.1060 - case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 16.1061 - case DOUBLE: case BOOLEAN: 16.1062 - if (typeArgs != null) illegal(); 16.1063 - t = bracketsSuffix(bracketsOpt(basicType())); 16.1064 - break; 16.1065 - case VOID: 16.1066 - if (typeArgs != null) illegal(); 16.1067 - if ((mode & EXPR) != 0) { 16.1068 - S.nextToken(); 16.1069 - if (S.token() == DOT) { 16.1070 - JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); 16.1071 - t = bracketsSuffix(ti); 16.1072 - } else { 16.1073 - return illegal(pos); 16.1074 - } 16.1075 - } else { 16.1076 - return illegal(); 16.1077 - } 16.1078 - break; 16.1079 - default: 16.1080 - return illegal(); 16.1081 - } 16.1082 - if (typeArgs != null) illegal(); 16.1083 - while (true) { 16.1084 - int pos1 = S.pos(); 16.1085 - if (S.token() == LBRACKET) { 16.1086 - S.nextToken(); 16.1087 - if ((mode & TYPE) != 0) { 16.1088 - int oldmode = mode; 16.1089 - mode = TYPE; 16.1090 - if (S.token() == RBRACKET) { 16.1091 - S.nextToken(); 16.1092 - t = bracketsOpt(t); 16.1093 - t = toP(F.at(pos1).TypeArray(t)); 16.1094 - return t; 16.1095 - } 16.1096 - mode = oldmode; 16.1097 - } 16.1098 - if ((mode & EXPR) != 0) { 16.1099 - mode = EXPR; 16.1100 - JCExpression t1 = term(); 16.1101 - t = to(F.at(pos1).Indexed(t, t1)); 16.1102 - } 16.1103 - accept(RBRACKET); 16.1104 - } else if (S.token() == DOT) { 16.1105 - S.nextToken(); 16.1106 - typeArgs = typeArgumentsOpt(EXPR); 16.1107 - if (S.token() == SUPER && (mode & EXPR) != 0) { 16.1108 - mode = EXPR; 16.1109 - t = to(F.at(pos1).Select(t, names._super)); 16.1110 - S.nextToken(); 16.1111 - t = arguments(typeArgs, t); 16.1112 - typeArgs = null; 16.1113 - } else if (S.token() == NEW && (mode & EXPR) != 0) { 16.1114 - if (typeArgs != null) return illegal(); 16.1115 - mode = EXPR; 16.1116 - int pos2 = S.pos(); 16.1117 - S.nextToken(); 16.1118 - if (S.token() == LT) typeArgs = typeArguments(); 16.1119 - t = innerCreator(pos2, typeArgs, t); 16.1120 - typeArgs = null; 16.1121 - } else { 16.1122 - t = toP(F.at(pos1).Select(t, ident())); 16.1123 - t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 16.1124 - typeArgs = null; 16.1125 - } 16.1126 - } else { 16.1127 - break; 16.1128 - } 16.1129 - } 16.1130 - while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 16.1131 - mode = EXPR; 16.1132 - t = to(F.at(S.pos()).Unary( 16.1133 - S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 16.1134 - S.nextToken(); 16.1135 - } 16.1136 - return toP(t); 16.1137 - } 16.1138 - 16.1139 - /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 16.1140 - */ 16.1141 - JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 16.1142 - S.nextToken(); 16.1143 - if (S.token() == LPAREN || typeArgs != null) { 16.1144 - t = arguments(typeArgs, t); 16.1145 - } else { 16.1146 - int pos = S.pos(); 16.1147 - accept(DOT); 16.1148 - typeArgs = (S.token() == LT) ? typeArguments() : null; 16.1149 - t = toP(F.at(pos).Select(t, ident())); 16.1150 - t = argumentsOpt(typeArgs, t); 16.1151 - } 16.1152 - return t; 16.1153 - } 16.1154 - 16.1155 - /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 16.1156 - */ 16.1157 - JCPrimitiveTypeTree basicType() { 16.1158 - JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token()))); 16.1159 - S.nextToken(); 16.1160 - return t; 16.1161 - } 16.1162 - 16.1163 - /** ArgumentsOpt = [ Arguments ] 16.1164 - */ 16.1165 - JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 16.1166 - if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) { 16.1167 - mode = EXPR; 16.1168 - return arguments(typeArgs, t); 16.1169 - } else { 16.1170 - return t; 16.1171 - } 16.1172 - } 16.1173 - 16.1174 - /** Arguments = "(" [Expression { COMMA Expression }] ")" 16.1175 - */ 16.1176 - List<JCExpression> arguments() { 16.1177 - ListBuffer<JCExpression> args = lb(); 16.1178 - if (S.token() == LPAREN) { 16.1179 - S.nextToken(); 16.1180 - if (S.token() != RPAREN) { 16.1181 - args.append(expression()); 16.1182 - while (S.token() == COMMA) { 16.1183 - S.nextToken(); 16.1184 - args.append(expression()); 16.1185 - } 16.1186 - } 16.1187 - accept(RPAREN); 16.1188 - } else { 16.1189 - syntaxError(S.pos(), "expected", LPAREN); 16.1190 - } 16.1191 - return args.toList(); 16.1192 - } 16.1193 - 16.1194 - JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 16.1195 - int pos = S.pos(); 16.1196 - List<JCExpression> args = arguments(); 16.1197 - return toP(F.at(pos).Apply(typeArgs, t, args)); 16.1198 - } 16.1199 - 16.1200 - /** TypeArgumentsOpt = [ TypeArguments ] 16.1201 - */ 16.1202 - JCExpression typeArgumentsOpt(JCExpression t) { 16.1203 - if (S.token() == LT && 16.1204 - (mode & TYPE) != 0 && 16.1205 - (mode & NOPARAMS) == 0) { 16.1206 - mode = TYPE; 16.1207 - checkGenerics(); 16.1208 - return typeArguments(t); 16.1209 - } else { 16.1210 - return t; 16.1211 - } 16.1212 - } 16.1213 - List<JCExpression> typeArgumentsOpt() { 16.1214 - return typeArgumentsOpt(TYPE); 16.1215 - } 16.1216 - 16.1217 - List<JCExpression> typeArgumentsOpt(int useMode) { 16.1218 - if (S.token() == LT) { 16.1219 - checkGenerics(); 16.1220 - if ((mode & useMode) == 0 || 16.1221 - (mode & NOPARAMS) != 0) { 16.1222 - illegal(); 16.1223 - } 16.1224 - mode = useMode; 16.1225 - return typeArguments(); 16.1226 - } 16.1227 - return null; 16.1228 - } 16.1229 - 16.1230 - /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 16.1231 - */ 16.1232 - List<JCExpression> typeArguments() { 16.1233 - ListBuffer<JCExpression> args = lb(); 16.1234 - if (S.token() == LT) { 16.1235 - S.nextToken(); 16.1236 - args.append(((mode & EXPR) == 0) ? typeArgument() : type()); 16.1237 - while (S.token() == COMMA) { 16.1238 - S.nextToken(); 16.1239 - args.append(((mode & EXPR) == 0) ? typeArgument() : type()); 16.1240 - } 16.1241 - switch (S.token()) { 16.1242 - case GTGTGTEQ: 16.1243 - S.token(GTGTEQ); 16.1244 - break; 16.1245 - case GTGTEQ: 16.1246 - S.token(GTEQ); 16.1247 - break; 16.1248 - case GTEQ: 16.1249 - S.token(EQ); 16.1250 - break; 16.1251 - case GTGTGT: 16.1252 - S.token(GTGT); 16.1253 - break; 16.1254 - case GTGT: 16.1255 - S.token(GT); 16.1256 - break; 16.1257 - default: 16.1258 - accept(GT); 16.1259 - break; 16.1260 - } 16.1261 - } else { 16.1262 - syntaxError(S.pos(), "expected", LT); 16.1263 - } 16.1264 - return args.toList(); 16.1265 - } 16.1266 - 16.1267 - /** TypeArgument = Type 16.1268 - * | "?" 16.1269 - * | "?" EXTENDS Type {"&" Type} 16.1270 - * | "?" SUPER Type 16.1271 - */ 16.1272 - JCExpression typeArgument() { 16.1273 - if (S.token() != QUES) return type(); 16.1274 - int pos = S.pos(); 16.1275 - S.nextToken(); 16.1276 - if (S.token() == EXTENDS) { 16.1277 - TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS)); 16.1278 - S.nextToken(); 16.1279 - return F.at(pos).Wildcard(t, type()); 16.1280 - } else if (S.token() == SUPER) { 16.1281 - TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER)); 16.1282 - S.nextToken(); 16.1283 - return F.at(pos).Wildcard(t, type()); 16.1284 - } else if (S.token() == IDENTIFIER) { 16.1285 - //error recovery 16.1286 - reportSyntaxError(S.prevEndPos(), "expected3", 16.1287 - GT, EXTENDS, SUPER); 16.1288 - TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 16.1289 - JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 16.1290 - JCIdent id = toP(F.at(S.pos()).Ident(ident())); 16.1291 - return F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 16.1292 - } else { 16.1293 - TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 16.1294 - return toP(F.at(pos).Wildcard(t, null)); 16.1295 - } 16.1296 - } 16.1297 - 16.1298 - JCTypeApply typeArguments(JCExpression t) { 16.1299 - int pos = S.pos(); 16.1300 - List<JCExpression> args = typeArguments(); 16.1301 - return toP(F.at(pos).TypeApply(t, args)); 16.1302 - } 16.1303 - 16.1304 - /** BracketsOpt = {"[" "]"} 16.1305 - */ 16.1306 - private JCExpression bracketsOpt(JCExpression t) { 16.1307 - if (S.token() == LBRACKET) { 16.1308 - int pos = S.pos(); 16.1309 - S.nextToken(); 16.1310 - t = bracketsOptCont(t, pos); 16.1311 - F.at(pos); 16.1312 - } 16.1313 - return t; 16.1314 - } 16.1315 - 16.1316 - private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) { 16.1317 - accept(RBRACKET); 16.1318 - t = bracketsOpt(t); 16.1319 - return toP(F.at(pos).TypeArray(t)); 16.1320 - } 16.1321 - 16.1322 - /** BracketsSuffixExpr = "." CLASS 16.1323 - * BracketsSuffixType = 16.1324 - */ 16.1325 - JCExpression bracketsSuffix(JCExpression t) { 16.1326 - if ((mode & EXPR) != 0 && S.token() == DOT) { 16.1327 - mode = EXPR; 16.1328 - int pos = S.pos(); 16.1329 - S.nextToken(); 16.1330 - accept(CLASS); 16.1331 - if (S.pos() == errorEndPos) { 16.1332 - // error recovery 16.1333 - Name name = null; 16.1334 - if (S.token() == IDENTIFIER) { 16.1335 - name = S.name(); 16.1336 - S.nextToken(); 16.1337 - } else { 16.1338 - name = names.error; 16.1339 - } 16.1340 - t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name)))); 16.1341 - } else { 16.1342 - t = toP(F.at(pos).Select(t, names._class)); 16.1343 - } 16.1344 - } else if ((mode & TYPE) != 0) { 16.1345 - mode = TYPE; 16.1346 - } else { 16.1347 - syntaxError(S.pos(), "dot.class.expected"); 16.1348 - } 16.1349 - return t; 16.1350 - } 16.1351 - 16.1352 - /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 16.1353 - */ 16.1354 - JCExpression creator(int newpos, List<JCExpression> typeArgs) { 16.1355 - switch (S.token()) { 16.1356 - case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 16.1357 - case DOUBLE: case BOOLEAN: 16.1358 - if (typeArgs == null) 16.1359 - return arrayCreatorRest(newpos, basicType()); 16.1360 - break; 16.1361 - default: 16.1362 - } 16.1363 - JCExpression t = qualident(); 16.1364 - int oldmode = mode; 16.1365 - mode = TYPE; 16.1366 - if (S.token() == LT) { 16.1367 - checkGenerics(); 16.1368 - t = typeArguments(t); 16.1369 - } 16.1370 - while (S.token() == DOT) { 16.1371 - int pos = S.pos(); 16.1372 - S.nextToken(); 16.1373 - t = toP(F.at(pos).Select(t, ident())); 16.1374 - if (S.token() == LT) { 16.1375 - checkGenerics(); 16.1376 - t = typeArguments(t); 16.1377 - } 16.1378 - } 16.1379 - mode = oldmode; 16.1380 - if (S.token() == LBRACKET) { 16.1381 - JCExpression e = arrayCreatorRest(newpos, t); 16.1382 - if (typeArgs != null) { 16.1383 - int pos = newpos; 16.1384 - if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 16.1385 - // note: this should always happen but we should 16.1386 - // not rely on this as the parser is continuously 16.1387 - // modified to improve error recovery. 16.1388 - pos = typeArgs.head.pos; 16.1389 - } 16.1390 - setErrorEndPos(S.prevEndPos()); 16.1391 - reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 16.1392 - return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 16.1393 - } 16.1394 - return e; 16.1395 - } else if (S.token() == LPAREN) { 16.1396 - return classCreatorRest(newpos, null, typeArgs, t); 16.1397 - } else { 16.1398 - reportSyntaxError(S.pos(), "expected2", 16.1399 - LPAREN, LBRACKET); 16.1400 - t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 16.1401 - return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 16.1402 - } 16.1403 - } 16.1404 - 16.1405 - /** InnerCreator = Ident [TypeArguments] ClassCreatorRest 16.1406 - */ 16.1407 - JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 16.1408 - JCExpression t = toP(F.at(S.pos()).Ident(ident())); 16.1409 - if (S.token() == LT) { 16.1410 - checkGenerics(); 16.1411 - t = typeArguments(t); 16.1412 - } 16.1413 - return classCreatorRest(newpos, encl, typeArgs, t); 16.1414 - } 16.1415 - 16.1416 - /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer 16.1417 - * | Expression "]" {"[" Expression "]"} BracketsOpt ) 16.1418 - */ 16.1419 - JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 16.1420 - accept(LBRACKET); 16.1421 - if (S.token() == RBRACKET) { 16.1422 - accept(RBRACKET); 16.1423 - elemtype = bracketsOpt(elemtype); 16.1424 - if (S.token() == LBRACE) { 16.1425 - return arrayInitializer(newpos, elemtype); 16.1426 - } else { 16.1427 - return syntaxError(S.pos(), "array.dimension.missing"); 16.1428 - } 16.1429 - } else { 16.1430 - ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 16.1431 - dims.append(expression()); 16.1432 - accept(RBRACKET); 16.1433 - while (S.token() == LBRACKET) { 16.1434 - int pos = S.pos(); 16.1435 - S.nextToken(); 16.1436 - if (S.token() == RBRACKET) { 16.1437 - elemtype = bracketsOptCont(elemtype, pos); 16.1438 - } else { 16.1439 - dims.append(expression()); 16.1440 - accept(RBRACKET); 16.1441 - } 16.1442 - } 16.1443 - return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); 16.1444 - } 16.1445 - } 16.1446 - 16.1447 - /** ClassCreatorRest = Arguments [ClassBody] 16.1448 - */ 16.1449 - JCExpression classCreatorRest(int newpos, 16.1450 - JCExpression encl, 16.1451 - List<JCExpression> typeArgs, 16.1452 - JCExpression t) 16.1453 - { 16.1454 - List<JCExpression> args = arguments(); 16.1455 - JCClassDecl body = null; 16.1456 - if (S.token() == LBRACE) { 16.1457 - int pos = S.pos(); 16.1458 - List<JCTree> defs = classOrInterfaceBody(names.empty, false); 16.1459 - JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 16.1460 - body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 16.1461 - } 16.1462 - return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); 16.1463 - } 16.1464 - 16.1465 - /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}" 16.1466 - */ 16.1467 - JCExpression arrayInitializer(int newpos, JCExpression t) { 16.1468 - accept(LBRACE); 16.1469 - ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 16.1470 - if (S.token() == COMMA) { 16.1471 - S.nextToken(); 16.1472 - } else if (S.token() != RBRACE) { 16.1473 - elems.append(variableInitializer()); 16.1474 - while (S.token() == COMMA) { 16.1475 - S.nextToken(); 16.1476 - if (S.token() == RBRACE) break; 16.1477 - elems.append(variableInitializer()); 16.1478 - } 16.1479 - } 16.1480 - accept(RBRACE); 16.1481 - return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList())); 16.1482 - } 16.1483 - 16.1484 - /** VariableInitializer = ArrayInitializer | Expression 16.1485 - */ 16.1486 - public JCExpression variableInitializer() { 16.1487 - return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : expression(); 16.1488 - } 16.1489 - 16.1490 - /** ParExpression = "(" Expression ")" 16.1491 - */ 16.1492 - JCExpression parExpression() { 16.1493 - accept(LPAREN); 16.1494 - JCExpression t = expression(); 16.1495 - accept(RPAREN); 16.1496 - return t; 16.1497 - } 16.1498 - 16.1499 - /** Block = "{" BlockStatements "}" 16.1500 - */ 16.1501 - JCBlock block(int pos, long flags) { 16.1502 - accept(LBRACE); 16.1503 - List<JCStatement> stats = blockStatements(); 16.1504 - JCBlock t = F.at(pos).Block(flags, stats); 16.1505 - while (S.token() == CASE || S.token() == DEFAULT) { 16.1506 - syntaxError("orphaned", S.token()); 16.1507 - switchBlockStatementGroups(); 16.1508 - } 16.1509 - // the Block node has a field "endpos" for first char of last token, which is 16.1510 - // usually but not necessarily the last char of the last token. 16.1511 - t.endpos = S.pos(); 16.1512 - accept(RBRACE); 16.1513 - return toP(t); 16.1514 - } 16.1515 - 16.1516 - public JCBlock block() { 16.1517 - return block(S.pos(), 0); 16.1518 - } 16.1519 - 16.1520 - /** BlockStatements = { BlockStatement } 16.1521 - * BlockStatement = LocalVariableDeclarationStatement 16.1522 - * | ClassOrInterfaceOrEnumDeclaration 16.1523 - * | [Ident ":"] Statement 16.1524 - * LocalVariableDeclarationStatement 16.1525 - * = { FINAL | '@' Annotation } Type VariableDeclarators ";" 16.1526 - */ 16.1527 - @SuppressWarnings("fallthrough") 16.1528 - List<JCStatement> blockStatements() { 16.1529 -//todo: skip to anchor on error(?) 16.1530 - int lastErrPos = -1; 16.1531 - ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 16.1532 - while (true) { 16.1533 - int pos = S.pos(); 16.1534 - switch (S.token()) { 16.1535 - case RBRACE: case CASE: case DEFAULT: case EOF: 16.1536 - return stats.toList(); 16.1537 - case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 16.1538 - case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 16.1539 - case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 16.1540 - stats.append(statement()); 16.1541 - break; 16.1542 - case MONKEYS_AT: 16.1543 - case FINAL: { 16.1544 - String dc = S.docComment(); 16.1545 - JCModifiers mods = modifiersOpt(); 16.1546 - if (S.token() == INTERFACE || 16.1547 - S.token() == CLASS || 16.1548 - allowEnums && S.token() == ENUM) { 16.1549 - stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 16.1550 - } else { 16.1551 - JCExpression t = type(); 16.1552 - stats.appendList(variableDeclarators(mods, t, 16.1553 - new ListBuffer<JCStatement>())); 16.1554 - // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 16.1555 - storeEnd(stats.elems.last(), S.endPos()); 16.1556 - accept(SEMI); 16.1557 - } 16.1558 - break; 16.1559 - } 16.1560 - case ABSTRACT: case STRICTFP: { 16.1561 - String dc = S.docComment(); 16.1562 - JCModifiers mods = modifiersOpt(); 16.1563 - stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 16.1564 - break; 16.1565 - } 16.1566 - case INTERFACE: 16.1567 - case CLASS: 16.1568 - stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 16.1569 - S.docComment())); 16.1570 - break; 16.1571 - case ENUM: 16.1572 - case ASSERT: 16.1573 - if (allowEnums && S.token() == ENUM) { 16.1574 - log.error(S.pos(), "local.enum"); 16.1575 - stats. 16.1576 - append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 16.1577 - S.docComment())); 16.1578 - break; 16.1579 - } else if (allowAsserts && S.token() == ASSERT) { 16.1580 - stats.append(statement()); 16.1581 - break; 16.1582 - } 16.1583 - /* fall through to default */ 16.1584 - default: 16.1585 - Name name = S.name(); 16.1586 - JCExpression t = term(EXPR | TYPE); 16.1587 - if (S.token() == COLON && t.getTag() == JCTree.IDENT) { 16.1588 - S.nextToken(); 16.1589 - JCStatement stat = statement(); 16.1590 - stats.append(F.at(pos).Labelled(name, stat)); 16.1591 - } else if ((lastmode & TYPE) != 0 && 16.1592 - (S.token() == IDENTIFIER || 16.1593 - S.token() == ASSERT || 16.1594 - S.token() == ENUM)) { 16.1595 - pos = S.pos(); 16.1596 - JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 16.1597 - F.at(pos); 16.1598 - stats.appendList(variableDeclarators(mods, t, 16.1599 - new ListBuffer<JCStatement>())); 16.1600 - // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 16.1601 - storeEnd(stats.elems.last(), S.endPos()); 16.1602 - accept(SEMI); 16.1603 - } else { 16.1604 - // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 16.1605 - stats.append(to(F.at(pos).Exec(checkExprStat(t)))); 16.1606 - accept(SEMI); 16.1607 - } 16.1608 - } 16.1609 - 16.1610 - // error recovery 16.1611 - if (S.pos() == lastErrPos) 16.1612 - return stats.toList(); 16.1613 - if (S.pos() <= errorEndPos) { 16.1614 - skip(false, true, true, true); 16.1615 - lastErrPos = S.pos(); 16.1616 - } 16.1617 - 16.1618 - // ensure no dangling /** @deprecated */ active 16.1619 - S.resetDeprecatedFlag(); 16.1620 - } 16.1621 - } 16.1622 - 16.1623 - /** Statement = 16.1624 - * Block 16.1625 - * | IF ParExpression Statement [ELSE Statement] 16.1626 - * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement 16.1627 - * | FOR "(" FormalParameter : Expression ")" Statement 16.1628 - * | WHILE ParExpression Statement 16.1629 - * | DO Statement WHILE ParExpression ";" 16.1630 - * | TRY Block ( Catches | [Catches] FinallyPart ) 16.1631 - * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" 16.1632 - * | SYNCHRONIZED ParExpression Block 16.1633 - * | RETURN [Expression] ";" 16.1634 - * | THROW Expression ";" 16.1635 - * | BREAK [Ident] ";" 16.1636 - * | CONTINUE [Ident] ";" 16.1637 - * | ASSERT Expression [ ":" Expression ] ";" 16.1638 - * | ";" 16.1639 - * | ExpressionStatement 16.1640 - * | Ident ":" Statement 16.1641 - */ 16.1642 - @SuppressWarnings("fallthrough") 16.1643 - public JCStatement statement() { 16.1644 - int pos = S.pos(); 16.1645 - switch (S.token()) { 16.1646 - case LBRACE: 16.1647 - return block(); 16.1648 - case IF: { 16.1649 - S.nextToken(); 16.1650 - JCExpression cond = parExpression(); 16.1651 - JCStatement thenpart = statement(); 16.1652 - JCStatement elsepart = null; 16.1653 - if (S.token() == ELSE) { 16.1654 - S.nextToken(); 16.1655 - elsepart = statement(); 16.1656 - } 16.1657 - return F.at(pos).If(cond, thenpart, elsepart); 16.1658 - } 16.1659 - case FOR: { 16.1660 - S.nextToken(); 16.1661 - accept(LPAREN); 16.1662 - List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); 16.1663 - if (inits.length() == 1 && 16.1664 - inits.head.getTag() == JCTree.VARDEF && 16.1665 - ((JCVariableDecl) inits.head).init == null && 16.1666 - S.token() == COLON) { 16.1667 - checkForeach(); 16.1668 - JCVariableDecl var = (JCVariableDecl)inits.head; 16.1669 - accept(COLON); 16.1670 - JCExpression expr = expression(); 16.1671 - accept(RPAREN); 16.1672 - JCStatement body = statement(); 16.1673 - return F.at(pos).ForeachLoop(var, expr, body); 16.1674 - } else { 16.1675 - accept(SEMI); 16.1676 - JCExpression cond = S.token() == SEMI ? null : expression(); 16.1677 - accept(SEMI); 16.1678 - List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 16.1679 - accept(RPAREN); 16.1680 - JCStatement body = statement(); 16.1681 - return F.at(pos).ForLoop(inits, cond, steps, body); 16.1682 - } 16.1683 - } 16.1684 - case WHILE: { 16.1685 - S.nextToken(); 16.1686 - JCExpression cond = parExpression(); 16.1687 - JCStatement body = statement(); 16.1688 - return F.at(pos).WhileLoop(cond, body); 16.1689 - } 16.1690 - case DO: { 16.1691 - S.nextToken(); 16.1692 - JCStatement body = statement(); 16.1693 - accept(WHILE); 16.1694 - JCExpression cond = parExpression(); 16.1695 - JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond)); 16.1696 - accept(SEMI); 16.1697 - return t; 16.1698 - } 16.1699 - case TRY: { 16.1700 - S.nextToken(); 16.1701 - JCBlock body = block(); 16.1702 - ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); 16.1703 - JCBlock finalizer = null; 16.1704 - if (S.token() == CATCH || S.token() == FINALLY) { 16.1705 - while (S.token() == CATCH) catchers.append(catchClause()); 16.1706 - if (S.token() == FINALLY) { 16.1707 - S.nextToken(); 16.1708 - finalizer = block(); 16.1709 - } 16.1710 - } else { 16.1711 - log.error(pos, "try.without.catch.or.finally"); 16.1712 - } 16.1713 - return F.at(pos).Try(body, catchers.toList(), finalizer); 16.1714 - } 16.1715 - case SWITCH: { 16.1716 - S.nextToken(); 16.1717 - JCExpression selector = parExpression(); 16.1718 - accept(LBRACE); 16.1719 - List<JCCase> cases = switchBlockStatementGroups(); 16.1720 - JCSwitch t = to(F.at(pos).Switch(selector, cases)); 16.1721 - accept(RBRACE); 16.1722 - return t; 16.1723 - } 16.1724 - case SYNCHRONIZED: { 16.1725 - S.nextToken(); 16.1726 - JCExpression lock = parExpression(); 16.1727 - JCBlock body = block(); 16.1728 - return F.at(pos).Synchronized(lock, body); 16.1729 - } 16.1730 - case RETURN: { 16.1731 - S.nextToken(); 16.1732 - JCExpression result = S.token() == SEMI ? null : expression(); 16.1733 - JCReturn t = to(F.at(pos).Return(result)); 16.1734 - accept(SEMI); 16.1735 - return t; 16.1736 - } 16.1737 - case THROW: { 16.1738 - S.nextToken(); 16.1739 - JCExpression exc = expression(); 16.1740 - JCThrow t = to(F.at(pos).Throw(exc)); 16.1741 - accept(SEMI); 16.1742 - return t; 16.1743 - } 16.1744 - case BREAK: { 16.1745 - S.nextToken(); 16.1746 - Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 16.1747 - JCBreak t = to(F.at(pos).Break(label)); 16.1748 - accept(SEMI); 16.1749 - return t; 16.1750 - } 16.1751 - case CONTINUE: { 16.1752 - S.nextToken(); 16.1753 - Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 16.1754 - JCContinue t = to(F.at(pos).Continue(label)); 16.1755 - accept(SEMI); 16.1756 - return t; 16.1757 - } 16.1758 - case SEMI: 16.1759 - S.nextToken(); 16.1760 - return toP(F.at(pos).Skip()); 16.1761 - case ELSE: 16.1762 - return toP(F.Exec(syntaxError("else.without.if"))); 16.1763 - case FINALLY: 16.1764 - return toP(F.Exec(syntaxError("finally.without.try"))); 16.1765 - case CATCH: 16.1766 - return toP(F.Exec(syntaxError("catch.without.try"))); 16.1767 - case ASSERT: { 16.1768 - if (allowAsserts && S.token() == ASSERT) { 16.1769 - S.nextToken(); 16.1770 - JCExpression assertion = expression(); 16.1771 - JCExpression message = null; 16.1772 - if (S.token() == COLON) { 16.1773 - S.nextToken(); 16.1774 - message = expression(); 16.1775 - } 16.1776 - JCAssert t = to(F.at(pos).Assert(assertion, message)); 16.1777 - accept(SEMI); 16.1778 - return t; 16.1779 - } 16.1780 - /* else fall through to default case */ 16.1781 - } 16.1782 - case ENUM: 16.1783 - default: 16.1784 - Name name = S.name(); 16.1785 - JCExpression expr = expression(); 16.1786 - if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { 16.1787 - S.nextToken(); 16.1788 - JCStatement stat = statement(); 16.1789 - return F.at(pos).Labelled(name, stat); 16.1790 - } else { 16.1791 - // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 16.1792 - JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); 16.1793 - accept(SEMI); 16.1794 - return stat; 16.1795 - } 16.1796 - } 16.1797 - } 16.1798 - 16.1799 - /** CatchClause = CATCH "(" FormalParameter ")" Block 16.1800 - */ 16.1801 - JCCatch catchClause() { 16.1802 - int pos = S.pos(); 16.1803 - accept(CATCH); 16.1804 - accept(LPAREN); 16.1805 - JCVariableDecl formal = 16.1806 - variableDeclaratorId(optFinal(Flags.PARAMETER), 16.1807 - qualident()); 16.1808 - accept(RPAREN); 16.1809 - JCBlock body = block(); 16.1810 - return F.at(pos).Catch(formal, body); 16.1811 - } 16.1812 - 16.1813 - /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 16.1814 - * SwitchBlockStatementGroup = SwitchLabel BlockStatements 16.1815 - * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 16.1816 - */ 16.1817 - List<JCCase> switchBlockStatementGroups() { 16.1818 - ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); 16.1819 - while (true) { 16.1820 - int pos = S.pos(); 16.1821 - switch (S.token()) { 16.1822 - case CASE: { 16.1823 - S.nextToken(); 16.1824 - JCExpression pat = expression(); 16.1825 - accept(COLON); 16.1826 - List<JCStatement> stats = blockStatements(); 16.1827 - JCCase c = F.at(pos).Case(pat, stats); 16.1828 - if (stats.isEmpty()) 16.1829 - storeEnd(c, S.prevEndPos()); 16.1830 - cases.append(c); 16.1831 - break; 16.1832 - } 16.1833 - case DEFAULT: { 16.1834 - S.nextToken(); 16.1835 - accept(COLON); 16.1836 - List<JCStatement> stats = blockStatements(); 16.1837 - JCCase c = F.at(pos).Case(null, stats); 16.1838 - if (stats.isEmpty()) 16.1839 - storeEnd(c, S.prevEndPos()); 16.1840 - cases.append(c); 16.1841 - break; 16.1842 - } 16.1843 - case RBRACE: case EOF: 16.1844 - return cases.toList(); 16.1845 - default: 16.1846 - S.nextToken(); // to ensure progress 16.1847 - syntaxError(pos, "expected3", 16.1848 - CASE, DEFAULT, RBRACE); 16.1849 - } 16.1850 - } 16.1851 - } 16.1852 - 16.1853 - /** MoreStatementExpressions = { COMMA StatementExpression } 16.1854 - */ 16.1855 - <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos, 16.1856 - JCExpression first, 16.1857 - T stats) { 16.1858 - // This Exec is a "StatementExpression"; it subsumes no terminating token 16.1859 - stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 16.1860 - while (S.token() == COMMA) { 16.1861 - S.nextToken(); 16.1862 - pos = S.pos(); 16.1863 - JCExpression t = expression(); 16.1864 - // This Exec is a "StatementExpression"; it subsumes no terminating token 16.1865 - stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 16.1866 - } 16.1867 - return stats; 16.1868 - } 16.1869 - 16.1870 - /** ForInit = StatementExpression MoreStatementExpressions 16.1871 - * | { FINAL | '@' Annotation } Type VariableDeclarators 16.1872 - */ 16.1873 - List<JCStatement> forInit() { 16.1874 - ListBuffer<JCStatement> stats = lb(); 16.1875 - int pos = S.pos(); 16.1876 - if (S.token() == FINAL || S.token() == MONKEYS_AT) { 16.1877 - return variableDeclarators(optFinal(0), type(), stats).toList(); 16.1878 - } else { 16.1879 - JCExpression t = term(EXPR | TYPE); 16.1880 - if ((lastmode & TYPE) != 0 && 16.1881 - (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) 16.1882 - return variableDeclarators(modifiersOpt(), t, stats).toList(); 16.1883 - else 16.1884 - return moreStatementExpressions(pos, t, stats).toList(); 16.1885 - } 16.1886 - } 16.1887 - 16.1888 - /** ForUpdate = StatementExpression MoreStatementExpressions 16.1889 - */ 16.1890 - List<JCExpressionStatement> forUpdate() { 16.1891 - return moreStatementExpressions(S.pos(), 16.1892 - expression(), 16.1893 - new ListBuffer<JCExpressionStatement>()).toList(); 16.1894 - } 16.1895 - 16.1896 - /** AnnotationsOpt = { '@' Annotation } 16.1897 - */ 16.1898 - List<JCAnnotation> annotationsOpt() { 16.1899 - if (S.token() != MONKEYS_AT) return List.nil(); // optimization 16.1900 - ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 16.1901 - while (S.token() == MONKEYS_AT) { 16.1902 - int pos = S.pos(); 16.1903 - S.nextToken(); 16.1904 - buf.append(annotation(pos)); 16.1905 - } 16.1906 - return buf.toList(); 16.1907 - } 16.1908 - 16.1909 - /** ModifiersOpt = { Modifier } 16.1910 - * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 16.1911 - * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 16.1912 - * | "@" Annotation 16.1913 - */ 16.1914 - JCModifiers modifiersOpt() { 16.1915 - return modifiersOpt(null); 16.1916 - } 16.1917 - JCModifiers modifiersOpt(JCModifiers partial) { 16.1918 - long flags = (partial == null) ? 0 : partial.flags; 16.1919 - if (S.deprecatedFlag()) { 16.1920 - flags |= Flags.DEPRECATED; 16.1921 - S.resetDeprecatedFlag(); 16.1922 - } 16.1923 - ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>(); 16.1924 - if (partial != null) annotations.appendList(partial.annotations); 16.1925 - int pos = S.pos(); 16.1926 - int lastPos = Position.NOPOS; 16.1927 - loop: 16.1928 - while (true) { 16.1929 - long flag; 16.1930 - switch (S.token()) { 16.1931 - case PRIVATE : flag = Flags.PRIVATE; break; 16.1932 - case PROTECTED : flag = Flags.PROTECTED; break; 16.1933 - case PUBLIC : flag = Flags.PUBLIC; break; 16.1934 - case STATIC : flag = Flags.STATIC; break; 16.1935 - case TRANSIENT : flag = Flags.TRANSIENT; break; 16.1936 - case FINAL : flag = Flags.FINAL; break; 16.1937 - case ABSTRACT : flag = Flags.ABSTRACT; break; 16.1938 - case NATIVE : flag = Flags.NATIVE; break; 16.1939 - case VOLATILE : flag = Flags.VOLATILE; break; 16.1940 - case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 16.1941 - case STRICTFP : flag = Flags.STRICTFP; break; 16.1942 - case MONKEYS_AT : flag = Flags.ANNOTATION; break; 16.1943 - default: break loop; 16.1944 - } 16.1945 - if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier"); 16.1946 - lastPos = S.pos(); 16.1947 - S.nextToken(); 16.1948 - if (flag == Flags.ANNOTATION) { 16.1949 - checkAnnotations(); 16.1950 - if (S.token() != INTERFACE) { 16.1951 - JCAnnotation ann = annotation(lastPos); 16.1952 - // if first modifier is an annotation, set pos to annotation's. 16.1953 - if (flags == 0 && annotations.isEmpty()) 16.1954 - pos = ann.pos; 16.1955 - annotations.append(ann); 16.1956 - lastPos = ann.pos; 16.1957 - flag = 0; 16.1958 - } 16.1959 - } 16.1960 - flags |= flag; 16.1961 - } 16.1962 - switch (S.token()) { 16.1963 - case ENUM: flags |= Flags.ENUM; break; 16.1964 - case INTERFACE: flags |= Flags.INTERFACE; break; 16.1965 - default: break; 16.1966 - } 16.1967 - 16.1968 - /* A modifiers tree with no modifier tokens or annotations 16.1969 - * has no text position. */ 16.1970 - if (flags == 0 && annotations.isEmpty()) 16.1971 - pos = Position.NOPOS; 16.1972 - 16.1973 - JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 16.1974 - if (pos != Position.NOPOS) 16.1975 - storeEnd(mods, S.prevEndPos()); 16.1976 - return mods; 16.1977 - } 16.1978 - 16.1979 - /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 16.1980 - * @param pos position of "@" token 16.1981 - */ 16.1982 - JCAnnotation annotation(int pos) { 16.1983 - // accept(AT); // AT consumed by caller 16.1984 - checkAnnotations(); 16.1985 - JCTree ident = qualident(); 16.1986 - List<JCExpression> fieldValues = annotationFieldValuesOpt(); 16.1987 - JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); 16.1988 - storeEnd(ann, S.prevEndPos()); 16.1989 - return ann; 16.1990 - } 16.1991 - 16.1992 - List<JCExpression> annotationFieldValuesOpt() { 16.1993 - return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 16.1994 - } 16.1995 - 16.1996 - /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 16.1997 - List<JCExpression> annotationFieldValues() { 16.1998 - accept(LPAREN); 16.1999 - ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 16.2000 - if (S.token() != RPAREN) { 16.2001 - buf.append(annotationFieldValue()); 16.2002 - while (S.token() == COMMA) { 16.2003 - S.nextToken(); 16.2004 - buf.append(annotationFieldValue()); 16.2005 - } 16.2006 - } 16.2007 - accept(RPAREN); 16.2008 - return buf.toList(); 16.2009 - } 16.2010 - 16.2011 - /** AnnotationFieldValue = AnnotationValue 16.2012 - * | Identifier "=" AnnotationValue 16.2013 - */ 16.2014 - JCExpression annotationFieldValue() { 16.2015 - if (S.token() == IDENTIFIER) { 16.2016 - mode = EXPR; 16.2017 - JCExpression t1 = term1(); 16.2018 - if (t1.getTag() == JCTree.IDENT && S.token() == EQ) { 16.2019 - int pos = S.pos(); 16.2020 - accept(EQ); 16.2021 - return toP(F.at(pos).Assign(t1, annotationValue())); 16.2022 - } else { 16.2023 - return t1; 16.2024 - } 16.2025 - } 16.2026 - return annotationValue(); 16.2027 - } 16.2028 - 16.2029 - /* AnnotationValue = ConditionalExpression 16.2030 - * | Annotation 16.2031 - * | "{" [ AnnotationValue { "," AnnotationValue } ] "}" 16.2032 - */ 16.2033 - JCExpression annotationValue() { 16.2034 - int pos; 16.2035 - switch (S.token()) { 16.2036 - case MONKEYS_AT: 16.2037 - pos = S.pos(); 16.2038 - S.nextToken(); 16.2039 - return annotation(pos); 16.2040 - case LBRACE: 16.2041 - pos = S.pos(); 16.2042 - accept(LBRACE); 16.2043 - ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 16.2044 - if (S.token() != RBRACE) { 16.2045 - buf.append(annotationValue()); 16.2046 - while (S.token() == COMMA) { 16.2047 - S.nextToken(); 16.2048 - if (S.token() == RPAREN) break; 16.2049 - buf.append(annotationValue()); 16.2050 - } 16.2051 - } 16.2052 - accept(RBRACE); 16.2053 - return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList())); 16.2054 - default: 16.2055 - mode = EXPR; 16.2056 - return term1(); 16.2057 - } 16.2058 - } 16.2059 - 16.2060 - /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator } 16.2061 - */ 16.2062 - public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods, 16.2063 - JCExpression type, 16.2064 - T vdefs) 16.2065 - { 16.2066 - return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs); 16.2067 - } 16.2068 - 16.2069 - /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 16.2070 - * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator } 16.2071 - * 16.2072 - * @param reqInit Is an initializer always required? 16.2073 - * @param dc The documentation comment for the variable declarations, or null. 16.2074 - */ 16.2075 - <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos, 16.2076 - JCModifiers mods, 16.2077 - JCExpression type, 16.2078 - Name name, 16.2079 - boolean reqInit, 16.2080 - String dc, 16.2081 - T vdefs) 16.2082 - { 16.2083 - vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc)); 16.2084 - while (S.token() == COMMA) { 16.2085 - // All but last of multiple declarators subsume a comma 16.2086 - storeEnd((JCTree)vdefs.elems.last(), S.endPos()); 16.2087 - S.nextToken(); 16.2088 - vdefs.append(variableDeclarator(mods, type, reqInit, dc)); 16.2089 - } 16.2090 - return vdefs; 16.2091 - } 16.2092 - 16.2093 - /** VariableDeclarator = Ident VariableDeclaratorRest 16.2094 - * ConstantDeclarator = Ident ConstantDeclaratorRest 16.2095 - */ 16.2096 - JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) { 16.2097 - return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc); 16.2098 - } 16.2099 - 16.2100 - /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 16.2101 - * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer 16.2102 - * 16.2103 - * @param reqInit Is an initializer always required? 16.2104 - * @param dc The documentation comment for the variable declarations, or null. 16.2105 - */ 16.2106 - JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, 16.2107 - boolean reqInit, String dc) { 16.2108 - type = bracketsOpt(type); 16.2109 - JCExpression init = null; 16.2110 - if (S.token() == EQ) { 16.2111 - S.nextToken(); 16.2112 - init = variableInitializer(); 16.2113 - } 16.2114 - else if (reqInit) syntaxError(S.pos(), "expected", EQ); 16.2115 - JCVariableDecl result = 16.2116 - toP(F.at(pos).VarDef(mods, name, type, init)); 16.2117 - attach(result, dc); 16.2118 - return result; 16.2119 - } 16.2120 - 16.2121 - /** VariableDeclaratorId = Ident BracketsOpt 16.2122 - */ 16.2123 - JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 16.2124 - int pos = S.pos(); 16.2125 - Name name = ident(); 16.2126 - if ((mods.flags & Flags.VARARGS) == 0) 16.2127 - type = bracketsOpt(type); 16.2128 - return toP(F.at(pos).VarDef(mods, name, type, null)); 16.2129 - } 16.2130 - 16.2131 - /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 16.2132 - */ 16.2133 - public JCTree.JCCompilationUnit compilationUnit() { 16.2134 - int pos = S.pos(); 16.2135 - JCExpression pid = null; 16.2136 - String dc = S.docComment(); 16.2137 - JCModifiers mods = null; 16.2138 - List<JCAnnotation> packageAnnotations = List.nil(); 16.2139 - if (S.token() == MONKEYS_AT) 16.2140 - mods = modifiersOpt(); 16.2141 - 16.2142 - if (S.token() == PACKAGE) { 16.2143 - if (mods != null) { 16.2144 - checkNoMods(mods.flags); 16.2145 - packageAnnotations = mods.annotations; 16.2146 - mods = null; 16.2147 - } 16.2148 - S.nextToken(); 16.2149 - pid = qualident(); 16.2150 - accept(SEMI); 16.2151 - } 16.2152 - ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 16.2153 - boolean checkForImports = true; 16.2154 - while (S.token() != EOF) { 16.2155 - if (S.pos() <= errorEndPos) { 16.2156 - // error recovery 16.2157 - skip(checkForImports, false, false, false); 16.2158 - if (S.token() == EOF) 16.2159 - break; 16.2160 - } 16.2161 - if (checkForImports && mods == null && S.token() == IMPORT) { 16.2162 - defs.append(importDeclaration()); 16.2163 - } else { 16.2164 - JCTree def = typeDeclaration(mods); 16.2165 - if (def instanceof JCExpressionStatement) 16.2166 - def = ((JCExpressionStatement)def).expr; 16.2167 - defs.append(def); 16.2168 - if (def instanceof JCClassDecl) 16.2169 - checkForImports = false; 16.2170 - mods = null; 16.2171 - } 16.2172 - } 16.2173 - JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList()); 16.2174 - attach(toplevel, dc); 16.2175 - if (defs.elems.isEmpty()) 16.2176 - storeEnd(toplevel, S.prevEndPos()); 16.2177 - if (keepDocComments) toplevel.docComments = docComments; 16.2178 - return toplevel; 16.2179 - } 16.2180 - 16.2181 - /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 16.2182 - */ 16.2183 - JCTree importDeclaration() { 16.2184 - int pos = S.pos(); 16.2185 - S.nextToken(); 16.2186 - boolean importStatic = false; 16.2187 - if (S.token() == STATIC) { 16.2188 - checkStaticImports(); 16.2189 - importStatic = true; 16.2190 - S.nextToken(); 16.2191 - } 16.2192 - JCExpression pid = toP(F.at(S.pos()).Ident(ident())); 16.2193 - do { 16.2194 - int pos1 = S.pos(); 16.2195 - accept(DOT); 16.2196 - if (S.token() == STAR) { 16.2197 - pid = to(F.at(pos1).Select(pid, names.asterisk)); 16.2198 - S.nextToken(); 16.2199 - break; 16.2200 - } else { 16.2201 - pid = toP(F.at(pos1).Select(pid, ident())); 16.2202 - } 16.2203 - } while (S.token() == DOT); 16.2204 - accept(SEMI); 16.2205 - return toP(F.at(pos).Import(pid, importStatic)); 16.2206 - } 16.2207 - 16.2208 - /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 16.2209 - * | ";" 16.2210 - */ 16.2211 - JCTree typeDeclaration(JCModifiers mods) { 16.2212 - int pos = S.pos(); 16.2213 - if (mods == null && S.token() == SEMI) { 16.2214 - S.nextToken(); 16.2215 - return toP(F.at(pos).Skip()); 16.2216 - } else { 16.2217 - String dc = S.docComment(); 16.2218 - return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc); 16.2219 - } 16.2220 - } 16.2221 - 16.2222 - /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt 16.2223 - * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) 16.2224 - * @param mods Any modifiers starting the class or interface declaration 16.2225 - * @param dc The documentation comment for the class, or null. 16.2226 - */ 16.2227 - JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) { 16.2228 - if (S.token() == CLASS) { 16.2229 - return classDeclaration(mods, dc); 16.2230 - } else if (S.token() == INTERFACE) { 16.2231 - return interfaceDeclaration(mods, dc); 16.2232 - } else if (allowEnums) { 16.2233 - if (S.token() == ENUM) { 16.2234 - return enumDeclaration(mods, dc); 16.2235 - } else { 16.2236 - int pos = S.pos(); 16.2237 - List<JCTree> errs; 16.2238 - if (S.token() == IDENTIFIER) { 16.2239 - errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 16.2240 - setErrorEndPos(S.pos()); 16.2241 - } else { 16.2242 - errs = List.<JCTree>of(mods); 16.2243 - } 16.2244 - return toP(F.Exec(syntaxError(pos, errs, "expected3", 16.2245 - CLASS, INTERFACE, ENUM))); 16.2246 - } 16.2247 - } else { 16.2248 - if (S.token() == ENUM) { 16.2249 - log.error(S.pos(), "enums.not.supported.in.source", source.name); 16.2250 - allowEnums = true; 16.2251 - return enumDeclaration(mods, dc); 16.2252 - } 16.2253 - int pos = S.pos(); 16.2254 - List<JCTree> errs; 16.2255 - if (S.token() == IDENTIFIER) { 16.2256 - errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 16.2257 - setErrorEndPos(S.pos()); 16.2258 - } else { 16.2259 - errs = List.<JCTree>of(mods); 16.2260 - } 16.2261 - return toP(F.Exec(syntaxError(pos, errs, "expected2", 16.2262 - CLASS, INTERFACE))); 16.2263 - } 16.2264 - } 16.2265 - 16.2266 - /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type] 16.2267 - * [IMPLEMENTS TypeList] ClassBody 16.2268 - * @param mods The modifiers starting the class declaration 16.2269 - * @param dc The documentation comment for the class, or null. 16.2270 - */ 16.2271 - JCClassDecl classDeclaration(JCModifiers mods, String dc) { 16.2272 - int pos = S.pos(); 16.2273 - accept(CLASS); 16.2274 - Name name = ident(); 16.2275 - 16.2276 - List<JCTypeParameter> typarams = typeParametersOpt(); 16.2277 - 16.2278 - JCTree extending = null; 16.2279 - if (S.token() == EXTENDS) { 16.2280 - S.nextToken(); 16.2281 - extending = type(); 16.2282 - } 16.2283 - List<JCExpression> implementing = List.nil(); 16.2284 - if (S.token() == IMPLEMENTS) { 16.2285 - S.nextToken(); 16.2286 - implementing = typeList(); 16.2287 - } 16.2288 - List<JCTree> defs = classOrInterfaceBody(name, false); 16.2289 - JCClassDecl result = toP(F.at(pos).ClassDef( 16.2290 - mods, name, typarams, extending, implementing, defs)); 16.2291 - attach(result, dc); 16.2292 - return result; 16.2293 - } 16.2294 - 16.2295 - /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt 16.2296 - * [EXTENDS TypeList] InterfaceBody 16.2297 - * @param mods The modifiers starting the interface declaration 16.2298 - * @param dc The documentation comment for the interface, or null. 16.2299 - */ 16.2300 - JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 16.2301 - int pos = S.pos(); 16.2302 - accept(INTERFACE); 16.2303 - Name name = ident(); 16.2304 - 16.2305 - List<JCTypeParameter> typarams = typeParametersOpt(); 16.2306 - 16.2307 - List<JCExpression> extending = List.nil(); 16.2308 - if (S.token() == EXTENDS) { 16.2309 - S.nextToken(); 16.2310 - extending = typeList(); 16.2311 - } 16.2312 - List<JCTree> defs = classOrInterfaceBody(name, true); 16.2313 - JCClassDecl result = toP(F.at(pos).ClassDef( 16.2314 - mods, name, typarams, null, extending, defs)); 16.2315 - attach(result, dc); 16.2316 - return result; 16.2317 - } 16.2318 - 16.2319 - /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody 16.2320 - * @param mods The modifiers starting the enum declaration 16.2321 - * @param dc The documentation comment for the enum, or null. 16.2322 - */ 16.2323 - JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 16.2324 - int pos = S.pos(); 16.2325 - accept(ENUM); 16.2326 - Name name = ident(); 16.2327 - 16.2328 - List<JCExpression> implementing = List.nil(); 16.2329 - if (S.token() == IMPLEMENTS) { 16.2330 - S.nextToken(); 16.2331 - implementing = typeList(); 16.2332 - } 16.2333 - 16.2334 - List<JCTree> defs = enumBody(name); 16.2335 - JCModifiers newMods = 16.2336 - F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations); 16.2337 - JCClassDecl result = toP(F.at(pos). 16.2338 - ClassDef(newMods, name, List.<JCTypeParameter>nil(), 16.2339 - null, implementing, defs)); 16.2340 - attach(result, dc); 16.2341 - return result; 16.2342 - } 16.2343 - 16.2344 - /** EnumBody = "{" { EnumeratorDeclarationList } [","] 16.2345 - * [ ";" {ClassBodyDeclaration} ] "}" 16.2346 - */ 16.2347 - List<JCTree> enumBody(Name enumName) { 16.2348 - accept(LBRACE); 16.2349 - ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 16.2350 - if (S.token() == COMMA) { 16.2351 - S.nextToken(); 16.2352 - } else if (S.token() != RBRACE && S.token() != SEMI) { 16.2353 - defs.append(enumeratorDeclaration(enumName)); 16.2354 - while (S.token() == COMMA) { 16.2355 - S.nextToken(); 16.2356 - if (S.token() == RBRACE || S.token() == SEMI) break; 16.2357 - defs.append(enumeratorDeclaration(enumName)); 16.2358 - } 16.2359 - if (S.token() != SEMI && S.token() != RBRACE) { 16.2360 - defs.append(syntaxError(S.pos(), "expected3", 16.2361 - COMMA, RBRACE, SEMI)); 16.2362 - S.nextToken(); 16.2363 - } 16.2364 - } 16.2365 - if (S.token() == SEMI) { 16.2366 - S.nextToken(); 16.2367 - while (S.token() != RBRACE && S.token() != EOF) { 16.2368 - defs.appendList(classOrInterfaceBodyDeclaration(enumName, 16.2369 - false)); 16.2370 - if (S.pos() <= errorEndPos) { 16.2371 - // error recovery 16.2372 - skip(false, true, true, false); 16.2373 - } 16.2374 - } 16.2375 - } 16.2376 - accept(RBRACE); 16.2377 - return defs.toList(); 16.2378 - } 16.2379 - 16.2380 - /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 16.2381 - */ 16.2382 - JCTree enumeratorDeclaration(Name enumName) { 16.2383 - String dc = S.docComment(); 16.2384 - int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 16.2385 - if (S.deprecatedFlag()) { 16.2386 - flags |= Flags.DEPRECATED; 16.2387 - S.resetDeprecatedFlag(); 16.2388 - } 16.2389 - int pos = S.pos(); 16.2390 - List<JCAnnotation> annotations = annotationsOpt(); 16.2391 - JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 16.2392 - List<JCExpression> typeArgs = typeArgumentsOpt(); 16.2393 - int identPos = S.pos(); 16.2394 - Name name = ident(); 16.2395 - int createPos = S.pos(); 16.2396 - List<JCExpression> args = (S.token() == LPAREN) 16.2397 - ? arguments() : List.<JCExpression>nil(); 16.2398 - JCClassDecl body = null; 16.2399 - if (S.token() == LBRACE) { 16.2400 - JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC); 16.2401 - List<JCTree> defs = classOrInterfaceBody(names.empty, false); 16.2402 - body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 16.2403 - } 16.2404 - if (args.isEmpty() && body == null) 16.2405 - createPos = Position.NOPOS; 16.2406 - JCIdent ident = F.at(Position.NOPOS).Ident(enumName); 16.2407 - JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 16.2408 - if (createPos != Position.NOPOS) 16.2409 - storeEnd(create, S.prevEndPos()); 16.2410 - ident = F.at(Position.NOPOS).Ident(enumName); 16.2411 - JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 16.2412 - attach(result, dc); 16.2413 - return result; 16.2414 - } 16.2415 - 16.2416 - /** TypeList = Type {"," Type} 16.2417 - */ 16.2418 - List<JCExpression> typeList() { 16.2419 - ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 16.2420 - ts.append(type()); 16.2421 - while (S.token() == COMMA) { 16.2422 - S.nextToken(); 16.2423 - ts.append(type()); 16.2424 - } 16.2425 - return ts.toList(); 16.2426 - } 16.2427 - 16.2428 - /** ClassBody = "{" {ClassBodyDeclaration} "}" 16.2429 - * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 16.2430 - */ 16.2431 - List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 16.2432 - accept(LBRACE); 16.2433 - if (S.pos() <= errorEndPos) { 16.2434 - // error recovery 16.2435 - skip(false, true, false, false); 16.2436 - if (S.token() == LBRACE) 16.2437 - S.nextToken(); 16.2438 - } 16.2439 - ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 16.2440 - while (S.token() != RBRACE && S.token() != EOF) { 16.2441 - defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 16.2442 - if (S.pos() <= errorEndPos) { 16.2443 - // error recovery 16.2444 - skip(false, true, true, false); 16.2445 - } 16.2446 - } 16.2447 - accept(RBRACE); 16.2448 - return defs.toList(); 16.2449 - } 16.2450 - 16.2451 - /** ClassBodyDeclaration = 16.2452 - * ";" 16.2453 - * | [STATIC] Block 16.2454 - * | ModifiersOpt 16.2455 - * ( Type Ident 16.2456 - * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) 16.2457 - * | VOID Ident MethodDeclaratorRest 16.2458 - * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest 16.2459 - * | Ident ConstructorDeclaratorRest 16.2460 - * | TypeParameters Ident ConstructorDeclaratorRest 16.2461 - * | ClassOrInterfaceOrEnumDeclaration 16.2462 - * ) 16.2463 - * InterfaceBodyDeclaration = 16.2464 - * ";" 16.2465 - * | ModifiersOpt Type Ident 16.2466 - * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 16.2467 - */ 16.2468 - List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 16.2469 - if (S.token() == SEMI) { 16.2470 - S.nextToken(); 16.2471 - return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil())); 16.2472 - } else { 16.2473 - String dc = S.docComment(); 16.2474 - int pos = S.pos(); 16.2475 - JCModifiers mods = modifiersOpt(); 16.2476 - if (S.token() == CLASS || 16.2477 - S.token() == INTERFACE || 16.2478 - allowEnums && S.token() == ENUM) { 16.2479 - return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc)); 16.2480 - } else if (S.token() == LBRACE && !isInterface && 16.2481 - (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 16.2482 - mods.annotations.isEmpty()) { 16.2483 - return List.<JCTree>of(block(pos, mods.flags)); 16.2484 - } else { 16.2485 - pos = S.pos(); 16.2486 - List<JCTypeParameter> typarams = typeParametersOpt(); 16.2487 - // Hack alert: if there are type arguments but no Modifiers, the start 16.2488 - // position will be lost unless we set the Modifiers position. There 16.2489 - // should be an AST node for type parameters (BugId 5005090). 16.2490 - if (typarams.length() > 0 && mods.pos == Position.NOPOS) { 16.2491 - mods.pos = pos; 16.2492 - } 16.2493 - Token token = S.token(); 16.2494 - Name name = S.name(); 16.2495 - pos = S.pos(); 16.2496 - JCExpression type; 16.2497 - boolean isVoid = S.token() == VOID; 16.2498 - if (isVoid) { 16.2499 - type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 16.2500 - S.nextToken(); 16.2501 - } else { 16.2502 - type = type(); 16.2503 - } 16.2504 - if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 16.2505 - if (isInterface || name != className) 16.2506 - log.error(pos, "invalid.meth.decl.ret.type.req"); 16.2507 - return List.of(methodDeclaratorRest( 16.2508 - pos, mods, null, names.init, typarams, 16.2509 - isInterface, true, dc)); 16.2510 - } else { 16.2511 - pos = S.pos(); 16.2512 - name = ident(); 16.2513 - if (S.token() == LPAREN) { 16.2514 - return List.of(methodDeclaratorRest( 16.2515 - pos, mods, type, name, typarams, 16.2516 - isInterface, isVoid, dc)); 16.2517 - } else if (!isVoid && typarams.isEmpty()) { 16.2518 - List<JCTree> defs = 16.2519 - variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 16.2520 - new ListBuffer<JCTree>()).toList(); 16.2521 - storeEnd(defs.last(), S.endPos()); 16.2522 - accept(SEMI); 16.2523 - return defs; 16.2524 - } else { 16.2525 - pos = S.pos(); 16.2526 - List<JCTree> err = isVoid 16.2527 - ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 16.2528 - List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null))) 16.2529 - : null; 16.2530 - return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN)); 16.2531 - } 16.2532 - } 16.2533 - } 16.2534 - } 16.2535 - } 16.2536 - 16.2537 - /** MethodDeclaratorRest = 16.2538 - * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 16.2539 - * VoidMethodDeclaratorRest = 16.2540 - * FormalParameters [Throws TypeList] ( MethodBody | ";") 16.2541 - * InterfaceMethodDeclaratorRest = 16.2542 - * FormalParameters BracketsOpt [THROWS TypeList] ";" 16.2543 - * VoidInterfaceMethodDeclaratorRest = 16.2544 - * FormalParameters [THROWS TypeList] ";" 16.2545 - * ConstructorDeclaratorRest = 16.2546 - * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody 16.2547 - */ 16.2548 - JCTree methodDeclaratorRest(int pos, 16.2549 - JCModifiers mods, 16.2550 - JCExpression type, 16.2551 - Name name, 16.2552 - List<JCTypeParameter> typarams, 16.2553 - boolean isInterface, boolean isVoid, 16.2554 - String dc) { 16.2555 - List<JCVariableDecl> params = formalParameters(); 16.2556 - if (!isVoid) type = bracketsOpt(type); 16.2557 - List<JCExpression> thrown = List.nil(); 16.2558 - if (S.token() == THROWS) { 16.2559 - S.nextToken(); 16.2560 - thrown = qualidentList(); 16.2561 - } 16.2562 - JCBlock body = null; 16.2563 - JCExpression defaultValue; 16.2564 - if (S.token() == LBRACE) { 16.2565 - body = block(); 16.2566 - defaultValue = null; 16.2567 - } else { 16.2568 - if (S.token() == DEFAULT) { 16.2569 - accept(DEFAULT); 16.2570 - defaultValue = annotationValue(); 16.2571 - } else { 16.2572 - defaultValue = null; 16.2573 - } 16.2574 - accept(SEMI); 16.2575 - if (S.pos() <= errorEndPos) { 16.2576 - // error recovery 16.2577 - skip(false, true, false, false); 16.2578 - if (S.token() == LBRACE) { 16.2579 - body = block(); 16.2580 - } 16.2581 - } 16.2582 - } 16.2583 - JCMethodDecl result = 16.2584 - toP(F.at(pos).MethodDef(mods, name, type, typarams, 16.2585 - params, thrown, 16.2586 - body, defaultValue)); 16.2587 - attach(result, dc); 16.2588 - return result; 16.2589 - } 16.2590 - 16.2591 - /** QualidentList = Qualident {"," Qualident} 16.2592 - */ 16.2593 - List<JCExpression> qualidentList() { 16.2594 - ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 16.2595 - ts.append(qualident()); 16.2596 - while (S.token() == COMMA) { 16.2597 - S.nextToken(); 16.2598 - ts.append(qualident()); 16.2599 - } 16.2600 - return ts.toList(); 16.2601 - } 16.2602 - 16.2603 - /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 16.2604 - */ 16.2605 - List<JCTypeParameter> typeParametersOpt() { 16.2606 - if (S.token() == LT) { 16.2607 - checkGenerics(); 16.2608 - ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>(); 16.2609 - S.nextToken(); 16.2610 - typarams.append(typeParameter()); 16.2611 - while (S.token() == COMMA) { 16.2612 - S.nextToken(); 16.2613 - typarams.append(typeParameter()); 16.2614 - } 16.2615 - accept(GT); 16.2616 - return typarams.toList(); 16.2617 - } else { 16.2618 - return List.nil(); 16.2619 - } 16.2620 - } 16.2621 - 16.2622 - /** TypeParameter = TypeVariable [TypeParameterBound] 16.2623 - * TypeParameterBound = EXTENDS Type {"&" Type} 16.2624 - * TypeVariable = Ident 16.2625 - */ 16.2626 - JCTypeParameter typeParameter() { 16.2627 - int pos = S.pos(); 16.2628 - Name name = ident(); 16.2629 - ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 16.2630 - if (S.token() == EXTENDS) { 16.2631 - S.nextToken(); 16.2632 - bounds.append(type()); 16.2633 - while (S.token() == AMP) { 16.2634 - S.nextToken(); 16.2635 - bounds.append(type()); 16.2636 - } 16.2637 - } 16.2638 - return toP(F.at(pos).TypeParameter(name, bounds.toList())); 16.2639 - } 16.2640 - 16.2641 - /** FormalParameters = "(" [ FormalParameterList ] ")" 16.2642 - * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 16.2643 - * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 16.2644 - */ 16.2645 - List<JCVariableDecl> formalParameters() { 16.2646 - ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 16.2647 - JCVariableDecl lastParam = null; 16.2648 - accept(LPAREN); 16.2649 - if (S.token() != RPAREN) { 16.2650 - params.append(lastParam = formalParameter()); 16.2651 - while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) { 16.2652 - S.nextToken(); 16.2653 - params.append(lastParam = formalParameter()); 16.2654 - } 16.2655 - } 16.2656 - accept(RPAREN); 16.2657 - return params.toList(); 16.2658 - } 16.2659 - 16.2660 - JCModifiers optFinal(long flags) { 16.2661 - JCModifiers mods = modifiersOpt(); 16.2662 - checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 16.2663 - mods.flags |= flags; 16.2664 - return mods; 16.2665 - } 16.2666 - 16.2667 - /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 16.2668 - * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 16.2669 - */ 16.2670 - JCVariableDecl formalParameter() { 16.2671 - JCModifiers mods = optFinal(Flags.PARAMETER); 16.2672 - JCExpression type = type(); 16.2673 - if (S.token() == ELLIPSIS) { 16.2674 - checkVarargs(); 16.2675 - mods.flags |= Flags.VARARGS; 16.2676 - type = to(F.at(S.pos()).TypeArray(type)); 16.2677 - S.nextToken(); 16.2678 - } 16.2679 - return variableDeclaratorId(mods, type); 16.2680 - } 16.2681 - 16.2682 -/* ---------- auxiliary methods -------------- */ 16.2683 - 16.2684 - /** Check that given tree is a legal expression statement. 16.2685 - */ 16.2686 - protected JCExpression checkExprStat(JCExpression t) { 16.2687 - switch(t.getTag()) { 16.2688 - case JCTree.PREINC: case JCTree.PREDEC: 16.2689 - case JCTree.POSTINC: case JCTree.POSTDEC: 16.2690 - case JCTree.ASSIGN: 16.2691 - case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG: 16.2692 - case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG: 16.2693 - case JCTree.PLUS_ASG: case JCTree.MINUS_ASG: 16.2694 - case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG: 16.2695 - case JCTree.APPLY: case JCTree.NEWCLASS: 16.2696 - case JCTree.ERRONEOUS: 16.2697 - return t; 16.2698 - default: 16.2699 - log.error(t.pos, "not.stmt"); 16.2700 - return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 16.2701 - } 16.2702 - } 16.2703 - 16.2704 - /** Return precedence of operator represented by token, 16.2705 - * -1 if token is not a binary operator. @see TreeInfo.opPrec 16.2706 - */ 16.2707 - static int prec(Token token) { 16.2708 - int oc = optag(token); 16.2709 - return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 16.2710 - } 16.2711 - 16.2712 - /** Return operation tag of binary operator represented by token, 16.2713 - * -1 if token is not a binary operator. 16.2714 - */ 16.2715 - static int optag(Token token) { 16.2716 - switch (token) { 16.2717 - case BARBAR: 16.2718 - return JCTree.OR; 16.2719 - case AMPAMP: 16.2720 - return JCTree.AND; 16.2721 - case BAR: 16.2722 - return JCTree.BITOR; 16.2723 - case BAREQ: 16.2724 - return JCTree.BITOR_ASG; 16.2725 - case CARET: 16.2726 - return JCTree.BITXOR; 16.2727 - case CARETEQ: 16.2728 - return JCTree.BITXOR_ASG; 16.2729 - case AMP: 16.2730 - return JCTree.BITAND; 16.2731 - case AMPEQ: 16.2732 - return JCTree.BITAND_ASG; 16.2733 - case EQEQ: 16.2734 - return JCTree.EQ; 16.2735 - case BANGEQ: 16.2736 - return JCTree.NE; 16.2737 - case LT: 16.2738 - return JCTree.LT; 16.2739 - case GT: 16.2740 - return JCTree.GT; 16.2741 - case LTEQ: 16.2742 - return JCTree.LE; 16.2743 - case GTEQ: 16.2744 - return JCTree.GE; 16.2745 - case LTLT: 16.2746 - return JCTree.SL; 16.2747 - case LTLTEQ: 16.2748 - return JCTree.SL_ASG; 16.2749 - case GTGT: 16.2750 - return JCTree.SR; 16.2751 - case GTGTEQ: 16.2752 - return JCTree.SR_ASG; 16.2753 - case GTGTGT: 16.2754 - return JCTree.USR; 16.2755 - case GTGTGTEQ: 16.2756 - return JCTree.USR_ASG; 16.2757 - case PLUS: 16.2758 - return JCTree.PLUS; 16.2759 - case PLUSEQ: 16.2760 - return JCTree.PLUS_ASG; 16.2761 - case SUB: 16.2762 - return JCTree.MINUS; 16.2763 - case SUBEQ: 16.2764 - return JCTree.MINUS_ASG; 16.2765 - case STAR: 16.2766 - return JCTree.MUL; 16.2767 - case STAREQ: 16.2768 - return JCTree.MUL_ASG; 16.2769 - case SLASH: 16.2770 - return JCTree.DIV; 16.2771 - case SLASHEQ: 16.2772 - return JCTree.DIV_ASG; 16.2773 - case PERCENT: 16.2774 - return JCTree.MOD; 16.2775 - case PERCENTEQ: 16.2776 - return JCTree.MOD_ASG; 16.2777 - case INSTANCEOF: 16.2778 - return JCTree.TYPETEST; 16.2779 - default: 16.2780 - return -1; 16.2781 - } 16.2782 - } 16.2783 - 16.2784 - /** Return operation tag of unary operator represented by token, 16.2785 - * -1 if token is not a binary operator. 16.2786 - */ 16.2787 - static int unoptag(Token token) { 16.2788 - switch (token) { 16.2789 - case PLUS: 16.2790 - return JCTree.POS; 16.2791 - case SUB: 16.2792 - return JCTree.NEG; 16.2793 - case BANG: 16.2794 - return JCTree.NOT; 16.2795 - case TILDE: 16.2796 - return JCTree.COMPL; 16.2797 - case PLUSPLUS: 16.2798 - return JCTree.PREINC; 16.2799 - case SUBSUB: 16.2800 - return JCTree.PREDEC; 16.2801 - default: 16.2802 - return -1; 16.2803 - } 16.2804 - } 16.2805 - 16.2806 - /** Return type tag of basic type represented by token, 16.2807 - * -1 if token is not a basic type identifier. 16.2808 - */ 16.2809 - static int typetag(Token token) { 16.2810 - switch (token) { 16.2811 - case BYTE: 16.2812 - return TypeTags.BYTE; 16.2813 - case CHAR: 16.2814 - return TypeTags.CHAR; 16.2815 - case SHORT: 16.2816 - return TypeTags.SHORT; 16.2817 - case INT: 16.2818 - return TypeTags.INT; 16.2819 - case LONG: 16.2820 - return TypeTags.LONG; 16.2821 - case FLOAT: 16.2822 - return TypeTags.FLOAT; 16.2823 - case DOUBLE: 16.2824 - return TypeTags.DOUBLE; 16.2825 - case BOOLEAN: 16.2826 - return TypeTags.BOOLEAN; 16.2827 - default: 16.2828 - return -1; 16.2829 - } 16.2830 - } 16.2831 - 16.2832 - void checkGenerics() { 16.2833 - if (!allowGenerics) { 16.2834 - log.error(S.pos(), "generics.not.supported.in.source", source.name); 16.2835 - allowGenerics = true; 16.2836 - } 16.2837 - } 16.2838 - void checkVarargs() { 16.2839 - if (!allowVarargs) { 16.2840 - log.error(S.pos(), "varargs.not.supported.in.source", source.name); 16.2841 - allowVarargs = true; 16.2842 - } 16.2843 - } 16.2844 - void checkForeach() { 16.2845 - if (!allowForeach) { 16.2846 - log.error(S.pos(), "foreach.not.supported.in.source", source.name); 16.2847 - allowForeach = true; 16.2848 - } 16.2849 - } 16.2850 - void checkStaticImports() { 16.2851 - if (!allowStaticImport) { 16.2852 - log.error(S.pos(), "static.import.not.supported.in.source", source.name); 16.2853 - allowStaticImport = true; 16.2854 - } 16.2855 - } 16.2856 - void checkAnnotations() { 16.2857 - if (!allowAnnotations) { 16.2858 - log.error(S.pos(), "annotations.not.supported.in.source", source.name); 16.2859 - allowAnnotations = true; 16.2860 - } 16.2861 - } 16.2862 -}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Fri Sep 12 23:32:51 2008 -0700 17.3 @@ -0,0 +1,79 @@ 17.4 +/* 17.5 + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. 17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.7 + * 17.8 + * This code is free software; you can redistribute it and/or modify it 17.9 + * under the terms of the GNU General Public License version 2 only, as 17.10 + * published by the Free Software Foundation. Sun designates this 17.11 + * particular file as subject to the "Classpath" exception as provided 17.12 + * by Sun in the LICENSE file that accompanied this code. 17.13 + * 17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17.17 + * version 2 for more details (a copy is included in the LICENSE file that 17.18 + * accompanied this code). 17.19 + * 17.20 + * You should have received a copy of the GNU General Public License version 17.21 + * 2 along with this work; if not, write to the Free Software Foundation, 17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17.23 + * 17.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 17.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 17.26 + * have any questions. 17.27 + */ 17.28 + 17.29 +package com.sun.tools.javac.parser; 17.30 + 17.31 +import com.sun.tools.javac.code.Source; 17.32 +import com.sun.tools.javac.tree.TreeMaker; 17.33 +import com.sun.tools.javac.util.Context; 17.34 +import com.sun.tools.javac.util.Log; 17.35 +import com.sun.tools.javac.util.Name; 17.36 +import com.sun.tools.javac.util.Options; 17.37 + 17.38 +/** 17.39 + * A factory for creating parsers. 17.40 + */ 17.41 +public class ParserFactory { 17.42 + 17.43 + /** The context key for the parser factory. */ 17.44 + protected static final Context.Key<ParserFactory> parserFactoryKey = new Context.Key<ParserFactory>(); 17.45 + 17.46 + public static ParserFactory instance(Context context) { 17.47 + ParserFactory instance = context.get(parserFactoryKey); 17.48 + if (instance == null) { 17.49 + instance = new ParserFactory(context); 17.50 + } 17.51 + return instance; 17.52 + } 17.53 + 17.54 + final TreeMaker F; 17.55 + final Log log; 17.56 + final Keywords keywords; 17.57 + final Source source; 17.58 + final Name.Table names; 17.59 + final Options options; 17.60 + final Scanner.Factory scannerFactory; 17.61 + 17.62 + protected ParserFactory(Context context) { 17.63 + super(); 17.64 + context.put(parserFactoryKey, this); 17.65 + this.F = TreeMaker.instance(context); 17.66 + this.log = Log.instance(context); 17.67 + this.names = Name.Table.instance(context); 17.68 + this.keywords = Keywords.instance(context); 17.69 + this.source = Source.instance(context); 17.70 + this.options = Options.instance(context); 17.71 + this.scannerFactory = Scanner.Factory.instance(context); 17.72 + } 17.73 + 17.74 + public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { 17.75 + Lexer lexer = scannerFactory.newScanner(input); 17.76 + if (keepEndPos) { 17.77 + return new EndPosParser(this, lexer, keepDocComments, keepLineMap); 17.78 + } else { 17.79 + return new JavacParser(this, lexer, keepDocComments, keepLineMap); 17.80 + } 17.81 + } 17.82 +}
18.1 --- a/src/share/classes/javax/lang/model/type/ErrorType.java Fri Sep 12 14:35:51 2008 -0700 18.2 +++ b/src/share/classes/javax/lang/model/type/ErrorType.java Fri Sep 12 23:32:51 2008 -0700 18.3 @@ -25,10 +25,6 @@ 18.4 18.5 package javax.lang.model.type; 18.6 18.7 - 18.8 -import javax.lang.model.element.TypeElement; 18.9 - 18.10 - 18.11 /** 18.12 * Represents a class or interface type that cannot be properly modeled. 18.13 * This may be the result of a processing error,
19.1 --- a/test/tools/javac/6304921/TestLog.java Fri Sep 12 14:35:51 2008 -0700 19.2 +++ b/test/tools/javac/6304921/TestLog.java Fri Sep 12 23:32:51 2008 -0700 19.3 @@ -34,6 +34,7 @@ 19.4 import javax.tools.SimpleJavaFileObject; 19.5 import com.sun.tools.javac.file.JavacFileManager; 19.6 import com.sun.tools.javac.parser.Parser; 19.7 +import com.sun.tools.javac.parser.ParserFactory; 19.8 import com.sun.tools.javac.parser.Scanner; 19.9 import com.sun.tools.javac.tree.JCTree; 19.10 import com.sun.tools.javac.tree.TreeScanner; 19.11 @@ -60,7 +61,7 @@ 19.12 19.13 JavacFileManager.preRegister(context); 19.14 Scanner.Factory sfac = Scanner.Factory.instance(context); 19.15 - Parser.Factory pfac = Parser.Factory.instance(context); 19.16 + ParserFactory pfac = ParserFactory.instance(context); 19.17 19.18 final String text = 19.19 "public class Foo {\n" 19.20 @@ -74,9 +75,9 @@ 19.21 JavaFileObject fo = new StringJavaFileObject("Foo", text); 19.22 log.useSource(fo); 19.23 19.24 - Scanner s = sfac.newScanner(fo.getCharContent(true)); 19.25 - Parser parser = pfac.newParser(s, false, genEndPos); 19.26 - JCTree.JCCompilationUnit tree = parser.compilationUnit(); 19.27 + CharSequence cs = fo.getCharContent(true); 19.28 + Parser parser = pfac.newParser(cs, false, genEndPos, false); 19.29 + JCTree.JCCompilationUnit tree = parser.parseCompilationUnit(); 19.30 log.setEndPosTable(fo, tree.endPositions); 19.31 19.32 TreeScanner ts = new LogTester(log, tree.endPositions);
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javac/api/6557752/T6557752.java Fri Sep 12 23:32:51 2008 -0700 20.3 @@ -0,0 +1,133 @@ 20.4 +/* 20.5 + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 20.24 + * have any questions. 20.25 + */ 20.26 + 20.27 + 20.28 +/* 20.29 + * @test 20.30 + * @bug 6557752 20.31 + * @summary Test for wrapping the original type in ErrorType. 20.32 + * @library ../lib 20.33 + * @compile T6557752.java 20.34 + * @run main T6557752 20.35 + */ 20.36 + 20.37 +import com.sun.source.tree.AssignmentTree; 20.38 +import com.sun.source.tree.CompilationUnitTree; 20.39 +import com.sun.source.tree.MethodInvocationTree; 20.40 +import com.sun.source.util.JavacTask; 20.41 +import com.sun.source.util.TreePath; 20.42 +import com.sun.source.util.TreePathScanner; 20.43 +import com.sun.source.util.Trees; 20.44 +import com.sun.tools.javac.api.JavacTaskImpl; 20.45 +import com.sun.tools.javac.util.List; 20.46 +import java.io.IOException; 20.47 +import java.net.URI; 20.48 +import javax.lang.model.type.ErrorType; 20.49 +import javax.lang.model.type.TypeKind; 20.50 +import javax.lang.model.type.TypeMirror; 20.51 +import javax.tools.JavaCompiler; 20.52 +import javax.tools.JavaFileObject; 20.53 +import javax.tools.SimpleJavaFileObject; 20.54 +import javax.tools.ToolProvider; 20.55 +import javax.lang.model.util.Types; 20.56 + 20.57 +public class T6557752 { 20.58 + static class MyFileObject extends SimpleJavaFileObject { 20.59 + public MyFileObject() { 20.60 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 20.61 + } 20.62 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 20.63 + return "import java.util.*;\n" 20.64 + + "public class Test {\n" 20.65 + + " void foobar() {\n" 20.66 + + " Iterator<Number> itr = null;\n" 20.67 + + " String str = itr.next();\n" 20.68 + + " FooBar fooBar = FooBar.foobar();\n" 20.69 + + " }\n" 20.70 + + "}"; 20.71 + } 20.72 + } 20.73 + static Trees trees; 20.74 + static JavacTask task = null; 20.75 + public static void main(String[] args) throws IOException { 20.76 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 20.77 + task = (JavacTask) compiler.getTask(null, null, null, null, null, List.of(new MyFileObject())); 20.78 + Iterable<? extends CompilationUnitTree> asts = task.parse(); 20.79 + task.analyze(); 20.80 + trees = Trees.instance(task); 20.81 + MyVisitor myVisitor = new MyVisitor(); 20.82 + for (CompilationUnitTree ast : asts) { 20.83 + myVisitor.compilationUnit = ast; 20.84 + myVisitor.scan(ast, null); 20.85 + } 20.86 + 20.87 + if (!myVisitor.foundError) { 20.88 + throw new AssertionError("Expected error not found!"); 20.89 + } 20.90 + } 20.91 + 20.92 + static class MyVisitor extends TreePathScanner<Void,Void> { 20.93 + public boolean foundError = false; 20.94 + CompilationUnitTree compilationUnit = null; 20.95 + int i = 0; 20.96 + @Override 20.97 + public Void visitMethodInvocation(MethodInvocationTree node, Void ignored) { 20.98 + TreePath path = TreePath.getPath(compilationUnit, node); 20.99 + TypeMirror typeMirror = trees.getTypeMirror(path); 20.100 + if (typeMirror.getKind() == TypeKind.ERROR) { 20.101 + if (i == 0) { 20.102 + String str1 = trees.getOriginalType((ErrorType)typeMirror).toString(); 20.103 + if (!str1.equals("java.lang.Number")) { 20.104 + throw new AssertionError("Trees.getOriginalType() error!"); 20.105 + } 20.106 + 20.107 + Types types = task.getTypes(); 20.108 + 20.109 + str1 = types.asElement(trees.getOriginalType((ErrorType)typeMirror)).toString(); 20.110 + if (!str1.equals("java.lang.Number")) { 20.111 + throw new AssertionError("Types.asElement() error!"); 20.112 + } 20.113 + 20.114 + i++; 20.115 + } 20.116 + else if (i == 1) { 20.117 + String str1 = trees.getOriginalType((ErrorType)typeMirror).toString(); 20.118 + if (!str1.equals("FooBar")) { 20.119 + throw new AssertionError("Trees.getOriginalType() error!"); 20.120 + } 20.121 + 20.122 + Types types = task.getTypes(); 20.123 + 20.124 + if (types.asElement(trees.getOriginalType((ErrorType)typeMirror)) != null) { 20.125 + throw new AssertionError("Ttypes.asElement() error!"); 20.126 + } 20.127 + foundError = true; 20.128 + } 20.129 + } 20.130 + 20.131 + 20.132 + return null; 20.133 + } 20.134 + 20.135 + } 20.136 +}