langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
changeset 28147 72e7fdc79b78
parent 27991 8f4b68523da3
child 28454 63c31d7de8f6
equal deleted inserted replaced
28146:adf3a039cb7d 28147:72e7fdc79b78
   249      *     mode = EXPR        : an expression
   249      *     mode = EXPR        : an expression
   250      *     mode = TYPE        : a type
   250      *     mode = TYPE        : a type
   251      *     mode = NOPARAMS    : no parameters allowed for type
   251      *     mode = NOPARAMS    : no parameters allowed for type
   252      *     mode = TYPEARG     : type argument
   252      *     mode = TYPEARG     : type argument
   253      */
   253      */
   254     static final int EXPR = 0x1;
   254     protected static final int EXPR = 0x1;
   255     static final int TYPE = 0x2;
   255     protected static final int TYPE = 0x2;
   256     static final int NOPARAMS = 0x4;
   256     protected static final int NOPARAMS = 0x4;
   257     static final int TYPEARG = 0x8;
   257     protected static final int TYPEARG = 0x8;
   258     static final int DIAMOND = 0x10;
   258     protected static final int DIAMOND = 0x10;
   259 
   259 
   260     /** The current mode.
   260     /** The current mode.
   261      */
   261      */
   262     private int mode = 0;
   262     protected int mode = 0;
   263 
   263 
   264     /** The mode of the term that was parsed last.
   264     /** The mode of the term that was parsed last.
   265      */
   265      */
   266     private int lastmode = 0;
   266     protected int lastmode = 0;
   267 
   267 
   268     /* ---------- token management -------------- */
   268     /* ---------- token management -------------- */
   269 
   269 
   270     protected Token token;
   270     protected Token token;
   271 
   271 
   324 
   324 
   325     private JCErroneous errorTree;
   325     private JCErroneous errorTree;
   326 
   326 
   327     /** Skip forward until a suitable stop token is found.
   327     /** Skip forward until a suitable stop token is found.
   328      */
   328      */
   329     private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   329     protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   330          while (true) {
   330          while (true) {
   331              switch (token.kind) {
   331              switch (token.kind) {
   332                 case SEMI:
   332                 case SEMI:
   333                     nextToken();
   333                     nextToken();
   334                     return;
   334                     return;
   401             }
   401             }
   402             nextToken();
   402             nextToken();
   403         }
   403         }
   404     }
   404     }
   405 
   405 
   406     private JCErroneous syntaxError(int pos, String key, TokenKind... args) {
   406     protected JCErroneous syntaxError(int pos, String key, TokenKind... args) {
   407         return syntaxError(pos, List.<JCTree>nil(), key, args);
   407         return syntaxError(pos, List.<JCTree>nil(), key, args);
   408     }
   408     }
   409 
   409 
   410     private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
   410     protected JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
   411         setErrorEndPos(pos);
   411         setErrorEndPos(pos);
   412         JCErroneous err = F.at(pos).Erroneous(errs);
   412         JCErroneous err = F.at(pos).Erroneous(errs);
   413         reportSyntaxError(err, key, (Object[])args);
   413         reportSyntaxError(err, key, (Object[])args);
   414         if (errs != null) {
   414         if (errs != null) {
   415             JCTree last = errs.last();
   415             JCTree last = errs.last();
   425 
   425 
   426     /**
   426     /**
   427      * Report a syntax using the given the position parameter and arguments,
   427      * Report a syntax using the given the position parameter and arguments,
   428      * unless one was already reported at the same position.
   428      * unless one was already reported at the same position.
   429      */
   429      */
   430     private void reportSyntaxError(int pos, String key, Object... args) {
   430     protected void reportSyntaxError(int pos, String key, Object... args) {
   431         JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
   431         JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
   432         reportSyntaxError(diag, key, args);
   432         reportSyntaxError(diag, key, args);
   433     }
   433     }
   434 
   434 
   435     /**
   435     /**
   436      * Report a syntax error using the given DiagnosticPosition object and
   436      * Report a syntax error using the given DiagnosticPosition object and
   437      * arguments, unless one was already reported at the same position.
   437      * arguments, unless one was already reported at the same position.
   438      */
   438      */
   439     private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
   439     protected void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
   440         int pos = diagPos.getPreferredPosition();
   440         int pos = diagPos.getPreferredPosition();
   441         if (pos > S.errPos() || pos == Position.NOPOS) {
   441         if (pos > S.errPos() || pos == Position.NOPOS) {
   442             if (token.kind == EOF) {
   442             if (token.kind == EOF) {
   443                 error(diagPos, "premature.eof");
   443                 error(diagPos, "premature.eof");
   444             } else {
   444             } else {
   457 
   457 
   458 
   458 
   459     /** Generate a syntax error at current position unless one was already
   459     /** Generate a syntax error at current position unless one was already
   460      *  reported at the same position.
   460      *  reported at the same position.
   461      */
   461      */
   462     private JCErroneous syntaxError(String key) {
   462     protected JCErroneous syntaxError(String key) {
   463         return syntaxError(token.pos, key);
   463         return syntaxError(token.pos, key);
   464     }
   464     }
   465 
   465 
   466     /** Generate a syntax error at current position unless one was
   466     /** Generate a syntax error at current position unless one was
   467      *  already reported at the same position.
   467      *  already reported at the same position.
   468      */
   468      */
   469     private JCErroneous syntaxError(String key, TokenKind arg) {
   469     protected JCErroneous syntaxError(String key, TokenKind arg) {
   470         return syntaxError(token.pos, key, arg);
   470         return syntaxError(token.pos, key, arg);
   471     }
   471     }
   472 
   472 
   473     /** If next input token matches given token, skip it, otherwise report
   473     /** If next input token matches given token, skip it, otherwise report
   474      *  an error.
   474      *  an error.
   498     JCExpression illegal() {
   498     JCExpression illegal() {
   499         return illegal(token.pos);
   499         return illegal(token.pos);
   500     }
   500     }
   501 
   501 
   502     /** Diagnose a modifier flag from the set, if any. */
   502     /** Diagnose a modifier flag from the set, if any. */
   503     void checkNoMods(long mods) {
   503     protected void checkNoMods(long mods) {
   504         if (mods != 0) {
   504         if (mods != 0) {
   505             long lowestMod = mods & -mods;
   505             long lowestMod = mods & -mods;
   506             error(token.pos, "mod.not.allowed.here",
   506             error(token.pos, "mod.not.allowed.here",
   507                       Flags.asFlagSet(lowestMod));
   507                       Flags.asFlagSet(lowestMod));
   508         }
   508         }
   519     /** Make an entry into docComments hashtable,
   519     /** Make an entry into docComments hashtable,
   520      *  provided flag keepDocComments is set and given doc comment is non-null.
   520      *  provided flag keepDocComments is set and given doc comment is non-null.
   521      *  @param tree   The tree to be used as index in the hashtable
   521      *  @param tree   The tree to be used as index in the hashtable
   522      *  @param dc     The doc comment to associate with the tree, or null.
   522      *  @param dc     The doc comment to associate with the tree, or null.
   523      */
   523      */
   524     void attach(JCTree tree, Comment dc) {
   524     protected void attach(JCTree tree, Comment dc) {
   525         if (keepDocComments && dc != null) {
   525         if (keepDocComments && dc != null) {
   526 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   526 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   527             docComments.putComment(tree, dc);
   527             docComments.putComment(tree, dc);
   528         }
   528         }
   529     }
   529     }
   530 
   530 
   531 /* -------- source positions ------- */
   531 /* -------- source positions ------- */
   532 
   532 
   533     private void setErrorEndPos(int errPos) {
   533     protected void setErrorEndPos(int errPos) {
   534         endPosTable.setErrorEndPos(errPos);
   534         endPosTable.setErrorEndPos(errPos);
   535     }
   535     }
   536 
   536 
   537     private void storeEnd(JCTree tree, int endpos) {
   537     protected void storeEnd(JCTree tree, int endpos) {
   538         endPosTable.storeEnd(tree, endpos);
   538         endPosTable.storeEnd(tree, endpos);
   539     }
   539     }
   540 
   540 
   541     private <T extends JCTree> T to(T t) {
   541     protected <T extends JCTree> T to(T t) {
   542         return endPosTable.to(t);
   542         return endPosTable.to(t);
   543     }
   543     }
   544 
   544 
   545     private <T extends JCTree> T toP(T t) {
   545     protected <T extends JCTree> T toP(T t) {
   546         return endPosTable.toP(t);
   546         return endPosTable.toP(t);
   547     }
   547     }
   548 
   548 
   549     /** Get the start position for a tree node.  The start position is
   549     /** Get the start position for a tree node.  The start position is
   550      * defined to be the position of the first character of the first
   550      * defined to be the position of the first character of the first
   572 /* ---------- parsing -------------- */
   572 /* ---------- parsing -------------- */
   573 
   573 
   574     /**
   574     /**
   575      * Ident = IDENTIFIER
   575      * Ident = IDENTIFIER
   576      */
   576      */
   577     Name ident() {
   577     protected Name ident() {
   578         if (token.kind == IDENTIFIER) {
   578         if (token.kind == IDENTIFIER) {
   579             Name name = token.name();
   579             Name name = token.name();
   580             nextToken();
   580             nextToken();
   581             return name;
   581             return name;
   582         } else if (token.kind == ASSERT) {
   582         } else if (token.kind == ASSERT) {
   787 
   787 
   788     public JCExpression unannotatedType() {
   788     public JCExpression unannotatedType() {
   789         return term(TYPE);
   789         return term(TYPE);
   790     }
   790     }
   791 
   791 
   792     JCExpression term(int newmode) {
   792     protected JCExpression term(int newmode) {
   793         int prevmode = mode;
   793         int prevmode = mode;
   794         mode = newmode;
   794         mode = newmode;
   795         JCExpression t = term();
   795         JCExpression t = term();
   796         lastmode = mode;
   796         lastmode = mode;
   797         mode = prevmode;
   797         mode = prevmode;
  1667             }
  1667             }
  1668         }
  1668         }
  1669     }
  1669     }
  1670 
  1670 
  1671     /** Accepts all identifier-like tokens */
  1671     /** Accepts all identifier-like tokens */
  1672     Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
  1672     protected Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
  1673         public boolean accepts(TokenKind t) {
  1673         public boolean accepts(TokenKind t) {
  1674             return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
  1674             return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
  1675         }
  1675         }
  1676     };
  1676     };
  1677 
  1677 
  2406      *     | BREAK [Ident] ";"
  2406      *     | BREAK [Ident] ";"
  2407      *     | CONTINUE [Ident] ";"
  2407      *     | CONTINUE [Ident] ";"
  2408      *     | ASSERT Expression [ ":" Expression ] ";"
  2408      *     | ASSERT Expression [ ":" Expression ] ";"
  2409      *     | ";"
  2409      *     | ";"
  2410      */
  2410      */
  2411     JCStatement parseSimpleStatement() {
  2411     public JCStatement parseSimpleStatement() {
  2412         int pos = token.pos;
  2412         int pos = token.pos;
  2413         switch (token.kind) {
  2413         switch (token.kind) {
  2414         case LBRACE:
  2414         case LBRACE:
  2415             return block();
  2415             return block();
  2416         case IF: {
  2416         case IF: {
  2704 
  2704 
  2705     /** AnnotationsOpt = { '@' Annotation }
  2705     /** AnnotationsOpt = { '@' Annotation }
  2706      *
  2706      *
  2707      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2707      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2708      */
  2708      */
  2709     List<JCAnnotation> annotationsOpt(Tag kind) {
  2709     protected List<JCAnnotation> annotationsOpt(Tag kind) {
  2710         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  2710         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  2711         ListBuffer<JCAnnotation> buf = new ListBuffer<>();
  2711         ListBuffer<JCAnnotation> buf = new ListBuffer<>();
  2712         int prevmode = mode;
  2712         int prevmode = mode;
  2713         while (token.kind == MONKEYS_AT) {
  2713         while (token.kind == MONKEYS_AT) {
  2714             int pos = token.pos;
  2714             int pos = token.pos;
  2730     /** ModifiersOpt = { Modifier }
  2730     /** ModifiersOpt = { Modifier }
  2731      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  2731      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  2732      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  2732      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  2733      *           | "@" Annotation
  2733      *           | "@" Annotation
  2734      */
  2734      */
  2735     JCModifiers modifiersOpt() {
  2735     protected JCModifiers modifiersOpt() {
  2736         return modifiersOpt(null);
  2736         return modifiersOpt(null);
  2737     }
  2737     }
  2738     protected JCModifiers modifiersOpt(JCModifiers partial) {
  2738     protected JCModifiers modifiersOpt(JCModifiers partial) {
  2739         long flags;
  2739         long flags;
  2740         ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
  2740         ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
  2912      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  2912      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  2913      *
  2913      *
  2914      *  @param reqInit  Is an initializer always required?
  2914      *  @param reqInit  Is an initializer always required?
  2915      *  @param dc       The documentation comment for the variable declarations, or null.
  2915      *  @param dc       The documentation comment for the variable declarations, or null.
  2916      */
  2916      */
  2917     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  2917     protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  2918                                                                      JCModifiers mods,
  2918                                                                      JCModifiers mods,
  2919                                                                      JCExpression type,
  2919                                                                      JCExpression type,
  2920                                                                      Name name,
  2920                                                                      Name name,
  2921                                                                      boolean reqInit,
  2921                                                                      boolean reqInit,
  2922                                                                      Comment dc,
  2922                                                                      Comment dc,
  3115         return toplevel;
  3115         return toplevel;
  3116     }
  3116     }
  3117 
  3117 
  3118     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  3118     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  3119      */
  3119      */
  3120     JCTree importDeclaration() {
  3120     protected JCTree importDeclaration() {
  3121         int pos = token.pos;
  3121         int pos = token.pos;
  3122         nextToken();
  3122         nextToken();
  3123         boolean importStatic = false;
  3123         boolean importStatic = false;
  3124         if (token.kind == STATIC) {
  3124         if (token.kind == STATIC) {
  3125             importStatic = true;
  3125             importStatic = true;
  3157     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  3157     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  3158      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  3158      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  3159      *  @param mods     Any modifiers starting the class or interface declaration
  3159      *  @param mods     Any modifiers starting the class or interface declaration
  3160      *  @param dc       The documentation comment for the class, or null.
  3160      *  @param dc       The documentation comment for the class, or null.
  3161      */
  3161      */
  3162     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
  3162     protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
  3163         if (token.kind == CLASS) {
  3163         if (token.kind == CLASS) {
  3164             return classDeclaration(mods, dc);
  3164             return classDeclaration(mods, dc);
  3165         } else if (token.kind == INTERFACE) {
  3165         } else if (token.kind == INTERFACE) {
  3166             return interfaceDeclaration(mods, dc);
  3166             return interfaceDeclaration(mods, dc);
  3167         } else if (token.kind == ENUM) {
  3167         } else if (token.kind == ENUM) {
  3567     /**
  3567     /**
  3568      *  {@literal
  3568      *  {@literal
  3569      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  3569      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  3570      *  }
  3570      *  }
  3571      */
  3571      */
  3572     List<JCTypeParameter> typeParametersOpt() {
  3572     protected List<JCTypeParameter> typeParametersOpt() {
  3573         if (token.kind == LT) {
  3573         if (token.kind == LT) {
  3574             ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
  3574             ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
  3575             nextToken();
  3575             nextToken();
  3576             typarams.append(typeParameter());
  3576             typarams.append(typeParameter());
  3577             while (token.kind == COMMA) {
  3577             while (token.kind == COMMA) {
  4002         if (!allowTypeAnnotations) {
  4002         if (!allowTypeAnnotations) {
  4003             log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
  4003             log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
  4004             allowTypeAnnotations = true;
  4004             allowTypeAnnotations = true;
  4005         }
  4005         }
  4006     }
  4006     }
  4007     void checkAnnotationsAfterTypeParams(int pos) {
  4007     protected void checkAnnotationsAfterTypeParams(int pos) {
  4008         if (!allowAnnotationsAfterTypeParams) {
  4008         if (!allowAnnotationsAfterTypeParams) {
  4009             log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);
  4009             log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);
  4010             allowAnnotationsAfterTypeParams = true;
  4010             allowAnnotationsAfterTypeParams = true;
  4011         }
  4011         }
  4012     }
  4012     }
  4090         protected JavacParser parser;
  4090         protected JavacParser parser;
  4091 
  4091 
  4092         /**
  4092         /**
  4093          * Store the last error position.
  4093          * Store the last error position.
  4094          */
  4094          */
  4095         protected int errorEndPos = Position.NOPOS;
  4095         public int errorEndPos = Position.NOPOS;
  4096 
  4096 
  4097         public AbstractEndPosTable(JavacParser parser) {
  4097         public AbstractEndPosTable(JavacParser parser) {
  4098             this.parser = parser;
  4098             this.parser = parser;
  4099         }
  4099         }
  4100 
  4100 
  4117         /**
  4117         /**
  4118          * Set the error position during the parsing phases, the value of which
  4118          * Set the error position during the parsing phases, the value of which
  4119          * will be set only if it is greater than the last stored error position.
  4119          * will be set only if it is greater than the last stored error position.
  4120          * @param errPos The error position
  4120          * @param errPos The error position
  4121          */
  4121          */
  4122         protected void setErrorEndPos(int errPos) {
  4122         public void setErrorEndPos(int errPos) {
  4123             if (errPos > errorEndPos) {
  4123             if (errPos > errorEndPos) {
  4124                 errorEndPos = errPos;
  4124                 errorEndPos = errPos;
  4125             }
  4125             }
  4126         }
  4126         }
  4127 
  4127 
  4128         protected void setParser(JavacParser parser) {
  4128         public void setParser(JavacParser parser) {
  4129             this.parser = parser;
  4129             this.parser = parser;
  4130         }
  4130         }
  4131     }
  4131     }
  4132 }
  4132 }