Merge

Fri, 12 Sep 2008 23:32:51 -0700

author
tbell
date
Fri, 12 Sep 2008 23:32:51 -0700
changeset 112
7e2249b1c13d
parent 108
258af9b67b7c
parent 111
a92b756a888f
child 113
eff38cc97183

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 +}

mercurial