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                     assert this.permitTypeAnnotationsPushBack;
1155                     typeAnnotationsPushedBack = annos;
1156                     break loop;
1157                 default:
1158                     break loop;
1159                 }
1160             }
1161             if (typeArgs != null) illegal();
1162             t = typeArgumentsOpt(t);
1163             break;
1164         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1165         case DOUBLE: case BOOLEAN:
1166             if (typeArgs != null) illegal();
1167             t = bracketsSuffix(bracketsOpt(basicType()));
1168             break;
1169         case VOID:
1170             if (typeArgs != null) illegal();
1171             if ((mode & EXPR) != 0) {
1172                 S.nextToken();
1173                 if (S.token() == DOT) {
1174                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
1175                     t = bracketsSuffix(ti);
1176                 } else {
1177                     return illegal(pos);
1178                 }
1179             } else {
1180                 // Support the corner case of myMethodHandle.<void>invoke() by passing
1181                 // a void type (like other primitive types) to the next phase.
1182                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1183                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
1184                 S.nextToken();
1185                 return ti;
1186                 //return illegal();
1187             }
1188             break;
1189         default:
1190             return illegal();
1191         }
1192         if (typeArgs != null) illegal();
1193         while (true) {
1194             int pos1 = S.pos();
1195 
1196             final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1197 
1198             if (S.token() == LBRACKET) {
1199                 S.nextToken();
1200 
1201                 if ((mode & TYPE) != 0) {
1202                     int oldmode = mode;
1203                     mode = TYPE;
1204                     if (S.token() == RBRACKET) {
1205                         S.nextToken();
1206                         t = bracketsOpt(t, annos);
1207                         t = toP(F.at(pos1).TypeArray(t));
1208                         return t;
1209                     }
1210                     mode = oldmode;
1211                 }
1212                 if ((mode & EXPR) != 0) {
1213                     mode = EXPR;
1214                     JCExpression t1 = term();
1215                     t = to(F.at(pos1).Indexed(t, t1));
1216                 }
1217                 accept(RBRACKET);
1218             } else if (S.token() == DOT) {
1219                 S.nextToken();
1220                 typeArgs = typeArgumentsOpt(EXPR);
1221                 if (S.token() == SUPER && (mode & EXPR) != 0) {
1222                     mode = EXPR;
1223                     t = to(F.at(pos1).Select(t, names._super));
1224                     S.nextToken();
1225                     t = arguments(typeArgs, t);
1226                     typeArgs = null;
1227                 } else if (S.token() == NEW && (mode & EXPR) != 0) {
1228                     if (typeArgs != null) return illegal();
1229                     mode = EXPR;
1230                     int pos2 = S.pos();
1231                     S.nextToken();
1232                     if (S.token() == LT) typeArgs = typeArguments();
1233                     t = innerCreator(pos2, typeArgs, t);
1234                     typeArgs = null;
1235                 } else {
1236                     t = toP(F.at(pos1).Select(t, ident()));
1237                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1238                     typeArgs = null;
1239                 }
1240             } else {
1241                 if (!annos.isEmpty()) {
1242                     if (permitTypeAnnotationsPushBack)
1243                         typeAnnotationsPushedBack = annos;
1244                     else
1245                         return illegal(annos.head.pos);
1246                 }
1247                 break;
1248             }
1249         }
1250         while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
1251             mode = EXPR;
1252             t = to(F.at(S.pos()).Unary(
1253                   S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1254             S.nextToken();
1255         }
1256 
1257         return toP(t);
1258     }
1259 
1260     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1261      */
1262     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1263         S.nextToken();
1264         if (S.token() == LPAREN || typeArgs != null) {
1265             t = arguments(typeArgs, t);
1266         } else {
1267             int pos = S.pos();
1268             accept(DOT);
1269             typeArgs = (S.token() == LT) ? typeArguments() : null;
1270             t = toP(F.at(pos).Select(t, ident()));
1271             t = argumentsOpt(typeArgs, t);
1272         }
1273         return t;
1274     }
1275 
1276     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1277      */
1278     JCPrimitiveTypeTree basicType() {
1279         JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
1280         S.nextToken();
1281         return t;
1282     }
1283 
1284     /** ArgumentsOpt = [ Arguments ]
1285      */
1286     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1287         if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
1288             mode = EXPR;
1289             return arguments(typeArgs, t);
1290         } else {
1291             return t;
1292         }
1293     }
1294 
1295     /** Arguments = "(" [Expression { COMMA Expression }] ")"
1296      */
1297     List<JCExpression> arguments() {
1298         ListBuffer<JCExpression> args = lb();
1299         if (S.token() == LPAREN) {
1300             S.nextToken();
1301             if (S.token() != RPAREN) {
1302                 args.append(parseExpression());
1303                 while (S.token() == COMMA) {
1304                     S.nextToken();
1305                     args.append(parseExpression());
1306                 }
1307             }
1308             accept(RPAREN);
1309         } else {
1310             syntaxError(S.pos(), "expected", LPAREN);
1311         }
1312         return args.toList();
1313     }
1314 
1315     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1316         int pos = S.pos();
1317         List<JCExpression> args = arguments();
1318         return toP(F.at(pos).Apply(typeArgs, t, args));
1319     }
1320 
1321     /**  TypeArgumentsOpt = [ TypeArguments ]
1322      */
1323     JCExpression typeArgumentsOpt(JCExpression t) {
1324         if (S.token() == LT &&
1325             (mode & TYPE) != 0 &&
1326             (mode & NOPARAMS) == 0) {
1327             mode = TYPE;
1328             checkGenerics();
1329             return typeArguments(t);
1330         } else {
1331             return t;
1332         }
1333     }
1334     List<JCExpression> typeArgumentsOpt() {
1335         return typeArgumentsOpt(TYPE);
1336     }
1337 
1338     List<JCExpression> typeArgumentsOpt(int useMode) {
1339         if (S.token() == LT) {
1340             checkGenerics();
1341             if ((mode & useMode) == 0 ||
1342                 (mode & NOPARAMS) != 0) {
1343                 illegal();
1344             }
1345             mode = useMode;
1346             return typeArguments();
1347         }
1348         return null;
1349     }
1350 
1351     /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1352      */
1353     List<JCExpression> typeArguments() {
1354         ListBuffer<JCExpression> args = lb();
1355         if (S.token() == LT) {
1356             S.nextToken();
1357             if (S.token() == GT && (mode & DIAMOND) != 0) {
1358                 checkDiamond();
1359                 S.nextToken();
1360                 return List.nil();
1361             }
1362             args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1363             while (S.token() == COMMA) {
1364                 S.nextToken();
1365                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1366             }
1367             switch (S.token()) {
1368             case GTGTGTEQ:
1369                 S.token(GTGTEQ);
1370                 break;
1371             case GTGTEQ:
1372                 S.token(GTEQ);
1373                 break;
1374             case GTEQ:
1375                 S.token(EQ);
1376                 break;
1377             case GTGTGT:
1378                 S.token(GTGT);
1379                 break;
1380             case GTGT:
1381                 S.token(GT);
1382                 break;
1383             default:
1384                 accept(GT);
1385                 break;
1386             }
1387         } else {
1388             syntaxError(S.pos(), "expected", LT);
1389         }
1390         return args.toList();
1391     }
1392 
1393     /** TypeArgument = Type
1394      *               | [Annotations] "?"
1395      *               | [Annotations] "?" EXTENDS Type {"&" Type}
1396      *               | [Annotations] "?" SUPER Type
1397      */
1398     JCExpression typeArgument() {
1399         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
1400         if (S.token() != QUES) return parseType(annotations);
1401         int pos = S.pos();
1402         S.nextToken();
1403         JCExpression result;
1404         if (S.token() == EXTENDS) {
1405             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
1406             S.nextToken();
1407             JCExpression bound = parseType();
1408             result = F.at(pos).Wildcard(t, bound);
1409         } else if (S.token() == SUPER) {
1410             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
1411             S.nextToken();
1412             JCExpression bound = parseType();
1413             result = F.at(pos).Wildcard(t, bound);
1414         } else if (S.token() == IDENTIFIER) {
1415             //error recovery
1416             reportSyntaxError(S.prevEndPos(), "expected3",
1417                     GT, EXTENDS, SUPER);
1418             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1419             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1420             JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1421             result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1422         } else {
1423             TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
1424             result = toP(F.at(pos).Wildcard(t, null));
1425         }
1426         if (!annotations.isEmpty())
1427             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1428         return result;
1429     }
1430 
1431     JCTypeApply typeArguments(JCExpression t) {
1432         int pos = S.pos();
1433         List<JCExpression> args = typeArguments();
1434         return toP(F.at(pos).TypeApply(t, args));
1435     }
1436 
1437     /**
1438      * BracketsOpt = { [Annotations] "[" "]" }
1439      *
1440      * <p>
1441      *
1442      * <code>annotations</code> is the list of annotations targeting
1443      * the expression <code>t</code>.
1444      */
1445     private JCExpression bracketsOpt(JCExpression t,
1446             List<JCTypeAnnotation> annotations) {
1447         List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1448 
1449         if (S.token() == LBRACKET) {
1450             int pos = S.pos();
1451             S.nextToken();
1452 
1453             JCExpression orig = t;
1454             t = bracketsOptCont(t, pos, nextLevelAnnotations);
1455         } else if (!nextLevelAnnotations.isEmpty()) {
1456             if (permitTypeAnnotationsPushBack) {
1457                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1458             } else
1459                 return illegal(nextLevelAnnotations.head.pos);
1460         }
1461 
1462         int apos = S.pos();
1463         if (!annotations.isEmpty())
1464             t = F.at(apos).AnnotatedType(annotations, t);
1465         return t;
1466     }
1467 
1468     /** BracketsOpt = {"[" TypeAnnotations "]"}
1469      */
1470     private JCExpression bracketsOpt(JCExpression t) {
1471         return bracketsOpt(t, List.<JCTypeAnnotation>nil());
1472     }
1473 
1474     private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
1475             List<JCTypeAnnotation> annotations) {
1476         accept(RBRACKET);
1477         t = bracketsOpt(t, annotations);
1478         return toP(F.at(pos).TypeArray(t));
1479     }
1480 
1481     /** BracketsSuffixExpr = "." CLASS
1482      *  BracketsSuffixType =
1483      */
1484     JCExpression bracketsSuffix(JCExpression t) {
1485         if ((mode & EXPR) != 0 && S.token() == DOT) {
1486             mode = EXPR;
1487             int pos = S.pos();
1488             S.nextToken();
1489             accept(CLASS);
1490             if (S.pos() == errorEndPos) {
1491                 // error recovery
1492                 Name name = null;
1493                 if (S.token() == IDENTIFIER) {
1494                     name = S.name();
1495                     S.nextToken();
1496                 } else {
1497                     name = names.error;
1498                 }
1499                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
1500             } else {
1501                 t = toP(F.at(pos).Select(t, names._class));
1502             }
1503         } else if ((mode & TYPE) != 0) {
1504             mode = TYPE;
1505         } else {
1506             syntaxError(S.pos(), "dot.class.expected");
1507         }
1508         return t;
1509     }
1510 
1511     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1512      */
1513     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1514 
1515         List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
1516 
1517         switch (S.token()) {
1518         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1519         case DOUBLE: case BOOLEAN:
1520             if (typeArgs == null) {
1521                 if (newAnnotations.isEmpty())
1522                     return arrayCreatorRest(newpos, basicType());
1523                 else
1524                     return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
1525             }
1526             break;
1527         default:
1528         }
1529         JCExpression t = qualident();
1530         // handle type annotations for non primitive arrays
1531         if (!newAnnotations.isEmpty())
1532             t = F.AnnotatedType(newAnnotations, t);
1533 
1534         int oldmode = mode;
1535         mode = TYPE | DIAMOND;
1536         if (S.token() == LT) {
1537             checkGenerics();
1538             t = typeArguments(t);
1539         }
1540         while (S.token() == DOT) {
1541             int pos = S.pos();
1542             S.nextToken();
1543             t = toP(F.at(pos).Select(t, ident()));
1544             if (S.token() == LT) {
1545                 checkGenerics();
1546                 t = typeArguments(t);
1547             }
1548         }
1549         mode = oldmode;
1550         if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
1551             JCExpression e = arrayCreatorRest(newpos, t);
1552             if (typeArgs != null) {
1553                 int pos = newpos;
1554                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
1555                     // note: this should always happen but we should
1556                     // not rely on this as the parser is continuously
1557                     // modified to improve error recovery.
1558                     pos = typeArgs.head.pos;
1559                 }
1560                 setErrorEndPos(S.prevEndPos());
1561                 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
1562                 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1563             }
1564             return e;
1565         } else if (S.token() == LPAREN) {
1566             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
1567             if (newClass.def != null) {
1568                 assert newClass.def.mods.annotations.isEmpty();
1569                 if (newAnnotations.nonEmpty()) {
1570                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
1571                     newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
1572                 }
1573             }
1574             return newClass;
1575         } else {
1576             reportSyntaxError(S.pos(), "expected2",
1577                                LPAREN, LBRACKET);
1578             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
1579             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
1580         }
1581     }
1582 
1583     /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
1584      */
1585     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
1586         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
1587         if (S.token() == LT) {
1588             int oldmode = mode;
1589             mode |= DIAMOND;
1590             checkGenerics();
1591             t = typeArguments(t);
1592             mode = oldmode;
1593         }
1594         return classCreatorRest(newpos, encl, typeArgs, t);
1595     }
1596 
1597     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
1598      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
1599      */
1600     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1601 
1602         List<JCTypeAnnotation> topAnnos = List.nil();
1603         if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
1604             JCAnnotatedType atype = (JCAnnotatedType) elemtype;
1605             topAnnos = atype.annotations;
1606             elemtype = atype.underlyingType;
1607         }
1608 
1609         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1610 
1611         accept(LBRACKET);
1612 
1613         if (S.token() == RBRACKET) {
1614             accept(RBRACKET);
1615 
1616             elemtype = bracketsOpt(elemtype, annos);
1617 
1618             if (S.token() == LBRACE) {
1619                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
1620 
1621                 na.annotations = topAnnos;
1622 
1623                 return na;
1624             } else {
1625                 return syntaxError(S.pos(), "array.dimension.missing");
1626             }
1627         } else {
1628             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1629 
1630             // maintain array dimension type annotations
1631             ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
1632             dimAnnotations.append(annos);
1633 
1634             dims.append(parseExpression());
1635             accept(RBRACKET);
1636             while (S.token() == LBRACKET
1637                     || (S.token() == MONKEYS_AT)) {
1638                 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
1639                 int pos = S.pos();
1640                 S.nextToken();
1641                 if (S.token() == RBRACKET) {
1642                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1643                 } else {
1644                     if (S.token() == RBRACKET) { // no dimension
1645                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1646                     } else {
1647                         dimAnnotations.append(maybeDimAnnos);
1648                         dims.append(parseExpression());
1649                         accept(RBRACKET);
1650                     }
1651                 }
1652             }
1653 
1654             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
1655             na.annotations = topAnnos;
1656             na.dimAnnotations = dimAnnotations.toList();
1657             return na;
1658         }
1659     }
1660 
1661     /** ClassCreatorRest = Arguments [ClassBody]
1662      */
1663     JCNewClass classCreatorRest(int newpos,
1664                                   JCExpression encl,
1665                                   List<JCExpression> typeArgs,
1666                                   JCExpression t)
1667     {
1668         List<JCExpression> args = arguments();
1669         JCClassDecl body = null;
1670         if (S.token() == LBRACE) {
1671             int pos = S.pos();
1672             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
1673             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1674             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
1675         }
1676         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
1677     }
1678 
1679     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
1680      */
1681     JCExpression arrayInitializer(int newpos, JCExpression t) {
1682         accept(LBRACE);
1683         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
1684         if (S.token() == COMMA) {
1685             S.nextToken();
1686         } else if (S.token() != RBRACE) {
1687             elems.append(variableInitializer());
1688             while (S.token() == COMMA) {
1689                 S.nextToken();
1690                 if (S.token() == RBRACE) break;
1691                 elems.append(variableInitializer());
1692             }
1693         }
1694         accept(RBRACE);
1695         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
1696     }
1697 
1698     /** VariableInitializer = ArrayInitializer | Expression
1699      */
1700     public JCExpression variableInitializer() {
1701         return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
1702     }
1703 
1704     /** ParExpression = "(" Expression ")"
1705      */
1706     JCExpression parExpression() {
1707         accept(LPAREN);
1708         JCExpression t = parseExpression();
1709         accept(RPAREN);
1710         return t;
1711     }
1712 
1713     /** Block = "{" BlockStatements "}"
1714      */
1715     JCBlock block(int pos, long flags) {
1716         accept(LBRACE);
1717         List<JCStatement> stats = blockStatements();
1718         JCBlock t = F.at(pos).Block(flags, stats);
1719         while (S.token() == CASE || S.token() == DEFAULT) {
1720             syntaxError("orphaned", S.token());
1721             switchBlockStatementGroups();
1722         }
1723         // the Block node has a field "endpos" for first char of last token, which is
1724         // usually but not necessarily the last char of the last token.
1725         t.endpos = S.pos();
1726         accept(RBRACE);
1727         return toP(t);
1728     }
1729 
1730     public JCBlock block() {
1731         return block(S.pos(), 0);
1732     }
1733 
1734     /** BlockStatements = { BlockStatement }
1735      *  BlockStatement  = LocalVariableDeclarationStatement
1736      *                  | ClassOrInterfaceOrEnumDeclaration
1737      *                  | [Ident ":"] Statement
1738      *  LocalVariableDeclarationStatement
1739      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
1740      */
1741     @SuppressWarnings("fallthrough")
1742     List<JCStatement> blockStatements() {
1743 //todo: skip to anchor on error(?)
1744         int lastErrPos = -1;
1745         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1746         while (true) {
1747             int pos = S.pos();
1748             switch (S.token()) {
1749             case RBRACE: case CASE: case DEFAULT: case EOF:
1750                 return stats.toList();
1751             case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
1752             case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
1753             case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
1754                 stats.append(parseStatement());
1755                 break;
1756             case MONKEYS_AT:
1757             case FINAL: {
1758                 String dc = S.docComment();
1759                 JCModifiers mods = modifiersOpt();
1760                 if (S.token() == INTERFACE ||
1761                     S.token() == CLASS ||
1762                     allowEnums && S.token() == ENUM) {
1763                     stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1764                 } else {
1765                     JCExpression t = parseType();
1766                     stats.appendList(variableDeclarators(mods, t,
1767                                                          new ListBuffer<JCStatement>()));
1768                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1769                     storeEnd(stats.elems.last(), S.endPos());
1770                     accept(SEMI);
1771                 }
1772                 break;
1773             }
1774             case ABSTRACT: case STRICTFP: {
1775                 String dc = S.docComment();
1776                 JCModifiers mods = modifiersOpt();
1777                 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1778                 break;
1779             }
1780             case INTERFACE:
1781             case CLASS:
1782                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1783                                                                S.docComment()));
1784                 break;
1785             case ENUM:
1786             case ASSERT:
1787                 if (allowEnums && S.token() == ENUM) {
1788                     log.error(S.pos(), "local.enum");
1789                     stats.
1790                         append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1791                                                                  S.docComment()));
1792                     break;
1793                 } else if (allowAsserts && S.token() == ASSERT) {
1794                     stats.append(parseStatement());
1795                     break;
1796                 }
1797                 /* fall through to default */
1798             default:
1799                 Name name = S.name();
1800                 JCExpression t = term(EXPR | TYPE);
1801                 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
1802                     S.nextToken();
1803                     JCStatement stat = parseStatement();
1804                     stats.append(F.at(pos).Labelled(name, stat));
1805                 } else if ((lastmode & TYPE) != 0 &&
1806                            (S.token() == IDENTIFIER ||
1807                             S.token() == ASSERT ||
1808                             S.token() == ENUM)) {
1809                     pos = S.pos();
1810                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1811                     F.at(pos);
1812                     stats.appendList(variableDeclarators(mods, t,
1813                                                          new ListBuffer<JCStatement>()));
1814                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1815                     storeEnd(stats.elems.last(), S.endPos());
1816                     accept(SEMI);
1817                 } else {
1818                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1819                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1820                     accept(SEMI);
1821                 }
1822             }
1823 
1824             // error recovery
1825             if (S.pos() == lastErrPos)
1826                 return stats.toList();
1827             if (S.pos() <= errorEndPos) {
1828                 skip(false, true, true, true);
1829                 lastErrPos = S.pos();
1830             }
1831 
1832             // ensure no dangling /** @deprecated */ active
1833             S.resetDeprecatedFlag();
1834         }
1835     }
1836 
1837     /** Statement =
1838      *       Block
1839      *     | IF ParExpression Statement [ELSE Statement]
1840      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1841      *     | FOR "(" FormalParameter : Expression ")" Statement
1842      *     | WHILE ParExpression Statement
1843      *     | DO Statement WHILE ParExpression ";"
1844      *     | TRY Block ( Catches | [Catches] FinallyPart )
1845      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1846      *     | SYNCHRONIZED ParExpression Block
1847      *     | RETURN [Expression] ";"
1848      *     | THROW Expression ";"
1849      *     | BREAK [Ident] ";"
1850      *     | CONTINUE [Ident] ";"
1851      *     | ASSERT Expression [ ":" Expression ] ";"
1852      *     | ";"
1853      *     | ExpressionStatement
1854      *     | Ident ":" Statement
1855      */
1856     @SuppressWarnings("fallthrough")
1857     public JCStatement parseStatement() {
1858         int pos = S.pos();
1859         switch (S.token()) {
1860         case LBRACE:
1861             return block();
1862         case IF: {
1863             S.nextToken();
1864             JCExpression cond = parExpression();
1865             JCStatement thenpart = parseStatement();
1866             JCStatement elsepart = null;
1867             if (S.token() == ELSE) {
1868                 S.nextToken();
1869                 elsepart = parseStatement();
1870             }
1871             return F.at(pos).If(cond, thenpart, elsepart);
1872         }
1873         case FOR: {
1874             S.nextToken();
1875             accept(LPAREN);
1876             List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
1877             if (inits.length() == 1 &&
1878                 inits.head.getTag() == JCTree.VARDEF &&
1879                 ((JCVariableDecl) inits.head).init == null &&
1880                 S.token() == COLON) {
1881                 checkForeach();
1882                 JCVariableDecl var = (JCVariableDecl)inits.head;
1883                 accept(COLON);
1884                 JCExpression expr = parseExpression();
1885                 accept(RPAREN);
1886                 JCStatement body = parseStatement();
1887                 return F.at(pos).ForeachLoop(var, expr, body);
1888             } else {
1889                 accept(SEMI);
1890                 JCExpression cond = S.token() == SEMI ? null : parseExpression();
1891                 accept(SEMI);
1892                 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1893                 accept(RPAREN);
1894                 JCStatement body = parseStatement();
1895                 return F.at(pos).ForLoop(inits, cond, steps, body);
1896             }
1897         }
1898         case WHILE: {
1899             S.nextToken();
1900             JCExpression cond = parExpression();
1901             JCStatement body = parseStatement();
1902             return F.at(pos).WhileLoop(cond, body);
1903         }
1904         case DO: {
1905             S.nextToken();
1906             JCStatement body = parseStatement();
1907             accept(WHILE);
1908             JCExpression cond = parExpression();
1909             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1910             accept(SEMI);
1911             return t;
1912         }
1913         case TRY: {
1914             S.nextToken();
1915             JCBlock body = block();
1916             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1917             JCBlock finalizer = null;
1918             if (S.token() == CATCH || S.token() == FINALLY) {
1919                 while (S.token() == CATCH) catchers.append(catchClause());
1920                 if (S.token() == FINALLY) {
1921                     S.nextToken();
1922                     finalizer = block();
1923                 }
1924             } else {
1925                 log.error(pos, "try.without.catch.or.finally");
1926             }
1927             return F.at(pos).Try(body, catchers.toList(), finalizer);
1928         }
1929         case SWITCH: {
1930             S.nextToken();
1931             JCExpression selector = parExpression();
1932             accept(LBRACE);
1933             List<JCCase> cases = switchBlockStatementGroups();
1934             JCSwitch t = to(F.at(pos).Switch(selector, cases));
1935             accept(RBRACE);
1936             return t;
1937         }
1938         case SYNCHRONIZED: {
1939             S.nextToken();
1940             JCExpression lock = parExpression();
1941             JCBlock body = block();
1942             return F.at(pos).Synchronized(lock, body);
1943         }
1944         case RETURN: {
1945             S.nextToken();
1946             JCExpression result = S.token() == SEMI ? null : parseExpression();
1947             JCReturn t = to(F.at(pos).Return(result));
1948             accept(SEMI);
1949             return t;
1950         }
1951         case THROW: {
1952             S.nextToken();
1953             JCExpression exc = parseExpression();
1954             JCThrow t = to(F.at(pos).Throw(exc));
1955             accept(SEMI);
1956             return t;
1957         }
1958         case BREAK: {
1959             S.nextToken();
1960             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1961             JCBreak t = to(F.at(pos).Break(label));
1962             accept(SEMI);
1963             return t;
1964         }
1965         case CONTINUE: {
1966             S.nextToken();
1967             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1968             JCContinue t =  to(F.at(pos).Continue(label));
1969             accept(SEMI);
1970             return t;
1971         }
1972         case SEMI:
1973             S.nextToken();
1974             return toP(F.at(pos).Skip());
1975         case ELSE:
1976             return toP(F.Exec(syntaxError("else.without.if")));
1977         case FINALLY:
1978             return toP(F.Exec(syntaxError("finally.without.try")));
1979         case CATCH:
1980             return toP(F.Exec(syntaxError("catch.without.try")));
1981         case ASSERT: {
1982             if (allowAsserts && S.token() == ASSERT) {
1983                 S.nextToken();
1984                 JCExpression assertion = parseExpression();
1985                 JCExpression message = null;
1986                 if (S.token() == COLON) {
1987                     S.nextToken();
1988                     message = parseExpression();
1989                 }
1990                 JCAssert t = to(F.at(pos).Assert(assertion, message));
1991                 accept(SEMI);
1992                 return t;
1993             }
1994             /* else fall through to default case */
1995         }
1996         case ENUM:
1997         default:
1998             Name name = S.name();
1999             JCExpression expr = parseExpression();
2000             if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
2001                 S.nextToken();
2002                 JCStatement stat = parseStatement();
2003                 return F.at(pos).Labelled(name, stat);
2004             } else {
2005                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2006                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
2007                 accept(SEMI);
2008                 return stat;
2009             }
2010         }
2011     }
2012 
2013     /** CatchClause     = CATCH "(" FormalParameter ")" Block
2014      */
2015     JCCatch catchClause() {
2016         int pos = S.pos();
2017         accept(CATCH);
2018         accept(LPAREN);
2019         JCModifiers mods = optFinal(Flags.PARAMETER);
2020         List<JCExpression> catchTypes = catchTypes();
2021         JCExpression paramType = catchTypes.size() > 1 ?
2022                 toP(F.at(catchTypes.head.getStartPosition()).TypeDisjoint(catchTypes)) :
2023                 catchTypes.head;
2024         JCVariableDecl formal = variableDeclaratorId(mods, paramType);
2025         accept(RPAREN);
2026         JCBlock body = block();
2027         return F.at(pos).Catch(formal, body);
2028     }
2029 
2030     List<JCExpression> catchTypes() {
2031         ListBuffer<JCExpression> catchTypes = ListBuffer.lb();
2032         catchTypes.add(parseType());
2033         while (S.token() == BAR) {
2034             checkMulticatch();
2035             S.nextToken();
2036             catchTypes.add(qualident());
2037         }
2038         return catchTypes.toList();
2039     }
2040 
2041     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2042      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2043      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2044      */
2045     List<JCCase> switchBlockStatementGroups() {
2046         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2047         while (true) {
2048             int pos = S.pos();
2049             switch (S.token()) {
2050             case CASE: {
2051                 S.nextToken();
2052                 JCExpression pat = parseExpression();
2053                 accept(COLON);
2054                 List<JCStatement> stats = blockStatements();
2055                 JCCase c = F.at(pos).Case(pat, stats);
2056                 if (stats.isEmpty())
2057                     storeEnd(c, S.prevEndPos());
2058                 cases.append(c);
2059                 break;
2060             }
2061             case DEFAULT: {
2062                 S.nextToken();
2063                 accept(COLON);
2064                 List<JCStatement> stats = blockStatements();
2065                 JCCase c = F.at(pos).Case(null, stats);
2066                 if (stats.isEmpty())
2067                     storeEnd(c, S.prevEndPos());
2068                 cases.append(c);
2069                 break;
2070             }
2071             case RBRACE: case EOF:
2072                 return cases.toList();
2073             default:
2074                 S.nextToken(); // to ensure progress
2075                 syntaxError(pos, "expected3",
2076                     CASE, DEFAULT, RBRACE);
2077             }
2078         }
2079     }
2080 
2081     /** MoreStatementExpressions = { COMMA StatementExpression }
2082      */
2083     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2084                                                                     JCExpression first,
2085                                                                     T stats) {
2086         // This Exec is a "StatementExpression"; it subsumes no terminating token
2087         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2088         while (S.token() == COMMA) {
2089             S.nextToken();
2090             pos = S.pos();
2091             JCExpression t = parseExpression();
2092             // This Exec is a "StatementExpression"; it subsumes no terminating token
2093             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2094         }
2095         return stats;
2096     }
2097 
2098     /** ForInit = StatementExpression MoreStatementExpressions
2099      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2100      */
2101     List<JCStatement> forInit() {
2102         ListBuffer<JCStatement> stats = lb();
2103         int pos = S.pos();
2104         if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2105             return variableDeclarators(optFinal(0), parseType(), stats).toList();
2106         } else {
2107             JCExpression t = term(EXPR | TYPE);
2108             if ((lastmode & TYPE) != 0 &&
2109                 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
2110                 return variableDeclarators(modifiersOpt(), t, stats).toList();
2111             else
2112                 return moreStatementExpressions(pos, t, stats).toList();
2113         }
2114     }
2115 
2116     /** ForUpdate = StatementExpression MoreStatementExpressions
2117      */
2118     List<JCExpressionStatement> forUpdate() {
2119         return moreStatementExpressions(S.pos(),
2120                                         parseExpression(),
2121                                         new ListBuffer<JCExpressionStatement>()).toList();
2122     }
2123 
2124     enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
2125 
2126     /** AnnotationsOpt = { '@' Annotation }
2127      */
2128     List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
2129         if (S.token() != MONKEYS_AT) return List.nil(); // optimization
2130         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2131         int prevmode = mode;
2132         while (S.token() == MONKEYS_AT) {
2133             int pos = S.pos();
2134             S.nextToken();
2135             buf.append(annotation(pos, kind));
2136         }
2137         lastmode = mode;
2138         mode = prevmode;
2139         List<JCAnnotation> annotations = buf.toList();
2140 
2141         if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
2142             System.out.println("TA: parsing " + annotations
2143                     + " in " + log.currentSourceFile());
2144         return annotations;
2145     }
2146 
2147     List<JCTypeAnnotation> typeAnnotationsOpt() {
2148         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
2149         return List.convert(JCTypeAnnotation.class, annotations);
2150     }
2151 
2152     /** ModifiersOpt = { Modifier }
2153      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2154      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2155      *           | "@" Annotation
2156      */
2157     JCModifiers modifiersOpt() {
2158         return modifiersOpt(null);
2159     }
2160     JCModifiers modifiersOpt(JCModifiers partial) {
2161         long flags;
2162         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2163         int pos;
2164         if (partial == null) {
2165             flags = 0;
2166             pos = S.pos();
2167         } else {
2168             flags = partial.flags;
2169             annotations.appendList(partial.annotations);
2170             pos = partial.pos;
2171         }
2172         if (S.deprecatedFlag()) {
2173             flags |= Flags.DEPRECATED;
2174             S.resetDeprecatedFlag();
2175         }
2176         int lastPos = Position.NOPOS;
2177     loop:
2178         while (true) {
2179             long flag;
2180             switch (S.token()) {
2181             case PRIVATE     : flag = Flags.PRIVATE; break;
2182             case PROTECTED   : flag = Flags.PROTECTED; break;
2183             case PUBLIC      : flag = Flags.PUBLIC; break;
2184             case STATIC      : flag = Flags.STATIC; break;
2185             case TRANSIENT   : flag = Flags.TRANSIENT; break;
2186             case FINAL       : flag = Flags.FINAL; break;
2187             case ABSTRACT    : flag = Flags.ABSTRACT; break;
2188             case NATIVE      : flag = Flags.NATIVE; break;
2189             case VOLATILE    : flag = Flags.VOLATILE; break;
2190             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2191             case STRICTFP    : flag = Flags.STRICTFP; break;
2192             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2193             default: break loop;
2194             }
2195             if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
2196             lastPos = S.pos();
2197             S.nextToken();
2198             if (flag == Flags.ANNOTATION) {
2199                 checkAnnotations();
2200                 if (S.token() != INTERFACE) {
2201                     JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
2202                     // if first modifier is an annotation, set pos to annotation's.
2203                     if (flags == 0 && annotations.isEmpty())
2204                         pos = ann.pos;
2205                     annotations.append(ann);
2206                     lastPos = ann.pos;
2207                     flag = 0;
2208                 }
2209             }
2210             flags |= flag;
2211         }
2212         switch (S.token()) {
2213         case ENUM: flags |= Flags.ENUM; break;
2214         case INTERFACE: flags |= Flags.INTERFACE; break;
2215         default: break;
2216         }
2217 
2218         /* A modifiers tree with no modifier tokens or annotations
2219          * has no text position. */
2220         if ((flags & Flags.ModifierFlags) == 0 && annotations.isEmpty())
2221             pos = Position.NOPOS;
2222 
2223         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2224         if (pos != Position.NOPOS)
2225             storeEnd(mods, S.prevEndPos());
2226         return mods;
2227     }
2228 
2229     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2230      * @param pos position of "@" token
2231      */
2232     JCAnnotation annotation(int pos, AnnotationKind kind) {
2233         // accept(AT); // AT consumed by caller
2234         checkAnnotations();
2235         if (kind == AnnotationKind.TYPE_ANNO)
2236             checkTypeAnnotations();
2237         JCTree ident = qualident();
2238         List<JCExpression> fieldValues = annotationFieldValuesOpt();
2239         JCAnnotation ann;
2240         if (kind == AnnotationKind.DEFAULT_ANNO)
2241             ann = F.at(pos).Annotation(ident, fieldValues);
2242         else
2243             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2244         storeEnd(ann, S.prevEndPos());
2245         return ann;
2246     }
2247 
2248     List<JCExpression> annotationFieldValuesOpt() {
2249         return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2250     }
2251 
2252     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2253     List<JCExpression> annotationFieldValues() {
2254         accept(LPAREN);
2255         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2256         if (S.token() != RPAREN) {
2257             buf.append(annotationFieldValue());
2258             while (S.token() == COMMA) {
2259                 S.nextToken();
2260                 buf.append(annotationFieldValue());
2261             }
2262         }
2263         accept(RPAREN);
2264         return buf.toList();
2265     }
2266 
2267     /** AnnotationFieldValue    = AnnotationValue
2268      *                          | Identifier "=" AnnotationValue
2269      */
2270     JCExpression annotationFieldValue() {
2271         if (S.token() == IDENTIFIER) {
2272             mode = EXPR;
2273             JCExpression t1 = term1();
2274             if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
2275                 int pos = S.pos();
2276                 accept(EQ);
2277                 JCExpression v = annotationValue();
2278                 return toP(F.at(pos).Assign(t1, v));
2279             } else {
2280                 return t1;
2281             }
2282         }
2283         return annotationValue();
2284     }
2285 
2286     /* AnnotationValue          = ConditionalExpression
2287      *                          | Annotation
2288      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2289      */
2290     JCExpression annotationValue() {
2291         int pos;
2292         switch (S.token()) {
2293         case MONKEYS_AT:
2294             pos = S.pos();
2295             S.nextToken();
2296             return annotation(pos, AnnotationKind.DEFAULT_ANNO);
2297         case LBRACE:
2298             pos = S.pos();
2299             accept(LBRACE);
2300             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2301             if (S.token() != RBRACE) {
2302                 buf.append(annotationValue());
2303                 while (S.token() == COMMA) {
2304                     S.nextToken();
2305                     if (S.token() == RBRACE) break;
2306                     buf.append(annotationValue());
2307                 }
2308             }
2309             accept(RBRACE);
2310             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2311         default:
2312             mode = EXPR;
2313             return term1();
2314         }
2315     }
2316 
2317     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2318      */
2319     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2320                                                                          JCExpression type,
2321                                                                          T vdefs)
2322     {
2323         return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
2324     }
2325 
2326     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2327      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2328      *
2329      *  @param reqInit  Is an initializer always required?
2330      *  @param dc       The documentation comment for the variable declarations, or null.
2331      */
2332     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2333                                                                      JCModifiers mods,
2334                                                                      JCExpression type,
2335                                                                      Name name,
2336                                                                      boolean reqInit,
2337                                                                      String dc,
2338                                                                      T vdefs)
2339     {
2340         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2341         while (S.token() == COMMA) {
2342             // All but last of multiple declarators subsume a comma
2343             storeEnd((JCTree)vdefs.elems.last(), S.endPos());
2344             S.nextToken();
2345             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2346         }
2347         return vdefs;
2348     }
2349 
2350     /** VariableDeclarator = Ident VariableDeclaratorRest
2351      *  ConstantDeclarator = Ident ConstantDeclaratorRest
2352      */
2353     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
2354         return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
2355     }
2356 
2357     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2358      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2359      *
2360      *  @param reqInit  Is an initializer always required?
2361      *  @param dc       The documentation comment for the variable declarations, or null.
2362      */
2363     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2364                                   boolean reqInit, String dc) {
2365         type = bracketsOpt(type);
2366         JCExpression init = null;
2367         if (S.token() == EQ) {
2368             S.nextToken();
2369             init = variableInitializer();
2370         }
2371         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2372         JCVariableDecl result =
2373             toP(F.at(pos).VarDef(mods, name, type, init));
2374         attach(result, dc);
2375         return result;
2376     }
2377 
2378     /** VariableDeclaratorId = Ident BracketsOpt
2379      */
2380     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2381         int pos = S.pos();
2382         Name name = ident();
2383         if ((mods.flags & Flags.VARARGS) == 0)
2384             type = bracketsOpt(type);
2385         return toP(F.at(pos).VarDef(mods, name, type, null));
2386     }
2387 
2388     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2389      */
2390     public JCTree.JCCompilationUnit parseCompilationUnit() {
2391         int pos = S.pos();
2392         JCExpression pid = null;
2393         String dc = S.docComment();
2394         JCModifiers mods = null;
2395         List<JCAnnotation> packageAnnotations = List.nil();
2396         if (S.token() == MONKEYS_AT)
2397             mods = modifiersOpt();
2398 
2399         if (S.token() == PACKAGE) {
2400             if (mods != null) {
2401                 checkNoMods(mods.flags);
2402                 packageAnnotations = mods.annotations;
2403                 mods = null;
2404             }
2405             S.nextToken();
2406             pid = qualident();
2407             accept(SEMI);
2408         }
2409         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2410         boolean checkForImports = true;
2411         while (S.token() != EOF) {
2412             if (S.pos() <= errorEndPos) {
2413                 // error recovery
2414                 skip(checkForImports, false, false, false);
2415                 if (S.token() == EOF)
2416                     break;
2417             }
2418             if (checkForImports && mods == null && S.token() == IMPORT) {
2419                 defs.append(importDeclaration());
2420             } else {
2421                 JCTree def = typeDeclaration(mods);
2422                 if (def instanceof JCExpressionStatement)
2423                     def = ((JCExpressionStatement)def).expr;
2424                 defs.append(def);
2425                 if (def instanceof JCClassDecl)
2426                     checkForImports = false;
2427                 mods = null;
2428             }
2429         }
2430         JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
2431         attach(toplevel, dc);
2432         if (defs.elems.isEmpty())
2433             storeEnd(toplevel, S.prevEndPos());
2434         if (keepDocComments)
2435             toplevel.docComments = docComments;
2436         if (keepLineMap)
2437             toplevel.lineMap = S.getLineMap();
2438         return toplevel;
2439     }
2440 
2441     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2442      */
2443     JCTree importDeclaration() {
2444         int pos = S.pos();
2445         S.nextToken();
2446         boolean importStatic = false;
2447         if (S.token() == STATIC) {
2448             checkStaticImports();
2449             importStatic = true;
2450             S.nextToken();
2451         }
2452         JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
2453         do {
2454             int pos1 = S.pos();
2455             accept(DOT);
2456             if (S.token() == STAR) {
2457                 pid = to(F.at(pos1).Select(pid, names.asterisk));
2458                 S.nextToken();
2459                 break;
2460             } else {
2461                 pid = toP(F.at(pos1).Select(pid, ident()));
2462             }
2463         } while (S.token() == DOT);
2464         accept(SEMI);
2465         return toP(F.at(pos).Import(pid, importStatic));
2466     }
2467 
2468     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
2469      *                  | ";"
2470      */
2471     JCTree typeDeclaration(JCModifiers mods) {
2472         int pos = S.pos();
2473         if (mods == null && S.token() == SEMI) {
2474             S.nextToken();
2475             return toP(F.at(pos).Skip());
2476         } else {
2477             String dc = S.docComment();
2478             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
2479         }
2480     }
2481 
2482     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
2483      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
2484      *  @param mods     Any modifiers starting the class or interface declaration
2485      *  @param dc       The documentation comment for the class, or null.
2486      */
2487     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
2488         if (S.token() == CLASS) {
2489             return classDeclaration(mods, dc);
2490         } else if (S.token() == INTERFACE) {
2491             return interfaceDeclaration(mods, dc);
2492         } else if (allowEnums) {
2493             if (S.token() == ENUM) {
2494                 return enumDeclaration(mods, dc);
2495             } else {
2496                 int pos = S.pos();
2497                 List<JCTree> errs;
2498                 if (S.token() == IDENTIFIER) {
2499                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2500                     setErrorEndPos(S.pos());
2501                 } else {
2502                     errs = List.<JCTree>of(mods);
2503                 }
2504                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
2505                                               CLASS, INTERFACE, ENUM)));
2506             }
2507         } else {
2508             if (S.token() == ENUM) {
2509                 log.error(S.pos(), "enums.not.supported.in.source", source.name);
2510                 allowEnums = true;
2511                 return enumDeclaration(mods, dc);
2512             }
2513             int pos = S.pos();
2514             List<JCTree> errs;
2515             if (S.token() == IDENTIFIER) {
2516                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2517                 setErrorEndPos(S.pos());
2518             } else {
2519                 errs = List.<JCTree>of(mods);
2520             }
2521             return toP(F.Exec(syntaxError(pos, errs, "expected2",
2522                                           CLASS, INTERFACE)));
2523         }
2524     }
2525 
2526     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
2527      *                     [IMPLEMENTS TypeList] ClassBody
2528      *  @param mods    The modifiers starting the class declaration
2529      *  @param dc       The documentation comment for the class, or null.
2530      */
2531     JCClassDecl classDeclaration(JCModifiers mods, String dc) {
2532         int pos = S.pos();
2533         accept(CLASS);
2534         Name name = ident();
2535 
2536         List<JCTypeParameter> typarams = typeParametersOpt();
2537 
2538         JCTree extending = null;
2539         if (S.token() == EXTENDS) {
2540             S.nextToken();
2541             extending = parseType();
2542         }
2543         List<JCExpression> implementing = List.nil();
2544         if (S.token() == IMPLEMENTS) {
2545             S.nextToken();
2546             implementing = typeList();
2547         }
2548         List<JCTree> defs = classOrInterfaceBody(name, false);
2549         JCClassDecl result = toP(F.at(pos).ClassDef(
2550             mods, name, typarams, extending, implementing, defs));
2551         attach(result, dc);
2552         return result;
2553     }
2554 
2555     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
2556      *                         [EXTENDS TypeList] InterfaceBody
2557      *  @param mods    The modifiers starting the interface declaration
2558      *  @param dc       The documentation comment for the interface, or null.
2559      */
2560     JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
2561         int pos = S.pos();
2562         accept(INTERFACE);
2563         Name name = ident();
2564 
2565         List<JCTypeParameter> typarams = typeParametersOpt();
2566 
2567         List<JCExpression> extending = List.nil();
2568         if (S.token() == EXTENDS) {
2569             S.nextToken();
2570             extending = typeList();
2571         }
2572         List<JCTree> defs = classOrInterfaceBody(name, true);
2573         JCClassDecl result = toP(F.at(pos).ClassDef(
2574             mods, name, typarams, null, extending, defs));
2575         attach(result, dc);
2576         return result;
2577     }
2578 
2579     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
2580      *  @param mods    The modifiers starting the enum declaration
2581      *  @param dc       The documentation comment for the enum, or null.
2582      */
2583     JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
2584         int pos = S.pos();
2585         accept(ENUM);
2586         Name name = ident();
2587 
2588         List<JCExpression> implementing = List.nil();
2589         if (S.token() == IMPLEMENTS) {
2590             S.nextToken();
2591             implementing = typeList();
2592         }
2593 
2594         List<JCTree> defs = enumBody(name);
2595         mods.flags |= Flags.ENUM;
2596         JCClassDecl result = toP(F.at(pos).
2597             ClassDef(mods, name, List.<JCTypeParameter>nil(),
2598                 null, implementing, defs));
2599         attach(result, dc);
2600         return result;
2601     }
2602 
2603     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
2604      *                  [ ";" {ClassBodyDeclaration} ] "}"
2605      */
2606     List<JCTree> enumBody(Name enumName) {
2607         accept(LBRACE);
2608         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2609         if (S.token() == COMMA) {
2610             S.nextToken();
2611         } else if (S.token() != RBRACE && S.token() != SEMI) {
2612             defs.append(enumeratorDeclaration(enumName));
2613             while (S.token() == COMMA) {
2614                 S.nextToken();
2615                 if (S.token() == RBRACE || S.token() == SEMI) break;
2616                 defs.append(enumeratorDeclaration(enumName));
2617             }
2618             if (S.token() != SEMI && S.token() != RBRACE) {
2619                 defs.append(syntaxError(S.pos(), "expected3",
2620                                 COMMA, RBRACE, SEMI));
2621                 S.nextToken();
2622             }
2623         }
2624         if (S.token() == SEMI) {
2625             S.nextToken();
2626             while (S.token() != RBRACE && S.token() != EOF) {
2627                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
2628                                                                 false));
2629                 if (S.pos() <= errorEndPos) {
2630                     // error recovery
2631                    skip(false, true, true, false);
2632                 }
2633             }
2634         }
2635         accept(RBRACE);
2636         return defs.toList();
2637     }
2638 
2639     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
2640      */
2641     JCTree enumeratorDeclaration(Name enumName) {
2642         String dc = S.docComment();
2643         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
2644         if (S.deprecatedFlag()) {
2645             flags |= Flags.DEPRECATED;
2646             S.resetDeprecatedFlag();
2647         }
2648         int pos = S.pos();
2649         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2650         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
2651         List<JCExpression> typeArgs = typeArgumentsOpt();
2652         int identPos = S.pos();
2653         Name name = ident();
2654         int createPos = S.pos();
2655         List<JCExpression> args = (S.token() == LPAREN)
2656             ? arguments() : List.<JCExpression>nil();
2657         JCClassDecl body = null;
2658         if (S.token() == LBRACE) {
2659             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
2660             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2661             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
2662         }
2663         if (args.isEmpty() && body == null)
2664             createPos = identPos;
2665         JCIdent ident = F.at(identPos).Ident(enumName);
2666         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
2667         if (createPos != identPos)
2668             storeEnd(create, S.prevEndPos());
2669         ident = F.at(identPos).Ident(enumName);
2670         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
2671         attach(result, dc);
2672         return result;
2673     }
2674 
2675     /** TypeList = Type {"," Type}
2676      */
2677     List<JCExpression> typeList() {
2678         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2679         ts.append(parseType());
2680         while (S.token() == COMMA) {
2681             S.nextToken();
2682             ts.append(parseType());
2683         }
2684         return ts.toList();
2685     }
2686 
2687     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
2688      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2689      */
2690     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
2691         accept(LBRACE);
2692         if (S.pos() <= errorEndPos) {
2693             // error recovery
2694             skip(false, true, false, false);
2695             if (S.token() == LBRACE)
2696                 S.nextToken();
2697         }
2698         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2699         while (S.token() != RBRACE && S.token() != EOF) {
2700             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
2701             if (S.pos() <= errorEndPos) {
2702                // error recovery
2703                skip(false, true, true, false);
2704            }
2705         }
2706         accept(RBRACE);
2707         return defs.toList();
2708     }
2709 
2710     /** ClassBodyDeclaration =
2711      *      ";"
2712      *    | [STATIC] Block
2713      *    | ModifiersOpt
2714      *      ( Type Ident
2715      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
2716      *      | VOID Ident MethodDeclaratorRest
2717      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
2718      *      | Ident ConstructorDeclaratorRest
2719      *      | TypeParameters Ident ConstructorDeclaratorRest
2720      *      | ClassOrInterfaceOrEnumDeclaration
2721      *      )
2722      *  InterfaceBodyDeclaration =
2723      *      ";"
2724      *    | ModifiersOpt Type Ident
2725      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
2726      */
2727     List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
2728         if (S.token() == SEMI) {
2729             S.nextToken();
2730             return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
2731         } else {
2732             String dc = S.docComment();
2733             int pos = S.pos();
2734             JCModifiers mods = modifiersOpt();
2735             if (S.token() == CLASS ||
2736                 S.token() == INTERFACE ||
2737                 allowEnums && S.token() == ENUM) {
2738                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
2739             } else if (S.token() == LBRACE && !isInterface &&
2740                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
2741                        mods.annotations.isEmpty()) {
2742                 return List.<JCTree>of(block(pos, mods.flags));
2743             } else {
2744                 pos = S.pos();
2745                 List<JCTypeParameter> typarams = typeParametersOpt();
2746                 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2747 
2748                 Name name = S.name();
2749                 pos = S.pos();
2750                 JCExpression type;
2751                 boolean isVoid = S.token() == VOID;
2752                 if (isVoid) {
2753                     if (annosAfterParams.nonEmpty())
2754                         illegal(annosAfterParams.head.pos);
2755                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2756                     S.nextToken();
2757                 } else {
2758                     if (annosAfterParams.nonEmpty()) {
2759                         mods.annotations = mods.annotations.appendList(annosAfterParams);
2760                         if (mods.pos == Position.NOPOS)
2761                             mods.pos = mods.annotations.head.pos;
2762                     }
2763                     // method returns types are un-annotated types
2764                     type = unannotatedType();
2765                 }
2766                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2767                     if (isInterface || name != className)
2768                         log.error(pos, "invalid.meth.decl.ret.type.req");
2769                     return List.of(methodDeclaratorRest(
2770                         pos, mods, null, names.init, typarams,
2771                         isInterface, true, dc));
2772                 } else {
2773                     pos = S.pos();
2774                     name = ident();
2775                     if (S.token() == LPAREN) {
2776                         return List.of(methodDeclaratorRest(
2777                             pos, mods, type, name, typarams,
2778                             isInterface, isVoid, dc));
2779                     } else if (!isVoid && typarams.isEmpty()) {
2780                         List<JCTree> defs =
2781                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2782                                                     new ListBuffer<JCTree>()).toList();
2783                         storeEnd(defs.last(), S.endPos());
2784                         accept(SEMI);
2785                         return defs;
2786                     } else {
2787                         pos = S.pos();
2788                         List<JCTree> err = isVoid
2789                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
2790                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
2791                             : null;
2792                         return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
2793                     }
2794                 }
2795             }
2796         }
2797     }
2798 
2799     /** MethodDeclaratorRest =
2800      *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2801      *  VoidMethodDeclaratorRest =
2802      *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
2803      *  InterfaceMethodDeclaratorRest =
2804      *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
2805      *  VoidInterfaceMethodDeclaratorRest =
2806      *      FormalParameters [Annotations] [THROWS TypeList] ";"
2807      *  ConstructorDeclaratorRest =
2808      *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
2809      */
2810     JCTree methodDeclaratorRest(int pos,
2811                               JCModifiers mods,
2812                               JCExpression type,
2813                               Name name,
2814                               List<JCTypeParameter> typarams,
2815                               boolean isInterface, boolean isVoid,
2816                               String dc) {
2817         List<JCVariableDecl> params = formalParameters();
2818 
2819         List<JCTypeAnnotation> receiverAnnotations;
2820         if (!isVoid) {
2821             // need to distinguish between receiver anno and array anno
2822             // look at typeAnnotationsPushedBack comment
2823             this.permitTypeAnnotationsPushBack = true;
2824             type = methodReturnArrayRest(type);
2825             this.permitTypeAnnotationsPushBack = false;
2826             if (typeAnnotationsPushedBack == null)
2827                 receiverAnnotations = List.nil();
2828             else
2829                 receiverAnnotations = typeAnnotationsPushedBack;
2830             typeAnnotationsPushedBack = null;
2831         } else
2832             receiverAnnotations = typeAnnotationsOpt();
2833 
2834         List<JCExpression> thrown = List.nil();
2835         if (S.token() == THROWS) {
2836             S.nextToken();
2837             thrown = qualidentList();
2838         }
2839         JCBlock body = null;
2840         JCExpression defaultValue;
2841         if (S.token() == LBRACE) {
2842             body = block();
2843             defaultValue = null;
2844         } else {
2845             if (S.token() == DEFAULT) {
2846                 accept(DEFAULT);
2847                 defaultValue = annotationValue();
2848             } else {
2849                 defaultValue = null;
2850             }
2851             accept(SEMI);
2852             if (S.pos() <= errorEndPos) {
2853                 // error recovery
2854                 skip(false, true, false, false);
2855                 if (S.token() == LBRACE) {
2856                     body = block();
2857                 }
2858             }
2859         }
2860 
2861         JCMethodDecl result =
2862             toP(F.at(pos).MethodDef(mods, name, type, typarams,
2863                                     params, receiverAnnotations, thrown,
2864                                     body, defaultValue));
2865         attach(result, dc);
2866         return result;
2867     }
2868 
2869     /** Parses the array levels after the format parameters list, and append
2870      * them to the return type, while preseving the order of type annotations
2871      */
2872     private JCExpression methodReturnArrayRest(JCExpression type) {
2873         if (type.getTag() != JCTree.TYPEARRAY)
2874             return bracketsOpt(type);
2875 
2876         JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
2877         while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
2878             baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
2879 
2880         if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
2881             JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
2882             at.underlyingType = bracketsOpt(at.underlyingType);
2883         } else {
2884             baseArray.elemtype = bracketsOpt(baseArray.elemtype);
2885         }
2886 
2887         return type;
2888     }
2889 
2890     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
2891      */
2892     List<JCExpression> qualidentList() {
2893         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2894 
2895         List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
2896         if (!typeAnnos.isEmpty())
2897             ts.append(F.AnnotatedType(typeAnnos, qualident()));
2898         else
2899             ts.append(qualident());
2900         while (S.token() == COMMA) {
2901             S.nextToken();
2902 
2903             typeAnnos = typeAnnotationsOpt();
2904             if (!typeAnnos.isEmpty())
2905                 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2906             else
2907                 ts.append(qualident());
2908         }
2909         return ts.toList();
2910     }
2911 
2912     /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2913      */
2914     List<JCTypeParameter> typeParametersOpt() {
2915         if (S.token() == LT) {
2916             checkGenerics();
2917             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
2918             S.nextToken();
2919             typarams.append(typeParameter());
2920             while (S.token() == COMMA) {
2921                 S.nextToken();
2922                 typarams.append(typeParameter());
2923             }
2924             accept(GT);
2925             return typarams.toList();
2926         } else {
2927             return List.nil();
2928         }
2929     }
2930 
2931     /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
2932      *  TypeParameterBound = EXTENDS Type {"&" Type}
2933      *  TypeVariable = Ident
2934      */
2935     JCTypeParameter typeParameter() {
2936         int pos = S.pos();
2937         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
2938         Name name = ident();
2939         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
2940         if (S.token() == EXTENDS) {
2941             S.nextToken();
2942             bounds.append(parseType());
2943             while (S.token() == AMP) {
2944                 S.nextToken();
2945                 bounds.append(parseType());
2946             }
2947         }
2948         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
2949     }
2950 
2951     /** FormalParameters = "(" [ FormalParameterList ] ")"
2952      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
2953      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
2954      */
2955     List<JCVariableDecl> formalParameters() {
2956         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
2957         JCVariableDecl lastParam = null;
2958         accept(LPAREN);
2959         if (S.token() != RPAREN) {
2960             params.append(lastParam = formalParameter());
2961             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
2962                 S.nextToken();
2963                 params.append(lastParam = formalParameter());
2964             }
2965         }
2966         accept(RPAREN);
2967         return params.toList();
2968     }
2969 
2970     JCModifiers optFinal(long flags) {
2971         JCModifiers mods = modifiersOpt();
2972         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
2973         mods.flags |= flags;
2974         return mods;
2975     }
2976 
2977     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
2978      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
2979      */
2980     JCVariableDecl formalParameter() {
2981         JCModifiers mods = optFinal(Flags.PARAMETER);
2982         // need to distinguish between vararg annos and array annos
2983         // look at typeAnnotaitonsPushedBack comment
2984         this.permitTypeAnnotationsPushBack = true;
2985         JCExpression type = parseType();
2986         this.permitTypeAnnotationsPushBack = false;
2987 
2988         if (S.token() == ELLIPSIS) {
2989             List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
2990             typeAnnotationsPushedBack = null;
2991             checkVarargs();
2992             mods.flags |= Flags.VARARGS;
2993             // insert var arg type annotations
2994             if (varargsAnnos != null && varargsAnnos.nonEmpty())
2995                 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
2996             type = to(F.at(S.pos()).TypeArray(type));
2997 
2998             S.nextToken();
2999         } else {
3000             // if not a var arg, then typeAnnotationsPushedBack should be null
3001             if (typeAnnotationsPushedBack != null
3002                     && !typeAnnotationsPushedBack.isEmpty()) {
3003                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3004                         "illegal.start.of.type");
3005             }
3006             typeAnnotationsPushedBack = null;
3007         }
3008         return variableDeclaratorId(mods, type);
3009     }
3010 
3011 /* ---------- auxiliary methods -------------- */
3012 
3013     /** Check that given tree is a legal expression statement.
3014      */
3015     protected JCExpression checkExprStat(JCExpression t) {
3016         switch(t.getTag()) {
3017         case JCTree.PREINC: case JCTree.PREDEC:
3018         case JCTree.POSTINC: case JCTree.POSTDEC:
3019         case JCTree.ASSIGN:
3020         case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
3021         case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
3022         case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
3023         case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
3024         case JCTree.APPLY: case JCTree.NEWCLASS:
3025         case JCTree.ERRONEOUS:
3026             return t;
3027         default:
3028             log.error(t.pos, "not.stmt");
3029             return F.at(t.pos).Erroneous(List.<JCTree>of(t));
3030         }
3031     }
3032 
3033     /** Return precedence of operator represented by token,
3034      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
3035      */
3036     static int prec(Token token) {
3037         int oc = optag(token);
3038         return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
3039     }
3040 
3041     /**
3042      * Return the lesser of two positions, making allowance for either one
3043      * being unset.
3044      */
3045     static int earlier(int pos1, int pos2) {
3046         if (pos1 == Position.NOPOS)
3047             return pos2;
3048         if (pos2 == Position.NOPOS)
3049             return pos1;
3050         return (pos1 < pos2 ? pos1 : pos2);
3051     }
3052 
3053     /** Return operation tag of binary operator represented by token,
3054      *  -1 if token is not a binary operator.
3055      */
3056     static int optag(Token token) {
3057         switch (token) {
3058         case BARBAR:
3059             return JCTree.OR;
3060         case AMPAMP:
3061             return JCTree.AND;
3062         case BAR:
3063             return JCTree.BITOR;
3064         case BAREQ:
3065             return JCTree.BITOR_ASG;
3066         case CARET:
3067             return JCTree.BITXOR;
3068         case CARETEQ:
3069             return JCTree.BITXOR_ASG;
3070         case AMP:
3071             return JCTree.BITAND;
3072         case AMPEQ:
3073             return JCTree.BITAND_ASG;
3074         case EQEQ:
3075             return JCTree.EQ;
3076         case BANGEQ:
3077             return JCTree.NE;
3078         case LT:
3079             return JCTree.LT;
3080         case GT:
3081             return JCTree.GT;
3082         case LTEQ:
3083             return JCTree.LE;
3084         case GTEQ:
3085             return JCTree.GE;
3086         case LTLT:
3087             return JCTree.SL;
3088         case LTLTEQ:
3089             return JCTree.SL_ASG;
3090         case GTGT:
3091             return JCTree.SR;
3092         case GTGTEQ:
3093             return JCTree.SR_ASG;
3094         case GTGTGT:
3095             return JCTree.USR;
3096         case GTGTGTEQ:
3097             return JCTree.USR_ASG;
3098         case PLUS:
3099             return JCTree.PLUS;
3100         case PLUSEQ:
3101             return JCTree.PLUS_ASG;
3102         case SUB:
3103             return JCTree.MINUS;
3104         case SUBEQ:
3105             return JCTree.MINUS_ASG;
3106         case STAR:
3107             return JCTree.MUL;
3108         case STAREQ:
3109             return JCTree.MUL_ASG;
3110         case SLASH:
3111             return JCTree.DIV;
3112         case SLASHEQ:
3113             return JCTree.DIV_ASG;
3114         case PERCENT:
3115             return JCTree.MOD;
3116         case PERCENTEQ:
3117             return JCTree.MOD_ASG;
3118         case INSTANCEOF:
3119             return JCTree.TYPETEST;
3120         default:
3121             return -1;
3122         }
3123     }
3124 
3125     /** Return operation tag of unary operator represented by token,
3126      *  -1 if token is not a binary operator.
3127      */
3128     static int unoptag(Token token) {
3129         switch (token) {
3130         case PLUS:
3131             return JCTree.POS;
3132         case SUB:
3133             return JCTree.NEG;
3134         case BANG:
3135             return JCTree.NOT;
3136         case TILDE:
3137             return JCTree.COMPL;
3138         case PLUSPLUS:
3139             return JCTree.PREINC;
3140         case SUBSUB:
3141             return JCTree.PREDEC;
3142         default:
3143             return -1;
3144         }
3145     }
3146 
3147     /** Return type tag of basic type represented by token,
3148      *  -1 if token is not a basic type identifier.
3149      */
3150     static int typetag(Token token) {
3151         switch (token) {
3152         case BYTE:
3153             return TypeTags.BYTE;
3154         case CHAR:
3155             return TypeTags.CHAR;
3156         case SHORT:
3157             return TypeTags.SHORT;
3158         case INT:
3159             return TypeTags.INT;
3160         case LONG:
3161             return TypeTags.LONG;
3162         case FLOAT:
3163             return TypeTags.FLOAT;
3164         case DOUBLE:
3165             return TypeTags.DOUBLE;
3166         case BOOLEAN:
3167             return TypeTags.BOOLEAN;
3168         default:
3169             return -1;
3170         }
3171     }
3172 
3173     void checkGenerics() {
3174         if (!allowGenerics) {
3175             log.error(S.pos(), "generics.not.supported.in.source", source.name);
3176             allowGenerics = true;
3177         }
3178     }
3179     void checkVarargs() {
3180         if (!allowVarargs) {
3181             log.error(S.pos(), "varargs.not.supported.in.source", source.name);
3182             allowVarargs = true;
3183         }
3184     }
3185     void checkForeach() {
3186         if (!allowForeach) {
3187             log.error(S.pos(), "foreach.not.supported.in.source", source.name);
3188             allowForeach = true;
3189         }
3190     }
3191     void checkStaticImports() {
3192         if (!allowStaticImport) {
3193             log.error(S.pos(), "static.import.not.supported.in.source", source.name);
3194             allowStaticImport = true;
3195         }
3196     }
3197     void checkAnnotations() {
3198         if (!allowAnnotations) {
3199             log.error(S.pos(), "annotations.not.supported.in.source", source.name);
3200             allowAnnotations = true;
3201         }
3202     }
3203     void checkTypeAnnotations() {
3204         if (!allowTypeAnnotations) {
3205             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3206             allowTypeAnnotations = true;
3207         }
3208     }
3209     void checkDiamond() {
3210         if (!allowDiamond) {
3211             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3212             allowDiamond = true;
3213         }
3214     }
3215     void checkMulticatch() {
3216         if (!allowMulticatch) {
3217             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3218             allowMulticatch = true;
3219             }
3220     }
3221 }