langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java
changeset 41450 83877f4dd010
parent 40771 bf0e92ede33f
child 42267 a0c712fc6575
equal deleted inserted replaced
41449:de8df2220540 41450:83877f4dd010
   164     private static final int XSTMT1        = XSTMT1o | XSTMT;           // OK in statement framework (anywhere)
   164     private static final int XSTMT1        = XSTMT1o | XSTMT;           // OK in statement framework (anywhere)
   165     private static final int XANY1         = XEXPR1o | XDECL1o | XSTMT1o;  // Mask: first in statement, declaration, or expression
   165     private static final int XANY1         = XEXPR1o | XDECL1o | XSTMT1o;  // Mask: first in statement, declaration, or expression
   166     private static final int XTERM         = 0b100000000;               // Can terminate (last before EOF)
   166     private static final int XTERM         = 0b100000000;               // Can terminate (last before EOF)
   167     private static final int XSTART        = 0b1000000000;              // Boundary, must be XTERM before
   167     private static final int XSTART        = 0b1000000000;              // Boundary, must be XTERM before
   168     private static final int XERRO         = 0b10000000000;             // Is an error
   168     private static final int XERRO         = 0b10000000000;             // Is an error
       
   169     private static final int XBRACESNEEDED = 0b100000000000;            // Expect {ANY} LBRACE
   169 
   170 
   170     /**
   171     /**
   171      * An extension of the compiler's TokenKind which adds our combined/processed
   172      * An extension of the compiler's TokenKind which adds our combined/processed
   172      * kinds. Also associates each TK with a union of acceptable kinds of code
   173      * kinds. Also associates each TK with a union of acceptable kinds of code
   173      * position it can occupy.  For example: IDENTIFER is XEXPR1|XDECL1|XTERM,
   174      * position it can occupy.  For example: IDENTIFER is XEXPR1|XDECL1|XTERM,
   188         // Special
   189         // Special
   189         EOF(TokenKind.EOF, 0),  //
   190         EOF(TokenKind.EOF, 0),  //
   190         ERROR(TokenKind.ERROR, XERRO),  //
   191         ERROR(TokenKind.ERROR, XERRO),  //
   191         IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM),  //
   192         IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM),  //
   192         UNDERSCORE(TokenKind.UNDERSCORE, XERRO),  //  _
   193         UNDERSCORE(TokenKind.UNDERSCORE, XERRO),  //  _
   193         CLASS(TokenKind.CLASS, XEXPR|XDECL1),  //  class decl (MAPPED: DOTCLASS)
   194         CLASS(TokenKind.CLASS, XEXPR|XDECL1|XBRACESNEEDED),  //  class decl (MAPPED: DOTCLASS)
   194         MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1),  //  @
   195         MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1),  //  @
   195         IMPORT(TokenKind.IMPORT, XDECL1|XSTART),  //  import -- consider declaration
   196         IMPORT(TokenKind.IMPORT, XDECL1|XSTART),  //  import -- consider declaration
   196         SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART),  //  ;
   197         SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART),  //  ;
   197 
   198 
   198         // Shouldn't see -- error
   199         // Shouldn't see -- error
   200         CONST(TokenKind.CONST, XERRO),  //  reserved keyword -- const
   201         CONST(TokenKind.CONST, XERRO),  //  reserved keyword -- const
   201         GOTO(TokenKind.GOTO, XERRO),  //  reserved keyword -- goto
   202         GOTO(TokenKind.GOTO, XERRO),  //  reserved keyword -- goto
   202         CUSTOM(TokenKind.CUSTOM, XERRO),  // No uses
   203         CUSTOM(TokenKind.CUSTOM, XERRO),  // No uses
   203 
   204 
   204         // Declarations
   205         // Declarations
   205         ENUM(TokenKind.ENUM, XDECL1),  //  enum
   206         ENUM(TokenKind.ENUM, XDECL1|XBRACESNEEDED),  //  enum
   206         IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL),  //  implements
   207         IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL),  //  implements
   207         INTERFACE(TokenKind.INTERFACE, XDECL1),  //  interface
   208         INTERFACE(TokenKind.INTERFACE, XDECL1|XBRACESNEEDED),  //  interface
   208         THROWS(TokenKind.THROWS, XDECL),  //  throws
   209         THROWS(TokenKind.THROWS, XDECL|XBRACESNEEDED),  //  throws
   209 
   210 
   210         // Primarive type names
   211         // Primarive type names
   211         BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1),  //  boolean
   212         BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1),  //  boolean
   212         BYTE(TokenKind.BYTE, XEXPR1|XDECL1),  //  byte
   213         BYTE(TokenKind.BYTE, XEXPR1|XDECL1),  //  byte
   213         CHAR(TokenKind.CHAR, XEXPR1|XDECL1),  //  char
   214         CHAR(TokenKind.CHAR, XEXPR1|XDECL1),  //  char
   379 
   380 
   380         boolean isStart() {
   381         boolean isStart() {
   381             return (belongs & XSTART) != 0;
   382             return (belongs & XSTART) != 0;
   382         }
   383         }
   383 
   384 
       
   385         boolean isBracesNeeded() {
       
   386             return (belongs & XBRACESNEEDED) != 0;
       
   387         }
       
   388 
   384         /**
   389         /**
   385          * After construction, check that all compiler TokenKind values have
   390          * After construction, check that all compiler TokenKind values have
   386          * corresponding TK values.
   391          * corresponding TK values.
   387          */
   392          */
   388         static {
   393         static {
   639             }
   644             }
   640         }
   645         }
   641 
   646 
   642         public Completeness parseDeclaration() {
   647         public Completeness parseDeclaration() {
   643             boolean isImport = token.kind == IMPORT;
   648             boolean isImport = token.kind == IMPORT;
       
   649             boolean isBracesNeeded = false;
   644             while (token.kind.isDeclaration()) {
   650             while (token.kind.isDeclaration()) {
       
   651                 isBracesNeeded |= token.kind.isBracesNeeded();
   645                 nextToken();
   652                 nextToken();
   646             }
   653             }
   647             switch (token.kind) {
   654             switch (token.kind) {
   648                 case EQ:
   655                 case EQ:
   649                     // Check for array initializer
   656                     // Check for array initializer
   664                     switch (in.prevCT.kind) {
   671                     switch (in.prevCT.kind) {
   665                         case BRACES:
   672                         case BRACES:
   666                         case SEMI:
   673                         case SEMI:
   667                             return Completeness.COMPLETE;
   674                             return Completeness.COMPLETE;
   668                         case IDENTIFIER:
   675                         case IDENTIFIER:
       
   676                             return isBracesNeeded
       
   677                                     ? Completeness.DEFINITELY_INCOMPLETE
       
   678                                     : Completeness.COMPLETE_WITH_SEMI;
   669                         case BRACKETS:
   679                         case BRACKETS:
   670                             return Completeness.COMPLETE_WITH_SEMI;
   680                             return Completeness.COMPLETE_WITH_SEMI;
   671                         case DOTSTAR:
   681                         case DOTSTAR:
   672                             if (isImport) {
   682                             if (isImport) {
   673                                 return Completeness.COMPLETE_WITH_SEMI;
   683                                 return Completeness.COMPLETE_WITH_SEMI;