mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8167343: JShell: Completeness analysis infers an incomplete declaration as COMPLETE_WITH_SEMI, which is a first line of Allman style
Reviewed-by: rfield
This commit is contained in:
parent
ece1def9ae
commit
a53b8b8a5d
2 changed files with 29 additions and 6 deletions
|
@ -166,6 +166,7 @@ class CompletenessAnalyzer {
|
||||||
private static final int XTERM = 0b100000000; // Can terminate (last before EOF)
|
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 XSTART = 0b1000000000; // Boundary, must be XTERM before
|
||||||
private static final int XERRO = 0b10000000000; // Is an error
|
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
|
* An extension of the compiler's TokenKind which adds our combined/processed
|
||||||
|
@ -190,7 +191,7 @@ class CompletenessAnalyzer {
|
||||||
ERROR(TokenKind.ERROR, XERRO), //
|
ERROR(TokenKind.ERROR, XERRO), //
|
||||||
IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM), //
|
IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM), //
|
||||||
UNDERSCORE(TokenKind.UNDERSCORE, XERRO), // _
|
UNDERSCORE(TokenKind.UNDERSCORE, XERRO), // _
|
||||||
CLASS(TokenKind.CLASS, XEXPR|XDECL1), // class decl (MAPPED: DOTCLASS)
|
CLASS(TokenKind.CLASS, XEXPR|XDECL1|XBRACESNEEDED), // class decl (MAPPED: DOTCLASS)
|
||||||
MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1), // @
|
MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1), // @
|
||||||
IMPORT(TokenKind.IMPORT, XDECL1|XSTART), // import -- consider declaration
|
IMPORT(TokenKind.IMPORT, XDECL1|XSTART), // import -- consider declaration
|
||||||
SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART), // ;
|
SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART), // ;
|
||||||
|
@ -202,10 +203,10 @@ class CompletenessAnalyzer {
|
||||||
CUSTOM(TokenKind.CUSTOM, XERRO), // No uses
|
CUSTOM(TokenKind.CUSTOM, XERRO), // No uses
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
ENUM(TokenKind.ENUM, XDECL1), // enum
|
ENUM(TokenKind.ENUM, XDECL1|XBRACESNEEDED), // enum
|
||||||
IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL), // implements
|
IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL), // implements
|
||||||
INTERFACE(TokenKind.INTERFACE, XDECL1), // interface
|
INTERFACE(TokenKind.INTERFACE, XDECL1|XBRACESNEEDED), // interface
|
||||||
THROWS(TokenKind.THROWS, XDECL), // throws
|
THROWS(TokenKind.THROWS, XDECL|XBRACESNEEDED), // throws
|
||||||
|
|
||||||
// Primarive type names
|
// Primarive type names
|
||||||
BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1), // boolean
|
BOOLEAN(TokenKind.BOOLEAN, XEXPR1|XDECL1), // boolean
|
||||||
|
@ -381,6 +382,10 @@ class CompletenessAnalyzer {
|
||||||
return (belongs & XSTART) != 0;
|
return (belongs & XSTART) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isBracesNeeded() {
|
||||||
|
return (belongs & XBRACESNEEDED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After construction, check that all compiler TokenKind values have
|
* After construction, check that all compiler TokenKind values have
|
||||||
* corresponding TK values.
|
* corresponding TK values.
|
||||||
|
@ -641,7 +646,9 @@ class CompletenessAnalyzer {
|
||||||
|
|
||||||
public Completeness parseDeclaration() {
|
public Completeness parseDeclaration() {
|
||||||
boolean isImport = token.kind == IMPORT;
|
boolean isImport = token.kind == IMPORT;
|
||||||
|
boolean isBracesNeeded = false;
|
||||||
while (token.kind.isDeclaration()) {
|
while (token.kind.isDeclaration()) {
|
||||||
|
isBracesNeeded |= token.kind.isBracesNeeded();
|
||||||
nextToken();
|
nextToken();
|
||||||
}
|
}
|
||||||
switch (token.kind) {
|
switch (token.kind) {
|
||||||
|
@ -666,6 +673,9 @@ class CompletenessAnalyzer {
|
||||||
case SEMI:
|
case SEMI:
|
||||||
return Completeness.COMPLETE;
|
return Completeness.COMPLETE;
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
|
return isBracesNeeded
|
||||||
|
? Completeness.DEFINITELY_INCOMPLETE
|
||||||
|
: Completeness.COMPLETE_WITH_SEMI;
|
||||||
case BRACKETS:
|
case BRACKETS:
|
||||||
return Completeness.COMPLETE_WITH_SEMI;
|
return Completeness.COMPLETE_WITH_SEMI;
|
||||||
case DOTSTAR:
|
case DOTSTAR:
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8149524 8131024 8165211 8080071 8130454
|
* @bug 8149524 8131024 8165211 8080071 8130454 8167343
|
||||||
* @summary Test SourceCodeAnalysis
|
* @summary Test SourceCodeAnalysis
|
||||||
* @build KullaTesting TestingInputStream
|
* @build KullaTesting TestingInputStream
|
||||||
* @run testng CompletenessTest
|
* @run testng CompletenessTest
|
||||||
|
@ -117,6 +117,7 @@ public class CompletenessTest extends KullaTesting {
|
||||||
"bar: g()",
|
"bar: g()",
|
||||||
"baz: while (true) if (t()) printf('-'); else break baz",
|
"baz: while (true) if (t()) printf('-'); else break baz",
|
||||||
"java.util.function.IntFunction<int[]> ggg = int[]::new",
|
"java.util.function.IntFunction<int[]> ggg = int[]::new",
|
||||||
|
"List<? extends Object> l",
|
||||||
};
|
};
|
||||||
|
|
||||||
static final String[] considered_incomplete = new String[] {
|
static final String[] considered_incomplete = new String[] {
|
||||||
|
@ -162,7 +163,19 @@ public class CompletenessTest extends KullaTesting {
|
||||||
"enum TK { EOF(TokenKind.EOF, 0),",
|
"enum TK { EOF(TokenKind.EOF, 0),",
|
||||||
"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM)",
|
"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM)",
|
||||||
"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); ",
|
"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); ",
|
||||||
"enum Tt { FOO, BAR, BAZ,;"
|
"enum Tt { FOO, BAR, BAZ,;",
|
||||||
|
"class C",
|
||||||
|
"class C extends D",
|
||||||
|
"class C implements D",
|
||||||
|
"class C implements D, E",
|
||||||
|
"interface I extends D",
|
||||||
|
"interface I extends D, E",
|
||||||
|
"enum E",
|
||||||
|
"enum E implements I1",
|
||||||
|
"enum E implements I1, I2",
|
||||||
|
"@interface Anno",
|
||||||
|
"void f()",
|
||||||
|
"void f() throws E",
|
||||||
};
|
};
|
||||||
|
|
||||||
static final String[] unknown = new String[] {
|
static final String[] unknown = new String[] {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue