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