Source Code Cross Referenced for Parser.java in  » 6.0-JDK-Modules-com.sun » tools » com » sun » tools » javac » parser » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun » tools » com.sun.tools.javac.parser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.tools.javac.parser;
0027:
0028:        import java.util.*;
0029:
0030:        import com.sun.tools.javac.tree.*;
0031:        import com.sun.tools.javac.code.*;
0032:        import com.sun.tools.javac.util.*;
0033:        import com.sun.tools.javac.util.List;
0034:        import static com.sun.tools.javac.util.ListBuffer.lb;
0035:
0036:        import com.sun.tools.javac.tree.JCTree.*;
0037:
0038:        import static com.sun.tools.javac.parser.Token.*;
0039:
0040:        /** The parser maps a token sequence into an abstract syntax
0041:         *  tree. It operates by recursive descent, with code derived
0042:         *  systematically from an LL(1) grammar. For efficiency reasons, an
0043:         *  operator precedence scheme is used for parsing binary operation
0044:         *  expressions.
0045:         *
0046:         *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
0047:         *  you write code that depends on this, you do so at your own risk.
0048:         *  This code and its internal interfaces are subject to change or
0049:         *  deletion without notice.</b>
0050:         */
0051:        @Version("@(#)Parser.java	1.108 07/06/14")
0052:        public class Parser {
0053:
0054:            /** A factory for creating parsers. */
0055:            public static class Factory {
0056:                /** The context key for the parser factory. */
0057:                protected static final Context.Key<Parser.Factory> parserFactoryKey = new Context.Key<Parser.Factory>();
0058:
0059:                /** Get the Factory instance for this context. */
0060:                public static Factory instance(Context context) {
0061:                    Factory instance = context.get(parserFactoryKey);
0062:                    if (instance == null)
0063:                        instance = new Factory(context);
0064:                    return instance;
0065:                }
0066:
0067:                final TreeMaker F;
0068:                final Log log;
0069:                final Keywords keywords;
0070:                final Source source;
0071:                final Name.Table names;
0072:                final Options options;
0073:
0074:                /** Create a new parser factory. */
0075:                protected Factory(Context context) {
0076:                    context.put(parserFactoryKey, this );
0077:                    this .F = TreeMaker.instance(context);
0078:                    this .log = Log.instance(context);
0079:                    this .names = Name.Table.instance(context);
0080:                    this .keywords = Keywords.instance(context);
0081:                    this .source = Source.instance(context);
0082:                    this .options = Options.instance(context);
0083:                }
0084:
0085:                /**
0086:                 * Create a new Parser.
0087:                 * @param S Lexer for getting tokens while parsing
0088:                 * @param keepDocComments true if javadoc comments should be kept
0089:                 * @param genEndPos true if end positions should be generated
0090:                 */
0091:                public Parser newParser(Lexer S, boolean keepDocComments,
0092:                        boolean genEndPos) {
0093:                    if (!genEndPos)
0094:                        return new Parser(this , S, keepDocComments);
0095:                    else
0096:                        return new EndPosParser(this , S, keepDocComments);
0097:                }
0098:            }
0099:
0100:            /** The number of precedence levels of infix operators.
0101:             */
0102:            private static final int infixPrecedenceLevels = 10;
0103:
0104:            /** The scanner used for lexical analysis.
0105:             */
0106:            private Lexer S;
0107:
0108:            /** The factory to be used for abstract syntax tree construction.
0109:             */
0110:            protected TreeMaker F;
0111:
0112:            /** The log to be used for error diagnostics.
0113:             */
0114:            private Log log;
0115:
0116:            /** The keyword table. */
0117:            private Keywords keywords;
0118:
0119:            /** The Source language setting. */
0120:            private Source source;
0121:
0122:            /** The name table. */
0123:            private Name.Table names;
0124:
0125:            /** Construct a parser from a given scanner, tree factory and log.
0126:             */
0127:            protected Parser(Factory fac, Lexer S, boolean keepDocComments) {
0128:                this .S = S;
0129:                S.nextToken(); // prime the pump
0130:                this .F = fac.F;
0131:                this .log = fac.log;
0132:                this .names = fac.names;
0133:                this .keywords = fac.keywords;
0134:                this .source = fac.source;
0135:                Options options = fac.options;
0136:                this .allowGenerics = source.allowGenerics();
0137:                this .allowVarargs = source.allowVarargs();
0138:                this .allowAsserts = source.allowAsserts();
0139:                this .allowEnums = source.allowEnums();
0140:                this .allowForeach = source.allowForeach();
0141:                this .allowStaticImport = source.allowStaticImport();
0142:                this .allowAnnotations = source.allowAnnotations();
0143:                this .keepDocComments = keepDocComments;
0144:                if (keepDocComments)
0145:                    docComments = new HashMap<JCTree, String>();
0146:                this .errorTree = F.Erroneous();
0147:            }
0148:
0149:            /** Switch: Should generics be recognized?
0150:             */
0151:            boolean allowGenerics;
0152:
0153:            /** Switch: Should varargs be recognized?
0154:             */
0155:            boolean allowVarargs;
0156:
0157:            /** Switch: should we recognize assert statements, or just give a warning?
0158:             */
0159:            boolean allowAsserts;
0160:
0161:            /** Switch: should we recognize enums, or just give a warning?
0162:             */
0163:            boolean allowEnums;
0164:
0165:            /** Switch: should we recognize foreach?
0166:             */
0167:            boolean allowForeach;
0168:
0169:            /** Switch: should we recognize foreach?
0170:             */
0171:            boolean allowStaticImport;
0172:
0173:            /** Switch: should we recognize annotations?
0174:             */
0175:            boolean allowAnnotations;
0176:
0177:            /** Switch: should we keep docComments?
0178:             */
0179:            boolean keepDocComments;
0180:
0181:            /** When terms are parsed, the mode determines which is expected:
0182:             *     mode = EXPR        : an expression
0183:             *     mode = TYPE        : a type
0184:             *     mode = NOPARAMS    : no parameters allowed for type
0185:             *     mode = TYPEARG     : type argument
0186:             */
0187:            static final int EXPR = 1;
0188:            static final int TYPE = 2;
0189:            static final int NOPARAMS = 4;
0190:            static final int TYPEARG = 8;
0191:
0192:            /** The current mode.
0193:             */
0194:            private int mode = 0;
0195:
0196:            /** The mode of the term that was parsed last.
0197:             */
0198:            private int lastmode = 0;
0199:
0200:            /* ---------- error recovery -------------- */
0201:
0202:            private JCErroneous errorTree;
0203:
0204:            /** Skip forward until a suitable stop token is found.
0205:             */
0206:            private void skip(boolean stopAtImport, boolean stopAtMemberDecl,
0207:                    boolean stopAtIdentifier, boolean stopAtStatement) {
0208:                while (true) {
0209:                    switch (S.token()) {
0210:                    case SEMI:
0211:                        S.nextToken();
0212:                        return;
0213:                    case PUBLIC:
0214:                    case FINAL:
0215:                    case ABSTRACT:
0216:                    case MONKEYS_AT:
0217:                    case EOF:
0218:                    case CLASS:
0219:                    case INTERFACE:
0220:                    case ENUM:
0221:                        return;
0222:                    case IMPORT:
0223:                        if (stopAtImport)
0224:                            return;
0225:                        break;
0226:                    case LBRACE:
0227:                    case RBRACE:
0228:                    case PRIVATE:
0229:                    case PROTECTED:
0230:                    case STATIC:
0231:                    case TRANSIENT:
0232:                    case NATIVE:
0233:                    case VOLATILE:
0234:                    case SYNCHRONIZED:
0235:                    case STRICTFP:
0236:                    case LT:
0237:                    case BYTE:
0238:                    case SHORT:
0239:                    case CHAR:
0240:                    case INT:
0241:                    case LONG:
0242:                    case FLOAT:
0243:                    case DOUBLE:
0244:                    case BOOLEAN:
0245:                    case VOID:
0246:                        if (stopAtMemberDecl)
0247:                            return;
0248:                        break;
0249:                    case IDENTIFIER:
0250:                        if (stopAtIdentifier)
0251:                            return;
0252:                        break;
0253:                    case CASE:
0254:                    case DEFAULT:
0255:                    case IF:
0256:                    case FOR:
0257:                    case WHILE:
0258:                    case DO:
0259:                    case TRY:
0260:                    case SWITCH:
0261:                    case RETURN:
0262:                    case THROW:
0263:                    case BREAK:
0264:                    case CONTINUE:
0265:                    case ELSE:
0266:                    case FINALLY:
0267:                    case CATCH:
0268:                        if (stopAtStatement)
0269:                            return;
0270:                        break;
0271:                    }
0272:                    S.nextToken();
0273:                }
0274:            }
0275:
0276:            private JCErroneous syntaxError(int pos, String key, Object... arg) {
0277:                return syntaxError(pos, null, key, arg);
0278:            }
0279:
0280:            private JCErroneous syntaxError(int pos, List<JCTree> errs,
0281:                    String key, Object... arg) {
0282:                setErrorEndPos(pos);
0283:                reportSyntaxError(pos, key, arg);
0284:                return toP(F.at(pos).Erroneous(errs));
0285:            }
0286:
0287:            private int errorPos = Position.NOPOS;
0288:
0289:            /**
0290:             * Report a syntax error at given position using the given
0291:             * argument unless one was already reported at the same position.
0292:             */
0293:            private void reportSyntaxError(int pos, String key, Object... arg) {
0294:                if (pos > S.errPos() || pos == Position.NOPOS) {
0295:                    if (S.token() == EOF)
0296:                        log.error(pos, "premature.eof");
0297:                    else
0298:                        log.error(pos, key, arg);
0299:                }
0300:                S.errPos(pos);
0301:                if (S.pos() == errorPos)
0302:                    S.nextToken(); // guarantee progress
0303:                errorPos = S.pos();
0304:            }
0305:
0306:            /** Generate a syntax error at current position unless one was already
0307:             *  reported at the same position.
0308:             */
0309:            private JCErroneous syntaxError(String key) {
0310:                return syntaxError(S.pos(), key);
0311:            }
0312:
0313:            /** Generate a syntax error at current position unless one was
0314:             *  already reported at the same position.
0315:             */
0316:            private JCErroneous syntaxError(String key, String arg) {
0317:                return syntaxError(S.pos(), key, arg);
0318:            }
0319:
0320:            /** If next input token matches given token, skip it, otherwise report
0321:             *  an error.
0322:             */
0323:            public void accept(Token token) {
0324:                if (S.token() == token) {
0325:                    S.nextToken();
0326:                } else {
0327:                    setErrorEndPos(S.pos());
0328:                    reportSyntaxError(S.prevEndPos(), "expected", keywords
0329:                            .token2string(token));
0330:                }
0331:            }
0332:
0333:            /** Report an illegal start of expression/type error at given position.
0334:             */
0335:            JCExpression illegal(int pos) {
0336:                setErrorEndPos(S.pos());
0337:                if ((mode & EXPR) != 0)
0338:                    return syntaxError(pos, "illegal.start.of.expr");
0339:                else
0340:                    return syntaxError(pos, "illegal.start.of.type");
0341:
0342:            }
0343:
0344:            /** Report an illegal start of expression/type error at current position.
0345:             */
0346:            JCExpression illegal() {
0347:                return illegal(S.pos());
0348:            }
0349:
0350:            /** Diagnose a modifier flag from the set, if any. */
0351:            void checkNoMods(long mods) {
0352:                if (mods != 0) {
0353:                    long lowestMod = mods & -mods;
0354:                    log.error(S.pos(), "mod.not.allowed.here", Flags.toString(
0355:                            lowestMod).trim());
0356:                }
0357:            }
0358:
0359:            /* ---------- doc comments --------- */
0360:
0361:            /** A hashtable to store all documentation comments
0362:             *  indexed by the tree nodes they refer to.
0363:             *  defined only if option flag keepDocComment is set.
0364:             */
0365:            Map<JCTree, String> docComments;
0366:
0367:            /** Make an entry into docComments hashtable,
0368:             *  provided flag keepDocComments is set and given doc comment is non-null.
0369:             *  @param tree   The tree to be used as index in the hashtable
0370:             *  @param dc     The doc comment to associate with the tree, or null.
0371:             */
0372:            void attach(JCTree tree, String dc) {
0373:                if (keepDocComments && dc != null) {
0374:                    //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
0375:                    docComments.put(tree, dc);
0376:                }
0377:            }
0378:
0379:            /* -------- source positions ------- */
0380:
0381:            private int errorEndPos = -1;
0382:
0383:            private void setErrorEndPos(int errPos) {
0384:                if (errPos > errorEndPos)
0385:                    errorEndPos = errPos;
0386:            }
0387:
0388:            protected int getErrorEndPos() {
0389:                return errorEndPos;
0390:            }
0391:
0392:            /**
0393:             * Store ending position for a tree.
0394:             * @param tree   The tree.
0395:             * @param endpos The ending position to associate with the tree.
0396:             */
0397:            protected void storeEnd(JCTree tree, int endpos) {
0398:            }
0399:
0400:            /**
0401:             * Store ending position for a tree.  The ending position should
0402:             * be the ending position of the current token.
0403:             * @param t The tree.
0404:             */
0405:            protected <T extends JCTree> T to(T t) {
0406:                return t;
0407:            }
0408:
0409:            /**
0410:             * Store ending position for a tree.  The ending position should
0411:             * be greater of the ending position of the previous token and errorEndPos.
0412:             * @param t The tree.
0413:             */
0414:            protected <T extends JCTree> T toP(T t) {
0415:                return t;
0416:            }
0417:
0418:            /** Get the start position for a tree node.  The start position is
0419:             * defined to be the position of the first character of the first
0420:             * token of the node's source text.
0421:             * @param tree  The tree node
0422:             */
0423:            public int getStartPos(JCTree tree) {
0424:                return TreeInfo.getStartPos(tree);
0425:            }
0426:
0427:            /**
0428:             * Get the end position for a tree node.  The end position is
0429:             * defined to be the position of the last character of the last
0430:             * token of the node's source text.  Returns Position.NOPOS if end
0431:             * positions are not generated or the position is otherwise not
0432:             * found.
0433:             * @param tree  The tree node
0434:             */
0435:            public int getEndPos(JCTree tree) {
0436:                return Position.NOPOS;
0437:            }
0438:
0439:            /* ---------- parsing -------------- */
0440:
0441:            /**
0442:             * Ident = IDENTIFIER
0443:             */
0444:            Name ident() {
0445:                if (S.token() == IDENTIFIER) {
0446:                    Name name = S.name();
0447:                    S.nextToken();
0448:                    return name;
0449:                } else if (S.token() == ASSERT) {
0450:                    if (allowAsserts) {
0451:                        log.error(S.pos(), "assert.as.identifier");
0452:                        S.nextToken();
0453:                        return names.error;
0454:                    } else {
0455:                        log.warning(S.pos(), "assert.as.identifier");
0456:                        Name name = S.name();
0457:                        S.nextToken();
0458:                        return name;
0459:                    }
0460:                } else if (S.token() == ENUM) {
0461:                    if (allowEnums) {
0462:                        log.error(S.pos(), "enum.as.identifier");
0463:                        S.nextToken();
0464:                        return names.error;
0465:                    } else {
0466:                        log.warning(S.pos(), "enum.as.identifier");
0467:                        Name name = S.name();
0468:                        S.nextToken();
0469:                        return name;
0470:                    }
0471:                } else {
0472:                    accept(IDENTIFIER);
0473:                    return names.error;
0474:                }
0475:            }
0476:
0477:            /**
0478:             * Qualident = Ident { DOT Ident }
0479:             */
0480:            public JCExpression qualident() {
0481:                JCExpression t = toP(F.at(S.pos()).Ident(ident()));
0482:                while (S.token() == DOT) {
0483:                    int pos = S.pos();
0484:                    S.nextToken();
0485:                    t = toP(F.at(pos).Select(t, ident()));
0486:                }
0487:                return t;
0488:            }
0489:
0490:            /**
0491:             * Literal =
0492:             *     INTLITERAL
0493:             *   | LONGLITERAL
0494:             *   | FLOATLITERAL
0495:             *   | DOUBLELITERAL
0496:             *   | CHARLITERAL
0497:             *   | STRINGLITERAL
0498:             *   | TRUE
0499:             *   | FALSE
0500:             *   | NULL
0501:             */
0502:            JCExpression literal(Name prefix) {
0503:                int pos = S.pos();
0504:                JCExpression t = errorTree;
0505:                switch (S.token()) {
0506:                case INTLITERAL:
0507:                    try {
0508:                        t = F.at(pos).Literal(TypeTags.INT,
0509:                                Convert.string2int(strval(prefix), S.radix()));
0510:                    } catch (NumberFormatException ex) {
0511:                        log.error(S.pos(), "int.number.too.large",
0512:                                strval(prefix));
0513:                    }
0514:                    break;
0515:                case LONGLITERAL:
0516:                    try {
0517:                        t = F.at(pos).Literal(
0518:                                TypeTags.LONG,
0519:                                new Long(Convert.string2long(strval(prefix), S
0520:                                        .radix())));
0521:                    } catch (NumberFormatException ex) {
0522:                        log.error(S.pos(), "int.number.too.large",
0523:                                strval(prefix));
0524:                    }
0525:                    break;
0526:                case FLOATLITERAL: {
0527:                    String proper = (S.radix() == 16 ? ("0x" + S.stringVal())
0528:                            : S.stringVal());
0529:                    Float n;
0530:                    try {
0531:                        n = Float.valueOf(proper);
0532:                    } catch (NumberFormatException ex) {
0533:                        // error already repoted in scanner
0534:                        n = Float.NaN;
0535:                    }
0536:                    if (n.floatValue() == 0.0f && !isZero(proper))
0537:                        log.error(S.pos(), "fp.number.too.small");
0538:                    else if (n.floatValue() == Float.POSITIVE_INFINITY)
0539:                        log.error(S.pos(), "fp.number.too.large");
0540:                    else
0541:                        t = F.at(pos).Literal(TypeTags.FLOAT, n);
0542:                    break;
0543:                }
0544:                case DOUBLELITERAL: {
0545:                    String proper = (S.radix() == 16 ? ("0x" + S.stringVal())
0546:                            : S.stringVal());
0547:                    Double n;
0548:                    try {
0549:                        n = Double.valueOf(proper);
0550:                    } catch (NumberFormatException ex) {
0551:                        // error already reported in scanner
0552:                        n = Double.NaN;
0553:                    }
0554:                    if (n.doubleValue() == 0.0d && !isZero(proper))
0555:                        log.error(S.pos(), "fp.number.too.small");
0556:                    else if (n.doubleValue() == Double.POSITIVE_INFINITY)
0557:                        log.error(S.pos(), "fp.number.too.large");
0558:                    else
0559:                        t = F.at(pos).Literal(TypeTags.DOUBLE, n);
0560:                    break;
0561:                }
0562:                case CHARLITERAL:
0563:                    t = F.at(pos).Literal(TypeTags.CHAR,
0564:                            S.stringVal().charAt(0) + 0);
0565:                    break;
0566:                case STRINGLITERAL:
0567:                    t = F.at(pos).Literal(TypeTags.CLASS, S.stringVal());
0568:                    break;
0569:                case TRUE:
0570:                case FALSE:
0571:                    t = F.at(pos).Literal(TypeTags.BOOLEAN,
0572:                            (S.token() == TRUE ? 1 : 0));
0573:                    break;
0574:                case NULL:
0575:                    t = F.at(pos).Literal(TypeTags.BOT, null);
0576:                    break;
0577:                default:
0578:                    assert false;
0579:                }
0580:                if (t == errorTree)
0581:                    t = F.at(pos).Erroneous();
0582:                storeEnd(t, S.endPos());
0583:                S.nextToken();
0584:                return t;
0585:            }
0586:
0587:            //where
0588:            boolean isZero(String s) {
0589:                char[] cs = s.toCharArray();
0590:                int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16
0591:                        : 10);
0592:                int i = ((base == 16) ? 2 : 0);
0593:                while (i < cs.length && (cs[i] == '0' || cs[i] == '.'))
0594:                    i++;
0595:                return !(i < cs.length && (Character.digit(cs[i], base) > 0));
0596:            }
0597:
0598:            String strval(Name prefix) {
0599:                String s = S.stringVal();
0600:                return (prefix.len == 0) ? s : prefix + s;
0601:            }
0602:
0603:            /** terms can be either expressions or types.
0604:             */
0605:            public JCExpression expression() {
0606:                return term(EXPR);
0607:            }
0608:
0609:            public JCExpression type() {
0610:                return term(TYPE);
0611:            }
0612:
0613:            JCExpression term(int newmode) {
0614:                int prevmode = mode;
0615:                mode = newmode;
0616:                JCExpression t = term();
0617:                lastmode = mode;
0618:                mode = prevmode;
0619:                return t;
0620:            }
0621:
0622:            /**
0623:             *  Expression = Expression1 [ExpressionRest]
0624:             *  ExpressionRest = [AssignmentOperator Expression1]
0625:             *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
0626:             *                       "&=" | "|=" | "^=" |
0627:             *                       "%=" | "<<=" | ">>=" | ">>>="
0628:             *  Type = Type1
0629:             *  TypeNoParams = TypeNoParams1
0630:             *  StatementExpression = Expression
0631:             *  ConstantExpression = Expression
0632:             */
0633:            JCExpression term() {
0634:                JCExpression t = term1();
0635:                if ((mode & EXPR) != 0 && S.token() == EQ
0636:                        || PLUSEQ.compareTo(S.token()) <= 0
0637:                        && S.token().compareTo(GTGTGTEQ) <= 0)
0638:                    return termRest(t);
0639:                else
0640:                    return t;
0641:            }
0642:
0643:            JCExpression termRest(JCExpression t) {
0644:                switch (S.token()) {
0645:                case EQ: {
0646:                    int pos = S.pos();
0647:                    S.nextToken();
0648:                    mode = EXPR;
0649:                    JCExpression t1 = term();
0650:                    return toP(F.at(pos).Assign(t, t1));
0651:                }
0652:                case PLUSEQ:
0653:                case SUBEQ:
0654:                case STAREQ:
0655:                case SLASHEQ:
0656:                case PERCENTEQ:
0657:                case AMPEQ:
0658:                case BAREQ:
0659:                case CARETEQ:
0660:                case LTLTEQ:
0661:                case GTGTEQ:
0662:                case GTGTGTEQ:
0663:                    int pos = S.pos();
0664:                    Token token = S.token();
0665:                    S.nextToken();
0666:                    mode = EXPR;
0667:                    JCExpression t1 = term();
0668:                    return F.at(pos).Assignop(optag(token), t, t1);
0669:                default:
0670:                    return t;
0671:                }
0672:            }
0673:
0674:            /** Expression1   = Expression2 [Expression1Rest]
0675:             *  Type1         = Type2
0676:             *  TypeNoParams1 = TypeNoParams2
0677:             */
0678:            JCExpression term1() {
0679:                JCExpression t = term2();
0680:                if ((mode & EXPR) != 0 && S.token() == QUES) {
0681:                    mode = EXPR;
0682:                    return term1Rest(t);
0683:                } else {
0684:                    return t;
0685:                }
0686:            }
0687:
0688:            /** Expression1Rest = ["?" Expression ":" Expression1]
0689:             */
0690:            JCExpression term1Rest(JCExpression t) {
0691:                if (S.token() == QUES) {
0692:                    int pos = S.pos();
0693:                    S.nextToken();
0694:                    JCExpression t1 = term();
0695:                    accept(COLON);
0696:                    JCExpression t2 = term1();
0697:                    return F.at(pos).Conditional(t, t1, t2);
0698:                } else {
0699:                    return t;
0700:                }
0701:            }
0702:
0703:            /** Expression2   = Expression3 [Expression2Rest]
0704:             *  Type2         = Type3
0705:             *  TypeNoParams2 = TypeNoParams3
0706:             */
0707:            JCExpression term2() {
0708:                JCExpression t = term3();
0709:                if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
0710:                    mode = EXPR;
0711:                    return term2Rest(t, TreeInfo.orPrec);
0712:                } else {
0713:                    return t;
0714:                }
0715:            }
0716:
0717:            /*  Expression2Rest = {infixop Expression3}
0718:             *                  | Expression3 instanceof Type
0719:             *  infixop         = "||"
0720:             *                  | "&&"
0721:             *                  | "|"
0722:             *                  | "^"
0723:             *                  | "&"
0724:             *                  | "==" | "!="
0725:             *                  | "<" | ">" | "<=" | ">="
0726:             *                  | "<<" | ">>" | ">>>"
0727:             *                  | "+" | "-"
0728:             *                  | "*" | "/" | "%"
0729:             */
0730:            JCExpression term2Rest(JCExpression t, int minprec) {
0731:                List<JCExpression[]> savedOd = odStackSupply.elems;
0732:                JCExpression[] odStack = newOdStack();
0733:                List<Token[]> savedOp = opStackSupply.elems;
0734:                Token[] opStack = newOpStack();
0735:                // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
0736:                int top = 0;
0737:                odStack[0] = t;
0738:                int startPos = S.pos();
0739:                Token topOp = ERROR;
0740:                while (prec(S.token()) >= minprec) {
0741:                    opStack[top] = topOp;
0742:                    top++;
0743:                    topOp = S.token();
0744:                    int pos = S.pos();
0745:                    S.nextToken();
0746:                    odStack[top] = topOp == INSTANCEOF ? type() : term3();
0747:                    while (top > 0 && prec(topOp) >= prec(S.token())) {
0748:                        odStack[top - 1] = makeOp(pos, topOp, odStack[top - 1],
0749:                                odStack[top]);
0750:                        top--;
0751:                        topOp = opStack[top];
0752:                    }
0753:                }
0754:                assert top == 0;
0755:                t = odStack[0];
0756:
0757:                if (t.getTag() == JCTree.PLUS) {
0758:                    StringBuffer buf = foldStrings(t);
0759:                    if (buf != null) {
0760:                        t = toP(F.at(startPos).Literal(TypeTags.CLASS,
0761:                                buf.toString()));
0762:                    }
0763:                }
0764:
0765:                odStackSupply.elems = savedOd; // optimization
0766:                opStackSupply.elems = savedOp; // optimization
0767:                return t;
0768:            }
0769:
0770:            //where
0771:            /** Construct a binary or type test node.
0772:             */
0773:            private JCExpression makeOp(int pos, Token topOp, JCExpression od1,
0774:                    JCExpression od2) {
0775:                if (topOp == INSTANCEOF) {
0776:                    return F.at(pos).TypeTest(od1, od2);
0777:                } else {
0778:                    return F.at(pos).Binary(optag(topOp), od1, od2);
0779:                }
0780:            }
0781:
0782:            /** If tree is a concatenation of string literals, replace it
0783:             *  by a single literal representing the concatenated string.
0784:             */
0785:            protected StringBuffer foldStrings(JCTree tree) {
0786:                List<String> buf = List.nil();
0787:                while (true) {
0788:                    if (tree.getTag() == JCTree.LITERAL) {
0789:                        JCLiteral lit = (JCLiteral) tree;
0790:                        if (lit.typetag == TypeTags.CLASS) {
0791:                            StringBuffer sbuf = new StringBuffer(
0792:                                    (String) lit.value);
0793:                            while (buf.nonEmpty()) {
0794:                                sbuf.append(buf.head);
0795:                                buf = buf.tail;
0796:                            }
0797:                            return sbuf;
0798:                        }
0799:                    } else if (tree.getTag() == JCTree.PLUS) {
0800:                        JCBinary op = (JCBinary) tree;
0801:                        if (op.rhs.getTag() == JCTree.LITERAL) {
0802:                            JCLiteral lit = (JCLiteral) op.rhs;
0803:                            if (lit.typetag == TypeTags.CLASS) {
0804:                                buf = buf.prepend((String) lit.value);
0805:                                tree = op.lhs;
0806:                                continue;
0807:                            }
0808:                        }
0809:                    }
0810:                    return null;
0811:                }
0812:            }
0813:
0814:            /** optimization: To save allocating a new operand/operator stack
0815:             *  for every binary operation, we use supplys.
0816:             */
0817:            ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
0818:            ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
0819:
0820:            private JCExpression[] newOdStack() {
0821:                if (odStackSupply.elems == odStackSupply.last)
0822:                    odStackSupply
0823:                            .append(new JCExpression[infixPrecedenceLevels + 1]);
0824:                JCExpression[] odStack = odStackSupply.elems.head;
0825:                odStackSupply.elems = odStackSupply.elems.tail;
0826:                return odStack;
0827:            }
0828:
0829:            private Token[] newOpStack() {
0830:                if (opStackSupply.elems == opStackSupply.last)
0831:                    opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
0832:                Token[] opStack = opStackSupply.elems.head;
0833:                opStackSupply.elems = opStackSupply.elems.tail;
0834:                return opStack;
0835:            }
0836:
0837:            /** Expression3    = PrefixOp Expression3
0838:             *                 | "(" Expr | TypeNoParams ")" Expression3
0839:             *                 | Primary {Selector} {PostfixOp}
0840:             *  Primary        = "(" Expression ")"
0841:             *                 | Literal
0842:             *                 | [TypeArguments] THIS [Arguments]
0843:             *                 | [TypeArguments] SUPER SuperSuffix
0844:             *                 | NEW [TypeArguments] Creator
0845:             *                 | Ident { "." Ident }
0846:             *                   [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
0847:             *                   | Arguments
0848:             *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
0849:             *                   ]
0850:             *                 | BasicType BracketsOpt "." CLASS
0851:             *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
0852:             *  PostfixOp      = "++" | "--"
0853:             *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
0854:             *                 | BasicType
0855:             *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
0856:             *  Selector       = "." [TypeArguments] Ident [Arguments]
0857:             *                 | "." THIS
0858:             *                 | "." [TypeArguments] SUPER SuperSuffix
0859:             *                 | "." NEW [TypeArguments] InnerCreator
0860:             *                 | "[" Expression "]"
0861:             *  TypeSelector   = "." Ident [TypeArguments]
0862:             *  SuperSuffix    = Arguments | "." Ident [Arguments]
0863:             */
0864:            protected JCExpression term3() {
0865:                int pos = S.pos();
0866:                JCExpression t;
0867:                List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
0868:                switch (S.token()) {
0869:                case QUES:
0870:                    if ((mode & TYPE) != 0
0871:                            && (mode & (TYPEARG | NOPARAMS)) == TYPEARG) {
0872:                        mode = TYPE;
0873:                        return typeArgument();
0874:                    } else
0875:                        return illegal();
0876:                case PLUSPLUS:
0877:                case SUBSUB:
0878:                case BANG:
0879:                case TILDE:
0880:                case PLUS:
0881:                case SUB:
0882:                    if (typeArgs == null && (mode & EXPR) != 0) {
0883:                        Token token = S.token();
0884:                        S.nextToken();
0885:                        mode = EXPR;
0886:                        if (token == SUB
0887:                                && (S.token() == INTLITERAL || S.token() == LONGLITERAL)
0888:                                && S.radix() == 10) {
0889:                            mode = EXPR;
0890:                            t = literal(names.hyphen);
0891:                        } else {
0892:                            t = term3();
0893:                            return F.at(pos).Unary(unoptag(token), t);
0894:                        }
0895:                    } else
0896:                        return illegal();
0897:                    break;
0898:                case LPAREN:
0899:                    if (typeArgs == null && (mode & EXPR) != 0) {
0900:                        S.nextToken();
0901:                        mode = EXPR | TYPE | NOPARAMS;
0902:                        t = term3();
0903:                        if ((mode & TYPE) != 0 && S.token() == LT) {
0904:                            // Could be a cast to a parameterized type
0905:                            int op = JCTree.LT;
0906:                            int pos1 = S.pos();
0907:                            S.nextToken();
0908:                            mode &= (EXPR | TYPE);
0909:                            mode |= TYPEARG;
0910:                            JCExpression t1 = term3();
0911:                            if ((mode & TYPE) != 0
0912:                                    && (S.token() == COMMA || S.token() == GT)) {
0913:                                mode = TYPE;
0914:                                ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
0915:                                args.append(t1);
0916:                                while (S.token() == COMMA) {
0917:                                    S.nextToken();
0918:                                    args.append(typeArgument());
0919:                                }
0920:                                accept(GT);
0921:                                t = F.at(pos1).TypeApply(t, args.toList());
0922:                                checkGenerics();
0923:                                t = bracketsOpt(toP(t));
0924:                            } else if ((mode & EXPR) != 0) {
0925:                                mode = EXPR;
0926:                                t = F.at(pos1).Binary(op, t,
0927:                                        term2Rest(t1, TreeInfo.shiftPrec));
0928:                                t = termRest(term1Rest(term2Rest(t,
0929:                                        TreeInfo.orPrec)));
0930:                            } else {
0931:                                accept(GT);
0932:                            }
0933:                        } else {
0934:                            t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
0935:                        }
0936:                        accept(RPAREN);
0937:                        lastmode = mode;
0938:                        mode = EXPR;
0939:                        if ((lastmode & EXPR) == 0) {
0940:                            JCExpression t1 = term3();
0941:                            return F.at(pos).TypeCast(t, t1);
0942:                        } else if ((lastmode & TYPE) != 0) {
0943:                            switch (S.token()) {
0944:                            /*case PLUSPLUS: case SUBSUB: */
0945:                            case BANG:
0946:                            case TILDE:
0947:                            case LPAREN:
0948:                            case THIS:
0949:                            case SUPER:
0950:                            case INTLITERAL:
0951:                            case LONGLITERAL:
0952:                            case FLOATLITERAL:
0953:                            case DOUBLELITERAL:
0954:                            case CHARLITERAL:
0955:                            case STRINGLITERAL:
0956:                            case TRUE:
0957:                            case FALSE:
0958:                            case NULL:
0959:                            case NEW:
0960:                            case IDENTIFIER:
0961:                            case ASSERT:
0962:                            case ENUM:
0963:                            case BYTE:
0964:                            case SHORT:
0965:                            case CHAR:
0966:                            case INT:
0967:                            case LONG:
0968:                            case FLOAT:
0969:                            case DOUBLE:
0970:                            case BOOLEAN:
0971:                            case VOID:
0972:                                JCExpression t1 = term3();
0973:                                return F.at(pos).TypeCast(t, t1);
0974:                            }
0975:                        }
0976:                    } else
0977:                        return illegal();
0978:                    t = toP(F.at(pos).Parens(t));
0979:                    break;
0980:                case THIS:
0981:                    if ((mode & EXPR) != 0) {
0982:                        mode = EXPR;
0983:                        t = to(F.at(pos).Ident(names._this ));
0984:                        S.nextToken();
0985:                        if (typeArgs == null)
0986:                            t = argumentsOpt(null, t);
0987:                        else
0988:                            t = arguments(typeArgs, t);
0989:                        typeArgs = null;
0990:                    } else
0991:                        return illegal();
0992:                    break;
0993:                case SUPER:
0994:                    if ((mode & EXPR) != 0) {
0995:                        mode = EXPR;
0996:                        t = to(super Suffix(typeArgs, F.at(pos).Ident(
0997:                                names._super )));
0998:                        typeArgs = null;
0999:                    } else
1000:                        return illegal();
1001:                    break;
1002:                case INTLITERAL:
1003:                case LONGLITERAL:
1004:                case FLOATLITERAL:
1005:                case DOUBLELITERAL:
1006:                case CHARLITERAL:
1007:                case STRINGLITERAL:
1008:                case TRUE:
1009:                case FALSE:
1010:                case NULL:
1011:                    if (typeArgs == null && (mode & EXPR) != 0) {
1012:                        mode = EXPR;
1013:                        t = literal(names.empty);
1014:                    } else
1015:                        return illegal();
1016:                    break;
1017:                case NEW:
1018:                    if (typeArgs != null)
1019:                        return illegal();
1020:                    if ((mode & EXPR) != 0) {
1021:                        mode = EXPR;
1022:                        S.nextToken();
1023:                        if (S.token() == LT)
1024:                            typeArgs = typeArguments();
1025:                        t = creator(pos, typeArgs);
1026:                        typeArgs = null;
1027:                    } else
1028:                        return illegal();
1029:                    break;
1030:                case IDENTIFIER:
1031:                case ASSERT:
1032:                case ENUM:
1033:                    if (typeArgs != null)
1034:                        return illegal();
1035:                    t = toP(F.at(S.pos()).Ident(ident()));
1036:                    loop: while (true) {
1037:                        pos = S.pos();
1038:                        switch (S.token()) {
1039:                        case LBRACKET:
1040:                            S.nextToken();
1041:                            if (S.token() == RBRACKET) {
1042:                                S.nextToken();
1043:                                t = bracketsOpt(t);
1044:                                t = toP(F.at(pos).TypeArray(t));
1045:                                t = bracketsSuffix(t);
1046:                            } else {
1047:                                if ((mode & EXPR) != 0) {
1048:                                    mode = EXPR;
1049:                                    JCExpression t1 = term();
1050:                                    t = to(F.at(pos).Indexed(t, t1));
1051:                                }
1052:                                accept(RBRACKET);
1053:                            }
1054:                            break loop;
1055:                        case LPAREN:
1056:                            if ((mode & EXPR) != 0) {
1057:                                mode = EXPR;
1058:                                t = arguments(typeArgs, t);
1059:                                typeArgs = null;
1060:                            }
1061:                            break loop;
1062:                        case DOT:
1063:                            S.nextToken();
1064:                            typeArgs = typeArgumentsOpt(EXPR);
1065:                            if ((mode & EXPR) != 0) {
1066:                                switch (S.token()) {
1067:                                case CLASS:
1068:                                    if (typeArgs != null)
1069:                                        return illegal();
1070:                                    mode = EXPR;
1071:                                    t = to(F.at(pos).Select(t, names._class));
1072:                                    S.nextToken();
1073:                                    break loop;
1074:                                case THIS:
1075:                                    if (typeArgs != null)
1076:                                        return illegal();
1077:                                    mode = EXPR;
1078:                                    t = to(F.at(pos).Select(t, names._this ));
1079:                                    S.nextToken();
1080:                                    break loop;
1081:                                case SUPER:
1082:                                    mode = EXPR;
1083:                                    t = to(F.at(pos).Select(t, names._super ));
1084:                                    t = super Suffix(typeArgs, t);
1085:                                    typeArgs = null;
1086:                                    break loop;
1087:                                case NEW:
1088:                                    if (typeArgs != null)
1089:                                        return illegal();
1090:                                    mode = EXPR;
1091:                                    int pos1 = S.pos();
1092:                                    S.nextToken();
1093:                                    if (S.token() == LT)
1094:                                        typeArgs = typeArguments();
1095:                                    t = innerCreator(pos1, typeArgs, t);
1096:                                    typeArgs = null;
1097:                                    break loop;
1098:                                }
1099:                            }
1100:                            // typeArgs saved for next loop iteration.
1101:                            t = toP(F.at(pos).Select(t, ident()));
1102:                            break;
1103:                        default:
1104:                            break loop;
1105:                        }
1106:                    }
1107:                    if (typeArgs != null)
1108:                        illegal();
1109:                    t = typeArgumentsOpt(t);
1110:                    break;
1111:                case BYTE:
1112:                case SHORT:
1113:                case CHAR:
1114:                case INT:
1115:                case LONG:
1116:                case FLOAT:
1117:                case DOUBLE:
1118:                case BOOLEAN:
1119:                    if (typeArgs != null)
1120:                        illegal();
1121:                    t = bracketsSuffix(bracketsOpt(basicType()));
1122:                    break;
1123:                case VOID:
1124:                    if (typeArgs != null)
1125:                        illegal();
1126:                    if ((mode & EXPR) != 0) {
1127:                        S.nextToken();
1128:                        if (S.token() == DOT) {
1129:                            JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(
1130:                                    TypeTags.VOID));
1131:                            t = bracketsSuffix(ti);
1132:                        } else {
1133:                            return illegal(pos);
1134:                        }
1135:                    } else {
1136:                        return illegal();
1137:                    }
1138:                    break;
1139:                default:
1140:                    return illegal();
1141:                }
1142:                if (typeArgs != null)
1143:                    illegal();
1144:                while (true) {
1145:                    int pos1 = S.pos();
1146:                    if (S.token() == LBRACKET) {
1147:                        S.nextToken();
1148:                        if ((mode & TYPE) != 0) {
1149:                            int oldmode = mode;
1150:                            mode = TYPE;
1151:                            if (S.token() == RBRACKET) {
1152:                                S.nextToken();
1153:                                t = bracketsOpt(t);
1154:                                t = toP(F.at(pos1).TypeArray(t));
1155:                                return t;
1156:                            }
1157:                            mode = oldmode;
1158:                        }
1159:                        if ((mode & EXPR) != 0) {
1160:                            mode = EXPR;
1161:                            JCExpression t1 = term();
1162:                            t = to(F.at(pos1).Indexed(t, t1));
1163:                        }
1164:                        accept(RBRACKET);
1165:                    } else if (S.token() == DOT) {
1166:                        S.nextToken();
1167:                        typeArgs = typeArgumentsOpt(EXPR);
1168:                        if (S.token() == SUPER && (mode & EXPR) != 0) {
1169:                            mode = EXPR;
1170:                            t = to(F.at(pos1).Select(t, names._super ));
1171:                            S.nextToken();
1172:                            t = arguments(typeArgs, t);
1173:                            typeArgs = null;
1174:                        } else if (S.token() == NEW && (mode & EXPR) != 0) {
1175:                            if (typeArgs != null)
1176:                                return illegal();
1177:                            mode = EXPR;
1178:                            int pos2 = S.pos();
1179:                            S.nextToken();
1180:                            if (S.token() == LT)
1181:                                typeArgs = typeArguments();
1182:                            t = innerCreator(pos2, typeArgs, t);
1183:                            typeArgs = null;
1184:                        } else {
1185:                            t = toP(F.at(pos1).Select(t, ident()));
1186:                            t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1187:                            typeArgs = null;
1188:                        }
1189:                    } else {
1190:                        break;
1191:                    }
1192:                }
1193:                while ((S.token() == PLUSPLUS || S.token() == SUBSUB)
1194:                        && (mode & EXPR) != 0) {
1195:                    mode = EXPR;
1196:                    t = to(F.at(S.pos()).Unary(
1197:                            S.token() == PLUSPLUS ? JCTree.POSTINC
1198:                                    : JCTree.POSTDEC, t));
1199:                    S.nextToken();
1200:                }
1201:                return toP(t);
1202:            }
1203:
1204:            /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1205:             */
1206:            JCExpression super Suffix(List<JCExpression> typeArgs, JCExpression t) {
1207:                S.nextToken();
1208:                if (S.token() == LPAREN || typeArgs != null) {
1209:                    t = arguments(typeArgs, t);
1210:                } else {
1211:                    int pos = S.pos();
1212:                    accept(DOT);
1213:                    typeArgs = (S.token() == LT) ? typeArguments() : null;
1214:                    t = toP(F.at(pos).Select(t, ident()));
1215:                    t = argumentsOpt(typeArgs, t);
1216:                }
1217:                return t;
1218:            }
1219:
1220:            /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1221:             */
1222:            JCPrimitiveTypeTree basicType() {
1223:                JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(
1224:                        typetag(S.token())));
1225:                S.nextToken();
1226:                return t;
1227:            }
1228:
1229:            /** ArgumentsOpt = [ Arguments ]
1230:             */
1231:            JCExpression argumentsOpt(List<JCExpression> typeArgs,
1232:                    JCExpression t) {
1233:                if ((mode & EXPR) != 0 && S.token() == LPAREN
1234:                        || typeArgs != null) {
1235:                    mode = EXPR;
1236:                    return arguments(typeArgs, t);
1237:                } else {
1238:                    return t;
1239:                }
1240:            }
1241:
1242:            /** Arguments = "(" [Expression { COMMA Expression }] ")"
1243:             */
1244:            List<JCExpression> arguments() {
1245:                ListBuffer<JCExpression> args = lb();
1246:                if (S.token() == LPAREN) {
1247:                    S.nextToken();
1248:                    if (S.token() != RPAREN) {
1249:                        args.append(expression());
1250:                        while (S.token() == COMMA) {
1251:                            S.nextToken();
1252:                            args.append(expression());
1253:                        }
1254:                    }
1255:                    accept(RPAREN);
1256:                } else {
1257:                    syntaxError(S.pos(), "expected", keywords
1258:                            .token2string(LPAREN));
1259:                }
1260:                return args.toList();
1261:            }
1262:
1263:            JCMethodInvocation arguments(List<JCExpression> typeArgs,
1264:                    JCExpression t) {
1265:                int pos = S.pos();
1266:                List<JCExpression> args = arguments();
1267:                return toP(F.at(pos).Apply(typeArgs, t, args));
1268:            }
1269:
1270:            /**  TypeArgumentsOpt = [ TypeArguments ]
1271:             */
1272:            JCExpression typeArgumentsOpt(JCExpression t) {
1273:                if (S.token() == LT && (mode & TYPE) != 0
1274:                        && (mode & NOPARAMS) == 0) {
1275:                    mode = TYPE;
1276:                    checkGenerics();
1277:                    return typeArguments(t);
1278:                } else {
1279:                    return t;
1280:                }
1281:            }
1282:
1283:            List<JCExpression> typeArgumentsOpt() {
1284:                return typeArgumentsOpt(TYPE);
1285:            }
1286:
1287:            List<JCExpression> typeArgumentsOpt(int useMode) {
1288:                if (S.token() == LT) {
1289:                    checkGenerics();
1290:                    if ((mode & useMode) == 0 || (mode & NOPARAMS) != 0) {
1291:                        illegal();
1292:                    }
1293:                    mode = useMode;
1294:                    return typeArguments();
1295:                }
1296:                return null;
1297:            }
1298:
1299:            /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1300:             */
1301:            List<JCExpression> typeArguments() {
1302:                ListBuffer<JCExpression> args = lb();
1303:                if (S.token() == LT) {
1304:                    S.nextToken();
1305:                    args.append(((mode & EXPR) == 0) ? typeArgument() : type());
1306:                    while (S.token() == COMMA) {
1307:                        S.nextToken();
1308:                        args.append(((mode & EXPR) == 0) ? typeArgument()
1309:                                : type());
1310:                    }
1311:                    switch (S.token()) {
1312:                    case GTGTGTEQ:
1313:                        S.token(GTGTEQ);
1314:                        break;
1315:                    case GTGTEQ:
1316:                        S.token(GTEQ);
1317:                        break;
1318:                    case GTEQ:
1319:                        S.token(EQ);
1320:                        break;
1321:                    case GTGTGT:
1322:                        S.token(GTGT);
1323:                        break;
1324:                    case GTGT:
1325:                        S.token(GT);
1326:                        break;
1327:                    default:
1328:                        accept(GT);
1329:                        break;
1330:                    }
1331:                } else {
1332:                    syntaxError(S.pos(), "expected", keywords.token2string(LT));
1333:                }
1334:                return args.toList();
1335:            }
1336:
1337:            /** TypeArgument = Type
1338:             *               | "?"
1339:             *               | "?" EXTENDS Type {"&" Type}
1340:             *               | "?" SUPER Type
1341:             */
1342:            JCExpression typeArgument() {
1343:                if (S.token() != QUES)
1344:                    return type();
1345:                int pos = S.pos();
1346:                S.nextToken();
1347:                if (S.token() == EXTENDS) {
1348:                    TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(
1349:                            BoundKind.EXTENDS));
1350:                    S.nextToken();
1351:                    return F.at(pos).Wildcard(t, type());
1352:                } else if (S.token() == SUPER) {
1353:                    TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(
1354:                            BoundKind.SUPER));
1355:                    S.nextToken();
1356:                    return F.at(pos).Wildcard(t, type());
1357:                } else if (S.token() == IDENTIFIER) {
1358:                    //error recovery
1359:                    reportSyntaxError(S.prevEndPos(), "expected3", keywords
1360:                            .token2string(GT), keywords.token2string(EXTENDS),
1361:                            keywords.token2string(SUPER));
1362:                    TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(
1363:                            BoundKind.UNBOUND);
1364:                    JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1365:                    JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1366:                    return F.at(pos).Erroneous(List.<JCTree> of(wc, id));
1367:                } else {
1368:                    TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(
1369:                            BoundKind.UNBOUND);
1370:                    return toP(F.at(pos).Wildcard(t, null));
1371:                }
1372:            }
1373:
1374:            JCTypeApply typeArguments(JCExpression t) {
1375:                int pos = S.pos();
1376:                List<JCExpression> args = typeArguments();
1377:                return toP(F.at(pos).TypeApply(t, args));
1378:            }
1379:
1380:            /** BracketsOpt = {"[" "]"}
1381:             */
1382:            private JCExpression bracketsOpt(JCExpression t) {
1383:                if (S.token() == LBRACKET) {
1384:                    int pos = S.pos();
1385:                    S.nextToken();
1386:                    t = bracketsOptCont(t, pos);
1387:                    F.at(pos);
1388:                }
1389:                return t;
1390:            }
1391:
1392:            private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
1393:                accept(RBRACKET);
1394:                t = bracketsOpt(t);
1395:                return toP(F.at(pos).TypeArray(t));
1396:            }
1397:
1398:            /** BracketsSuffixExpr = "." CLASS
1399:             *  BracketsSuffixType =
1400:             */
1401:            JCExpression bracketsSuffix(JCExpression t) {
1402:                if ((mode & EXPR) != 0 && S.token() == DOT) {
1403:                    mode = EXPR;
1404:                    int pos = S.pos();
1405:                    S.nextToken();
1406:                    accept(CLASS);
1407:                    if (S.pos() == errorEndPos) {
1408:                        // error recovery
1409:                        Name name = null;
1410:                        if (S.token() == IDENTIFIER) {
1411:                            name = S.name();
1412:                            S.nextToken();
1413:                        } else {
1414:                            name = names.error;
1415:                        }
1416:                        t = F.at(pos).Erroneous(
1417:                                List
1418:                                        .<JCTree> of(toP(F.at(pos).Select(t,
1419:                                                name))));
1420:                    } else {
1421:                        t = toP(F.at(pos).Select(t, names._class));
1422:                    }
1423:                } else if ((mode & TYPE) != 0) {
1424:                    mode = TYPE;
1425:                } else {
1426:                    syntaxError(S.pos(), "dot.class.expected");
1427:                }
1428:                return t;
1429:            }
1430:
1431:            /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1432:             */
1433:            JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1434:                switch (S.token()) {
1435:                case BYTE:
1436:                case SHORT:
1437:                case CHAR:
1438:                case INT:
1439:                case LONG:
1440:                case FLOAT:
1441:                case DOUBLE:
1442:                case BOOLEAN:
1443:                    if (typeArgs == null)
1444:                        return arrayCreatorRest(newpos, basicType());
1445:                    break;
1446:                default:
1447:                }
1448:                JCExpression t = qualident();
1449:                int oldmode = mode;
1450:                mode = TYPE;
1451:                if (S.token() == LT) {
1452:                    checkGenerics();
1453:                    t = typeArguments(t);
1454:                }
1455:                while (S.token() == DOT) {
1456:                    int pos = S.pos();
1457:                    S.nextToken();
1458:                    t = toP(F.at(pos).Select(t, ident()));
1459:                    if (S.token() == LT) {
1460:                        checkGenerics();
1461:                        t = typeArguments(t);
1462:                    }
1463:                }
1464:                mode = oldmode;
1465:                if (S.token() == LBRACKET) {
1466:                    JCExpression e = arrayCreatorRest(newpos, t);
1467:                    if (typeArgs != null) {
1468:                        int pos = newpos;
1469:                        if (!typeArgs.isEmpty()
1470:                                && typeArgs.head.pos != Position.NOPOS) {
1471:                            // note: this should always happen but we should
1472:                            // not rely on this as the parser is continuously
1473:                            // modified to improve error recovery.
1474:                            pos = typeArgs.head.pos;
1475:                        }
1476:                        setErrorEndPos(S.prevEndPos());
1477:                        reportSyntaxError(pos,
1478:                                "cannot.create.array.with.type.arguments");
1479:                        return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1480:                    }
1481:                    return e;
1482:                } else if (S.token() == LPAREN) {
1483:                    return classCreatorRest(newpos, null, typeArgs, t);
1484:                } else {
1485:                    reportSyntaxError(S.pos(), "expected2", keywords
1486:                            .token2string(LPAREN), keywords
1487:                            .token2string(LBRACKET));
1488:                    t = toP(F.at(newpos).NewClass(null, typeArgs, t,
1489:                            List.<JCExpression> nil(), null));
1490:                    return toP(F.at(newpos).Erroneous(List.<JCTree> of(t)));
1491:                }
1492:            }
1493:
1494:            /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
1495:             */
1496:            JCExpression innerCreator(int newpos, List<JCExpression> typeArgs,
1497:                    JCExpression encl) {
1498:                JCExpression t = toP(F.at(S.pos()).Ident(ident()));
1499:                if (S.token() == LT) {
1500:                    checkGenerics();
1501:                    t = typeArguments(t);
1502:                }
1503:                return classCreatorRest(newpos, encl, typeArgs, t);
1504:            }
1505:
1506:            /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
1507:             *                         | Expression "]" {"[" Expression "]"} BracketsOpt )
1508:             */
1509:            JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1510:                accept(LBRACKET);
1511:                if (S.token() == RBRACKET) {
1512:                    accept(RBRACKET);
1513:                    elemtype = bracketsOpt(elemtype);
1514:                    if (S.token() == LBRACE) {
1515:                        return arrayInitializer(newpos, elemtype);
1516:                    } else {
1517:                        return syntaxError(S.pos(), "array.dimension.missing");
1518:                    }
1519:                } else {
1520:                    ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1521:                    dims.append(expression());
1522:                    accept(RBRACKET);
1523:                    while (S.token() == LBRACKET) {
1524:                        int pos = S.pos();
1525:                        S.nextToken();
1526:                        if (S.token() == RBRACKET) {
1527:                            elemtype = bracketsOptCont(elemtype, pos);
1528:                        } else {
1529:                            dims.append(expression());
1530:                            accept(RBRACKET);
1531:                        }
1532:                    }
1533:                    return toP(F.at(newpos).NewArray(elemtype, dims.toList(),
1534:                            null));
1535:                }
1536:            }
1537:
1538:            /** ClassCreatorRest = Arguments [ClassBody]
1539:             */
1540:            JCExpression classCreatorRest(int newpos, JCExpression encl,
1541:                    List<JCExpression> typeArgs, JCExpression t) {
1542:                List<JCExpression> args = arguments();
1543:                JCClassDecl body = null;
1544:                if (S.token() == LBRACE) {
1545:                    int pos = S.pos();
1546:                    List<JCTree> defs = classOrInterfaceBody(names.empty, false);
1547:                    JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1548:                    body = toP(F.at(pos).AnonymousClassDef(mods, defs));
1549:                }
1550:                return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
1551:            }
1552:
1553:            /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
1554:             */
1555:            JCExpression arrayInitializer(int newpos, JCExpression t) {
1556:                accept(LBRACE);
1557:                ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
1558:                if (S.token() == COMMA) {
1559:                    S.nextToken();
1560:                } else if (S.token() != RBRACE) {
1561:                    elems.append(variableInitializer());
1562:                    while (S.token() == COMMA) {
1563:                        S.nextToken();
1564:                        if (S.token() == RBRACE)
1565:                            break;
1566:                        elems.append(variableInitializer());
1567:                    }
1568:                }
1569:                accept(RBRACE);
1570:                return toP(F.at(newpos).NewArray(t, List.<JCExpression> nil(),
1571:                        elems.toList()));
1572:            }
1573:
1574:            /** VariableInitializer = ArrayInitializer | Expression
1575:             */
1576:            public JCExpression variableInitializer() {
1577:                return S.token() == LBRACE ? arrayInitializer(S.pos(), null)
1578:                        : expression();
1579:            }
1580:
1581:            /** ParExpression = "(" Expression ")"
1582:             */
1583:            JCExpression parExpression() {
1584:                accept(LPAREN);
1585:                JCExpression t = expression();
1586:                accept(RPAREN);
1587:                return t;
1588:            }
1589:
1590:            /** Block = "{" BlockStatements "}"
1591:             */
1592:            JCBlock block(int pos, long flags) {
1593:                accept(LBRACE);
1594:                List<JCStatement> stats = blockStatements();
1595:                JCBlock t = F.at(pos).Block(flags, stats);
1596:                while (S.token() == CASE || S.token() == DEFAULT) {
1597:                    syntaxError("orphaned", keywords.token2string(S.token()));
1598:                    switchBlockStatementGroups();
1599:                }
1600:                // the Block node has a field "endpos" for first char of last token, which is
1601:                // usually but not necessarily the last char of the last token.
1602:                t.endpos = S.pos();
1603:                accept(RBRACE);
1604:                return toP(t);
1605:            }
1606:
1607:            public JCBlock block() {
1608:                return block(S.pos(), 0);
1609:            }
1610:
1611:            /** BlockStatements = { BlockStatement }
1612:             *  BlockStatement  = LocalVariableDeclarationStatement
1613:             *                  | ClassOrInterfaceOrEnumDeclaration
1614:             *                  | [Ident ":"] Statement
1615:             *  LocalVariableDeclarationStatement
1616:             *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
1617:             */
1618:            @SuppressWarnings("fallthrough")
1619:            List<JCStatement> blockStatements() {
1620:                //todo: skip to anchor on error(?)
1621:                int lastErrPos = -1;
1622:                ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1623:                while (true) {
1624:                    int pos = S.pos();
1625:                    switch (S.token()) {
1626:                    case RBRACE:
1627:                    case CASE:
1628:                    case DEFAULT:
1629:                    case EOF:
1630:                        return stats.toList();
1631:                    case LBRACE:
1632:                    case IF:
1633:                    case FOR:
1634:                    case WHILE:
1635:                    case DO:
1636:                    case TRY:
1637:                    case SWITCH:
1638:                    case SYNCHRONIZED:
1639:                    case RETURN:
1640:                    case THROW:
1641:                    case BREAK:
1642:                    case CONTINUE:
1643:                    case SEMI:
1644:                    case ELSE:
1645:                    case FINALLY:
1646:                    case CATCH:
1647:                        stats.append(statement());
1648:                        break;
1649:                    case MONKEYS_AT:
1650:                    case FINAL: {
1651:                        String dc = S.docComment();
1652:                        JCModifiers mods = modifiersOpt();
1653:                        if (S.token() == INTERFACE || S.token() == CLASS
1654:                                || allowEnums && S.token() == ENUM) {
1655:                            stats.append(classOrInterfaceOrEnumDeclaration(
1656:                                    mods, dc));
1657:                        } else {
1658:                            JCExpression t = type();
1659:                            stats.appendList(variableDeclarators(mods, t,
1660:                                    new ListBuffer<JCStatement>()));
1661:                            // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1662:                            storeEnd(stats.elems.last(), S.endPos());
1663:                            accept(SEMI);
1664:                        }
1665:                        break;
1666:                    }
1667:                    case ABSTRACT:
1668:                    case STRICTFP: {
1669:                        String dc = S.docComment();
1670:                        JCModifiers mods = modifiersOpt();
1671:                        stats
1672:                                .append(classOrInterfaceOrEnumDeclaration(mods,
1673:                                        dc));
1674:                        break;
1675:                    }
1676:                    case INTERFACE:
1677:                    case CLASS:
1678:                        stats.append(classOrInterfaceOrEnumDeclaration(
1679:                                modifiersOpt(), S.docComment()));
1680:                        break;
1681:                    case ENUM:
1682:                    case ASSERT:
1683:                        if (allowEnums && S.token() == ENUM) {
1684:                            log.error(S.pos(), "local.enum");
1685:                            stats.append(classOrInterfaceOrEnumDeclaration(
1686:                                    modifiersOpt(), S.docComment()));
1687:                            break;
1688:                        } else if (allowAsserts && S.token() == ASSERT) {
1689:                            stats.append(statement());
1690:                            break;
1691:                        }
1692:                        /* fall through to default */
1693:                    default:
1694:                        Name name = S.name();
1695:                        JCExpression t = term(EXPR | TYPE);
1696:                        if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
1697:                            S.nextToken();
1698:                            JCStatement stat = statement();
1699:                            stats.append(F.at(pos).Labelled(name, stat));
1700:                        } else if ((lastmode & TYPE) != 0
1701:                                && (S.token() == IDENTIFIER
1702:                                        || S.token() == ASSERT || S.token() == ENUM)) {
1703:                            pos = S.pos();
1704:                            JCModifiers mods = F.at(Position.NOPOS)
1705:                                    .Modifiers(0);
1706:                            F.at(pos);
1707:                            stats.appendList(variableDeclarators(mods, t,
1708:                                    new ListBuffer<JCStatement>()));
1709:                            // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1710:                            storeEnd(stats.elems.last(), S.endPos());
1711:                            accept(SEMI);
1712:                        } else {
1713:                            // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1714:                            stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1715:                            accept(SEMI);
1716:                        }
1717:                    }
1718:
1719:                    // error recovery
1720:                    if (S.pos() == lastErrPos)
1721:                        return stats.toList();
1722:                    if (S.pos() <= errorEndPos) {
1723:                        skip(false, true, true, true);
1724:                        lastErrPos = S.pos();
1725:                    }
1726:
1727:                    // ensure no dangling /** @deprecated */ active
1728:                    S.resetDeprecatedFlag();
1729:                }
1730:            }
1731:
1732:            /** Statement =
1733:             *       Block
1734:             *     | IF ParExpression Statement [ELSE Statement]
1735:             *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1736:             *     | FOR "(" FormalParameter : Expression ")" Statement
1737:             *     | WHILE ParExpression Statement
1738:             *     | DO Statement WHILE ParExpression ";"
1739:             *     | TRY Block ( Catches | [Catches] FinallyPart )
1740:             *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1741:             *     | SYNCHRONIZED ParExpression Block
1742:             *     | RETURN [Expression] ";"
1743:             *     | THROW Expression ";"
1744:             *     | BREAK [Ident] ";"
1745:             *     | CONTINUE [Ident] ";"
1746:             *     | ASSERT Expression [ ":" Expression ] ";"
1747:             *     | ";"
1748:             *     | ExpressionStatement
1749:             *     | Ident ":" Statement
1750:             */
1751:            @SuppressWarnings("fallthrough")
1752:            public JCStatement statement() {
1753:                int pos = S.pos();
1754:                switch (S.token()) {
1755:                case LBRACE:
1756:                    return block();
1757:                case IF: {
1758:                    S.nextToken();
1759:                    JCExpression cond = parExpression();
1760:                    JCStatement thenpart = statement();
1761:                    JCStatement elsepart = null;
1762:                    if (S.token() == ELSE) {
1763:                        S.nextToken();
1764:                        elsepart = statement();
1765:                    }
1766:                    return F.at(pos).If(cond, thenpart, elsepart);
1767:                }
1768:                case FOR: {
1769:                    S.nextToken();
1770:                    accept(LPAREN);
1771:                    List<JCStatement> inits = S.token() == SEMI ? List
1772:                            .<JCStatement> nil() : forInit();
1773:                    if (inits.length() == 1
1774:                            && inits.head.getTag() == JCTree.VARDEF
1775:                            && ((JCVariableDecl) inits.head).init == null
1776:                            && S.token() == COLON) {
1777:                        checkForeach();
1778:                        JCVariableDecl var = (JCVariableDecl) inits.head;
1779:                        accept(COLON);
1780:                        JCExpression expr = expression();
1781:                        accept(RPAREN);
1782:                        JCStatement body = statement();
1783:                        return F.at(pos).ForeachLoop(var, expr, body);
1784:                    } else {
1785:                        accept(SEMI);
1786:                        JCExpression cond = S.token() == SEMI ? null
1787:                                : expression();
1788:                        accept(SEMI);
1789:                        List<JCExpressionStatement> steps = S.token() == RPAREN ? List
1790:                                .<JCExpressionStatement> nil()
1791:                                : forUpdate();
1792:                        accept(RPAREN);
1793:                        JCStatement body = statement();
1794:                        return F.at(pos).ForLoop(inits, cond, steps, body);
1795:                    }
1796:                }
1797:                case WHILE: {
1798:                    S.nextToken();
1799:                    JCExpression cond = parExpression();
1800:                    JCStatement body = statement();
1801:                    return F.at(pos).WhileLoop(cond, body);
1802:                }
1803:                case DO: {
1804:                    S.nextToken();
1805:                    JCStatement body = statement();
1806:                    accept(WHILE);
1807:                    JCExpression cond = parExpression();
1808:                    JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1809:                    accept(SEMI);
1810:                    return t;
1811:                }
1812:                case TRY: {
1813:                    S.nextToken();
1814:                    JCBlock body = block();
1815:                    ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1816:                    JCBlock finalizer = null;
1817:                    if (S.token() == CATCH || S.token() == FINALLY) {
1818:                        while (S.token() == CATCH)
1819:                            catchers.append(catchClause());
1820:                        if (S.token() == FINALLY) {
1821:                            S.nextToken();
1822:                            finalizer = block();
1823:                        }
1824:                    } else {
1825:                        log.error(pos, "try.without.catch.or.finally");
1826:                    }
1827:                    return F.at(pos).Try(body, catchers.toList(), finalizer);
1828:                }
1829:                case SWITCH: {
1830:                    S.nextToken();
1831:                    JCExpression selector = parExpression();
1832:                    accept(LBRACE);
1833:                    List<JCCase> cases = switchBlockStatementGroups();
1834:                    JCSwitch t = to(F.at(pos).Switch(selector, cases));
1835:                    accept(RBRACE);
1836:                    return t;
1837:                }
1838:                case SYNCHRONIZED: {
1839:                    S.nextToken();
1840:                    JCExpression lock = parExpression();
1841:                    JCBlock body = block();
1842:                    return F.at(pos).Synchronized(lock, body);
1843:                }
1844:                case RETURN: {
1845:                    S.nextToken();
1846:                    JCExpression result = S.token() == SEMI ? null
1847:                            : expression();
1848:                    JCReturn t = to(F.at(pos).Return(result));
1849:                    accept(SEMI);
1850:                    return t;
1851:                }
1852:                case THROW: {
1853:                    S.nextToken();
1854:                    JCExpression exc = expression();
1855:                    JCThrow t = to(F.at(pos).Throw(exc));
1856:                    accept(SEMI);
1857:                    return t;
1858:                }
1859:                case BREAK: {
1860:                    S.nextToken();
1861:                    Name label = (S.token() == IDENTIFIER
1862:                            || S.token() == ASSERT || S.token() == ENUM) ? ident()
1863:                            : null;
1864:                    JCBreak t = to(F.at(pos).Break(label));
1865:                    accept(SEMI);
1866:                    return t;
1867:                }
1868:                case CONTINUE: {
1869:                    S.nextToken();
1870:                    Name label = (S.token() == IDENTIFIER
1871:                            || S.token() == ASSERT || S.token() == ENUM) ? ident()
1872:                            : null;
1873:                    JCContinue t = to(F.at(pos).Continue(label));
1874:                    accept(SEMI);
1875:                    return t;
1876:                }
1877:                case SEMI:
1878:                    S.nextToken();
1879:                    return toP(F.at(pos).Skip());
1880:                case ELSE:
1881:                    return toP(F.Exec(syntaxError("else.without.if")));
1882:                case FINALLY:
1883:                    return toP(F.Exec(syntaxError("finally.without.try")));
1884:                case CATCH:
1885:                    return toP(F.Exec(syntaxError("catch.without.try")));
1886:                case ASSERT: {
1887:                    if (allowAsserts && S.token() == ASSERT) {
1888:                        S.nextToken();
1889:                        JCExpression assertion = expression();
1890:                        JCExpression message = null;
1891:                        if (S.token() == COLON) {
1892:                            S.nextToken();
1893:                            message = expression();
1894:                        }
1895:                        JCAssert t = to(F.at(pos).Assert(assertion, message));
1896:                        accept(SEMI);
1897:                        return t;
1898:                    }
1899:                    /* else fall through to default case */
1900:                }
1901:                case ENUM:
1902:                default:
1903:                    Name name = S.name();
1904:                    JCExpression expr = expression();
1905:                    if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
1906:                        S.nextToken();
1907:                        JCStatement stat = statement();
1908:                        return F.at(pos).Labelled(name, stat);
1909:                    } else {
1910:                        // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1911:                        JCExpressionStatement stat = to(F.at(pos).Exec(
1912:                                checkExprStat(expr)));
1913:                        accept(SEMI);
1914:                        return stat;
1915:                    }
1916:                }
1917:            }
1918:
1919:            /** CatchClause     = CATCH "(" FormalParameter ")" Block
1920:             */
1921:            JCCatch catchClause() {
1922:                int pos = S.pos();
1923:                accept(CATCH);
1924:                accept(LPAREN);
1925:                JCVariableDecl formal = variableDeclaratorId(
1926:                        optFinal(Flags.PARAMETER), qualident());
1927:                accept(RPAREN);
1928:                JCBlock body = block();
1929:                return F.at(pos).Catch(formal, body);
1930:            }
1931:
1932:            /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
1933:             *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
1934:             *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
1935:             */
1936:            List<JCCase> switchBlockStatementGroups() {
1937:                ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
1938:                while (true) {
1939:                    int pos = S.pos();
1940:                    switch (S.token()) {
1941:                    case CASE: {
1942:                        S.nextToken();
1943:                        JCExpression pat = expression();
1944:                        accept(COLON);
1945:                        List<JCStatement> stats = blockStatements();
1946:                        JCCase c = F.at(pos).Case(pat, stats);
1947:                        if (stats.isEmpty())
1948:                            storeEnd(c, S.prevEndPos());
1949:                        cases.append(c);
1950:                        break;
1951:                    }
1952:                    case DEFAULT: {
1953:                        S.nextToken();
1954:                        accept(COLON);
1955:                        List<JCStatement> stats = blockStatements();
1956:                        JCCase c = F.at(pos).Case(null, stats);
1957:                        if (stats.isEmpty())
1958:                            storeEnd(c, S.prevEndPos());
1959:                        cases.append(c);
1960:                        break;
1961:                    }
1962:                    case RBRACE:
1963:                    case EOF:
1964:                        return cases.toList();
1965:                    default:
1966:                        S.nextToken(); // to ensure progress
1967:                        syntaxError(pos, "expected3", keywords
1968:                                .token2string(CASE), keywords
1969:                                .token2string(DEFAULT), keywords
1970:                                .token2string(RBRACE));
1971:                    }
1972:                }
1973:            }
1974:
1975:            /** MoreStatementExpressions = { COMMA StatementExpression }
1976:             */
1977:            <T extends ListBuffer<? super  JCExpressionStatement>> T moreStatementExpressions(
1978:                    int pos, JCExpression first, T stats) {
1979:                // This Exec is a "StatementExpression"; it subsumes no terminating token
1980:                stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
1981:                while (S.token() == COMMA) {
1982:                    S.nextToken();
1983:                    pos = S.pos();
1984:                    JCExpression t = expression();
1985:                    // This Exec is a "StatementExpression"; it subsumes no terminating token
1986:                    stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
1987:                }
1988:                return stats;
1989:            }
1990:
1991:            /** ForInit = StatementExpression MoreStatementExpressions
1992:             *           |  { FINAL | '@' Annotation } Type VariableDeclarators
1993:             */
1994:            List<JCStatement> forInit() {
1995:                ListBuffer<JCStatement> stats = lb();
1996:                int pos = S.pos();
1997:                if (S.token() == FINAL || S.token() == MONKEYS_AT) {
1998:                    return variableDeclarators(optFinal(0), type(), stats)
1999:                            .toList();
2000:                } else {
2001:                    JCExpression t = term(EXPR | TYPE);
2002:                    if ((lastmode & TYPE) != 0
2003:                            && (S.token() == IDENTIFIER || S.token() == ASSERT || S
2004:                                    .token() == ENUM))
2005:                        return variableDeclarators(modifiersOpt(), t, stats)
2006:                                .toList();
2007:                    else
2008:                        return moreStatementExpressions(pos, t, stats).toList();
2009:                }
2010:            }
2011:
2012:            /** ForUpdate = StatementExpression MoreStatementExpressions
2013:             */
2014:            List<JCExpressionStatement> forUpdate() {
2015:                return moreStatementExpressions(S.pos(), expression(),
2016:                        new ListBuffer<JCExpressionStatement>()).toList();
2017:            }
2018:
2019:            /** AnnotationsOpt = { '@' Annotation }
2020:             */
2021:            List<JCAnnotation> annotationsOpt() {
2022:                if (S.token() != MONKEYS_AT)
2023:                    return List.nil(); // optimization
2024:                ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2025:                while (S.token() == MONKEYS_AT) {
2026:                    int pos = S.pos();
2027:                    S.nextToken();
2028:                    buf.append(annotation(pos));
2029:                }
2030:                return buf.toList();
2031:            }
2032:
2033:            /** ModifiersOpt = { Modifier }
2034:             *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2035:             *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2036:             *           | "@" Annotation
2037:             */
2038:            JCModifiers modifiersOpt() {
2039:                return modifiersOpt(null);
2040:            }
2041:
2042:            JCModifiers modifiersOpt(JCModifiers partial) {
2043:                long flags = (partial == null) ? 0 : partial.flags;
2044:                if (S.deprecatedFlag()) {
2045:                    flags |= Flags.DEPRECATED;
2046:                    S.resetDeprecatedFlag();
2047:                }
2048:                ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2049:                if (partial != null)
2050:                    annotations.appendList(partial.annotations);
2051:                int pos = S.pos();
2052:                int lastPos = Position.NOPOS;
2053:                loop: while (true) {
2054:                    long flag;
2055:                    switch (S.token()) {
2056:                    case PRIVATE:
2057:                        flag = Flags.PRIVATE;
2058:                        break;
2059:                    case PROTECTED:
2060:                        flag = Flags.PROTECTED;
2061:                        break;
2062:                    case PUBLIC:
2063:                        flag = Flags.PUBLIC;
2064:                        break;
2065:                    case STATIC:
2066:                        flag = Flags.STATIC;
2067:                        break;
2068:                    case TRANSIENT:
2069:                        flag = Flags.TRANSIENT;
2070:                        break;
2071:                    case FINAL:
2072:                        flag = Flags.FINAL;
2073:                        break;
2074:                    case ABSTRACT:
2075:                        flag = Flags.ABSTRACT;
2076:                        break;
2077:                    case NATIVE:
2078:                        flag = Flags.NATIVE;
2079:                        break;
2080:                    case VOLATILE:
2081:                        flag = Flags.VOLATILE;
2082:                        break;
2083:                    case SYNCHRONIZED:
2084:                        flag = Flags.SYNCHRONIZED;
2085:                        break;
2086:                    case STRICTFP:
2087:                        flag = Flags.STRICTFP;
2088:                        break;
2089:                    case MONKEYS_AT:
2090:                        flag = Flags.ANNOTATION;
2091:                        break;
2092:                    default:
2093:                        break loop;
2094:                    }
2095:                    if ((flags & flag) != 0)
2096:                        log.error(S.pos(), "repeated.modifier");
2097:                    lastPos = S.pos();
2098:                    S.nextToken();
2099:                    if (flag == Flags.ANNOTATION) {
2100:                        checkAnnotations();
2101:                        if (S.token() != INTERFACE) {
2102:                            JCAnnotation ann = annotation(lastPos);
2103:                            // if first modifier is an annotation, set pos to annotation's.
2104:                            if (flags == 0 && annotations.isEmpty())
2105:                                pos = ann.pos;
2106:                            annotations.append(ann);
2107:                            lastPos = ann.pos;
2108:                            flag = 0;
2109:                        }
2110:                    }
2111:                    flags |= flag;
2112:                }
2113:                switch (S.token()) {
2114:                case ENUM:
2115:                    flags |= Flags.ENUM;
2116:                    break;
2117:                case INTERFACE:
2118:                    flags |= Flags.INTERFACE;
2119:                    break;
2120:                default:
2121:                    break;
2122:                }
2123:
2124:                /* A modifiers tree with no modifier tokens or annotations
2125:                 * has no text position. */
2126:                if (flags == 0 && annotations.isEmpty())
2127:                    pos = Position.NOPOS;
2128:
2129:                JCModifiers mods = F.at(pos).Modifiers(flags,
2130:                        annotations.toList());
2131:                if (pos != Position.NOPOS)
2132:                    storeEnd(mods, S.prevEndPos());
2133:                return mods;
2134:            }
2135:
2136:            /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2137:             * @param pos position of "@" token
2138:             */
2139:            JCAnnotation annotation(int pos) {
2140:                // accept(AT); // AT consumed by caller
2141:                checkAnnotations();
2142:                JCTree ident = qualident();
2143:                List<JCExpression> fieldValues = annotationFieldValuesOpt();
2144:                JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
2145:                storeEnd(ann, S.prevEndPos());
2146:                return ann;
2147:            }
2148:
2149:            List<JCExpression> annotationFieldValuesOpt() {
2150:                return (S.token() == LPAREN) ? annotationFieldValues() : List
2151:                        .<JCExpression> nil();
2152:            }
2153:
2154:            /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2155:            List<JCExpression> annotationFieldValues() {
2156:                accept(LPAREN);
2157:                ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2158:                if (S.token() != RPAREN) {
2159:                    buf.append(annotationFieldValue());
2160:                    while (S.token() == COMMA) {
2161:                        S.nextToken();
2162:                        buf.append(annotationFieldValue());
2163:                    }
2164:                }
2165:                accept(RPAREN);
2166:                return buf.toList();
2167:            }
2168:
2169:            /** AnnotationFieldValue    = AnnotationValue
2170:             *                          | Identifier "=" AnnotationValue
2171:             */
2172:            JCExpression annotationFieldValue() {
2173:                if (S.token() == IDENTIFIER) {
2174:                    mode = EXPR;
2175:                    JCExpression t1 = term1();
2176:                    if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
2177:                        int pos = S.pos();
2178:                        accept(EQ);
2179:                        return toP(F.at(pos).Assign(t1, annotationValue()));
2180:                    } else {
2181:                        return t1;
2182:                    }
2183:                }
2184:                return annotationValue();
2185:            }
2186:
2187:            /* AnnotationValue          = ConditionalExpression
2188:             *                          | Annotation
2189:             *                          | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
2190:             */
2191:            JCExpression annotationValue() {
2192:                int pos;
2193:                switch (S.token()) {
2194:                case MONKEYS_AT:
2195:                    pos = S.pos();
2196:                    S.nextToken();
2197:                    return annotation(pos);
2198:                case LBRACE:
2199:                    pos = S.pos();
2200:                    accept(LBRACE);
2201:                    ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2202:                    if (S.token() != RBRACE) {
2203:                        buf.append(annotationValue());
2204:                        while (S.token() == COMMA) {
2205:                            S.nextToken();
2206:                            if (S.token() == RPAREN)
2207:                                break;
2208:                            buf.append(annotationValue());
2209:                        }
2210:                    }
2211:                    accept(RBRACE);
2212:                    return toP(F.at(pos).NewArray(null,
2213:                            List.<JCExpression> nil(), buf.toList()));
2214:                default:
2215:                    mode = EXPR;
2216:                    return term1();
2217:                }
2218:            }
2219:
2220:            /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2221:             */
2222:            public <T extends ListBuffer<? super  JCVariableDecl>> T variableDeclarators(
2223:                    JCModifiers mods, JCExpression type, T vdefs) {
2224:                return variableDeclaratorsRest(S.pos(), mods, type, ident(),
2225:                        false, null, vdefs);
2226:            }
2227:
2228:            /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2229:             *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2230:             *
2231:             *  @param reqInit  Is an initializer always required?
2232:             *  @param dc       The documentation comment for the variable declarations, or null.
2233:             */
2234:            <T extends ListBuffer<? super  JCVariableDecl>> T variableDeclaratorsRest(
2235:                    int pos, JCModifiers mods, JCExpression type, Name name,
2236:                    boolean reqInit, String dc, T vdefs) {
2237:                vdefs.append(variableDeclaratorRest(pos, mods, type, name,
2238:                        reqInit, dc));
2239:                while (S.token() == COMMA) {
2240:                    // All but last of multiple declarators subsume a comma
2241:                    storeEnd((JCTree) vdefs.elems.last(), S.endPos());
2242:                    S.nextToken();
2243:                    vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2244:                }
2245:                return vdefs;
2246:            }
2247:
2248:            /** VariableDeclarator = Ident VariableDeclaratorRest
2249:             *  ConstantDeclarator = Ident ConstantDeclaratorRest
2250:             */
2251:            JCVariableDecl variableDeclarator(JCModifiers mods,
2252:                    JCExpression type, boolean reqInit, String dc) {
2253:                return variableDeclaratorRest(S.pos(), mods, type, ident(),
2254:                        reqInit, dc);
2255:            }
2256:
2257:            /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2258:             *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2259:             *
2260:             *  @param reqInit  Is an initializer always required?
2261:             *  @param dc       The documentation comment for the variable declarations, or null.
2262:             */
2263:            JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods,
2264:                    JCExpression type, Name name, boolean reqInit, String dc) {
2265:                type = bracketsOpt(type);
2266:                JCExpression init = null;
2267:                if (S.token() == EQ) {
2268:                    S.nextToken();
2269:                    init = variableInitializer();
2270:                } else if (reqInit)
2271:                    syntaxError(S.pos(), "expected", keywords.token2string(EQ));
2272:                JCVariableDecl result = toP(F.at(pos).VarDef(mods, name, type,
2273:                        init));
2274:                attach(result, dc);
2275:                return result;
2276:            }
2277:
2278:            /** VariableDeclaratorId = Ident BracketsOpt
2279:             */
2280:            JCVariableDecl variableDeclaratorId(JCModifiers mods,
2281:                    JCExpression type) {
2282:                int pos = S.pos();
2283:                Name name = ident();
2284:                if ((mods.flags & Flags.VARARGS) == 0)
2285:                    type = bracketsOpt(type);
2286:                return toP(F.at(pos).VarDef(mods, name, type, null));
2287:            }
2288:
2289:            /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2290:             */
2291:            public JCTree.JCCompilationUnit compilationUnit() {
2292:                int pos = S.pos();
2293:                JCExpression pid = null;
2294:                String dc = S.docComment();
2295:                JCModifiers mods = null;
2296:                List<JCAnnotation> packageAnnotations = List.nil();
2297:                if (S.token() == MONKEYS_AT)
2298:                    mods = modifiersOpt();
2299:
2300:                if (S.token() == PACKAGE) {
2301:                    if (mods != null) {
2302:                        checkNoMods(mods.flags);
2303:                        packageAnnotations = mods.annotations;
2304:                        mods = null;
2305:                    }
2306:                    S.nextToken();
2307:                    pid = qualident();
2308:                    accept(SEMI);
2309:                }
2310:                ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2311:                boolean checkForImports = true;
2312:                while (S.token() != EOF) {
2313:                    if (S.pos() <= errorEndPos) {
2314:                        // error recovery
2315:                        skip(checkForImports, false, false, false);
2316:                        if (S.token() == EOF)
2317:                            break;
2318:                    }
2319:                    if (checkForImports && mods == null && S.token() == IMPORT) {
2320:                        defs.append(importDeclaration());
2321:                    } else {
2322:                        JCTree def = typeDeclaration(mods);
2323:                        if (def instanceof  JCExpressionStatement)
2324:                            def = ((JCExpressionStatement) def).expr;
2325:                        defs.append(def);
2326:                        if (def instanceof  JCClassDecl)
2327:                            checkForImports = false;
2328:                        mods = null;
2329:                    }
2330:                }
2331:                JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(
2332:                        packageAnnotations, pid, defs.toList());
2333:                attach(toplevel, dc);
2334:                if (defs.elems.isEmpty())
2335:                    storeEnd(toplevel, S.prevEndPos());
2336:                if (keepDocComments)
2337:                    toplevel.docComments = docComments;
2338:                return toplevel;
2339:            }
2340:
2341:            /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2342:             */
2343:            JCTree importDeclaration() {
2344:                int pos = S.pos();
2345:                S.nextToken();
2346:                boolean importStatic = false;
2347:                if (S.token() == STATIC) {
2348:                    checkStaticImports();
2349:                    importStatic = true;
2350:                    S.nextToken();
2351:                }
2352:                JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
2353:                do {
2354:                    int pos1 = S.pos();
2355:                    accept(DOT);
2356:                    if (S.token() == STAR) {
2357:                        pid = to(F.at(pos1).Select(pid, names.asterisk));
2358:                        S.nextToken();
2359:                        break;
2360:                    } else {
2361:                        pid = toP(F.at(pos1).Select(pid, ident()));
2362:                    }
2363:                } while (S.token() == DOT);
2364:                accept(SEMI);
2365:                return toP(F.at(pos).Import(pid, importStatic));
2366:            }
2367:
2368:            /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
2369:             *                  | ";"
2370:             */
2371:            JCTree typeDeclaration(JCModifiers mods) {
2372:                int pos = S.pos();
2373:                if (mods == null && S.token() == SEMI) {
2374:                    S.nextToken();
2375:                    return toP(F.at(pos).Skip());
2376:                } else {
2377:                    String dc = S.docComment();
2378:                    return classOrInterfaceOrEnumDeclaration(
2379:                            modifiersOpt(mods), dc);
2380:                }
2381:            }
2382:
2383:            /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
2384:             *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
2385:             *  @param mods     Any modifiers starting the class or interface declaration
2386:             *  @param dc       The documentation comment for the class, or null.
2387:             */
2388:            JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods,
2389:                    String dc) {
2390:                if (S.token() == CLASS) {
2391:                    return classDeclaration(mods, dc);
2392:                } else if (S.token() == INTERFACE) {
2393:                    return interfaceDeclaration(mods, dc);
2394:                } else if (allowEnums) {
2395:                    if (S.token() == ENUM) {
2396:                        return enumDeclaration(mods, dc);
2397:                    } else {
2398:                        int pos = S.pos();
2399:                        List<JCTree> errs;
2400:                        if (S.token() == IDENTIFIER) {
2401:                            errs = List.<JCTree> of(mods, toP(F.at(pos).Ident(
2402:                                    ident())));
2403:                            setErrorEndPos(S.pos());
2404:                        } else {
2405:                            errs = List.<JCTree> of(mods);
2406:                        }
2407:                        return toP(F.Exec(syntaxError(pos, errs, "expected3",
2408:                                keywords.token2string(CLASS), keywords
2409:                                        .token2string(INTERFACE), keywords
2410:                                        .token2string(ENUM))));
2411:                    }
2412:                } else {
2413:                    if (S.token() == ENUM) {
2414:                        log.error(S.pos(), "enums.not.supported.in.source",
2415:                                source.name);
2416:                        allowEnums = true;
2417:                        return enumDeclaration(mods, dc);
2418:                    }
2419:                    int pos = S.pos();
2420:                    List<JCTree> errs;
2421:                    if (S.token() == IDENTIFIER) {
2422:                        errs = List.<JCTree> of(mods, toP(F.at(pos).Ident(
2423:                                ident())));
2424:                        setErrorEndPos(S.pos());
2425:                    } else {
2426:                        errs = List.<JCTree> of(mods);
2427:                    }
2428:                    return toP(F.Exec(syntaxError(pos, errs, "expected2",
2429:                            keywords.token2string(CLASS), keywords
2430:                                    .token2string(INTERFACE))));
2431:                }
2432:            }
2433:
2434:            /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
2435:             *                     [IMPLEMENTS TypeList] ClassBody
2436:             *  @param mods    The modifiers starting the class declaration
2437:             *  @param dc       The documentation comment for the class, or null.
2438:             */
2439:            JCClassDecl classDeclaration(JCModifiers mods, String dc) {
2440:                int pos = S.pos();
2441:                accept(CLASS);
2442:                Name name = ident();
2443:
2444:                List<JCTypeParameter> typarams = typeParametersOpt();
2445:
2446:                JCTree extending = null;
2447:                if (S.token() == EXTENDS) {
2448:                    S.nextToken();
2449:                    extending = type();
2450:                }
2451:                List<JCExpression> implementing = List.nil();
2452:                if (S.token() == IMPLEMENTS) {
2453:                    S.nextToken();
2454:                    implementing = typeList();
2455:                }
2456:                List<JCTree> defs = classOrInterfaceBody(name, false);
2457:                JCClassDecl result = toP(F.at(pos).ClassDef(mods, name,
2458:                        typarams, extending, implementing, defs));
2459:                attach(result, dc);
2460:                return result;
2461:            }
2462:
2463:            /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
2464:             *                         [EXTENDS TypeList] InterfaceBody
2465:             *  @param mods    The modifiers starting the interface declaration
2466:             *  @param dc       The documentation comment for the interface, or null.
2467:             */
2468:            JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
2469:                int pos = S.pos();
2470:                accept(INTERFACE);
2471:                Name name = ident();
2472:
2473:                List<JCTypeParameter> typarams = typeParametersOpt();
2474:
2475:                List<JCExpression> extending = List.nil();
2476:                if (S.token() == EXTENDS) {
2477:                    S.nextToken();
2478:                    extending = typeList();
2479:                }
2480:                List<JCTree> defs = classOrInterfaceBody(name, true);
2481:                JCClassDecl result = toP(F.at(pos).ClassDef(mods, name,
2482:                        typarams, null, extending, defs));
2483:                attach(result, dc);
2484:                return result;
2485:            }
2486:
2487:            /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
2488:             *  @param mods    The modifiers starting the enum declaration
2489:             *  @param dc       The documentation comment for the enum, or null.
2490:             */
2491:            JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
2492:                int pos = S.pos();
2493:                accept(ENUM);
2494:                Name name = ident();
2495:
2496:                List<JCExpression> implementing = List.nil();
2497:                if (S.token() == IMPLEMENTS) {
2498:                    S.nextToken();
2499:                    implementing = typeList();
2500:                }
2501:
2502:                List<JCTree> defs = enumBody(name);
2503:                JCModifiers newMods = F.at(mods.pos).Modifiers(
2504:                        mods.flags | Flags.ENUM, mods.annotations);
2505:                JCClassDecl result = toP(F.at(pos).ClassDef(newMods, name,
2506:                        List.<JCTypeParameter> nil(), null, implementing, defs));
2507:                attach(result, dc);
2508:                return result;
2509:            }
2510:
2511:            /** EnumBody = "{" { EnumeratorDeclarationList } [","]
2512:             *                  [ ";" {ClassBodyDeclaration} ] "}"
2513:             */
2514:            List<JCTree> enumBody(Name enumName) {
2515:                accept(LBRACE);
2516:                ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2517:                if (S.token() == COMMA) {
2518:                    S.nextToken();
2519:                } else if (S.token() != RBRACE && S.token() != SEMI) {
2520:                    defs.append(enumeratorDeclaration(enumName));
2521:                    while (S.token() == COMMA) {
2522:                        S.nextToken();
2523:                        if (S.token() == RBRACE || S.token() == SEMI)
2524:                            break;
2525:                        defs.append(enumeratorDeclaration(enumName));
2526:                    }
2527:                    if (S.token() != SEMI && S.token() != RBRACE) {
2528:                        defs.append(syntaxError(S.pos(), "expected3", keywords
2529:                                .token2string(COMMA), keywords
2530:                                .token2string(RBRACE), keywords
2531:                                .token2string(SEMI)));
2532:                        S.nextToken();
2533:                    }
2534:                }
2535:                if (S.token() == SEMI) {
2536:                    S.nextToken();
2537:                    while (S.token() != RBRACE && S.token() != EOF) {
2538:                        defs.appendList(classOrInterfaceBodyDeclaration(
2539:                                enumName, false));
2540:                        if (S.pos() <= errorEndPos) {
2541:                            // error recovery
2542:                            skip(false, true, true, false);
2543:                        }
2544:                    }
2545:                }
2546:                accept(RBRACE);
2547:                return defs.toList();
2548:            }
2549:
2550:            /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
2551:             */
2552:            JCTree enumeratorDeclaration(Name enumName) {
2553:                String dc = S.docComment();
2554:                int flags = Flags.PUBLIC | Flags.STATIC | Flags.FINAL
2555:                        | Flags.ENUM;
2556:                if (S.deprecatedFlag()) {
2557:                    flags |= Flags.DEPRECATED;
2558:                    S.resetDeprecatedFlag();
2559:                }
2560:                int pos = S.pos();
2561:                List<JCAnnotation> annotations = annotationsOpt();
2562:                JCModifiers mods = F.at(
2563:                        annotations.isEmpty() ? Position.NOPOS : pos)
2564:                        .Modifiers(flags, annotations);
2565:                List<JCExpression> typeArgs = typeArgumentsOpt();
2566:                int identPos = S.pos();
2567:                Name name = ident();
2568:                int createPos = S.pos();
2569:                List<JCExpression> args = (S.token() == LPAREN) ? arguments()
2570:                        : List.<JCExpression> nil();
2571:                JCClassDecl body = null;
2572:                if (S.token() == LBRACE) {
2573:                    JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(
2574:                            Flags.ENUM | Flags.STATIC);
2575:                    List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2576:                    body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
2577:                }
2578:                if (args.isEmpty() && body == null)
2579:                    createPos = Position.NOPOS;
2580:                JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
2581:                JCNewClass create = F.at(createPos).NewClass(null, typeArgs,
2582:                        ident, args, body);
2583:                if (createPos != Position.NOPOS)
2584:                    storeEnd(create, S.prevEndPos());
2585:                ident = F.at(Position.NOPOS).Ident(enumName);
2586:                JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
2587:                attach(result, dc);
2588:                return result;
2589:            }
2590:
2591:            /** TypeList = Type {"," Type}
2592:             */
2593:            List<JCExpression> typeList() {
2594:                ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2595:                ts.append(type());
2596:                while (S.token() == COMMA) {
2597:                    S.nextToken();
2598:                    ts.append(type());
2599:                }
2600:                return ts.toList();
2601:            }
2602:
2603:            /** ClassBody     = "{" {ClassBodyDeclaration} "}"
2604:             *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2605:             */
2606:            List<JCTree> classOrInterfaceBody(Name className,
2607:                    boolean isInterface) {
2608:                accept(LBRACE);
2609:                if (S.pos() <= errorEndPos) {
2610:                    // error recovery
2611:                    skip(false, true, false, false);
2612:                    if (S.token() == LBRACE)
2613:                        S.nextToken();
2614:                }
2615:                ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2616:                while (S.token() != RBRACE && S.token() != EOF) {
2617:                    defs.appendList(classOrInterfaceBodyDeclaration(className,
2618:                            isInterface));
2619:                    if (S.pos() <= errorEndPos) {
2620:                        // error recovery
2621:                        skip(false, true, true, false);
2622:                    }
2623:                }
2624:                accept(RBRACE);
2625:                return defs.toList();
2626:            }
2627:
2628:            /** ClassBodyDeclaration =
2629:             *      ";"
2630:             *    | [STATIC] Block
2631:             *    | ModifiersOpt
2632:             *      ( Type Ident
2633:             *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
2634:             *      | VOID Ident MethodDeclaratorRest
2635:             *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
2636:             *      | Ident ConstructorDeclaratorRest
2637:             *      | TypeParameters Ident ConstructorDeclaratorRest
2638:             *      | ClassOrInterfaceOrEnumDeclaration
2639:             *      )
2640:             *  InterfaceBodyDeclaration =
2641:             *      ";"
2642:             *    | ModifiersOpt Type Ident
2643:             *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
2644:             */
2645:            List<JCTree> classOrInterfaceBodyDeclaration(Name className,
2646:                    boolean isInterface) {
2647:                if (S.token() == SEMI) {
2648:                    S.nextToken();
2649:                    return List.<JCTree> of(F.at(Position.NOPOS).Block(0,
2650:                            List.<JCStatement> nil()));
2651:                } else {
2652:                    String dc = S.docComment();
2653:                    int pos = S.pos();
2654:                    JCModifiers mods = modifiersOpt();
2655:                    if (S.token() == CLASS || S.token() == INTERFACE
2656:                            || allowEnums && S.token() == ENUM) {
2657:                        return List
2658:                                .<JCTree> of(classOrInterfaceOrEnumDeclaration(
2659:                                        mods, dc));
2660:                    } else if (S.token() == LBRACE
2661:                            && !isInterface
2662:                            && (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0
2663:                            && mods.annotations.isEmpty()) {
2664:                        return List.<JCTree> of(block(pos, mods.flags));
2665:                    } else {
2666:                        pos = S.pos();
2667:                        List<JCTypeParameter> typarams = typeParametersOpt();
2668:                        // Hack alert:  if there are type arguments but no Modifiers, the start
2669:                        // position will be lost unless we set the Modifiers position.  There
2670:                        // should be an AST node for type parameters (BugId 5005090).
2671:                        if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
2672:                            mods.pos = pos;
2673:                        }
2674:                        Token token = S.token();
2675:                        Name name = S.name();
2676:                        pos = S.pos();
2677:                        JCExpression type;
2678:                        boolean isVoid = S.token() == VOID;
2679:                        if (isVoid) {
2680:                            type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2681:                            S.nextToken();
2682:                        } else {
2683:                            type = type();
2684:                        }
2685:                        if (S.token() == LPAREN && !isInterface
2686:                                && type.getTag() == JCTree.IDENT) {
2687:                            if (isInterface || name != className)
2688:                                log
2689:                                        .error(pos,
2690:                                                "invalid.meth.decl.ret.type.req");
2691:                            return List.of(methodDeclaratorRest(pos, mods,
2692:                                    null, names.init, typarams, isInterface,
2693:                                    true, dc));
2694:                        } else {
2695:                            pos = S.pos();
2696:                            name = ident();
2697:                            if (S.token() == LPAREN) {
2698:                                return List.of(methodDeclaratorRest(pos, mods,
2699:                                        type, name, typarams, isInterface,
2700:                                        isVoid, dc));
2701:                            } else if (!isVoid && typarams.isEmpty()) {
2702:                                List<JCTree> defs = variableDeclaratorsRest(
2703:                                        pos, mods, type, name, isInterface, dc,
2704:                                        new ListBuffer<JCTree>()).toList();
2705:                                storeEnd(defs.last(), S.endPos());
2706:                                accept(SEMI);
2707:                                return defs;
2708:                            } else {
2709:                                pos = S.pos();
2710:                                List<JCTree> err = isVoid ? List
2711:                                        .<JCTree> of(toP(F.at(pos).MethodDef(
2712:                                                mods, name, type, typarams,
2713:                                                List.<JCVariableDecl> nil(),
2714:                                                List.<JCExpression> nil(),
2715:                                                null, null))) : null;
2716:                                return List.<JCTree> of(syntaxError(S.pos(),
2717:                                        err, "expected", keywords
2718:                                                .token2string(LPAREN)));
2719:                            }
2720:                        }
2721:                    }
2722:                }
2723:            }
2724:
2725:            /** MethodDeclaratorRest =
2726:             *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2727:             *  VoidMethodDeclaratorRest =
2728:             *      FormalParameters [Throws TypeList] ( MethodBody | ";")
2729:             *  InterfaceMethodDeclaratorRest =
2730:             *      FormalParameters BracketsOpt [THROWS TypeList] ";"
2731:             *  VoidInterfaceMethodDeclaratorRest =
2732:             *      FormalParameters [THROWS TypeList] ";"
2733:             *  ConstructorDeclaratorRest =
2734:             *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
2735:             */
2736:            JCTree methodDeclaratorRest(int pos, JCModifiers mods,
2737:                    JCExpression type, Name name,
2738:                    List<JCTypeParameter> typarams, boolean isInterface,
2739:                    boolean isVoid, String dc) {
2740:                List<JCVariableDecl> params = formalParameters();
2741:                if (!isVoid)
2742:                    type = bracketsOpt(type);
2743:                List<JCExpression> thrown = List.nil();
2744:                if (S.token() == THROWS) {
2745:                    S.nextToken();
2746:                    thrown = qualidentList();
2747:                }
2748:                JCBlock body = null;
2749:                JCExpression defaultValue;
2750:                if (S.token() == LBRACE) {
2751:                    body = block();
2752:                    defaultValue = null;
2753:                } else {
2754:                    if (S.token() == DEFAULT) {
2755:                        accept(DEFAULT);
2756:                        defaultValue = annotationValue();
2757:                    } else {
2758:                        defaultValue = null;
2759:                    }
2760:                    accept(SEMI);
2761:                    if (S.pos() <= errorEndPos) {
2762:                        // error recovery
2763:                        skip(false, true, false, false);
2764:                        if (S.token() == LBRACE) {
2765:                            body = block();
2766:                        }
2767:                    }
2768:                }
2769:                JCMethodDecl result = toP(F.at(pos).MethodDef(mods, name, type,
2770:                        typarams, params, thrown, body, defaultValue));
2771:                attach(result, dc);
2772:                return result;
2773:            }
2774:
2775:            /** QualidentList = Qualident {"," Qualident}
2776:             */
2777:            List<JCExpression> qualidentList() {
2778:                ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2779:                ts.append(qualident());
2780:                while (S.token() == COMMA) {
2781:                    S.nextToken();
2782:                    ts.append(qualident());
2783:                }
2784:                return ts.toList();
2785:            }
2786:
2787:            /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2788:             */
2789:            List<JCTypeParameter> typeParametersOpt() {
2790:                if (S.token() == LT) {
2791:                    checkGenerics();
2792:                    ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
2793:                    S.nextToken();
2794:                    typarams.append(typeParameter());
2795:                    while (S.token() == COMMA) {
2796:                        S.nextToken();
2797:                        typarams.append(typeParameter());
2798:                    }
2799:                    accept(GT);
2800:                    return typarams.toList();
2801:                } else {
2802:                    return List.nil();
2803:                }
2804:            }
2805:
2806:            /** TypeParameter = TypeVariable [TypeParameterBound]
2807:             *  TypeParameterBound = EXTENDS Type {"&" Type}
2808:             *  TypeVariable = Ident
2809:             */
2810:            JCTypeParameter typeParameter() {
2811:                int pos = S.pos();
2812:                Name name = ident();
2813:                ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
2814:                if (S.token() == EXTENDS) {
2815:                    S.nextToken();
2816:                    bounds.append(type());
2817:                    while (S.token() == AMP) {
2818:                        S.nextToken();
2819:                        bounds.append(type());
2820:                    }
2821:                }
2822:                return toP(F.at(pos).TypeParameter(name, bounds.toList()));
2823:            }
2824:
2825:            /** FormalParameters = "(" [ FormalParameterList ] ")"
2826:             *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
2827:             *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
2828:             */
2829:            List<JCVariableDecl> formalParameters() {
2830:                ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
2831:                JCVariableDecl lastParam = null;
2832:                accept(LPAREN);
2833:                if (S.token() != RPAREN) {
2834:                    params.append(lastParam = formalParameter());
2835:                    while ((lastParam.mods.flags & Flags.VARARGS) == 0
2836:                            && S.token() == COMMA) {
2837:                        S.nextToken();
2838:                        params.append(lastParam = formalParameter());
2839:                    }
2840:                }
2841:                accept(RPAREN);
2842:                return params.toList();
2843:            }
2844:
2845:            JCModifiers optFinal(long flags) {
2846:                JCModifiers mods = modifiersOpt();
2847:                checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
2848:                mods.flags |= flags;
2849:                return mods;
2850:            }
2851:
2852:            /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
2853:             *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
2854:             */
2855:            JCVariableDecl formalParameter() {
2856:                JCModifiers mods = optFinal(Flags.PARAMETER);
2857:                JCExpression type = type();
2858:                if (S.token() == ELLIPSIS) {
2859:                    checkVarargs();
2860:                    mods.flags |= Flags.VARARGS;
2861:                    type = to(F.at(S.pos()).TypeArray(type));
2862:                    S.nextToken();
2863:                }
2864:                return variableDeclaratorId(mods, type);
2865:            }
2866:
2867:            /* ---------- auxiliary methods -------------- */
2868:
2869:            /** Check that given tree is a legal expression statement.
2870:             */
2871:            protected JCExpression checkExprStat(JCExpression t) {
2872:                switch (t.getTag()) {
2873:                case JCTree.PREINC:
2874:                case JCTree.PREDEC:
2875:                case JCTree.POSTINC:
2876:                case JCTree.POSTDEC:
2877:                case JCTree.ASSIGN:
2878:                case JCTree.BITOR_ASG:
2879:                case JCTree.BITXOR_ASG:
2880:                case JCTree.BITAND_ASG:
2881:                case JCTree.SL_ASG:
2882:                case JCTree.SR_ASG:
2883:                case JCTree.USR_ASG:
2884:                case JCTree.PLUS_ASG:
2885:                case JCTree.MINUS_ASG:
2886:                case JCTree.MUL_ASG:
2887:                case JCTree.DIV_ASG:
2888:                case JCTree.MOD_ASG:
2889:                case JCTree.APPLY:
2890:                case JCTree.NEWCLASS:
2891:                case JCTree.ERRONEOUS:
2892:                    return t;
2893:                default:
2894:                    log.error(t.pos, "not.stmt");
2895:                    return F.at(t.pos).Erroneous(List.<JCTree> of(t));
2896:                }
2897:            }
2898:
2899:            /** Return precedence of operator represented by token,
2900:             *  -1 if token is not a binary operator. @see TreeInfo.opPrec
2901:             */
2902:            static int prec(Token token) {
2903:                int oc = optag(token);
2904:                return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
2905:            }
2906:
2907:            /** Return operation tag of binary operator represented by token,
2908:             *  -1 if token is not a binary operator.
2909:             */
2910:            static int optag(Token token) {
2911:                switch (token) {
2912:                case BARBAR:
2913:                    return JCTree.OR;
2914:                case AMPAMP:
2915:                    return JCTree.AND;
2916:                case BAR:
2917:                    return JCTree.BITOR;
2918:                case BAREQ:
2919:                    return JCTree.BITOR_ASG;
2920:                case CARET:
2921:                    return JCTree.BITXOR;
2922:                case CARETEQ:
2923:                    return JCTree.BITXOR_ASG;
2924:                case AMP:
2925:                    return JCTree.BITAND;
2926:                case AMPEQ:
2927:                    return JCTree.BITAND_ASG;
2928:                case EQEQ:
2929:                    return JCTree.EQ;
2930:                case BANGEQ:
2931:                    return JCTree.NE;
2932:                case LT:
2933:                    return JCTree.LT;
2934:                case GT:
2935:                    return JCTree.GT;
2936:                case LTEQ:
2937:                    return JCTree.LE;
2938:                case GTEQ:
2939:                    return JCTree.GE;
2940:                case LTLT:
2941:                    return JCTree.SL;
2942:                case LTLTEQ:
2943:                    return JCTree.SL_ASG;
2944:                case GTGT:
2945:                    return JCTree.SR;
2946:                case GTGTEQ:
2947:                    return JCTree.SR_ASG;
2948:                case GTGTGT:
2949:                    return JCTree.USR;
2950:                case GTGTGTEQ:
2951:                    return JCTree.USR_ASG;
2952:                case PLUS:
2953:                    return JCTree.PLUS;
2954:                case PLUSEQ:
2955:                    return JCTree.PLUS_ASG;
2956:                case SUB:
2957:                    return JCTree.MINUS;
2958:                case SUBEQ:
2959:                    return JCTree.MINUS_ASG;
2960:                case STAR:
2961:                    return JCTree.MUL;
2962:                case STAREQ:
2963:                    return JCTree.MUL_ASG;
2964:                case SLASH:
2965:                    return JCTree.DIV;
2966:                case SLASHEQ:
2967:                    return JCTree.DIV_ASG;
2968:                case PERCENT:
2969:                    return JCTree.MOD;
2970:                case PERCENTEQ:
2971:                    return JCTree.MOD_ASG;
2972:                case INSTANCEOF:
2973:                    return JCTree.TYPETEST;
2974:                default:
2975:                    return -1;
2976:                }
2977:            }
2978:
2979:            /** Return operation tag of unary operator represented by token,
2980:             *  -1 if token is not a binary operator.
2981:             */
2982:            static int unoptag(Token token) {
2983:                switch (token) {
2984:                case PLUS:
2985:                    return JCTree.POS;
2986:                case SUB:
2987:                    return JCTree.NEG;
2988:                case BANG:
2989:                    return JCTree.NOT;
2990:                case TILDE:
2991:                    return JCTree.COMPL;
2992:                case PLUSPLUS:
2993:                    return JCTree.PREINC;
2994:                case SUBSUB:
2995:                    return JCTree.PREDEC;
2996:                default:
2997:                    return -1;
2998:                }
2999:            }
3000:
3001:            /** Return type tag of basic type represented by token,
3002:             *  -1 if token is not a basic type identifier.
3003:             */
3004:            static int typetag(Token token) {
3005:                switch (token) {
3006:                case BYTE:
3007:                    return TypeTags.BYTE;
3008:                case CHAR:
3009:                    return TypeTags.CHAR;
3010:                case SHORT:
3011:                    return TypeTags.SHORT;
3012:                case INT:
3013:                    return TypeTags.INT;
3014:                case LONG:
3015:                    return TypeTags.LONG;
3016:                case FLOAT:
3017:                    return TypeTags.FLOAT;
3018:                case DOUBLE:
3019:                    return TypeTags.DOUBLE;
3020:                case BOOLEAN:
3021:                    return TypeTags.BOOLEAN;
3022:                default:
3023:                    return -1;
3024:                }
3025:            }
3026:
3027:            void checkGenerics() {
3028:                if (!allowGenerics) {
3029:                    log.error(S.pos(), "generics.not.supported.in.source",
3030:                            source.name);
3031:                    allowGenerics = true;
3032:                }
3033:            }
3034:
3035:            void checkVarargs() {
3036:                if (!allowVarargs) {
3037:                    log.error(S.pos(), "varargs.not.supported.in.source",
3038:                            source.name);
3039:                    allowVarargs = true;
3040:                }
3041:            }
3042:
3043:            void checkForeach() {
3044:                if (!allowForeach) {
3045:                    log.error(S.pos(), "foreach.not.supported.in.source",
3046:                            source.name);
3047:                    allowForeach = true;
3048:                }
3049:            }
3050:
3051:            void checkStaticImports() {
3052:                if (!allowStaticImport) {
3053:                    log.error(S.pos(), "static.import.not.supported.in.source",
3054:                            source.name);
3055:                    allowStaticImport = true;
3056:                }
3057:            }
3058:
3059:            void checkAnnotations() {
3060:                if (!allowAnnotations) {
3061:                    log.error(S.pos(), "annotations.not.supported.in.source",
3062:                            source.name);
3063:                    allowAnnotations = true;
3064:                }
3065:            }
3066:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.