< prev index next >

src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java

Print this page

        

*** 50,67 **** --- 50,70 ---- import jdk.jshell.TaskFactory.Worker; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; + import com.sun.tools.javac.util.Names; + /** * Low level scanner to determine completeness of input. * @author Robert Field */ class CompletenessAnalyzer { private final ScannerFactory scannerFactory; private final JShell proc; + private final Names names; private static Completeness error() { return Completeness.UNKNOWN; // For breakpointing }
*** 79,95 **** --- 82,100 ---- this.proc = proc; Context context = new Context(); Log log = CaLog.createLog(context); context.put(Log.class, log); context.put(Source.class, Source.JDK9); + names = Names.instance(context); scannerFactory = ScannerFactory.instance(context); } CaInfo scan(String s) { try { Parser parser = new Parser( () -> new Matched(scannerFactory.newScanner(s, false)), + names, worker -> proc.taskFactory.parse(s, worker)); Completeness stat = parser.parseUnit(); int endPos = stat == Completeness.UNKNOWN ? s.length() : parser.endPos();
*** 159,168 **** --- 164,174 ---- private static final int XANY1 = XEXPR1o | XDECL1o | XSTMT1o; // Mask: first in statement, declaration, or expression private static final int XTERM = 0b100000000; // Can terminate (last before EOF) private static final int XSTART = 0b1000000000; // Boundary, must be XTERM before private static final int XERRO = 0b10000000000; // Is an error private static final int XBRACESNEEDED = 0b100000000000; // Expect {ANY} LBRACE + private static final int XMODIFIER = 0b1000000000000; // Modifier /** * An extension of the compiler's TokenKind which adds our combined/processed * kinds. Also associates each TK with a union of acceptable kinds of code * position it can occupy. For example: IDENTIFER is XEXPR1|XDECL1|XTERM,
*** 184,193 **** --- 190,202 ---- EOF(TokenKind.EOF, 0), // ERROR(TokenKind.ERROR, XERRO), // IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM), // UNDERSCORE(TokenKind.UNDERSCORE, XERRO), // _ CLASS(TokenKind.CLASS, XEXPR|XDECL1|XBRACESNEEDED), // class decl (MAPPED: DOTCLASS) + RECORD(TokenKind.RECORD, XEXPR|XDECL1), // record decl (MAPPED: DOTCLASS) + SEALED(TokenKind.SEALED, XEXPR|XDECL1), // sealed class decl (MAPPED: DOTCLASS) + PERMITS(TokenKind.PERMITS, XEXPR|XDECL), // permits classlist MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1), // @ IMPORT(TokenKind.IMPORT, XDECL1|XSTART), // import -- consider declaration SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART), // ; // Shouldn't see -- error
*** 210,231 **** FLOAT(TokenKind.FLOAT, XEXPR1|XDECL1), // float INT(TokenKind.INT, XEXPR1|XDECL1), // int LONG(TokenKind.LONG, XEXPR1|XDECL1), // long SHORT(TokenKind.SHORT, XEXPR1|XDECL1), // short VOID(TokenKind.VOID, XEXPR1|XDECL1), // void // Modifiers keywords ! ABSTRACT(TokenKind.ABSTRACT, XDECL1), // abstract ! FINAL(TokenKind.FINAL, XDECL1), // final ! NATIVE(TokenKind.NATIVE, XDECL1), // native ! STATIC(TokenKind.STATIC, XDECL1), // static ! STRICTFP(TokenKind.STRICTFP, XDECL1), // strictfp ! PRIVATE(TokenKind.PRIVATE, XDECL1), // private ! PROTECTED(TokenKind.PROTECTED, XDECL1), // protected ! PUBLIC(TokenKind.PUBLIC, XDECL1), // public ! TRANSIENT(TokenKind.TRANSIENT, XDECL1), // transient ! VOLATILE(TokenKind.VOLATILE, XDECL1), // volatile // Declarations and type parameters (thus expressions) EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL), // extends COMMA(TokenKind.COMMA, XEXPR|XDECL), // , AMP(TokenKind.AMP, XEXPR|XDECL, true), // & --- 219,241 ---- FLOAT(TokenKind.FLOAT, XEXPR1|XDECL1), // float INT(TokenKind.INT, XEXPR1|XDECL1), // int LONG(TokenKind.LONG, XEXPR1|XDECL1), // long SHORT(TokenKind.SHORT, XEXPR1|XDECL1), // short VOID(TokenKind.VOID, XEXPR1|XDECL1), // void + VAR(TokenKind.VAR, XEXPR1|XDECL1|XTERM), // var // Modifiers keywords ! ABSTRACT(TokenKind.ABSTRACT, XDECL1 | XMODIFIER), // abstract ! FINAL(TokenKind.FINAL, XDECL1 | XMODIFIER), // final ! NATIVE(TokenKind.NATIVE, XDECL1 | XMODIFIER), // native ! STATIC(TokenKind.STATIC, XDECL1 | XMODIFIER), // static ! STRICTFP(TokenKind.STRICTFP, XDECL1 | XMODIFIER), // strictfp ! PRIVATE(TokenKind.PRIVATE, XDECL1 | XMODIFIER), // private ! PROTECTED(TokenKind.PROTECTED, XDECL1 | XMODIFIER), // protected ! PUBLIC(TokenKind.PUBLIC, XDECL1 | XMODIFIER), // public ! TRANSIENT(TokenKind.TRANSIENT, XDECL1 | XMODIFIER), // transient ! VOLATILE(TokenKind.VOLATILE, XDECL1 | XMODIFIER), // volatile // Declarations and type parameters (thus expressions) EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL), // extends COMMA(TokenKind.COMMA, XEXPR|XDECL), // , AMP(TokenKind.AMP, XEXPR|XDECL, true), // &
*** 384,393 **** --- 394,407 ---- boolean isBracesNeeded() { return (belongs & XBRACESNEEDED) != 0; } + boolean isModifier() { + return (belongs & XMODIFIER) != 0; + } + /** * After construction, check that all compiler TokenKind values have * corresponding TK values. */ static {
*** 418,444 **** --- 432,463 ---- public final int endPos; /** The error message **/ public final String message; + public final Token tok; + private CT(TK tk, Token tok, String msg) { this.kind = tk; this.endPos = tok.endPos; this.message = msg; + this.tok = tok; //throw new InternalError(msg); /* for debugging */ } private CT(TK tk, Token tok) { this.kind = tk; this.endPos = tok.endPos; this.message = null; + this.tok = tok; } private CT(TK tk, int endPos) { this.kind = tk; this.endPos = endPos; this.message = null; + this.tok = null; } } /** * Look for matching tokens (like parens) and other special cases, like "new"
*** 563,577 **** --- 582,599 ---- private final Supplier<Matched> matchedFactory; private final Function<Worker<ParseTask, Completeness>, Completeness> parseFactory; private Matched in; private CT token; private Completeness checkResult; + private final Names names; Parser(Supplier<Matched> matchedFactory, + Names names, Function<Worker<ParseTask, Completeness>, Completeness> parseFactory) { this.matchedFactory = matchedFactory; this.parseFactory = parseFactory; + this.names = names; resetInput(); } final void resetInput() { this.in = matchedFactory.get();
*** 650,662 **** --- 672,688 ---- } } public Completeness parseDeclaration() { boolean isImport = token.kind == IMPORT; + boolean isDatum = false; + boolean afterModifiers = false; boolean isBracesNeeded = false; while (token.kind.isDeclaration()) { isBracesNeeded |= token.kind.isBracesNeeded(); + isDatum |= !afterModifiers && token.kind == TK.IDENTIFIER && token.tok.name() == names.record; + afterModifiers |= !token.kind.isModifier(); nextToken(); } switch (token.kind) { case EQ: nextToken();
*** 671,686 **** --- 697,719 ---- case EOF: switch (in.prevCT.kind) { case BRACES: case SEMI: return Completeness.COMPLETE; + case VAR: case IDENTIFIER: return isBracesNeeded ? Completeness.DEFINITELY_INCOMPLETE : Completeness.COMPLETE_WITH_SEMI; case BRACKETS: return Completeness.COMPLETE_WITH_SEMI; + case PARENS: + if (isDatum) { + return Completeness.COMPLETE_WITH_SEMI; + } else { + return Completeness.DEFINITELY_INCOMPLETE; + } case DOTSTAR: if (isImport) { return Completeness.COMPLETE_WITH_SEMI; } else { return Completeness.UNKNOWN;
< prev index next >