1 /*
   2  * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 
  30 import com.sun.tools.javac.tree.*;
  31 import com.sun.tools.javac.code.*;
  32 import com.sun.tools.javac.util.*;
  33 import com.sun.tools.javac.util.List;
  34 import static com.sun.tools.javac.util.ListBuffer.lb;
  35 
  36 import com.sun.tools.javac.tree.JCTree.*;
  37 
  38 import static com.sun.tools.javac.parser.Token.*;
  39 
  40 /** The parser maps a token sequence into an abstract syntax
  41  *  tree. It operates by recursive descent, with code derived
  42  *  systematically from an LL(1) grammar. For efficiency reasons, an
  43  *  operator precedence scheme is used for parsing binary operation
  44  *  expressions.
  45  *
  46  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
  47  *  you write code that depends on this, you do so at your own risk.
  48  *  This code and its internal interfaces are subject to change or
  49  *  deletion without notice.</b>
  50  */
  51 public class JavacParser implements Parser {
  52 
  53     /** The number of precedence levels of infix operators.
  54      */
  55     private static final int infixPrecedenceLevels = 10;
  56 
  57     /** The scanner used for lexical analysis.
  58      */
  59     private Lexer S;
  60 
  61     /** The factory to be used for abstract syntax tree construction.
  62      */
  63     protected TreeMaker F;
  64 
  65     /** The log to be used for error diagnostics.
  66      */
  67     private Log log;
  68 
  69     /** The keyword table. */
  70     private Keywords keywords;
  71 
  72     /** The Source language setting. */
  73     private Source source;
  74 
  75     /** The name table. */
  76     private Names names;
  77 
  78     // Because of javac's limited lookahead, some contexts are ambiguous in
  79     // the presence of type annotations even though they are not ambiguous
  80     // in the absence of type annotations.  Consider this code:
  81     //   void m(String [] m) { }
  82     //   void m(String ... m) { }
  83     // After parsing "String", javac calls bracketsOpt which immediately
  84     // returns if the next character is not '['.  Similarly, javac can see
  85     // if the next token is ... and in that case parse an ellipsis.  But in
  86     // the presence of type annotations:
  87     //   void m(String @A [] m) { }
  88     //   void m(String @A ... m) { }
  89     // no finite lookahead is enough to determine whether to read array
  90     // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
  91     // bracketsOpt first reads all the leading annotations and only then
  92     // discovers that it needs to fail.  bracketsOpt needs a way to push
  93     // back the extra annotations that it read.  (But, bracketsOpt should
  94     // not *always* be allowed to push back extra annotations that it finds
  95     // -- in most contexts, any such extra annotation is an error.
  96     // Another similar case occurs with arrays and receiver annotations:
  97     //   String b() @Array [] @Receiver { }
  98     //   String b() @Receiver { }
  99     //
 100     // The following two variables permit type annotations that have
 101     // already been read to be stored for later use.  Alternate
 102     // implementations are possible but would cause much larger changes to
 103     // the parser.
 104     /** Type annotations that have already been read but have not yet been used. **/
 105     private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
 106     /**
 107      * If the parser notices extra annotations, then it either immediately
 108      * issues an error (if this variable is false) or places the extra
 109      * annotations in variable typeAnnotationsPushedBack (if this variable
 110      * is true).
 111      */
 112     private boolean permitTypeAnnotationsPushBack = false;
 113 
 114     /** Construct a parser from a given scanner, tree factory and log.
 115      */
 116     protected JavacParser(ParserFactory fac,
 117                      Lexer S,
 118                      boolean keepDocComments,
 119                      boolean keepLineMap) {
 120         this.S = S;
 121         S.nextToken(); // prime the pump
 122         this.F = fac.F;
 123         this.log = fac.log;
 124         this.names = fac.names;
 125         this.keywords = fac.keywords;
 126         this.source = fac.source;
 127         this.allowGenerics = source.allowGenerics();
 128         this.allowVarargs = source.allowVarargs();
 129         this.allowAsserts = source.allowAsserts();
 130         this.allowEnums = source.allowEnums();
 131         this.allowForeach = source.allowForeach();
 132         this.allowStaticImport = source.allowStaticImport();
 133         this.allowAnnotations = source.allowAnnotations();
 134         this.allowDiamond = source.allowDiamond();
 135         this.allowTypeAnnotations = source.allowTypeAnnotations();
 136         this.allowFunctionType = source.allowFunctionType();
 137         this.allowLambda = source.allowLambda();
 138         this.keepDocComments = keepDocComments;
 139         if (keepDocComments)
 140             docComments = new HashMap<JCTree,String>();
 141         this.keepLineMap = keepLineMap;
 142         this.errorTree = F.Erroneous();
 143         this.debugJSR308 = fac.options.get("TA:parser") != null;
 144     }
 145 
 146     /** Switch: debug output for type-annotations operations
 147      */
 148     boolean debugJSR308;
 149 
 150     /** Switch: Should generics be recognized?
 151      */
 152     boolean allowGenerics;
 153 
 154     /** Switch: Should diamond operator be recognized?
 155      */
 156     boolean allowDiamond;
 157 
 158     /** Switch: Should varargs be recognized?
 159      */
 160     boolean allowVarargs;
 161 
 162     /** Switch: should we recognize assert statements, or just give a warning?
 163      */
 164     boolean allowAsserts;
 165 
 166     /** Switch: should we recognize enums, or just give a warning?
 167      */
 168     boolean allowEnums;
 169 
 170     /** Switch: should we recognize foreach?
 171      */
 172     boolean allowForeach;
 173 
 174     /** Switch: should we recognize static import?
 175      */
 176     boolean allowStaticImport;
 177 
 178     /** Switch: should we recognize annotations?
 179      */
 180     boolean allowAnnotations;
 181 
 182     /** Switch: should we recognize type annotations?
 183      */
 184     boolean allowTypeAnnotations;
 185     
 186     /** Switch: should we recognize function type?
 187      */
 188     boolean allowFunctionType;
 189     
 190     /** Switch: should we recognize lambda?
 191      */
 192     boolean allowLambda;
 193 
 194     /** Switch: should we keep docComments?
 195      */
 196     boolean keepDocComments;
 197 
 198     /** Switch: should we keep line table?
 199      */
 200     boolean keepLineMap;
 201 
 202     /** When terms are parsed, the mode determines which is expected:
 203      *     mode = EXPR        : an expression
 204      *     mode = TYPE        : a type
 205      *     mode = NOPARAMS    : no parameters allowed for type
 206      *     mode = TYPEARG     : type argument
 207      */
 208     static final int EXPR = 1;
 209     static final int TYPE = 2;
 210     static final int NOPARAMS = 4;
 211     static final int TYPEARG = 8;
 212     static final int DIAMOND = 16;
 213 
 214     /** The current mode.
 215      */
 216     private int mode = 0;
 217 
 218     /** The mode of the term that was parsed last.
 219      */
 220     private int lastmode = 0;
 221 
 222 /* ---------- error recovery -------------- */
 223 
 224     private JCErroneous errorTree;
 225 
 226     /** Skip forward until a suitable stop token is found.
 227      */
 228     private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
 229          while (true) {
 230              switch (S.token()) {
 231                 case SEMI:
 232                     S.nextToken();
 233                     return;
 234                 case PUBLIC:
 235                 case FINAL:
 236                 case ABSTRACT:
 237                 case MONKEYS_AT:
 238                 case EOF:
 239                 case CLASS:
 240                 case INTERFACE:
 241                 case ENUM:
 242                     return;
 243                 case IMPORT:
 244                     if (stopAtImport)
 245                         return;
 246                     break;
 247                 case LBRACE:
 248                 case RBRACE:
 249                 case PRIVATE:
 250                 case PROTECTED:
 251                 case STATIC:
 252                 case TRANSIENT:
 253                 case NATIVE:
 254                 case VOLATILE:
 255                 case SYNCHRONIZED:
 256                 case STRICTFP:
 257                 case LT:
 258                 case BYTE:
 259                 case SHORT:
 260                 case CHAR:
 261                 case INT:
 262                 case LONG:
 263                 case FLOAT:
 264                 case DOUBLE:
 265                 case BOOLEAN:
 266                 case VOID:
 267                     if (stopAtMemberDecl)
 268                         return;
 269                     break;
 270                 case IDENTIFIER:
 271                    if (stopAtIdentifier)
 272                         return;
 273                     break;
 274                 case CASE:
 275                 case DEFAULT:
 276                 case IF:
 277                 case FOR:
 278                 case WHILE:
 279                 case DO:
 280                 case TRY:
 281                 case SWITCH:
 282                 case RETURN:
 283                 case THROW:
 284                 case BREAK:
 285                 case CONTINUE:
 286                 case ELSE:
 287                 case FINALLY:
 288                 case CATCH:
 289                     if (stopAtStatement)
 290                         return;
 291                     break;
 292             }
 293             S.nextToken();
 294         }
 295     }
 296 
 297     private JCErroneous syntaxError(int pos, String key, Token... args) {
 298         return syntaxError(pos, null, key, args);
 299     }
 300 
 301     private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
 302         setErrorEndPos(pos);
 303         reportSyntaxError(pos, key, (Object[])args);
 304         return toP(F.at(pos).Erroneous(errs));
 305     }
 306 
 307     private int errorPos = Position.NOPOS;
 308     /**
 309      * Report a syntax error at given position using the given
 310      * argument unless one was already reported at the same position.
 311      */
 312     private void reportSyntaxError(int pos, String key, Object... args) {
 313         if (pos > S.errPos() || pos == Position.NOPOS) {
 314             if (S.token() == EOF)
 315                 log.error(pos, "premature.eof");
 316             else
 317                 log.error(pos, key, args);
 318         }
 319         S.errPos(pos);
 320         if (S.pos() == errorPos)
 321             S.nextToken(); // guarantee progress
 322         errorPos = S.pos();
 323     }
 324 
 325 
 326     /** Generate a syntax error at current position unless one was already
 327      *  reported at the same position.
 328      */
 329     private JCErroneous syntaxError(String key) {
 330         return syntaxError(S.pos(), key);
 331     }
 332 
 333     /** Generate a syntax error at current position unless one was
 334      *  already reported at the same position.
 335      */
 336     private JCErroneous syntaxError(String key, Token arg) {
 337         return syntaxError(S.pos(), key, arg);
 338     }
 339 
 340     /** If next input token matches given token, skip it, otherwise report
 341      *  an error.
 342      */
 343     public void accept(Token token) {
 344         if (S.token() == token) {
 345             S.nextToken();
 346         } else {
 347             setErrorEndPos(S.pos());
 348             reportSyntaxError(S.prevEndPos(), "expected", token);
 349         }
 350     }
 351 
 352     /** Report an illegal start of expression/type error at given position.
 353      */
 354     JCExpression illegal(int pos) {
 355         setErrorEndPos(S.pos());
 356         if ((mode & EXPR) != 0)
 357             return syntaxError(pos, "illegal.start.of.expr");
 358         else
 359             return syntaxError(pos, "illegal.start.of.type");
 360 
 361     }
 362 
 363     /** Report an illegal start of expression/type error at current position.
 364      */
 365     JCExpression illegal() {
 366         return illegal(S.pos());
 367     }
 368 
 369     /** Diagnose a modifier flag from the set, if any. */
 370     void checkNoMods(long mods) {
 371         if (mods != 0) {
 372             long lowestMod = mods & -mods;
 373             log.error(S.pos(), "mod.not.allowed.here",
 374                       Flags.asFlagSet(lowestMod));
 375         }
 376     }
 377 
 378 /* ---------- doc comments --------- */
 379 
 380     /** A hashtable to store all documentation comments
 381      *  indexed by the tree nodes they refer to.
 382      *  defined only if option flag keepDocComment is set.
 383      */
 384     Map<JCTree, String> docComments;
 385 
 386     /** Make an entry into docComments hashtable,
 387      *  provided flag keepDocComments is set and given doc comment is non-null.
 388      *  @param tree   The tree to be used as index in the hashtable
 389      *  @param dc     The doc comment to associate with the tree, or null.
 390      */
 391     void attach(JCTree tree, String dc) {
 392         if (keepDocComments && dc != null) {
 393 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
 394             docComments.put(tree, dc);
 395         }
 396     }
 397 
 398 /* -------- source positions ------- */
 399 
 400     private int errorEndPos = -1;
 401 
 402     private void setErrorEndPos(int errPos) {
 403         if (errPos > errorEndPos)
 404             errorEndPos = errPos;
 405     }
 406 
 407     protected int getErrorEndPos() {
 408         return errorEndPos;
 409     }
 410 
 411     /**
 412      * Store ending position for a tree.
 413      * @param tree   The tree.
 414      * @param endpos The ending position to associate with the tree.
 415      */
 416     protected void storeEnd(JCTree tree, int endpos) {}
 417 
 418     /**
 419      * Store ending position for a tree.  The ending position should
 420      * be the ending position of the current token.
 421      * @param t The tree.
 422      */
 423     protected <T extends JCTree> T to(T t) { return t; }
 424 
 425     /**
 426      * Store ending position for a tree.  The ending position should
 427      * be greater of the ending position of the previous token and errorEndPos.
 428      * @param t The tree.
 429      */
 430     protected <T extends JCTree> T toP(T t) { return t; }
 431 
 432     /** Get the start position for a tree node.  The start position is
 433      * defined to be the position of the first character of the first
 434      * token of the node's source text.
 435      * @param tree  The tree node
 436      */
 437     public int getStartPos(JCTree tree) {
 438         return TreeInfo.getStartPos(tree);
 439     }
 440 
 441     /**
 442      * Get the end position for a tree node.  The end position is
 443      * defined to be the position of the last character of the last
 444      * token of the node's source text.  Returns Position.NOPOS if end
 445      * positions are not generated or the position is otherwise not
 446      * found.
 447      * @param tree  The tree node
 448      */
 449     public int getEndPos(JCTree tree) {
 450         return Position.NOPOS;
 451     }
 452 
 453 
 454 
 455 /* ---------- parsing -------------- */
 456 
 457     /**
 458      * Ident = IDENTIFIER
 459      */
 460     Name ident() {
 461         if (S.token() == IDENTIFIER) {
 462             Name name = S.name();
 463             S.nextToken();
 464             return name;
 465         } else if (S.token() == ASSERT) {
 466             if (allowAsserts) {
 467                 log.error(S.pos(), "assert.as.identifier");
 468                 S.nextToken();
 469                 return names.error;
 470             } else {
 471                 log.warning(S.pos(), "assert.as.identifier");
 472                 Name name = S.name();
 473                 S.nextToken();
 474                 return name;
 475             }
 476         } else if (S.token() == ENUM) {
 477             if (allowEnums) {
 478                 log.error(S.pos(), "enum.as.identifier");
 479                 S.nextToken();
 480                 return names.error;
 481             } else {
 482                 log.warning(S.pos(), "enum.as.identifier");
 483                 Name name = S.name();
 484                 S.nextToken();
 485                 return name;
 486             }
 487         } else {
 488             accept(IDENTIFIER);
 489             return names.error;
 490         }
 491 }
 492 
 493     /**
 494      * Qualident = Ident { DOT Ident }
 495      */
 496     public JCExpression qualident() {
 497         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
 498         while (S.token() == DOT) {
 499             int pos = S.pos();
 500             S.nextToken();
 501             t = toP(F.at(pos).Select(t, ident()));
 502         }
 503         return t;
 504     }
 505 
 506     /**
 507      * Literal =
 508      *     INTLITERAL
 509      *   | LONGLITERAL
 510      *   | FLOATLITERAL
 511      *   | DOUBLELITERAL
 512      *   | CHARLITERAL
 513      *   | STRINGLITERAL
 514      *   | TRUE
 515      *   | FALSE
 516      *   | NULL
 517      */
 518     JCExpression literal(Name prefix) {
 519         int pos = S.pos();
 520         JCExpression t = errorTree;
 521         switch (S.token()) {
 522         case INTLITERAL:
 523             try {
 524                 t = F.at(pos).Literal(
 525                     TypeTags.INT,
 526                     Convert.string2int(strval(prefix), S.radix()));
 527             } catch (NumberFormatException ex) {
 528                 log.error(S.pos(), "int.number.too.large", strval(prefix));
 529             }
 530             break;
 531         case LONGLITERAL:
 532             try {
 533                 t = F.at(pos).Literal(
 534                     TypeTags.LONG,
 535                     new Long(Convert.string2long(strval(prefix), S.radix())));
 536             } catch (NumberFormatException ex) {
 537                 log.error(S.pos(), "int.number.too.large", strval(prefix));
 538             }
 539             break;
 540         case FLOATLITERAL: {
 541             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
 542             Float n;
 543             try {
 544                 n = Float.valueOf(proper);
 545             } catch (NumberFormatException ex) {
 546                 // error already repoted in scanner
 547                 n = Float.NaN;
 548             }
 549             if (n.floatValue() == 0.0f && !isZero(proper))
 550                 log.error(S.pos(), "fp.number.too.small");
 551             else if (n.floatValue() == Float.POSITIVE_INFINITY)
 552                 log.error(S.pos(), "fp.number.too.large");
 553             else
 554                 t = F.at(pos).Literal(TypeTags.FLOAT, n);
 555             break;
 556         }
 557         case DOUBLELITERAL: {
 558             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
 559             Double n;
 560             try {
 561                 n = Double.valueOf(proper);
 562             } catch (NumberFormatException ex) {
 563                 // error already reported in scanner
 564                 n = Double.NaN;
 565             }
 566             if (n.doubleValue() == 0.0d && !isZero(proper))
 567                 log.error(S.pos(), "fp.number.too.small");
 568             else if (n.doubleValue() == Double.POSITIVE_INFINITY)
 569                 log.error(S.pos(), "fp.number.too.large");
 570             else
 571                 t = F.at(pos).Literal(TypeTags.DOUBLE, n);
 572             break;
 573         }
 574         case CHARLITERAL:
 575             t = F.at(pos).Literal(
 576                 TypeTags.CHAR,
 577                 S.stringVal().charAt(0) + 0);
 578             break;
 579         case STRINGLITERAL:
 580             t = F.at(pos).Literal(
 581                 TypeTags.CLASS,
 582                 S.stringVal());
 583             break;
 584         case TRUE: case FALSE:
 585             t = F.at(pos).Literal(
 586                 TypeTags.BOOLEAN,
 587                 (S.token() == TRUE ? 1 : 0));
 588             break;
 589         case NULL:
 590             t = F.at(pos).Literal(
 591                 TypeTags.BOT,
 592                 null);
 593             break;
 594         default:
 595             assert false;
 596         }
 597         if (t == errorTree)
 598             t = F.at(pos).Erroneous();
 599         storeEnd(t, S.endPos());
 600         S.nextToken();
 601         return t;
 602     }
 603 //where
 604         boolean isZero(String s) {
 605             char[] cs = s.toCharArray();
 606             int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
 607             int i = ((base==16) ? 2 : 0);
 608             while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
 609             return !(i < cs.length && (Character.digit(cs[i], base) > 0));
 610         }
 611 
 612         String strval(Name prefix) {
 613             String s = S.stringVal();
 614             return prefix.isEmpty() ? s : prefix + s;
 615         }
 616 
 617     /** terms can be either expressions or types.
 618      */
 619     public JCExpression parseExpression() {
 620         return term(EXPR);
 621     }
 622 
 623     /**
 624      * parses (optional) type annotations followed by a type. If the
 625      * annotations are present before the type and are not consumed during array
 626      * parsing, this method returns a {@link JCAnnotatedType} consisting of
 627      * these annotations and the underlying type. Otherwise, it returns the
 628      * underlying type.
 629      *
 630      * <p>
 631      *
 632      * Note that this method sets {@code mode} to {@code TYPE} first, before
 633      * parsing annotations.
 634      */
 635     public JCExpression parseType() {
 636         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
 637         return parseType(annotations);
 638     }
 639 
 640     public JCExpression parseType(List<JCTypeAnnotation> annotations) {
 641         JCExpression result = unannotatedType();
 642 
 643         if (!annotations.isEmpty())
 644             result = F.AnnotatedType(annotations, result);
 645 
 646         return result;
 647     }
 648 
 649     public JCExpression unannotatedType() {
 650         return term(TYPE);
 651     }
 652 
 653     JCExpression term(int newmode) {
 654         int prevmode = mode;
 655         mode = newmode;
 656         JCExpression t = term();
 657         lastmode = mode;
 658         mode = prevmode;
 659         return t;
 660     }
 661 
 662     /**
 663      *  Expression = Expression1 [ExpressionRest]
 664      *  ExpressionRest = [AssignmentOperator Expression1]
 665      *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
 666      *                       "&=" | "|=" | "^=" |
 667      *                       "%=" | "<<=" | ">>=" | ">>>="
 668      *  Type = Type1
 669      *  TypeNoParams = TypeNoParams1
 670      *  StatementExpression = Expression
 671      *  ConstantExpression = Expression
 672      */
 673     JCExpression term() {
 674         JCExpression t = term1();
 675         if ((mode & EXPR) != 0 &&
 676             S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
 677             return termRest(t);
 678         else
 679             return t;
 680     }
 681 
 682     JCExpression termRest(JCExpression t) {
 683         switch (S.token()) {
 684         case EQ: {
 685             int pos = S.pos();
 686             S.nextToken();
 687             mode = EXPR;
 688             JCExpression t1 = term();
 689             return toP(F.at(pos).Assign(t, t1));
 690         }
 691         case PLUSEQ:
 692         case SUBEQ:
 693         case STAREQ:
 694         case SLASHEQ:
 695         case PERCENTEQ:
 696         case AMPEQ:
 697         case BAREQ:
 698         case CARETEQ:
 699         case LTLTEQ:
 700         case GTGTEQ:
 701         case GTGTGTEQ:
 702             int pos = S.pos();
 703             Token token = S.token();
 704             S.nextToken();
 705             mode = EXPR;
 706             JCExpression t1 = term();
 707             return F.at(pos).Assignop(optag(token), t, t1);
 708         default:
 709             return t;
 710         }
 711     }
 712 
 713     /** Expression1   = Expression2 [Expression1Rest]
 714      *  Type1         = Type2
 715      *  TypeNoParams1 = TypeNoParams2
 716      */
 717     JCExpression term1() {
 718         JCExpression t = term2();
 719         if ((mode & EXPR) != 0 && S.token() == QUES) {
 720             mode = EXPR;
 721             return term1Rest(t);
 722         } else {
 723             return t;
 724         }
 725     }
 726 
 727     /** Expression1Rest = ["?" Expression ":" Expression1]
 728      */
 729     JCExpression term1Rest(JCExpression t) {
 730         if (S.token() == QUES) {
 731             int pos = S.pos();
 732             S.nextToken();
 733             JCExpression t1 = term();
 734             accept(COLON);
 735             JCExpression t2 = term1();
 736             return F.at(pos).Conditional(t, t1, t2);
 737         } else {
 738             return t;
 739         }
 740     }
 741 
 742     /** Expression2   = Expression3 [Expression2Rest]
 743      *  Type2         = Type3
 744      *  TypeNoParams2 = TypeNoParams3
 745      */
 746     JCExpression term2() {
 747         JCExpression t = term3();
 748         if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
 749             mode = EXPR;
 750             return term2Rest(t, TreeInfo.orPrec);
 751         } else {
 752             return t;
 753         }
 754     }
 755 
 756     /*  Expression2Rest = {infixop Expression3}
 757      *                  | Expression3 instanceof Type
 758      *  infixop         = "||"
 759      *                  | "&&"
 760      *                  | "|"
 761      *                  | "^"
 762      *                  | "&"
 763      *                  | "==" | "!="
 764      *                  | "<" | ">" | "<=" | ">="
 765      *                  | "<<" | ">>" | ">>>"
 766      *                  | "+" | "-"
 767      *                  | "*" | "/" | "%"
 768      */
 769     JCExpression term2Rest(JCExpression t, int minprec) {
 770         List<JCExpression[]> savedOd = odStackSupply.elems;
 771         JCExpression[] odStack = newOdStack();
 772         List<Token[]> savedOp = opStackSupply.elems;
 773         Token[] opStack = newOpStack();
 774         // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
 775         int top = 0;
 776         odStack[0] = t;
 777         int startPos = S.pos();
 778         Token topOp = ERROR;
 779         while (prec(S.token()) >= minprec) {
 780             opStack[top] = topOp;
 781             top++;
 782             topOp = S.token();
 783             int pos = S.pos();
 784             S.nextToken();
 785             odStack[top] = topOp == INSTANCEOF ? parseType() : term3();
 786             while (top > 0 && prec(topOp) >= prec(S.token())) {
 787                 odStack[top-1] = makeOp(pos, topOp, odStack[top-1],
 788                                         odStack[top]);
 789                 top--;
 790                 topOp = opStack[top];
 791             }
 792         }
 793         assert top == 0;
 794         t = odStack[0];
 795 
 796         if (t.getTag() == JCTree.PLUS) {
 797             StringBuffer buf = foldStrings(t);
 798             if (buf != null) {
 799                 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
 800             }
 801         }
 802 
 803         odStackSupply.elems = savedOd; // optimization
 804         opStackSupply.elems = savedOp; // optimization
 805         return t;
 806     }
 807 //where
 808         /** Construct a binary or type test node.
 809          */
 810         private JCExpression makeOp(int pos,
 811                                     Token topOp,
 812                                     JCExpression od1,
 813                                     JCExpression od2)
 814         {
 815             if (topOp == INSTANCEOF) {
 816                 return F.at(pos).TypeTest(od1, od2);
 817             } else {
 818                 return F.at(pos).Binary(optag(topOp), od1, od2);
 819             }
 820         }
 821         /** If tree is a concatenation of string literals, replace it
 822          *  by a single literal representing the concatenated string.
 823          */
 824         protected StringBuffer foldStrings(JCTree tree) {
 825             List<String> buf = List.nil();
 826             while (true) {
 827                 if (tree.getTag() == JCTree.LITERAL) {
 828                     JCLiteral lit = (JCLiteral) tree;
 829                     if (lit.typetag == TypeTags.CLASS) {
 830                         StringBuffer sbuf =
 831                             new StringBuffer((String)lit.value);
 832                         while (buf.nonEmpty()) {
 833                             sbuf.append(buf.head);
 834                             buf = buf.tail;
 835                         }
 836                         return sbuf;
 837                     }
 838                 } else if (tree.getTag() == JCTree.PLUS) {
 839                     JCBinary op = (JCBinary)tree;
 840                     if (op.rhs.getTag() == JCTree.LITERAL) {
 841                         JCLiteral lit = (JCLiteral) op.rhs;
 842                         if (lit.typetag == TypeTags.CLASS) {
 843                             buf = buf.prepend((String) lit.value);
 844                             tree = op.lhs;
 845                             continue;
 846                         }
 847                     }
 848                 }
 849                 return null;
 850             }
 851         }
 852 
 853         /** optimization: To save allocating a new operand/operator stack
 854          *  for every binary operation, we use supplys.
 855          */
 856         ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
 857         ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
 858 
 859         private JCExpression[] newOdStack() {
 860             if (odStackSupply.elems == odStackSupply.last)
 861                 odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
 862             JCExpression[] odStack = odStackSupply.elems.head;
 863             odStackSupply.elems = odStackSupply.elems.tail;
 864             return odStack;
 865         }
 866 
 867         private Token[] newOpStack() {
 868             if (opStackSupply.elems == opStackSupply.last)
 869                 opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
 870             Token[] opStack = opStackSupply.elems.head;
 871             opStackSupply.elems = opStackSupply.elems.tail;
 872             return opStack;
 873         }
 874 
 875     /** Expression3    = PrefixOp Expression3
 876      *                 | "(" Expr | TypeNoParams ")" Expression3
 877      *                 | Primary {Selector} {PostfixOp}
 878      *  Primary        = "(" Expression ")"
 879      *                 | Literal
 880      *                 | [TypeArguments] THIS [Arguments]
 881      *                 | [TypeArguments] SUPER SuperSuffix
 882      *                 | NEW [TypeArguments] Creator
 883      *                 | [Annotations] Ident { "." Ident }
 884      *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
 885      *                   | Arguments
 886      *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
 887      *                   ]
 888      *                 | BasicType BracketsOpt "." CLASS
 889      *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
 890      *  PostfixOp      = "++" | "--"
 891      *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
 892      *                 | BasicType
 893      *                 | FunctionType
 894      *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
 895      *  Selector       = "." [TypeArguments] Ident [Arguments]
 896      *                 | "." THIS
 897      *                 | "." [TypeArguments] SUPER SuperSuffix
 898      *                 | "." NEW [TypeArguments] InnerCreator
 899      *                 | "[" Expression "]"
 900      *  TypeSelector   = "." Ident [TypeArguments]
 901      *  SuperSuffix    = Arguments | "." Ident [Arguments]
 902      */
 903     protected JCExpression term3() {
 904         int pos = S.pos();
 905         JCExpression t;
 906         List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
 907         switch (S.token()) {
 908         case QUES:
 909             if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
 910                 mode = TYPE;
 911                 return typeArgument();
 912             } else
 913                 return illegal();
 914         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
 915             if (typeArgs == null && (mode & EXPR) != 0) {
 916                 Token token = S.token();
 917                 S.nextToken();
 918                 mode = EXPR;
 919                 if (token == SUB &&
 920                     (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
 921                     S.radix() == 10) {
 922                     mode = EXPR;
 923                     t = literal(names.hyphen);
 924                 } else {
 925                     t = term3();
 926                     return F.at(pos).Unary(unoptag(token), t);
 927                 }
 928             } else return illegal();
 929             break;
 930         case LPAREN:
 931             if (typeArgs == null && (mode & EXPR) != 0) {
 932                 S.nextToken();
 933                 mode = EXPR | TYPE | NOPARAMS;
 934                 t = term3();
 935                 if ((mode & TYPE) != 0 && S.token() == LT) {
 936                     // Could be a cast to a parameterized type
 937                     int op = JCTree.LT;
 938                     int pos1 = S.pos();
 939                     S.nextToken();
 940                     mode &= (EXPR | TYPE);
 941                     mode |= TYPEARG;
 942                     JCExpression t1 = term3();
 943                     if ((mode & TYPE) != 0 &&
 944                         (S.token() == COMMA || S.token() == GT)) {
 945                         mode = TYPE;
 946                         ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
 947                         args.append(t1);
 948                         while (S.token() == COMMA) {
 949                             S.nextToken();
 950                             args.append(typeArgument());
 951                         }
 952                         accept(GT);
 953                         t = F.at(pos1).TypeApply(t, args.toList());
 954                         checkGenerics();
 955                         while (S.token() == DOT) {
 956                             S.nextToken();
 957                             mode = TYPE;
 958                             t = toP(F.at(S.pos()).Select(t, ident()));
 959                             t = typeArgumentsOpt(t);
 960                         }
 961                         t = bracketsOpt(toP(t));
 962                     } else if ((mode & EXPR) != 0) {
 963                         mode = EXPR;
 964                         t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec));
 965                         t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
 966                     } else {
 967                         accept(GT);
 968                     }
 969                 }
 970                 else {
 971                     t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
 972                 }
 973                 accept(RPAREN);
 974                 lastmode = mode;
 975                 mode = EXPR;
 976                 if ((lastmode & EXPR) == 0) {
 977                     JCExpression t1 = term3();
 978                     return F.at(pos).TypeCast(t, t1);
 979                 } else if ((lastmode & TYPE) != 0) {
 980                     switch (S.token()) {
 981                     /*case PLUSPLUS: case SUBSUB: */
 982                     case BANG: case TILDE:
 983                     case LPAREN: case THIS: case SUPER:
 984                     case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
 985                     case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
 986                     case TRUE: case FALSE: case NULL:
 987                     case NEW: case IDENTIFIER: case ASSERT: case ENUM:
 988                     case BYTE: case SHORT: case CHAR: case INT:
 989                     case LONG: case FLOAT: case DOUBLE: case BOOLEAN:
 990                     case VOID: case SHARP:
 991                         JCExpression t1 = term3();
 992                         return F.at(pos).TypeCast(t, t1);
 993                     }
 994                 }
 995             } else return illegal();
 996             t = toP(F.at(pos).Parens(t));
 997             break;
 998         case THIS:
 999             if ((mode & EXPR) != 0) {
1000                 mode = EXPR;
1001                 t = to(F.at(pos).Ident(names._this));
1002                 S.nextToken();
1003                 if (typeArgs == null)
1004                     t = argumentsOpt(null, t);
1005                 else
1006                     t = arguments(typeArgs, t);
1007                 typeArgs = null;
1008             } else return illegal();
1009             break;
1010         case SUPER:
1011             if ((mode & EXPR) != 0) {
1012                 mode = EXPR;
1013                 t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super)));
1014                 typeArgs = null;
1015             } else return illegal();
1016             break;
1017         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
1018         case CHARLITERAL: case STRINGLITERAL:
1019         case TRUE: case FALSE: case NULL:
1020             if (typeArgs == null && (mode & EXPR) != 0) {
1021                 mode = EXPR;
1022                 t = literal(names.empty);
1023             } else return illegal();
1024             break;
1025         case NEW:
1026             if (typeArgs != null) return illegal();
1027             if ((mode & EXPR) != 0) {
1028                 mode = EXPR;
1029                 S.nextToken();
1030                 if (S.token() == LT) typeArgs = typeArguments();
1031                 t = creator(pos, typeArgs);
1032                 typeArgs = null;
1033             } else return illegal();
1034             break;
1035         case MONKEYS_AT:
1036 
1037             // only annotated targetting class literals or cast types are valid
1038             List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
1039             if (typeAnnos.isEmpty()) {
1040                 // else there would be no '@'
1041                 throw new AssertionError("type annos is empty");
1042             }
1043 
1044             JCExpression expr = term3();
1045 
1046             // Type annotations: If term3 just parsed a non-type, expect a
1047             // class literal (and issue a syntax error if there is no class
1048             // literal). Otherwise, create a JCAnnotatedType.
1049             if ((mode & TYPE) == 0) {
1050                 if (expr.getTag() != JCTree.SELECT)
1051                     return illegal(typeAnnos.head.pos);
1052                 JCFieldAccess sel = (JCFieldAccess)expr;
1053                 if (sel.name != names._class)
1054                     return illegal();
1055                 else {
1056                     sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
1057                     t = expr;
1058                 }
1059             } else {
1060                 // type annotation targeting a cast
1061                 t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
1062             }
1063             break;
1064         case SHARP:
1065             if (typeArgs != null) illegal();
1066             JCExpression exprType = bracketsOpt(functionType());
1067             if (S.token() == DOT) {
1068               exprType = bracketsSuffix(exprType);
1069             }
1070             t = exprType;
1071             break;
1072         case IDENTIFIER: case ASSERT: case ENUM:
1073             if (typeArgs != null) return illegal();
1074             t = toP(F.at(S.pos()).Ident(ident()));
1075             loop: while (true) {
1076                 pos = S.pos();
1077                 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1078 
1079                 // need to report an error later if LBRACKET is for array
1080                 // index access rather than array creation level
1081                 if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
1082                     return illegal(annos.head.pos);
1083                 switch (S.token()) {
1084                 case LBRACKET:
1085                     S.nextToken();
1086 
1087                     if (S.token() == RBRACKET) {
1088 
1089                         S.nextToken();
1090 
1091                         t = bracketsOpt(t, annos);
1092                         t = toP(F.at(pos).TypeArray(t));
1093                         t = bracketsSuffix(t);
1094                     } else {
1095                         if ((mode & EXPR) != 0) {
1096                             mode = EXPR;
1097                             JCExpression t1 = term();
1098                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1099                             t = to(F.at(pos).Indexed(t, t1));
1100                         }
1101                         accept(RBRACKET);
1102                     }
1103                     break loop;
1104                 case LPAREN:
1105                     if ((mode & EXPR) != 0) {
1106                         mode = EXPR;
1107                         t = argumentsOrLambda(typeArgs, t);
1108                         typeArgs = null;
1109                     }
1110                     break loop;
1111                 case DOT:
1112                     S.nextToken();
1113                     int oldmode = mode;
1114                     mode &= ~NOPARAMS;
1115                     typeArgs = typeArgumentsOpt(EXPR);
1116                     mode = oldmode;
1117                     if ((mode & EXPR) != 0) {
1118                         switch (S.token()) {
1119                         case CLASS:
1120                             if (typeArgs != null) return illegal();
1121                             mode = EXPR;
1122                             t = to(F.at(pos).Select(t, names._class));
1123                             S.nextToken();
1124                             break loop;
1125                         case THIS:
1126                             if (typeArgs != null) return illegal();
1127                             mode = EXPR;
1128                             t = to(F.at(pos).Select(t, names._this));
1129                             S.nextToken();
1130                             break loop;
1131                         case SUPER:
1132                             mode = EXPR;
1133                             t = to(F.at(pos).Select(t, names._super));
1134                             t = superSuffix(typeArgs, t);
1135                             typeArgs = null;
1136                             break loop;
1137                         case NEW:
1138                             if (typeArgs != null) return illegal();
1139                             mode = EXPR;
1140                             int pos1 = S.pos();
1141                             S.nextToken();
1142                             if (S.token() == LT) typeArgs = typeArguments();
1143                             t = innerCreator(pos1, typeArgs, t);
1144                             typeArgs = null;
1145                             break loop;
1146                         }
1147                     }
1148                     // typeArgs saved for next loop iteration.
1149                     t = toP(F.at(pos).Select(t, ident()));
1150                     break;
1151                 case ELLIPSIS:
1152                     assert this.permitTypeAnnotationsPushBack;
1153                     typeAnnotationsPushedBack = annos;
1154                     break loop;
1155                 default:
1156                     break loop;
1157                 }
1158             }
1159             if (typeArgs != null) illegal();
1160             t = typeArgumentsOpt(t);
1161             break;
1162         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1163         case DOUBLE: case BOOLEAN:
1164             if (typeArgs != null) illegal();
1165             t = bracketsSuffix(bracketsOpt(basicType()));
1166             break;
1167         case VOID:
1168             if (typeArgs != null) illegal();
1169             if ((mode & EXPR) != 0) {
1170                 S.nextToken();
1171                 if (S.token() == DOT) {
1172                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
1173                     t = bracketsSuffix(ti);
1174                 } else {
1175                     return illegal(pos);
1176                 }
1177             } else {
1178                 // Support the corner case of myMethodHandle.<void>invoke() by passing
1179                 // a void type (like other primitive types) to the next phase.
1180                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1181                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
1182                 S.nextToken();
1183                 return ti;
1184                 //return illegal();
1185             }
1186             break;
1187         default:
1188             return illegal();
1189         }
1190         if (typeArgs != null) illegal();
1191         while (true) {
1192             int pos1 = S.pos();
1193 
1194             final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1195 
1196             if (S.token() == LBRACKET) {
1197                 S.nextToken();
1198 
1199                 if ((mode & TYPE) != 0) {
1200                     int oldmode = mode;
1201                     mode = TYPE;
1202                     if (S.token() == RBRACKET) {
1203                         S.nextToken();
1204                         t = bracketsOpt(t, annos);
1205                         t = toP(F.at(pos1).TypeArray(t));
1206                         return t;
1207                     }
1208                     mode = oldmode;
1209                 }
1210                 if ((mode & EXPR) != 0) {
1211                     mode = EXPR;
1212                     JCExpression t1 = term();
1213                     t = to(F.at(pos1).Indexed(t, t1));
1214                 }
1215                 accept(RBRACKET);
1216             } else if (S.token() == DOT) {
1217                 S.nextToken();
1218                 typeArgs = typeArgumentsOpt(EXPR);
1219                 if (S.token() == SUPER && (mode & EXPR) != 0) {
1220                     mode = EXPR;
1221                     t = to(F.at(pos1).Select(t, names._super));
1222                     S.nextToken();
1223                     t = arguments(typeArgs, t);
1224                     typeArgs = null;
1225                 } else if (S.token() == NEW && (mode & EXPR) != 0) {
1226                     if (typeArgs != null) return illegal();
1227                     mode = EXPR;
1228                     int pos2 = S.pos();
1229                     S.nextToken();
1230                     if (S.token() == LT) typeArgs = typeArguments();
1231                     t = innerCreator(pos2, typeArgs, t);
1232                     typeArgs = null;
1233                 } else {
1234                     t = toP(F.at(pos1).Select(t, ident()));
1235                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1236                     typeArgs = null;
1237                 }
1238             } else {
1239                 if (!annos.isEmpty()) {
1240                     if (permitTypeAnnotationsPushBack)
1241                         typeAnnotationsPushedBack = annos;
1242                     else
1243                         return illegal(annos.head.pos);
1244                 }
1245                 break;
1246             }
1247         }
1248         while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
1249             mode = EXPR;
1250             t = to(F.at(S.pos()).Unary(
1251                   S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1252             S.nextToken();
1253         }
1254 
1255         return toP(t);
1256     }
1257 
1258     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1259      */
1260     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1261         S.nextToken();
1262         if (S.token() == LPAREN || typeArgs != null) {
1263             t = arguments(typeArgs, t);
1264         } else {
1265             int pos = S.pos();
1266             accept(DOT);
1267             typeArgs = (S.token() == LT) ? typeArguments() : null;
1268             t = toP(F.at(pos).Select(t, ident()));
1269             t = argumentsOpt(typeArgs, t);
1270         }
1271         return t;
1272     }
1273 
1274     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1275      */
1276     JCPrimitiveTypeTree basicType() {
1277         JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
1278         S.nextToken();
1279         return t;
1280     }
1281     
1282     /** FunctionType = "#" Type "(" [Type { "," Type}] ")"
1283      */
1284     JCExpression functionType() {
1285       checkFunctionType();
1286       int pos = S.pos();
1287       S.nextToken();
1288       JCExpression returnType = parseType();
1289       accept(LPAREN);
1290       List<JCExpression> parameterTypes = (S.token() != RPAREN)? typeList(): List.<JCExpression>nil();
1291       accept(RPAREN);
1292       JCFunctionType t = to(F.at(S.pos()).FunctionType(parameterTypes, returnType));
1293       return t;
1294     }
1295 
1296     /** ArgumentsOpt = [ Arguments ]
1297      */
1298     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1299         if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
1300             mode = EXPR;
1301             return arguments(typeArgs, t);
1302         } else {
1303             return t;
1304         }
1305     }
1306 
1307     /** Arguments = "(" [Expression { COMMA Expression }] ")"
1308      */
1309     List<JCExpression> arguments() {
1310         ListBuffer<JCExpression> args = lb();
1311         if (S.token() == LPAREN) {
1312             S.nextToken();
1313             if (S.token() != RPAREN) {
1314                 args.append(parseExpression());
1315                 while (S.token() == COMMA) {
1316                     S.nextToken();
1317                     args.append(parseExpression());
1318                 }
1319             }
1320             accept(RPAREN);
1321         } else {
1322             syntaxError(S.pos(), "expected", LPAREN);
1323         }
1324         return args.toList();
1325     }
1326 
1327     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1328         int pos = S.pos();
1329         List<JCExpression> args = arguments();
1330         return toP(F.at(pos).Apply(typeArgs, t, args));
1331     }
1332     
1333     JCExpression argumentsOrLambda(List<JCExpression> typeArgs, JCExpression t) {
1334         if (typeArgs != null ||
1335             t.getTag() != JCTree.IDENT ||
1336             ((JCIdent)t).name != names._lambda)
1337             return arguments(typeArgs, t);
1338         
1339         
1340         int applyPos = S.pos();
1341         accept(LPAREN);
1342         
1343         if (S.token() != RPAREN) {
1344             int firstFormalPos = S.pos();
1345             if (S.token() == FINAL || S.token() == MONKEYS_AT) {
1346               return lambdaRest(t.pos, ListBuffer.<JCVariableDecl>lb());
1347             } 
1348             
1349             JCExpression exprOrType = term(EXPR | TYPE);
1350             if ((lastmode & TYPE) != 0 &&
1351                 (S.token() == IDENTIFIER ||
1352                  S.token() == ASSERT ||
1353                  S.token() == ENUM)) {
1354                 JCModifiers mods = toP(F.at(firstFormalPos).Modifiers(Flags.PARAMETER));
1355                 return lambdaRest(t.pos, ListBuffer.of(variableDeclaratorId(mods, exprOrType)));
1356             }
1357             
1358             // not a lambda, so it's a method call
1359             ListBuffer<JCExpression> args = ListBuffer.of(exprOrType);
1360             while (S.token() == COMMA) {
1361                 S.nextToken();
1362                 args.append(parseExpression());
1363             }
1364             accept(RPAREN);
1365             
1366             return toP(F.at(applyPos).Apply(typeArgs, t, args.toList()));
1367         }
1368         
1369         accept(RPAREN);
1370         
1371         switch(S.token()) {
1372         case LPAREN:  // lambda expression
1373             return toP(F.at(applyPos).Lambda(List.<JCVariableDecl>nil(), lambdaExpression()));
1374         case LBRACE:  // lambda statement
1375             return toP(F.at(applyPos).Lambda(List.<JCVariableDecl>nil(), block()));
1376         default:      // method call with no argument
1377             return toP(F.at(applyPos).Apply(typeArgs, t, List.<JCExpression>nil()));
1378         }   
1379     }
1380     
1381     JCLambda lambdaRest(int pos, ListBuffer<JCVariableDecl> formals) {
1382         if (S.token() != RPAREN) {
1383             if (!formals.isEmpty()) {
1384                 accept(COMMA);
1385             }
1386           
1387             formals.append(lambdaFormalParameter());
1388             while (S.token() == COMMA) {
1389                 S.nextToken();
1390                 formals.append(lambdaFormalParameter());
1391             }
1392         }
1393         accept(RPAREN);
1394         
1395         if (S.token() == LBRACE) {
1396           return toP(F.at(pos).Lambda(formals.toList(), block()));
1397         } else {
1398           return toP(F.at(pos).Lambda(formals.toList(), lambdaExpression()));
1399         }
1400     }
1401 
1402     JCVariableDecl lambdaFormalParameter() {
1403         JCModifiers mods = optFinal(Flags.PARAMETER);
1404         JCExpression type = parseType();
1405         return variableDeclaratorId(mods, type);
1406     }
1407     
1408     JCExpression lambdaExpression() {
1409         accept(LPAREN);
1410         JCExpression expr = parseExpression();
1411         accept(RPAREN);
1412         return expr;
1413     }
1414     
1415     
1416     /**  TypeArgumentsOpt = [ TypeArguments ]
1417      */
1418     JCExpression typeArgumentsOpt(JCExpression t) {
1419         if (S.token() == LT &&
1420             (mode & TYPE) != 0 &&
1421             (mode & NOPARAMS) == 0) {
1422             mode = TYPE;
1423             checkGenerics();
1424             return typeArguments(t);
1425         } else {
1426             return t;
1427         }
1428     }
1429     List<JCExpression> typeArgumentsOpt() {
1430         return typeArgumentsOpt(TYPE);
1431     }
1432 
1433     List<JCExpression> typeArgumentsOpt(int useMode) {
1434         if (S.token() == LT) {
1435             checkGenerics();
1436             if ((mode & useMode) == 0 ||
1437                 (mode & NOPARAMS) != 0) {
1438                 illegal();
1439             }
1440             mode = useMode;
1441             return typeArguments();
1442         }
1443         return null;
1444     }
1445 
1446     /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1447      */
1448     List<JCExpression> typeArguments() {
1449         ListBuffer<JCExpression> args = lb();
1450         if (S.token() == LT) {
1451             S.nextToken();
1452             if (S.token() == GT && (mode & DIAMOND) != 0) {
1453                 checkDiamond();
1454                 S.nextToken();
1455                 return List.nil();
1456             }
1457             args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1458             while (S.token() == COMMA) {
1459                 S.nextToken();
1460                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1461             }
1462             switch (S.token()) {
1463             case GTGTGTEQ:
1464                 S.token(GTGTEQ);
1465                 break;
1466             case GTGTEQ:
1467                 S.token(GTEQ);
1468                 break;
1469             case GTEQ:
1470                 S.token(EQ);
1471                 break;
1472             case GTGTGT:
1473                 S.token(GTGT);
1474                 break;
1475             case GTGT:
1476                 S.token(GT);
1477                 break;
1478             default:
1479                 accept(GT);
1480                 break;
1481             }
1482         } else {
1483             syntaxError(S.pos(), "expected", LT);
1484         }
1485         return args.toList();
1486     }
1487 
1488     /** TypeArgument = Type
1489      *               | [Annotations] "?"
1490      *               | [Annotations] "?" EXTENDS Type {"&" Type}
1491      *               | [Annotations] "?" SUPER Type
1492      */
1493     JCExpression typeArgument() {
1494         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
1495         if (S.token() != QUES) return parseType(annotations);
1496         int pos = S.pos();
1497         S.nextToken();
1498         JCExpression result;
1499         if (S.token() == EXTENDS) {
1500             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
1501             S.nextToken();
1502             result = F.at(pos).Wildcard(t, parseType());
1503         } else if (S.token() == SUPER) {
1504             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
1505             S.nextToken();
1506             result = F.at(pos).Wildcard(t, parseType());
1507         } else if (S.token() == IDENTIFIER) {
1508             //error recovery
1509             reportSyntaxError(S.prevEndPos(), "expected3",
1510                     GT, EXTENDS, SUPER);
1511             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1512             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1513             JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1514             result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1515         } else {
1516             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1517             result = toP(F.at(pos).Wildcard(t, null));
1518         }
1519         if (!annotations.isEmpty())
1520             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1521         return result;
1522     }
1523 
1524     JCTypeApply typeArguments(JCExpression t) {
1525         int pos = S.pos();
1526         List<JCExpression> args = typeArguments();
1527         return toP(F.at(pos).TypeApply(t, args));
1528     }
1529 
1530     /**
1531      * BracketsOpt = { [Annotations] "[" "]" }
1532      *
1533      * <p>
1534      *
1535      * <code>annotations</code> is the list of annotations targeting
1536      * the expression <code>t</code>.
1537      */
1538     private JCExpression bracketsOpt(JCExpression t,
1539             List<JCTypeAnnotation> annotations) {
1540         List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1541 
1542         if (S.token() == LBRACKET) {
1543             int pos = S.pos();
1544             S.nextToken();
1545 
1546             JCExpression orig = t;
1547             t = bracketsOptCont(t, pos, nextLevelAnnotations);
1548         } else if (!nextLevelAnnotations.isEmpty()) {
1549             if (permitTypeAnnotationsPushBack) {
1550                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1551             } else
1552                 return illegal(nextLevelAnnotations.head.pos);
1553         }
1554 
1555         int apos = S.pos();
1556         if (!annotations.isEmpty())
1557             t = F.at(apos).AnnotatedType(annotations, t);
1558         return t;
1559     }
1560 
1561     /** BracketsOpt = {"[" TypeAnnotations "]"}
1562      */
1563     private JCExpression bracketsOpt(JCExpression t) {
1564         return bracketsOpt(t, List.<JCTypeAnnotation>nil());
1565     }
1566 
1567     private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
1568             List<JCTypeAnnotation> annotations) {
1569         accept(RBRACKET);
1570         t = bracketsOpt(t, annotations);
1571         return toP(F.at(pos).TypeArray(t));
1572     }
1573 
1574     /** BracketsSuffixExpr = "." CLASS
1575      *  BracketsSuffixType =
1576      */
1577     JCExpression bracketsSuffix(JCExpression t) {
1578         if ((mode & EXPR) != 0 && S.token() == DOT) {
1579             mode = EXPR;
1580             int pos = S.pos();
1581             S.nextToken();
1582             accept(CLASS);
1583             if (S.pos() == errorEndPos) {
1584                 // error recovery
1585                 Name name = null;
1586                 if (S.token() == IDENTIFIER) {
1587                     name = S.name();
1588                     S.nextToken();
1589                 } else {
1590                     name = names.error;
1591                 }
1592                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
1593             } else {
1594                 t = toP(F.at(pos).Select(t, names._class));
1595             }
1596         } else if ((mode & TYPE) != 0) {
1597             mode = TYPE;
1598         } else {
1599             syntaxError(S.pos(), "dot.class.expected");
1600         }
1601         return t;
1602     }
1603 
1604     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1605      */
1606     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1607 
1608         List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
1609 
1610         switch (S.token()) {
1611         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1612         case DOUBLE: case BOOLEAN:
1613             if (typeArgs == null) {
1614                 if (newAnnotations.isEmpty())
1615                     return arrayCreatorRest(newpos, basicType());
1616                 else
1617                     return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
1618             }
1619             break;
1620         default:
1621         }
1622         JCExpression t = qualident();
1623         // handle type annotations for non primitive arrays
1624         if (!newAnnotations.isEmpty())
1625             t = F.AnnotatedType(newAnnotations, t);
1626 
1627         int oldmode = mode;
1628         mode = TYPE | DIAMOND;
1629         if (S.token() == LT) {
1630             checkGenerics();
1631             t = typeArguments(t);
1632         }
1633         while (S.token() == DOT) {
1634             int pos = S.pos();
1635             S.nextToken();
1636             t = toP(F.at(pos).Select(t, ident()));
1637             if (S.token() == LT) {
1638                 checkGenerics();
1639                 t = typeArguments(t);
1640             }
1641         }
1642         mode = oldmode;
1643         if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
1644             JCExpression e = arrayCreatorRest(newpos, t);
1645             if (typeArgs != null) {
1646                 int pos = newpos;
1647                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
1648                     // note: this should always happen but we should
1649                     // not rely on this as the parser is continuously
1650                     // modified to improve error recovery.
1651                     pos = typeArgs.head.pos;
1652                 }
1653                 setErrorEndPos(S.prevEndPos());
1654                 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
1655                 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1656             }
1657             return e;
1658         } else if (S.token() == LPAREN) {
1659             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
1660             if (newClass.def != null) {
1661                 assert newClass.def.mods.annotations.isEmpty();
1662                 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
1663             }
1664             return newClass;
1665         } else {
1666             reportSyntaxError(S.pos(), "expected2",
1667                                LPAREN, LBRACKET);
1668             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
1669             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
1670         }
1671     }
1672 
1673     /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
1674      */
1675     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
1676         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
1677         if (S.token() == LT) {
1678             int oldmode = mode;
1679             mode |= DIAMOND;
1680             checkGenerics();
1681             t = typeArguments(t);
1682             mode = oldmode;
1683         }
1684         return classCreatorRest(newpos, encl, typeArgs, t);
1685     }
1686 
1687     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
1688      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
1689      */
1690     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1691 
1692         List<JCTypeAnnotation> topAnnos = List.nil();
1693         if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
1694             JCAnnotatedType atype = (JCAnnotatedType) elemtype;
1695             topAnnos = atype.annotations;
1696             elemtype = atype.underlyingType;
1697         }
1698 
1699         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1700 
1701         accept(LBRACKET);
1702 
1703         if (S.token() == RBRACKET) {
1704             accept(RBRACKET);
1705 
1706             elemtype = bracketsOpt(elemtype, annos);
1707 
1708             if (S.token() == LBRACE) {
1709                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
1710 
1711                 na.annotations = topAnnos;
1712 
1713                 return na;
1714             } else {
1715                 return syntaxError(S.pos(), "array.dimension.missing");
1716             }
1717         } else {
1718             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1719 
1720             // maintain array dimension type annotations
1721             ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
1722             dimAnnotations.append(annos);
1723 
1724             dims.append(parseExpression());
1725             accept(RBRACKET);
1726             while (S.token() == LBRACKET
1727                     || (S.token() == MONKEYS_AT)) {
1728                 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
1729                 int pos = S.pos();
1730                 S.nextToken();
1731                 if (S.token() == RBRACKET) {
1732                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1733                 } else {
1734                     if (S.token() == RBRACKET) { // no dimension
1735                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1736                     } else {
1737                         dimAnnotations.append(maybeDimAnnos);
1738                         dims.append(parseExpression());
1739                         accept(RBRACKET);
1740                     }
1741                 }
1742             }
1743 
1744             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
1745             na.annotations = topAnnos;
1746             na.dimAnnotations = dimAnnotations.toList();
1747             return na;
1748         }
1749     }
1750 
1751     /** ClassCreatorRest = Arguments [ClassBody]
1752      */
1753     JCNewClass classCreatorRest(int newpos,
1754                                   JCExpression encl,
1755                                   List<JCExpression> typeArgs,
1756                                   JCExpression t)
1757     {
1758         List<JCExpression> args = arguments();
1759         JCClassDecl body = null;
1760         if (S.token() == LBRACE) {
1761             int pos = S.pos();
1762             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
1763             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1764             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
1765         }
1766         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
1767     }
1768 
1769     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
1770      */
1771     JCExpression arrayInitializer(int newpos, JCExpression t) {
1772         accept(LBRACE);
1773         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
1774         if (S.token() == COMMA) {
1775             S.nextToken();
1776         } else if (S.token() != RBRACE) {
1777             elems.append(variableInitializer());
1778             while (S.token() == COMMA) {
1779                 S.nextToken();
1780                 if (S.token() == RBRACE) break;
1781                 elems.append(variableInitializer());
1782             }
1783         }
1784         accept(RBRACE);
1785         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
1786     }
1787 
1788     /** VariableInitializer = ArrayInitializer | Expression
1789      */
1790     public JCExpression variableInitializer() {
1791         return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
1792     }
1793 
1794     /** ParExpression = "(" Expression ")"
1795      */
1796     JCExpression parExpression() {
1797         accept(LPAREN);
1798         JCExpression t = parseExpression();
1799         accept(RPAREN);
1800         return t;
1801     }
1802 
1803     /** Block = "{" BlockStatements "}"
1804      */
1805     JCBlock block(int pos, long flags) {
1806         accept(LBRACE);
1807         List<JCStatement> stats = blockStatements();
1808         JCBlock t = F.at(pos).Block(flags, stats);
1809         while (S.token() == CASE || S.token() == DEFAULT) {
1810             syntaxError("orphaned", S.token());
1811             switchBlockStatementGroups();
1812         }
1813         // the Block node has a field "endpos" for first char of last token, which is
1814         // usually but not necessarily the last char of the last token.
1815         t.endpos = S.pos();
1816         accept(RBRACE);
1817         return toP(t);
1818     }
1819 
1820     public JCBlock block() {
1821         return block(S.pos(), 0);
1822     }
1823 
1824     /** BlockStatements = { BlockStatement }
1825      *  BlockStatement  = LocalVariableDeclarationStatement
1826      *                  | ClassOrInterfaceOrEnumDeclaration
1827      *                  | [Ident ":"] Statement
1828      *  LocalVariableDeclarationStatement
1829      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
1830      */
1831     @SuppressWarnings("fallthrough")
1832     List<JCStatement> blockStatements() {
1833 //todo: skip to anchor on error(?)
1834         int lastErrPos = -1;
1835         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1836         while (true) {
1837             int pos = S.pos();
1838             switch (S.token()) {
1839             case RBRACE: case CASE: case DEFAULT: case EOF:
1840                 return stats.toList();
1841             case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
1842             case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
1843             case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
1844                 stats.append(parseStatement());
1845                 break;
1846             case MONKEYS_AT:
1847             case FINAL: {
1848                 String dc = S.docComment();
1849                 JCModifiers mods = modifiersOpt();
1850                 if (S.token() == INTERFACE ||
1851                     S.token() == CLASS ||
1852                     allowEnums && S.token() == ENUM) {
1853                     stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1854                 } else {
1855                     JCExpression t = parseType();
1856                     stats.appendList(variableDeclarators(mods, t,
1857                                                          new ListBuffer<JCStatement>()));
1858                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1859                     storeEnd(stats.elems.last(), S.endPos());
1860                     accept(SEMI);
1861                 }
1862                 break;
1863             }
1864             case ABSTRACT: case STRICTFP: {
1865                 String dc = S.docComment();
1866                 JCModifiers mods = modifiersOpt();
1867                 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1868                 break;
1869             }
1870             case INTERFACE:
1871             case CLASS:
1872                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1873                                                                S.docComment()));
1874                 break;
1875             case ENUM:
1876             case ASSERT:
1877                 if (allowEnums && S.token() == ENUM) {
1878                     log.error(S.pos(), "local.enum");
1879                     stats.
1880                         append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1881                                                                  S.docComment()));
1882                     break;
1883                 } else if (allowAsserts && S.token() == ASSERT) {
1884                     stats.append(parseStatement());
1885                     break;
1886                 }
1887                 /* fall through to default */
1888             default:
1889                 Name name = S.name();
1890                 JCExpression t = term(EXPR | TYPE);
1891                 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
1892                     S.nextToken();
1893                     JCStatement stat = parseStatement();
1894                     stats.append(F.at(pos).Labelled(name, stat));
1895                 } else if ((lastmode & TYPE) != 0 &&
1896                            (S.token() == IDENTIFIER ||
1897                             S.token() == ASSERT ||
1898                             S.token() == ENUM)) {
1899                     pos = S.pos();
1900                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1901                     F.at(pos);
1902                     stats.appendList(variableDeclarators(mods, t,
1903                                                          new ListBuffer<JCStatement>()));
1904                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1905                     storeEnd(stats.elems.last(), S.endPos());
1906                     accept(SEMI);
1907                 } else {
1908                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1909                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1910                     accept(SEMI);
1911                 }
1912             }
1913 
1914             // error recovery
1915             if (S.pos() == lastErrPos)
1916                 return stats.toList();
1917             if (S.pos() <= errorEndPos) {
1918                 skip(false, true, true, true);
1919                 lastErrPos = S.pos();
1920             }
1921 
1922             // ensure no dangling /** @deprecated */ active
1923             S.resetDeprecatedFlag();
1924         }
1925     }
1926 
1927     /** Statement =
1928      *       Block
1929      *     | IF ParExpression Statement [ELSE Statement]
1930      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1931      *     | FOR "(" FormalParameter : Expression ")" Statement
1932      *     | WHILE ParExpression Statement
1933      *     | DO Statement WHILE ParExpression ";"
1934      *     | TRY Block ( Catches | [Catches] FinallyPart )
1935      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1936      *     | SYNCHRONIZED ParExpression Block
1937      *     | RETURN [Expression] ";"
1938      *     | THROW Expression ";"
1939      *     | BREAK [Ident] ";"
1940      *     | CONTINUE [Ident] ";"
1941      *     | ASSERT Expression [ ":" Expression ] ";"
1942      *     | ";"
1943      *     | ExpressionStatement
1944      *     | Ident ":" Statement
1945      */
1946     @SuppressWarnings("fallthrough")
1947     public JCStatement parseStatement() {
1948         int pos = S.pos();
1949         switch (S.token()) {
1950         case LBRACE:
1951             return block();
1952         case IF: {
1953             S.nextToken();
1954             JCExpression cond = parExpression();
1955             JCStatement thenpart = parseStatement();
1956             JCStatement elsepart = null;
1957             if (S.token() == ELSE) {
1958                 S.nextToken();
1959                 elsepart = parseStatement();
1960             }
1961             return F.at(pos).If(cond, thenpart, elsepart);
1962         }
1963         case FOR: {
1964             S.nextToken();
1965             accept(LPAREN);
1966             List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
1967             if (inits.length() == 1 &&
1968                 inits.head.getTag() == JCTree.VARDEF &&
1969                 ((JCVariableDecl) inits.head).init == null &&
1970                 S.token() == COLON) {
1971                 checkForeach();
1972                 JCVariableDecl var = (JCVariableDecl)inits.head;
1973                 accept(COLON);
1974                 JCExpression expr = parseExpression();
1975                 accept(RPAREN);
1976                 JCStatement body = parseStatement();
1977                 return F.at(pos).ForeachLoop(var, expr, body);
1978             } else {
1979                 accept(SEMI);
1980                 JCExpression cond = S.token() == SEMI ? null : parseExpression();
1981                 accept(SEMI);
1982                 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1983                 accept(RPAREN);
1984                 JCStatement body = parseStatement();
1985                 return F.at(pos).ForLoop(inits, cond, steps, body);
1986             }
1987         }
1988         case WHILE: {
1989             S.nextToken();
1990             JCExpression cond = parExpression();
1991             JCStatement body = parseStatement();
1992             return F.at(pos).WhileLoop(cond, body);
1993         }
1994         case DO: {
1995             S.nextToken();
1996             JCStatement body = parseStatement();
1997             accept(WHILE);
1998             JCExpression cond = parExpression();
1999             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
2000             accept(SEMI);
2001             return t;
2002         }
2003         case TRY: {
2004             S.nextToken();
2005             JCBlock body = block();
2006             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
2007             JCBlock finalizer = null;
2008             if (S.token() == CATCH || S.token() == FINALLY) {
2009                 while (S.token() == CATCH) catchers.append(catchClause());
2010                 if (S.token() == FINALLY) {
2011                     S.nextToken();
2012                     finalizer = block();
2013                 }
2014             } else {
2015                 log.error(pos, "try.without.catch.or.finally");
2016             }
2017             return F.at(pos).Try(body, catchers.toList(), finalizer);
2018         }
2019         case SWITCH: {
2020             S.nextToken();
2021             JCExpression selector = parExpression();
2022             accept(LBRACE);
2023             List<JCCase> cases = switchBlockStatementGroups();
2024             JCSwitch t = to(F.at(pos).Switch(selector, cases));
2025             accept(RBRACE);
2026             return t;
2027         }
2028         case SYNCHRONIZED: {
2029             S.nextToken();
2030             JCExpression lock = parExpression();
2031             JCBlock body = block();
2032             return F.at(pos).Synchronized(lock, body);
2033         }
2034         case RETURN: {
2035             S.nextToken();
2036             JCExpression result = S.token() == SEMI ? null : parseExpression();
2037             JCReturn t = to(F.at(pos).Return(result));
2038             accept(SEMI);
2039             return t;
2040         }
2041         case THROW: {
2042             S.nextToken();
2043             JCExpression exc = parseExpression();
2044             JCThrow t = to(F.at(pos).Throw(exc));
2045             accept(SEMI);
2046             return t;
2047         }
2048         case BREAK: {
2049             S.nextToken();
2050             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
2051             JCBreak t = to(F.at(pos).Break(label));
2052             accept(SEMI);
2053             return t;
2054         }
2055         case CONTINUE: {
2056             S.nextToken();
2057             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
2058             JCContinue t =  to(F.at(pos).Continue(label));
2059             accept(SEMI);
2060             return t;
2061         }
2062         case SEMI:
2063             S.nextToken();
2064             return toP(F.at(pos).Skip());
2065         case ELSE:
2066             return toP(F.Exec(syntaxError("else.without.if")));
2067         case FINALLY:
2068             return toP(F.Exec(syntaxError("finally.without.try")));
2069         case CATCH:
2070             return toP(F.Exec(syntaxError("catch.without.try")));
2071         case ASSERT: {
2072             if (allowAsserts && S.token() == ASSERT) {
2073                 S.nextToken();
2074                 JCExpression assertion = parseExpression();
2075                 JCExpression message = null;
2076                 if (S.token() == COLON) {
2077                     S.nextToken();
2078                     message = parseExpression();
2079                 }
2080                 JCAssert t = to(F.at(pos).Assert(assertion, message));
2081                 accept(SEMI);
2082                 return t;
2083             }
2084             /* else fall through to default case */
2085         }
2086         case ENUM:
2087         default:
2088             Name name = S.name();
2089             JCExpression expr = parseExpression();
2090             if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
2091                 S.nextToken();
2092                 JCStatement stat = parseStatement();
2093                 return F.at(pos).Labelled(name, stat);
2094             } else {
2095                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2096                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
2097                 accept(SEMI);
2098                 return stat;
2099             }
2100         }
2101     }
2102 
2103     /** CatchClause     = CATCH "(" FormalParameter ")" Block
2104      */
2105     JCCatch catchClause() {
2106         int pos = S.pos();
2107         accept(CATCH);
2108         accept(LPAREN);
2109         JCVariableDecl formal =
2110             variableDeclaratorId(optFinal(Flags.PARAMETER),
2111                                  qualident());
2112         accept(RPAREN);
2113         JCBlock body = block();
2114         return F.at(pos).Catch(formal, body);
2115     }
2116 
2117     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2118      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2119      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2120      */
2121     List<JCCase> switchBlockStatementGroups() {
2122         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2123         while (true) {
2124             int pos = S.pos();
2125             switch (S.token()) {
2126             case CASE: {
2127                 S.nextToken();
2128                 JCExpression pat = parseExpression();
2129                 accept(COLON);
2130                 List<JCStatement> stats = blockStatements();
2131                 JCCase c = F.at(pos).Case(pat, stats);
2132                 if (stats.isEmpty())
2133                     storeEnd(c, S.prevEndPos());
2134                 cases.append(c);
2135                 break;
2136             }
2137             case DEFAULT: {
2138                 S.nextToken();
2139                 accept(COLON);
2140                 List<JCStatement> stats = blockStatements();
2141                 JCCase c = F.at(pos).Case(null, stats);
2142                 if (stats.isEmpty())
2143                     storeEnd(c, S.prevEndPos());
2144                 cases.append(c);
2145                 break;
2146             }
2147             case RBRACE: case EOF:
2148                 return cases.toList();
2149             default:
2150                 S.nextToken(); // to ensure progress
2151                 syntaxError(pos, "expected3",
2152                     CASE, DEFAULT, RBRACE);
2153             }
2154         }
2155     }
2156 
2157     /** MoreStatementExpressions = { COMMA StatementExpression }
2158      */
2159     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2160                                                                     JCExpression first,
2161                                                                     T stats) {
2162         // This Exec is a "StatementExpression"; it subsumes no terminating token
2163         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2164         while (S.token() == COMMA) {
2165             S.nextToken();
2166             pos = S.pos();
2167             JCExpression t = parseExpression();
2168             // This Exec is a "StatementExpression"; it subsumes no terminating token
2169             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2170         }
2171         return stats;
2172     }
2173 
2174     /** ForInit = StatementExpression MoreStatementExpressions
2175      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2176      */
2177     List<JCStatement> forInit() {
2178         ListBuffer<JCStatement> stats = lb();
2179         int pos = S.pos();
2180         if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2181             return variableDeclarators(optFinal(0), parseType(), stats).toList();
2182         } else {
2183             JCExpression t = term(EXPR | TYPE);
2184             if ((lastmode & TYPE) != 0 &&
2185                 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
2186                 return variableDeclarators(modifiersOpt(), t, stats).toList();
2187             else
2188                 return moreStatementExpressions(pos, t, stats).toList();
2189         }
2190     }
2191 
2192     /** ForUpdate = StatementExpression MoreStatementExpressions
2193      */
2194     List<JCExpressionStatement> forUpdate() {
2195         return moreStatementExpressions(S.pos(),
2196                                         parseExpression(),
2197                                         new ListBuffer<JCExpressionStatement>()).toList();
2198     }
2199 
2200     enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
2201 
2202     /** AnnotationsOpt = { '@' Annotation }
2203      */
2204     List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
2205         if (S.token() != MONKEYS_AT) return List.nil(); // optimization
2206         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2207         int prevmode = mode;
2208         while (S.token() == MONKEYS_AT) {
2209             int pos = S.pos();
2210             S.nextToken();
2211             buf.append(annotation(pos, kind));
2212         }
2213         lastmode = mode;
2214         mode = prevmode;
2215         List<JCAnnotation> annotations = buf.toList();
2216 
2217         if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
2218             System.out.println("TA: parsing " + annotations
2219                     + " in " + log.currentSourceFile());
2220         return annotations;
2221     }
2222 
2223     List<JCTypeAnnotation> typeAnnotationsOpt() {
2224         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
2225         return List.convert(JCTypeAnnotation.class, annotations);
2226     }
2227 
2228     /** ModifiersOpt = { Modifier }
2229      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2230      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2231      *           | "@" Annotation
2232      */
2233     JCModifiers modifiersOpt() {
2234         return modifiersOpt(null);
2235     }
2236     JCModifiers modifiersOpt(JCModifiers partial) {
2237         long flags = (partial == null) ? 0 : partial.flags;
2238         if (S.deprecatedFlag()) {
2239             flags |= Flags.DEPRECATED;
2240             S.resetDeprecatedFlag();
2241         }
2242         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2243         if (partial != null) annotations.appendList(partial.annotations);
2244         int pos = S.pos();
2245         int lastPos = Position.NOPOS;
2246     loop:
2247         while (true) {
2248             long flag;
2249             switch (S.token()) {
2250             case PRIVATE     : flag = Flags.PRIVATE; break;
2251             case PROTECTED   : flag = Flags.PROTECTED; break;
2252             case PUBLIC      : flag = Flags.PUBLIC; break;
2253             case STATIC      : flag = Flags.STATIC; break;
2254             case TRANSIENT   : flag = Flags.TRANSIENT; break;
2255             case FINAL       : flag = Flags.FINAL; break;
2256             case ABSTRACT    : flag = Flags.ABSTRACT; break;
2257             case NATIVE      : flag = Flags.NATIVE; break;
2258             case VOLATILE    : flag = Flags.VOLATILE; break;
2259             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2260             case STRICTFP    : flag = Flags.STRICTFP; break;
2261             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2262             default: break loop;
2263             }
2264             if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
2265             lastPos = S.pos();
2266             S.nextToken();
2267             if (flag == Flags.ANNOTATION) {
2268                 checkAnnotations();
2269                 if (S.token() != INTERFACE) {
2270                 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
2271                 // if first modifier is an annotation, set pos to annotation's.
2272                 if (flags == 0 && annotations.isEmpty())
2273                     pos = ann.pos;
2274                 annotations.append(ann);
2275                 lastPos = ann.pos;
2276                     flag = 0;
2277                 }
2278             }
2279             flags |= flag;
2280         }
2281         switch (S.token()) {
2282         case ENUM: flags |= Flags.ENUM; break;
2283         case INTERFACE: flags |= Flags.INTERFACE; break;
2284         default: break;
2285         }
2286 
2287         /* A modifiers tree with no modifier tokens or annotations
2288          * has no text position. */
2289         if (flags == 0 && annotations.isEmpty())
2290             pos = Position.NOPOS;
2291 
2292         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2293         if (pos != Position.NOPOS)
2294             storeEnd(mods, S.prevEndPos());
2295         return mods;
2296     }
2297 
2298     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2299      * @param pos position of "@" token
2300      */
2301     JCAnnotation annotation(int pos, AnnotationKind kind) {
2302         // accept(AT); // AT consumed by caller
2303         checkAnnotations();
2304         if (kind == AnnotationKind.TYPE_ANNO)
2305             checkTypeAnnotations();
2306         JCTree ident = qualident();
2307         List<JCExpression> fieldValues = annotationFieldValuesOpt();
2308         JCAnnotation ann;
2309         if (kind == AnnotationKind.DEFAULT_ANNO)
2310             ann = F.at(pos).Annotation(ident, fieldValues);
2311         else
2312             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2313         storeEnd(ann, S.prevEndPos());
2314         return ann;
2315     }
2316 
2317     List<JCExpression> annotationFieldValuesOpt() {
2318         return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2319     }
2320 
2321     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2322     List<JCExpression> annotationFieldValues() {
2323         accept(LPAREN);
2324         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2325         if (S.token() != RPAREN) {
2326             buf.append(annotationFieldValue());
2327             while (S.token() == COMMA) {
2328                 S.nextToken();
2329                 buf.append(annotationFieldValue());
2330             }
2331         }
2332         accept(RPAREN);
2333         return buf.toList();
2334     }
2335 
2336     /** AnnotationFieldValue    = AnnotationValue
2337      *                          | Identifier "=" AnnotationValue
2338      */
2339     JCExpression annotationFieldValue() {
2340         if (S.token() == IDENTIFIER) {
2341             mode = EXPR;
2342             JCExpression t1 = term1();
2343             if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
2344                 int pos = S.pos();
2345                 accept(EQ);
2346                 return toP(F.at(pos).Assign(t1, annotationValue()));
2347             } else {
2348                 return t1;
2349             }
2350         }
2351         return annotationValue();
2352     }
2353 
2354     /* AnnotationValue          = ConditionalExpression
2355      *                          | Annotation
2356      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2357      */
2358     JCExpression annotationValue() {
2359         int pos;
2360         switch (S.token()) {
2361         case MONKEYS_AT:
2362             pos = S.pos();
2363             S.nextToken();
2364             return annotation(pos, AnnotationKind.DEFAULT_ANNO);
2365         case LBRACE:
2366             pos = S.pos();
2367             accept(LBRACE);
2368             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2369             if (S.token() != RBRACE) {
2370                 buf.append(annotationValue());
2371                 while (S.token() == COMMA) {
2372                     S.nextToken();
2373                     if (S.token() == RBRACE) break;
2374                     buf.append(annotationValue());
2375                 }
2376             }
2377             accept(RBRACE);
2378             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2379         default:
2380             mode = EXPR;
2381             return term1();
2382         }
2383     }
2384 
2385     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2386      */
2387     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2388                                                                          JCExpression type,
2389                                                                          T vdefs)
2390     {
2391         return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
2392     }
2393 
2394     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2395      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2396      *
2397      *  @param reqInit  Is an initializer always required?
2398      *  @param dc       The documentation comment for the variable declarations, or null.
2399      */
2400     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2401                                                                      JCModifiers mods,
2402                                                                      JCExpression type,
2403                                                                      Name name,
2404                                                                      boolean reqInit,
2405                                                                      String dc,
2406                                                                      T vdefs)
2407     {
2408         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2409         while (S.token() == COMMA) {
2410             // All but last of multiple declarators subsume a comma
2411             storeEnd((JCTree)vdefs.elems.last(), S.endPos());
2412             S.nextToken();
2413             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2414         }
2415         return vdefs;
2416     }
2417 
2418     /** VariableDeclarator = Ident VariableDeclaratorRest
2419      *  ConstantDeclarator = Ident ConstantDeclaratorRest
2420      */
2421     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
2422         return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
2423     }
2424 
2425     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2426      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2427      *
2428      *  @param reqInit  Is an initializer always required?
2429      *  @param dc       The documentation comment for the variable declarations, or null.
2430      */
2431     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2432                                   boolean reqInit, String dc) {
2433         type = bracketsOpt(type);
2434         JCExpression init = null;
2435         if (S.token() == EQ) {
2436             S.nextToken();
2437             init = variableInitializer();
2438         }
2439         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2440         JCVariableDecl result =
2441             toP(F.at(pos).VarDef(mods, name, type, init));
2442         attach(result, dc);
2443         return result;
2444     }
2445 
2446     /** VariableDeclaratorId = Ident BracketsOpt
2447      */
2448     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2449         int pos = S.pos();
2450         Name name = ident();
2451         if ((mods.flags & Flags.VARARGS) == 0)
2452             type = bracketsOpt(type);
2453         return toP(F.at(pos).VarDef(mods, name, type, null));
2454     }
2455 
2456     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2457      */
2458     public JCTree.JCCompilationUnit parseCompilationUnit() {
2459         int pos = S.pos();
2460         JCExpression pid = null;
2461         String dc = S.docComment();
2462         JCModifiers mods = null;
2463         List<JCAnnotation> packageAnnotations = List.nil();
2464         if (S.token() == MONKEYS_AT)
2465             mods = modifiersOpt();
2466 
2467         if (S.token() == PACKAGE) {
2468             if (mods != null) {
2469                 checkNoMods(mods.flags);
2470                 packageAnnotations = mods.annotations;
2471                 mods = null;
2472             }
2473             S.nextToken();
2474             pid = qualident();
2475             accept(SEMI);
2476         }
2477         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2478         boolean checkForImports = true;
2479         while (S.token() != EOF) {
2480             if (S.pos() <= errorEndPos) {
2481                 // error recovery
2482                 skip(checkForImports, false, false, false);
2483                 if (S.token() == EOF)
2484                     break;
2485             }
2486             if (checkForImports && mods == null && S.token() == IMPORT) {
2487                 defs.append(importDeclaration());
2488             } else {
2489                 JCTree def = typeDeclaration(mods);
2490                 if (def instanceof JCExpressionStatement)
2491                     def = ((JCExpressionStatement)def).expr;
2492                 defs.append(def);
2493                 if (def instanceof JCClassDecl)
2494                     checkForImports = false;
2495                 mods = null;
2496             }
2497         }
2498         JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
2499         attach(toplevel, dc);
2500         if (defs.elems.isEmpty())
2501             storeEnd(toplevel, S.prevEndPos());
2502         if (keepDocComments)
2503             toplevel.docComments = docComments;
2504         if (keepLineMap)
2505             toplevel.lineMap = S.getLineMap();
2506         return toplevel;
2507     }
2508 
2509     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2510      */
2511     JCTree importDeclaration() {
2512         int pos = S.pos();
2513         S.nextToken();
2514         boolean importStatic = false;
2515         if (S.token() == STATIC) {
2516             checkStaticImports();
2517             importStatic = true;
2518             S.nextToken();
2519         }
2520         JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
2521         do {
2522             int pos1 = S.pos();
2523             accept(DOT);
2524             if (S.token() == STAR) {
2525                 pid = to(F.at(pos1).Select(pid, names.asterisk));
2526                 S.nextToken();
2527                 break;
2528             } else {
2529                 pid = toP(F.at(pos1).Select(pid, ident()));
2530             }
2531         } while (S.token() == DOT);
2532         accept(SEMI);
2533         return toP(F.at(pos).Import(pid, importStatic));
2534     }
2535 
2536     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
2537      *                  | ";"
2538      */
2539     JCTree typeDeclaration(JCModifiers mods) {
2540         int pos = S.pos();
2541         if (mods == null && S.token() == SEMI) {
2542             S.nextToken();
2543             return toP(F.at(pos).Skip());
2544         } else {
2545             String dc = S.docComment();
2546             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
2547         }
2548     }
2549 
2550     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
2551      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
2552      *  @param mods     Any modifiers starting the class or interface declaration
2553      *  @param dc       The documentation comment for the class, or null.
2554      */
2555     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
2556         if (S.token() == CLASS) {
2557             return classDeclaration(mods, dc);
2558         } else if (S.token() == INTERFACE) {
2559             return interfaceDeclaration(mods, dc);
2560         } else if (allowEnums) {
2561             if (S.token() == ENUM) {
2562                 return enumDeclaration(mods, dc);
2563             } else {
2564                 int pos = S.pos();
2565                 List<JCTree> errs;
2566                 if (S.token() == IDENTIFIER) {
2567                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2568                     setErrorEndPos(S.pos());
2569                 } else {
2570                     errs = List.<JCTree>of(mods);
2571                 }
2572                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
2573                                               CLASS, INTERFACE, ENUM)));
2574             }
2575         } else {
2576             if (S.token() == ENUM) {
2577                 log.error(S.pos(), "enums.not.supported.in.source", source.name);
2578                 allowEnums = true;
2579                 return enumDeclaration(mods, dc);
2580             }
2581             int pos = S.pos();
2582             List<JCTree> errs;
2583             if (S.token() == IDENTIFIER) {
2584                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2585                 setErrorEndPos(S.pos());
2586             } else {
2587                 errs = List.<JCTree>of(mods);
2588             }
2589             return toP(F.Exec(syntaxError(pos, errs, "expected2",
2590                                           CLASS, INTERFACE)));
2591         }
2592     }
2593 
2594     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
2595      *                     [IMPLEMENTS TypeList] ClassBody
2596      *  @param mods    The modifiers starting the class declaration
2597      *  @param dc       The documentation comment for the class, or null.
2598      */
2599     JCClassDecl classDeclaration(JCModifiers mods, String dc) {
2600         int pos = S.pos();
2601         accept(CLASS);
2602         Name name = ident();
2603 
2604         List<JCTypeParameter> typarams = typeParametersOpt();
2605 
2606         JCTree extending = null;
2607         if (S.token() == EXTENDS) {
2608             S.nextToken();
2609             extending = parseType();
2610         }
2611         List<JCExpression> implementing = List.nil();
2612         if (S.token() == IMPLEMENTS) {
2613             S.nextToken();
2614             implementing = typeList();
2615         }
2616         List<JCTree> defs = classOrInterfaceBody(name, false);
2617         JCClassDecl result = toP(F.at(pos).ClassDef(
2618             mods, name, typarams, extending, implementing, defs));
2619         attach(result, dc);
2620         return result;
2621     }
2622 
2623     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
2624      *                         [EXTENDS TypeList] InterfaceBody
2625      *  @param mods    The modifiers starting the interface declaration
2626      *  @param dc       The documentation comment for the interface, or null.
2627      */
2628     JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
2629         int pos = S.pos();
2630         accept(INTERFACE);
2631         Name name = ident();
2632 
2633         List<JCTypeParameter> typarams = typeParametersOpt();
2634 
2635         List<JCExpression> extending = List.nil();
2636         if (S.token() == EXTENDS) {
2637             S.nextToken();
2638             extending = typeList();
2639         }
2640         List<JCTree> defs = classOrInterfaceBody(name, true);
2641         JCClassDecl result = toP(F.at(pos).ClassDef(
2642             mods, name, typarams, null, extending, defs));
2643         attach(result, dc);
2644         return result;
2645     }
2646 
2647     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
2648      *  @param mods    The modifiers starting the enum declaration
2649      *  @param dc       The documentation comment for the enum, or null.
2650      */
2651     JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
2652         int pos = S.pos();
2653         accept(ENUM);
2654         Name name = ident();
2655 
2656         List<JCExpression> implementing = List.nil();
2657         if (S.token() == IMPLEMENTS) {
2658             S.nextToken();
2659             implementing = typeList();
2660         }
2661 
2662         List<JCTree> defs = enumBody(name);
2663         JCModifiers newMods =
2664             F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations);
2665         JCClassDecl result = toP(F.at(pos).
2666             ClassDef(newMods, name, List.<JCTypeParameter>nil(),
2667                 null, implementing, defs));
2668         attach(result, dc);
2669         return result;
2670     }
2671 
2672     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
2673      *                  [ ";" {ClassBodyDeclaration} ] "}"
2674      */
2675     List<JCTree> enumBody(Name enumName) {
2676         accept(LBRACE);
2677         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2678         if (S.token() == COMMA) {
2679             S.nextToken();
2680         } else if (S.token() != RBRACE && S.token() != SEMI) {
2681             defs.append(enumeratorDeclaration(enumName));
2682             while (S.token() == COMMA) {
2683                 S.nextToken();
2684                 if (S.token() == RBRACE || S.token() == SEMI) break;
2685                 defs.append(enumeratorDeclaration(enumName));
2686             }
2687             if (S.token() != SEMI && S.token() != RBRACE) {
2688                 defs.append(syntaxError(S.pos(), "expected3",
2689                                 COMMA, RBRACE, SEMI));
2690                 S.nextToken();
2691             }
2692         }
2693         if (S.token() == SEMI) {
2694             S.nextToken();
2695             while (S.token() != RBRACE && S.token() != EOF) {
2696                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
2697                                                                 false));
2698                 if (S.pos() <= errorEndPos) {
2699                     // error recovery
2700                    skip(false, true, true, false);
2701                 }
2702             }
2703         }
2704         accept(RBRACE);
2705         return defs.toList();
2706     }
2707 
2708     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
2709      */
2710     JCTree enumeratorDeclaration(Name enumName) {
2711         String dc = S.docComment();
2712         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
2713         if (S.deprecatedFlag()) {
2714             flags |= Flags.DEPRECATED;
2715             S.resetDeprecatedFlag();
2716         }
2717         int pos = S.pos();
2718         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2719         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
2720         List<JCExpression> typeArgs = typeArgumentsOpt();
2721         int identPos = S.pos();
2722         Name name = ident();
2723         int createPos = S.pos();
2724         List<JCExpression> args = (S.token() == LPAREN)
2725             ? arguments() : List.<JCExpression>nil();
2726         JCClassDecl body = null;
2727         if (S.token() == LBRACE) {
2728             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
2729             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2730             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
2731         }
2732         if (args.isEmpty() && body == null)
2733             createPos = Position.NOPOS;
2734         JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
2735         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
2736         if (createPos != Position.NOPOS)
2737             storeEnd(create, S.prevEndPos());
2738         ident = F.at(Position.NOPOS).Ident(enumName);
2739         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
2740         attach(result, dc);
2741         return result;
2742     }
2743 
2744     /** TypeList = Type {"," Type}
2745      */
2746     List<JCExpression> typeList() {
2747         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2748         ts.append(parseType());
2749         while (S.token() == COMMA) {
2750             S.nextToken();
2751             ts.append(parseType());
2752         }
2753         return ts.toList();
2754     }
2755 
2756     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
2757      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2758      */
2759     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
2760         accept(LBRACE);
2761         if (S.pos() <= errorEndPos) {
2762             // error recovery
2763             skip(false, true, false, false);
2764             if (S.token() == LBRACE)
2765                 S.nextToken();
2766         }
2767         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2768         while (S.token() != RBRACE && S.token() != EOF) {
2769             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
2770             if (S.pos() <= errorEndPos) {
2771                // error recovery
2772                skip(false, true, true, false);
2773            }
2774         }
2775         accept(RBRACE);
2776         return defs.toList();
2777     }
2778 
2779     /** ClassBodyDeclaration =
2780      *      ";"
2781      *    | [STATIC] Block
2782      *    | ModifiersOpt
2783      *      ( Type Ident
2784      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
2785      *      | VOID Ident MethodDeclaratorRest
2786      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
2787      *      | Ident ConstructorDeclaratorRest
2788      *      | TypeParameters Ident ConstructorDeclaratorRest
2789      *      | ClassOrInterfaceOrEnumDeclaration
2790      *      )
2791      *  InterfaceBodyDeclaration =
2792      *      ";"
2793      *    | ModifiersOpt Type Ident
2794      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
2795      */
2796     List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
2797         if (S.token() == SEMI) {
2798             S.nextToken();
2799             return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
2800         } else {
2801             String dc = S.docComment();
2802             int pos = S.pos();
2803             JCModifiers mods = modifiersOpt();
2804             if (S.token() == CLASS ||
2805                 S.token() == INTERFACE ||
2806                 allowEnums && S.token() == ENUM) {
2807                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
2808             } else if (S.token() == LBRACE && !isInterface &&
2809                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
2810                        mods.annotations.isEmpty()) {
2811                 return List.<JCTree>of(block(pos, mods.flags));
2812             } else {
2813                 pos = S.pos();
2814                 List<JCTypeParameter> typarams = typeParametersOpt();
2815                 // Hack alert:  if there are type arguments but no Modifiers, the start
2816                 // position will be lost unless we set the Modifiers position.  There
2817                 // should be an AST node for type parameters (BugId 5005090).
2818                 if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
2819                     mods.pos = pos;
2820                 }
2821 
2822                 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2823 
2824                 Token token = S.token();
2825                 Name name = S.name();
2826                 pos = S.pos();
2827                 JCExpression type;
2828                 boolean isVoid = S.token() == VOID;
2829                 if (isVoid) {
2830                     if (annosAfterParams.nonEmpty())
2831                         illegal(annosAfterParams.head.pos);
2832                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2833                     S.nextToken();
2834                 } else {
2835                     mods.annotations = mods.annotations.appendList(annosAfterParams);
2836                     // method returns types are un-annotated types
2837                     type = unannotatedType();
2838                 }
2839                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2840                     if (isInterface || name != className)
2841                         log.error(pos, "invalid.meth.decl.ret.type.req");
2842                     return List.of(methodDeclaratorRest(
2843                         pos, mods, null, names.init, typarams,
2844                         isInterface, true, dc));
2845                 } else {
2846                     pos = S.pos();
2847                     name = ident();
2848                     if (S.token() == LPAREN) {
2849                         return List.of(methodDeclaratorRest(
2850                             pos, mods, type, name, typarams,
2851                             isInterface, isVoid, dc));
2852                     } else if (!isVoid && typarams.isEmpty()) {
2853                         List<JCTree> defs =
2854                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2855                                                     new ListBuffer<JCTree>()).toList();
2856                         storeEnd(defs.last(), S.endPos());
2857                         accept(SEMI);
2858                         return defs;
2859                     } else {
2860                         pos = S.pos();
2861                         List<JCTree> err = isVoid
2862                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
2863                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
2864                             : null;
2865                         return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
2866                     }
2867                 }
2868             }
2869         }
2870     }
2871 
2872     /** MethodDeclaratorRest =
2873      *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2874      *  VoidMethodDeclaratorRest =
2875      *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
2876      *  InterfaceMethodDeclaratorRest =
2877      *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
2878      *  VoidInterfaceMethodDeclaratorRest =
2879      *      FormalParameters [Annotations] [THROWS TypeList] ";"
2880      *  ConstructorDeclaratorRest =
2881      *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
2882      */
2883     JCTree methodDeclaratorRest(int pos,
2884                               JCModifiers mods,
2885                               JCExpression type,
2886                               Name name,
2887                               List<JCTypeParameter> typarams,
2888                               boolean isInterface, boolean isVoid,
2889                               String dc) {
2890         List<JCVariableDecl> params = formalParameters();
2891 
2892         List<JCTypeAnnotation> receiverAnnotations;
2893         if (!isVoid) {
2894             // need to distinguish between receiver anno and array anno
2895             // look at typeAnnotationsPushedBack comment
2896             this.permitTypeAnnotationsPushBack = true;
2897             type = methodReturnArrayRest(type);
2898             this.permitTypeAnnotationsPushBack = false;
2899             if (typeAnnotationsPushedBack == null)
2900                 receiverAnnotations = List.nil();
2901             else
2902                 receiverAnnotations = typeAnnotationsPushedBack;
2903             typeAnnotationsPushedBack = null;
2904         } else
2905             receiverAnnotations = typeAnnotationsOpt();
2906 
2907         List<JCExpression> thrown = List.nil();
2908         if (S.token() == THROWS) {
2909             S.nextToken();
2910             thrown = qualidentList();
2911         }
2912         JCBlock body = null;
2913         JCExpression defaultValue;
2914         if (S.token() == LBRACE) {
2915             body = block();
2916             defaultValue = null;
2917         } else {
2918             if (S.token() == DEFAULT) {
2919                 accept(DEFAULT);
2920                 defaultValue = annotationValue();
2921             } else {
2922                 defaultValue = null;
2923             }
2924             accept(SEMI);
2925             if (S.pos() <= errorEndPos) {
2926                 // error recovery
2927                 skip(false, true, false, false);
2928                 if (S.token() == LBRACE) {
2929                     body = block();
2930                 }
2931             }
2932         }
2933         JCMethodDecl result =
2934             toP(F.at(pos).MethodDef(mods, name, type, typarams,
2935                                     params, receiverAnnotations, thrown,
2936                                     body, defaultValue));
2937         attach(result, dc);
2938         return result;
2939     }
2940 
2941     /** Parses the array levels after the format parameters list, and append
2942      * them to the return type, while preseving the order of type annotations
2943      */
2944     private JCExpression methodReturnArrayRest(JCExpression type) {
2945         if (type.getTag() != JCTree.TYPEARRAY)
2946             return bracketsOpt(type);
2947 
2948         JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
2949         while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
2950             baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
2951 
2952         if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
2953             JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
2954             at.underlyingType = bracketsOpt(at.underlyingType);
2955         } else {
2956             baseArray.elemtype = bracketsOpt(baseArray.elemtype);
2957         }
2958 
2959         return type;
2960     }
2961 
2962     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
2963      */
2964     List<JCExpression> qualidentList() {
2965         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2966 
2967         List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
2968         if (!typeAnnos.isEmpty())
2969             ts.append(F.AnnotatedType(typeAnnos, qualident()));
2970         else
2971             ts.append(qualident());
2972         while (S.token() == COMMA) {
2973             S.nextToken();
2974 
2975             typeAnnos = typeAnnotationsOpt();
2976             if (!typeAnnos.isEmpty())
2977                 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2978             else
2979                 ts.append(qualident());
2980         }
2981         return ts.toList();
2982     }
2983 
2984     /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2985      */
2986     List<JCTypeParameter> typeParametersOpt() {
2987         if (S.token() == LT) {
2988             checkGenerics();
2989             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
2990             S.nextToken();
2991             typarams.append(typeParameter());
2992             while (S.token() == COMMA) {
2993                 S.nextToken();
2994                 typarams.append(typeParameter());
2995             }
2996             accept(GT);
2997             return typarams.toList();
2998         } else {
2999             return List.nil();
3000         }
3001     }
3002 
3003     /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
3004      *  TypeParameterBound = EXTENDS Type {"&" Type}
3005      *  TypeVariable = Ident
3006      */
3007     JCTypeParameter typeParameter() {
3008         int pos = S.pos();
3009         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
3010         Name name = ident();
3011         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
3012         if (S.token() == EXTENDS) {
3013             S.nextToken();
3014             bounds.append(parseType());
3015             while (S.token() == AMP) {
3016                 S.nextToken();
3017                 bounds.append(parseType());
3018             }
3019         }
3020         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
3021     }
3022 
3023     /** FormalParameters = "(" [ FormalParameterList ] ")"
3024      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3025      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3026      */
3027     List<JCVariableDecl> formalParameters() {
3028         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
3029         JCVariableDecl lastParam = null;
3030         accept(LPAREN);
3031         if (S.token() != RPAREN) {
3032             params.append(lastParam = formalParameter());
3033             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
3034                 S.nextToken();
3035                 params.append(lastParam = formalParameter());
3036             }
3037         }
3038         accept(RPAREN);
3039         return params.toList();
3040     }
3041 
3042     JCModifiers optFinal(long flags) {
3043         JCModifiers mods = modifiersOpt();
3044         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
3045         mods.flags |= flags;
3046         return mods;
3047     }
3048 
3049     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3050      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3051      */
3052     JCVariableDecl formalParameter() {
3053         JCModifiers mods = optFinal(Flags.PARAMETER);
3054         // need to distinguish between vararg annos and array annos
3055         // look at typeAnnotaitonsPushedBack comment
3056         this.permitTypeAnnotationsPushBack = true;
3057         JCExpression type = parseType();
3058         this.permitTypeAnnotationsPushBack = false;
3059 
3060         if (S.token() == ELLIPSIS) {
3061             List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
3062             typeAnnotationsPushedBack = null;
3063             checkVarargs();
3064             mods.flags |= Flags.VARARGS;
3065             // insert var arg type annotations
3066             if (varargsAnnos != null && varargsAnnos.nonEmpty())
3067                 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
3068             type = to(F.at(S.pos()).TypeArray(type));
3069 
3070             S.nextToken();
3071         } else {
3072             // if not a var arg, then typeAnnotationsPushedBack should be null
3073             if (typeAnnotationsPushedBack != null
3074                     && !typeAnnotationsPushedBack.isEmpty()) {
3075                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3076                         "illegal.start.of.type");
3077             }
3078             typeAnnotationsPushedBack = null;
3079         }
3080         return variableDeclaratorId(mods, type);
3081     }
3082 
3083 /* ---------- auxiliary methods -------------- */
3084 
3085     /** Check that given tree is a legal expression statement.
3086      */
3087     protected JCExpression checkExprStat(JCExpression t) {
3088         switch(t.getTag()) {
3089         case JCTree.PREINC: case JCTree.PREDEC:
3090         case JCTree.POSTINC: case JCTree.POSTDEC:
3091         case JCTree.ASSIGN:
3092         case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
3093         case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
3094         case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
3095         case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
3096         case JCTree.APPLY: case JCTree.NEWCLASS:
3097         case JCTree.ERRONEOUS:
3098             return t;
3099         default:
3100             log.error(t.pos, "not.stmt");
3101             return F.at(t.pos).Erroneous(List.<JCTree>of(t));
3102         }
3103     }
3104 
3105     /** Return precedence of operator represented by token,
3106      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
3107      */
3108     static int prec(Token token) {
3109         int oc = optag(token);
3110         return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
3111     }
3112 
3113     /** Return operation tag of binary operator represented by token,
3114      *  -1 if token is not a binary operator.
3115      */
3116     static int optag(Token token) {
3117         switch (token) {
3118         case BARBAR:
3119             return JCTree.OR;
3120         case AMPAMP:
3121             return JCTree.AND;
3122         case BAR:
3123             return JCTree.BITOR;
3124         case BAREQ:
3125             return JCTree.BITOR_ASG;
3126         case CARET:
3127             return JCTree.BITXOR;
3128         case CARETEQ:
3129             return JCTree.BITXOR_ASG;
3130         case AMP:
3131             return JCTree.BITAND;
3132         case AMPEQ:
3133             return JCTree.BITAND_ASG;
3134         case EQEQ:
3135             return JCTree.EQ;
3136         case BANGEQ:
3137             return JCTree.NE;
3138         case LT:
3139             return JCTree.LT;
3140         case GT:
3141             return JCTree.GT;
3142         case LTEQ:
3143             return JCTree.LE;
3144         case GTEQ:
3145             return JCTree.GE;
3146         case LTLT:
3147             return JCTree.SL;
3148         case LTLTEQ:
3149             return JCTree.SL_ASG;
3150         case GTGT:
3151             return JCTree.SR;
3152         case GTGTEQ:
3153             return JCTree.SR_ASG;
3154         case GTGTGT:
3155             return JCTree.USR;
3156         case GTGTGTEQ:
3157             return JCTree.USR_ASG;
3158         case PLUS:
3159             return JCTree.PLUS;
3160         case PLUSEQ:
3161             return JCTree.PLUS_ASG;
3162         case SUB:
3163             return JCTree.MINUS;
3164         case SUBEQ:
3165             return JCTree.MINUS_ASG;
3166         case STAR:
3167             return JCTree.MUL;
3168         case STAREQ:
3169             return JCTree.MUL_ASG;
3170         case SLASH:
3171             return JCTree.DIV;
3172         case SLASHEQ:
3173             return JCTree.DIV_ASG;
3174         case PERCENT:
3175             return JCTree.MOD;
3176         case PERCENTEQ:
3177             return JCTree.MOD_ASG;
3178         case INSTANCEOF:
3179             return JCTree.TYPETEST;
3180         default:
3181             return -1;
3182         }
3183     }
3184 
3185     /** Return operation tag of unary operator represented by token,
3186      *  -1 if token is not a binary operator.
3187      */
3188     static int unoptag(Token token) {
3189         switch (token) {
3190         case PLUS:
3191             return JCTree.POS;
3192         case SUB:
3193             return JCTree.NEG;
3194         case BANG:
3195             return JCTree.NOT;
3196         case TILDE:
3197             return JCTree.COMPL;
3198         case PLUSPLUS:
3199             return JCTree.PREINC;
3200         case SUBSUB:
3201             return JCTree.PREDEC;
3202         default:
3203             return -1;
3204         }
3205     }
3206 
3207     /** Return type tag of basic type represented by token,
3208      *  -1 if token is not a basic type identifier.
3209      */
3210     static int typetag(Token token) {
3211         switch (token) {
3212         case BYTE:
3213             return TypeTags.BYTE;
3214         case CHAR:
3215             return TypeTags.CHAR;
3216         case SHORT:
3217             return TypeTags.SHORT;
3218         case INT:
3219             return TypeTags.INT;
3220         case LONG:
3221             return TypeTags.LONG;
3222         case FLOAT:
3223             return TypeTags.FLOAT;
3224         case DOUBLE:
3225             return TypeTags.DOUBLE;
3226         case BOOLEAN:
3227             return TypeTags.BOOLEAN;
3228         default:
3229             return -1;
3230         }
3231     }
3232 
3233     void checkDiamond() {
3234         if (!allowDiamond) {
3235             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3236             allowDiamond = true;
3237         }
3238     }
3239     void checkGenerics() {
3240         if (!allowGenerics) {
3241             log.error(S.pos(), "generics.not.supported.in.source", source.name);
3242             allowGenerics = true;
3243         }
3244     }
3245     void checkVarargs() {
3246         if (!allowVarargs) {
3247             log.error(S.pos(), "varargs.not.supported.in.source", source.name);
3248             allowVarargs = true;
3249         }
3250     }
3251     void checkForeach() {
3252         if (!allowForeach) {
3253             log.error(S.pos(), "foreach.not.supported.in.source", source.name);
3254             allowForeach = true;
3255         }
3256     }
3257     void checkStaticImports() {
3258         if (!allowStaticImport) {
3259             log.error(S.pos(), "static.import.not.supported.in.source", source.name);
3260             allowStaticImport = true;
3261         }
3262     }
3263     void checkAnnotations() {
3264         if (!allowAnnotations) {
3265             log.error(S.pos(), "annotations.not.supported.in.source", source.name);
3266             allowAnnotations = true;
3267         }
3268     }
3269     void checkTypeAnnotations() {
3270         if (!allowTypeAnnotations) {
3271             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3272             allowTypeAnnotations = true;
3273         }
3274     }
3275     void checkFunctionType() {
3276         if (!allowFunctionType) {
3277             log.error(S.pos(), "function.type.not.supported.in.source", source.name);
3278             allowFunctionType = true;
3279         }
3280     }
3281     void checkLambda() {
3282         if (!allowLambda) {
3283             log.error(S.pos(), "lambda.not.supported.in.source", source.name);
3284             allowLambda = true;
3285         }
3286     }
3287 }