Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
JDK 11 jdk.jshell.jmod - JShell Tool
JDK 11 jdk.jshell.jmod is the JMOD file for JDK 11 JShell tool, which can be invoked by the "jshell" command.
JDK 11 JShell tool compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.jshell.jmod.
JDK 11 JShell tool compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 JShell tool source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.jshell.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ jdk/jshell/CompletenessAnalyzer.java
/* * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package jdk.jshell; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.parser.ScannerFactory; import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.Error; import com.sun.tools.javac.util.Log; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayDeque; import java.util.Deque; import java.util.EnumMap; import java.util.Iterator; import jdk.jshell.SourceCodeAnalysis.Completeness; import com.sun.source.tree.Tree; import static jdk.jshell.CompletenessAnalyzer.TK.*; import jdk.jshell.TaskFactory.ParseTask; import jdk.jshell.TaskFactory.Worker; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; /** * Low level scanner to determine completeness of input. * @author Robert Field */ class CompletenessAnalyzer { private final ScannerFactory scannerFactory; private final JShell proc; private static Completeness error() { return Completeness.UNKNOWN; // For breakpointing } static class CaInfo { CaInfo(Completeness status, int unitEndPos) { this.status = status; this.unitEndPos = unitEndPos; } final int unitEndPos; final Completeness status; } CompletenessAnalyzer(JShell proc) { this.proc = proc; Context context = new Context(); Log log = CaLog.createLog(context); context.put(Log.class, log); context.put(Source.class, Source.JDK9); scannerFactory = ScannerFactory.instance(context); } CaInfo scan(String s) { try { Parser parser = new Parser( () -> new Matched(scannerFactory.newScanner(s, false)), worker -> proc.taskFactory.parse(s, worker)); Completeness stat = parser.parseUnit(); int endPos = stat == Completeness.UNKNOWN ? s.length() : parser.endPos(); return new CaInfo(stat, endPos); } catch (SyntaxException ex) { return new CaInfo(error(), s.length()); } } @SuppressWarnings("serial") // serialVersionUID intentionally omitted private static class SyntaxException extends RuntimeException { } private static void die() { throw new SyntaxException(); } /** * Subclass of Log used by compiler API to die on error and ignore * other messages */ private static class CaLog extends Log { private static CaLog createLog(Context context) { PrintWriter pw = new PrintWriter(new StringWriter()); CaLog log = new CaLog(context, pw); context.put(logKey, log); return log; } private CaLog(Context context, PrintWriter pw) { super(context, pw); } @Override public void error(String key, Object... args) { die(); } @Override public void error(int pos, Error errorKey) { die(); } @Override public void error(int pos, String key, Object... args) { die(); } @Override public void report(JCDiagnostic diagnostic) { // Ignore } } // Location position kinds -- a token is ... private static final int XEXPR = 0b1; // OK in expression (not first) private static final int XDECL = 0b10; // OK in declaration (not first) private static final int XSTMT = 0b100; // OK in statement framework (not first) private static final int XEXPR1o = 0b1000; // OK first in expression private static final int XDECL1o = 0b10000; // OK first in declaration private static final int XSTMT1o = 0b100000; // OK first or only in statement framework private static final int XEXPR1 = XEXPR1o | XEXPR; // OK in expression (anywhere) private static final int XDECL1 = XDECL1o | XDECL; // OK in declaration (anywhere) private static final int XSTMT1 = XSTMT1o | XSTMT; // OK in statement framework (anywhere) 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 /** * 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, * meaning it can occur in expressions or declarations (but not in the * framework of a statement and that can be the final (terminating) token * in a snippet. * <P> * There must be a TK defined for each compiler TokenKind, an exception * will * be thrown if a TokenKind is defined and a corresponding TK is not. Add a * new TK in the appropriate category. If it is like an existing category * (e.g. a new modifier or type this may be all that is needed. If it * is bracketing or modifies the acceptable positions of other tokens, * please closely examine the needed changes to this scanner. */ static enum TK { // Special 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) 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 PACKAGE(TokenKind.PACKAGE, XERRO), // package CONST(TokenKind.CONST, XERRO), // reserved keyword -- const GOTO(TokenKind.GOTO, XERRO), // reserved keyword -- goto CUSTOM(TokenKind.CUSTOM, XERRO), // No uses // Declarations ENUM(TokenKind.ENUM, XDECL1|XBRACESNEEDED), // enum IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL), // implements INTERFACE(TokenKind.INTERFACE, XDECL1|XBRACESNEEDED), // interface THROWS(TokenKind.THROWS, XDECL|XBRACESNEEDED), // throws // Primarive type names BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1), // boolean BYTE(TokenKind.BYTE, XEXPR1|XDECL1), // byte CHAR(TokenKind.CHAR, XEXPR1|XDECL1), // char DOUBLE(TokenKind.DOUBLE, XEXPR1|XDECL1), // double 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), // & GT(TokenKind.GT, XEXPR|XDECL), // > LT(TokenKind.LT, XEXPR|XDECL1), // < LTLT(TokenKind.LTLT, XEXPR|XDECL1), // << GTGT(TokenKind.GTGT, XEXPR|XDECL), // >> GTGTGT(TokenKind.GTGTGT, XEXPR|XDECL), // >>> QUES(TokenKind.QUES, XEXPR|XDECL), // ? DOT(TokenKind.DOT, XEXPR|XDECL), // . STAR(TokenKind.STAR, XEXPR), // * (MAPPED: DOTSTAR) // Statement keywords ASSERT(TokenKind.ASSERT, XSTMT1|XSTART), // assert BREAK(TokenKind.BREAK, XSTMT1|XTERM|XSTART), // break CATCH(TokenKind.CATCH, XSTMT1|XSTART), // catch CONTINUE(TokenKind.CONTINUE, XSTMT1|XTERM|XSTART), // continue DO(TokenKind.DO, XSTMT1|XSTART), // do ELSE(TokenKind.ELSE, XSTMT1|XTERM|XSTART), // else FINALLY(TokenKind.FINALLY, XSTMT1|XSTART), // finally FOR(TokenKind.FOR, XSTMT1|XSTART), // for IF(TokenKind.IF, XSTMT1|XSTART), // if RETURN(TokenKind.RETURN, XSTMT1|XTERM|XSTART), // return SWITCH(TokenKind.SWITCH, XSTMT1|XSTART), // switch SYNCHRONIZED(TokenKind.SYNCHRONIZED, XSTMT1|XDECL), // synchronized THROW(TokenKind.THROW, XSTMT1|XSTART), // throw TRY(TokenKind.TRY, XSTMT1|XSTART), // try WHILE(TokenKind.WHILE, XSTMT1|XSTART), // while // Statement keywords that we shouldn't see -- inside braces CASE(TokenKind.CASE, XSTMT|XSTART), // case DEFAULT(TokenKind.DEFAULT, XSTMT|XSTART), // default method, default case -- neither we should see // Expressions (can terminate) INTLITERAL(TokenKind.INTLITERAL, XEXPR1|XTERM), // LONGLITERAL(TokenKind.LONGLITERAL, XEXPR1|XTERM), // FLOATLITERAL(TokenKind.FLOATLITERAL, XEXPR1|XTERM), // DOUBLELITERAL(TokenKind.DOUBLELITERAL, XEXPR1|XTERM), // CHARLITERAL(TokenKind.CHARLITERAL, XEXPR1|XTERM), // STRINGLITERAL(TokenKind.STRINGLITERAL, XEXPR1|XTERM), // TRUE(TokenKind.TRUE, XEXPR1|XTERM), // true FALSE(TokenKind.FALSE, XEXPR1|XTERM), // false NULL(TokenKind.NULL, XEXPR1|XTERM), // null THIS(TokenKind.THIS, XEXPR1|XTERM), // this -- shouldn't see // Expressions maybe terminate //TODO handle these case separately PLUSPLUS(TokenKind.PLUSPLUS, XEXPR1|XTERM), // ++ SUBSUB(TokenKind.SUBSUB, XEXPR1|XTERM), // -- // Expressions cannot terminate INSTANCEOF(TokenKind.INSTANCEOF, XEXPR), // instanceof NEW(TokenKind.NEW, XEXPR1), // new (MAPPED: COLCOLNEW) SUPER(TokenKind.SUPER, XEXPR1|XDECL), // super -- shouldn't see as rec. But in type parameters ARROW(TokenKind.ARROW, XEXPR), // -> COLCOL(TokenKind.COLCOL, XEXPR), // :: LPAREN(TokenKind.LPAREN, XEXPR), // ( RPAREN(TokenKind.RPAREN, XEXPR), // ) LBRACE(TokenKind.LBRACE, XEXPR), // { RBRACE(TokenKind.RBRACE, XEXPR), // } LBRACKET(TokenKind.LBRACKET, XEXPR), // [ RBRACKET(TokenKind.RBRACKET, XEXPR), // ] ELLIPSIS(TokenKind.ELLIPSIS, XEXPR), // ... EQ(TokenKind.EQ, XEXPR), // = BANG(TokenKind.BANG, XEXPR1), // ! TILDE(TokenKind.TILDE, XEXPR1), // ~ COLON(TokenKind.COLON, XEXPR|XTERM), // : EQEQ(TokenKind.EQEQ, XEXPR), // == LTEQ(TokenKind.LTEQ, XEXPR), // <= GTEQ(TokenKind.GTEQ, XEXPR), // >= BANGEQ(TokenKind.BANGEQ, XEXPR), // != AMPAMP(TokenKind.AMPAMP, XEXPR), // && BARBAR(TokenKind.BARBAR, XEXPR), // || PLUS(TokenKind.PLUS, XEXPR1), // + SUB(TokenKind.SUB, XEXPR1), // - SLASH(TokenKind.SLASH, XEXPR), // / BAR(TokenKind.BAR, XEXPR), // | CARET(TokenKind.CARET, XEXPR), // ^ PERCENT(TokenKind.PERCENT, XEXPR), // % PLUSEQ(TokenKind.PLUSEQ, XEXPR), // += SUBEQ(TokenKind.SUBEQ, XEXPR), // -= STAREQ(TokenKind.STAREQ, XEXPR), // *= SLASHEQ(TokenKind.SLASHEQ, XEXPR), // /= AMPEQ(TokenKind.AMPEQ, XEXPR), // &= BAREQ(TokenKind.BAREQ, XEXPR), // |= CARETEQ(TokenKind.CARETEQ, XEXPR), // ^= PERCENTEQ(TokenKind.PERCENTEQ, XEXPR), // %= LTLTEQ(TokenKind.LTLTEQ, XEXPR), // <<= GTGTEQ(TokenKind.GTGTEQ, XEXPR), // >>= GTGTGTEQ(TokenKind.GTGTGTEQ, XEXPR), // >>>= // combined/processed kinds UNMATCHED(XERRO), PARENS(XEXPR1|XDECL|XSTMT|XTERM), BRACKETS(XEXPR|XDECL|XTERM), BRACES(XSTMT1|XEXPR|XTERM), DOTSTAR(XDECL|XTERM), // import foo.* COLCOLNEW(XEXPR|XTERM), // :: new DOTCLASS(XEXPR|XTERM), // class decl and .class ; static final EnumMap<TokenKind,TK> tokenKindToTKMap = new EnumMap<>(TokenKind.class); final TokenKind tokenKind; final int belongs; Function<TK,TK> mapping; TK(int b) { this(null, b); } TK(TokenKind tokenKind, int b) { this.tokenKind = tokenKind; this.belongs = b; this.mapping = null; } private static TK tokenKindToTK(TK prev, TokenKind kind) { TK tk = tokenKindToTKMap.get(kind); if (tk == null) { System.err.printf("No corresponding %s for %s: %s\n", TK.class.getCanonicalName(), TokenKind.class.getCanonicalName(), kind); throw new InternalError("No corresponding TK for TokenKind: " + kind); } return tk.mapping != null ? tk.mapping.apply(prev) : tk; } boolean isOkToTerminate() { return (belongs & XTERM) != 0; } boolean isExpression() { return (belongs & XEXPR) != 0; } boolean isDeclaration() { return (belongs & XDECL) != 0; } boolean isError() { return (belongs & XERRO) != 0; } boolean isStart() { return (belongs & XSTART) != 0; } boolean isBracesNeeded() { return (belongs & XBRACESNEEDED) != 0; } /** * After construction, check that all compiler TokenKind values have * corresponding TK values. */ static { for (TK tk : TK.values()) { if (tk.tokenKind != null) { tokenKindToTKMap.put(tk.tokenKind, tk); } } for (TokenKind kind : TokenKind.values()) { tokenKindToTK(null, kind); // assure they can be retrieved without error } // Mappings of disambiguated contexts STAR.mapping = prev -> prev == DOT ? DOTSTAR : STAR; NEW.mapping = prev -> prev == COLCOL ? COLCOLNEW : NEW; CLASS.mapping = prev -> prev == DOT ? DOTCLASS : CLASS; } } /** * A completeness scanner token. */ private static class CT { /** The token kind */ public final TK kind; /** The end position of this token */ public final int endPos; /** The error message **/ public final String message; private CT(TK tk, Token tok, String msg) { this.kind = tk; this.endPos = tok.endPos; this.message = msg; //throw new InternalError(msg); /* for debugging */ } private CT(TK tk, Token tok) { this.kind = tk; this.endPos = tok.endPos; this.message = null; } private CT(TK tk, int endPos) { this.kind = tk; this.endPos = endPos; this.message = null; } } /** * Look for matching tokens (like parens) and other special cases, like "new" */ private static class Matched implements Iterator<CT> { private final Scanner scanner; private Token current; private CT prevCT; private CT currentCT; private final Deque<Token> stack = new ArrayDeque<>(); Matched(Scanner scanner) { this.scanner = scanner; advance(); prevCT = currentCT = new CT(SEMI, 0); // So is valid for testing } @Override public boolean hasNext() { return currentCT.kind != EOF; } private Token advance() { Token prev = current; scanner.nextToken(); current = scanner.token(); return prev; } @Override public CT next() { prevCT = currentCT; currentCT = nextCT(); return currentCT; } private CT match(TK tk, TokenKind open) { Token tok = advance(); db("match desired-tk=%s, open=%s, seen-tok=%s", tk, open, tok.kind); if (stack.isEmpty()) { return new CT(ERROR, tok, "Encountered '" + tok + "' with no opening '" + open + "'"); } Token p = stack.pop(); if (p.kind != open) { return new CT(ERROR, tok, "No match for '" + p + "' instead encountered '" + tok + "'"); } return new CT(tk, tok); } private void db(String format, Object ... args) { // System.err.printf(format, args); // System.err.printf(" -- stack("); // if (stack.isEmpty()) { // // } else { // for (Token tok : stack) { // System.err.printf("%s ", tok.kind); // } // } // System.err.printf(") current=%s / currentCT=%s\n", current.kind, currentCT.kind); } /** * @return the next scanner token */ private CT nextCT() { // TODO Annotations? TK prevTK = currentCT.kind; while (true) { db("nextCT"); CT ct; switch (current.kind) { case EOF: db("eof"); if (stack.isEmpty()) { ct = new CT(EOF, current); } else { TokenKind unmatched = stack.pop().kind; stack.clear(); // So we will get EOF next time ct = new CT(UNMATCHED, current, "Unmatched " + unmatched); } break; case LPAREN: case LBRACE: case LBRACKET: stack.push(advance()); prevTK = SEMI; // new start continue; case RPAREN: ct = match(PARENS, TokenKind.LPAREN); break; case RBRACE: ct = match(BRACES, TokenKind.LBRACE); break; case RBRACKET: ct = match(BRACKETS, TokenKind.LBRACKET); break; default: ct = new CT(TK.tokenKindToTK(prevTK, current.kind), advance()); break; } // Detect an error if we are at starting position and the last // token wasn't a terminating one. Special case: within braces, // comma can proceed semicolon, e.g. the values list in enum if (ct.kind.isStart() && !prevTK.isOkToTerminate() && prevTK != COMMA) { return new CT(ERROR, current, "No '" + prevTK + "' before '" + ct.kind + "'"); } if (stack.isEmpty() || ct.kind.isError()) { return ct; } prevTK = ct.kind; } } } /** * Fuzzy parser based on token kinds */ private static class Parser { private final Supplier<Matched> matchedFactory; private final Function<Worker<ParseTask, Completeness>, Completeness> parseFactory; private Matched in; private CT token; private Completeness checkResult; Parser(Supplier<Matched> matchedFactory, Function<Worker<ParseTask, Completeness>, Completeness> parseFactory) { this.matchedFactory = matchedFactory; this.parseFactory = parseFactory; resetInput(); } final void resetInput() { this.in = matchedFactory.get(); nextToken(); } final void nextToken() { in.next(); token = in.currentCT; } boolean shouldAbort(TK tk) { if (token.kind == tk) { nextToken(); return false; } switch (token.kind) { case EOF: checkResult = ((tk == SEMI) && in.prevCT.kind.isOkToTerminate()) ? Completeness.COMPLETE_WITH_SEMI : Completeness.DEFINITELY_INCOMPLETE; return true; case UNMATCHED: checkResult = Completeness.DEFINITELY_INCOMPLETE; return true; default: checkResult = error(); return true; } } Completeness lastly(TK tk) { if (shouldAbort(tk)) return checkResult; return Completeness.COMPLETE; } Completeness optionalFinalSemi() { if (!shouldAbort(SEMI)) return Completeness.COMPLETE; if (checkResult == Completeness.COMPLETE_WITH_SEMI) return Completeness.COMPLETE; return checkResult; } boolean shouldAbort(Completeness flags) { checkResult = flags; return flags != Completeness.COMPLETE; } public int endPos() { return in.prevCT.endPos; } public Completeness parseUnit() { //System.err.printf("%s: belongs %o XANY1 %o\n", token.kind, token.kind.belongs, token.kind.belongs & XANY1); switch (token.kind.belongs & XANY1) { case XEXPR1o: return parseExpressionOptionalSemi(); case XSTMT1o: { Completeness stat = parseSimpleStatement(); return stat==null? error() : stat; } case XDECL1o: return parseDeclaration(); case XSTMT1o | XDECL1o: case XEXPR1o | XDECL1o: return disambiguateDeclarationVsExpression(); case 0: if ((token.kind.belongs & XERRO) != 0) { return parseExpressionStatement(); // Let this gen the status } return error(); default: throw new InternalError("Case not covered " + token.kind.belongs + " in " + token.kind); } } public Completeness parseDeclaration() { boolean isImport = token.kind == IMPORT; boolean isBracesNeeded = false; while (token.kind.isDeclaration()) { isBracesNeeded |= token.kind.isBracesNeeded(); nextToken(); } switch (token.kind) { case EQ: nextToken(); return parseExpressionStatement(); case BRACES: case SEMI: nextToken(); return Completeness.COMPLETE; case UNMATCHED: nextToken(); return Completeness.DEFINITELY_INCOMPLETE; case EOF: switch (in.prevCT.kind) { case BRACES: case SEMI: return Completeness.COMPLETE; case IDENTIFIER: return isBracesNeeded ? Completeness.DEFINITELY_INCOMPLETE : Completeness.COMPLETE_WITH_SEMI; case BRACKETS: return Completeness.COMPLETE_WITH_SEMI; case DOTSTAR: if (isImport) { return Completeness.COMPLETE_WITH_SEMI; } else { return Completeness.UNKNOWN; } default: return Completeness.DEFINITELY_INCOMPLETE; } default: return error(); } } public Completeness disambiguateDeclarationVsExpression() { // String folding messes up position information. return parseFactory.apply(pt -> { List<? extends Tree> units = pt.units(); if (units.isEmpty()) { return error(); } Tree unitTree = units.get(0); switch (unitTree.getKind()) { case EXPRESSION_STATEMENT: return parseExpressionOptionalSemi(); case LABELED_STATEMENT: if (shouldAbort(IDENTIFIER)) return checkResult; if (shouldAbort(COLON)) return checkResult; return parseStatement(); case VARIABLE: case IMPORT: case CLASS: case ENUM: case ANNOTATION_TYPE: case INTERFACE: case METHOD: return parseDeclaration(); default: return error(); } }); } public Completeness parseExpressionStatement() { if (shouldAbort(parseExpression())) return checkResult; return lastly(SEMI); } public Completeness parseExpressionOptionalSemi() { if (shouldAbort(parseExpression())) return checkResult; return optionalFinalSemi(); } public Completeness parseExpression() { while (token.kind.isExpression()) nextToken(); return Completeness.COMPLETE; } public Completeness parseStatement() { Completeness stat = parseSimpleStatement(); if (stat == null) { return parseExpressionStatement(); } return stat; } /** * Statement = Block | IF ParExpression Statement [ELSE Statement] | FOR * "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement | FOR * "(" FormalParameter : Expression ")" Statement | WHILE ParExpression * Statement | DO Statement WHILE ParExpression ";" | TRY Block ( * Catches | [Catches] FinallyPart ) | TRY "(" ResourceSpecification * ";"opt ")" Block [Catches] [FinallyPart] | SWITCH ParExpression "{" * SwitchBlockStatementGroups "}" | SYNCHRONIZED ParExpression Block | * RETURN [Expression] ";" | THROW Expression ";" | BREAK [Ident] ";" | * CONTINUE [Ident] ";" | ASSERT Expression [ ":" Expression ] ";" | ";" */ public Completeness parseSimpleStatement() { switch (token.kind) { case BRACES: return lastly(BRACES); case IF: { nextToken(); if (shouldAbort(PARENS)) return checkResult; Completeness thenpart = parseStatement(); if (shouldAbort(thenpart)) return thenpart; if (token.kind == ELSE) { nextToken(); return parseStatement(); } return thenpart; } case FOR: { nextToken(); if (shouldAbort(PARENS)) return checkResult; if (shouldAbort(parseStatement())) return checkResult; return Completeness.COMPLETE; } case WHILE: { nextToken(); if (shouldAbort(PARENS)) return error(); return parseStatement(); } case DO: { nextToken(); switch (parseStatement()) { case DEFINITELY_INCOMPLETE: case CONSIDERED_INCOMPLETE: case COMPLETE_WITH_SEMI: return Completeness.DEFINITELY_INCOMPLETE; case UNKNOWN: return error(); case COMPLETE: break; } if (shouldAbort(WHILE)) return checkResult; if (shouldAbort(PARENS)) return checkResult; return lastly(SEMI); } case TRY: { boolean hasResources = false; nextToken(); if (token.kind == PARENS) { nextToken(); hasResources = true; } if (shouldAbort(BRACES)) return checkResult; if (token.kind == CATCH || token.kind == FINALLY) { while (token.kind == CATCH) { if (shouldAbort(CATCH)) return checkResult; if (shouldAbort(PARENS)) return checkResult; if (shouldAbort(BRACES)) return checkResult; } if (token.kind == FINALLY) { if (shouldAbort(FINALLY)) return checkResult; if (shouldAbort(BRACES)) return checkResult; } } else if (!hasResources) { if (token.kind == EOF) { return Completeness.DEFINITELY_INCOMPLETE; } else { return error(); } } return Completeness.COMPLETE; } case SWITCH: { nextToken(); if (shouldAbort(PARENS)) return checkResult; return lastly(BRACES); } case SYNCHRONIZED: { nextToken(); if (shouldAbort(PARENS)) return checkResult; return lastly(BRACES); } case THROW: { nextToken(); if (shouldAbort(parseExpression())) return checkResult; return lastly(SEMI); } case SEMI: return lastly(SEMI); case ASSERT: nextToken(); // Crude expression parsing just happily eats the optional colon return parseExpressionStatement(); case RETURN: case BREAK: case CONTINUE: nextToken(); return parseExpressionStatement(); // What are these doing here? case ELSE: case FINALLY: case CATCH: return error(); case EOF: return Completeness.CONSIDERED_INCOMPLETE; default: return null; } } } }
⏎ jdk/jshell/CompletenessAnalyzer.java
Or download all of them as a single archive file:
File name: jdk.jshell-11.0.1-src.zip File size: 283093 bytes Release date: 2018-11-04 Download
⇒ JDK 11 jdk.jsobject.jmod - JS Object Module
2020-06-30, 29350👍, 0💬
Popular Posts:
Jaxen, Release 1.1.1, is an open source XPath library written in Java. It is adaptable to many diffe...
JDK 6 tools.jar is the JAR file for JDK 6 tools. It contains Java classes to support different JDK t...
Apache BCEL Source Code Files are inside the Apache BCEL source package file like bcel-6.6.1-src.zip...
How to download and install ojdbc7.jar for Oracle 12c R1? ojdbc8.jar for Oracle 12c R1 is a Java 7 a...
How to show the XML parsing flow with sax\DocumentTracer.java provided in the Apache Xerces package?...