Path: blob/master/test/langtools/jdk/jshell/CompletenessTest.java
40931 views
/*1* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268 8223782 8235474 824677426* @summary Test SourceCodeAnalysis27* @build KullaTesting TestingInputStream28* @run testng CompletenessTest29*/3031import java.util.Map;32import java.util.HashMap;33import java.util.function.Consumer;34import javax.lang.model.SourceVersion;35import jdk.jshell.JShell;3637import org.testng.annotations.Test;38import jdk.jshell.SourceCodeAnalysis.Completeness;3940import static jdk.jshell.SourceCodeAnalysis.Completeness.*;41import org.testng.annotations.BeforeMethod;4243@Test44public class CompletenessTest extends KullaTesting {4546// Add complete units that end with semicolon to complete_with_semi (without47// the semicolon). Both cases will be tested.48static final String[] complete = new String[] {49"{ x= 4; }",50"int mm(int x) {kll}",51"if (t) { ddd; }",52"for (int i = 0; i < lines.length(); ++i) { foo }",53"while (ct == null) { switch (current.kind) { case EOF: { } } }",54"if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched); }",55"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); }",56"List<T> f() { return null; }",57"List<?> f() { return null; }",58"List<? extends Object> f() { return null; }",59"Map<? extends Object, ? super Object> f() { return null; }",60"class C { int z; }",61"synchronized (r) { f(); }",62"try { } catch (Exception ex) { }",63"try { } catch (Exception ex) { } finally { }",64"try { } finally { }",65"try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)) { }",66"foo: while (true) { printf(\"Innn\"); break foo; }",67"class Case<E1 extends Enum<E1>, E2 extends Enum<E2>, E3 extends Enum<E3>> {}",68";",69"enum Tt { FOO, BAR, BAZ,; }",70"record D(int i) {}",71"static record D(int i) {}",72};7374static final String[] expression = new String[] {75"test",76"x + y",77"x + y ++",78"p = 9",79"match(BRACKETS, TokenKind.LBRACKET)",80"new C()",81"new C() { public String toString() { return \"Hi\"; } }",82"new int[]",83"new int[] {1, 2,3}",84"new Foo() {}",85"i >= 0 && Character.isWhitespace(s.charAt(i))",86"int.class",87"String.class",88"record.any",89"record()",90"record(1)",91"record.length()"92};9394static final String[] complete_with_semi = new String[] {95"int mm",96"if (t) ddd",97"int p = 9",98"int p",99"Deque<Token> stack = new ArrayDeque<>()",100"final Deque<Token> stack = new ArrayDeque<>()",101"java.util.Scanner input = new java.util.Scanner(System.in)",102"java.util.Scanner input = new java.util.Scanner(System.in) { }",103"int j = -i",104"String[] a = { \"AAA\" }",105"assert true",106"int path[]",107"int path[][]",108"int path[][] = new int[22][]",109"int path[] = new int[22]",110"int path[] = new int[] {1, 2, 3}",111"int[] path",112"int path[] = new int[22]",113"int path[][] = new int[22][]",114"for (Object o : a) System.out.println(\"Yep\")",115"while (os == null) System.out.println(\"Yep\")",116"do f(); while (t)",117"if (os == null) System.out.println(\"Yep\")",118"if (t) if (!t) System.out.println(123)",119"for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else break",120"for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else continue",121"for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else return",122"throw ex",123"C c = new C()",124"java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)",125"BufferedReader br = new BufferedReader(new FileReader(path))",126"bar: g()",127"baz: while (true) if (t()) printf('-'); else break baz",128"java.util.function.IntFunction<int[]> ggg = int[]::new",129"List<? extends Object> l",130"int[] m = {1, 2}",131"int[] m = {1, 2}, n = null",132"int[] m = {1, 2}, n",133"int[] m = {1, 2}, n = {3, 4}",134};135136static final String[] considered_incomplete = new String[] {137"if (t)",138"if (t) { } else",139"if (t) if (!t)",140"if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE))",141"for (int i = 0; i < 10; ++i)",142"while (os == null)",143};144145static final String[] definitely_incomplete = new String[] {146"int mm(",147"int mm(int x",148"int mm(int x)",149"int mm(int x) {",150"int mm(int x) {kll",151"if",152"if (",153"if (t",154"if (t) {",155"if (t) { ddd",156"if (t) { ddd;",157"if (t) if (",158"if (stack.isEmpty()) {",159"if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) {",160"if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched);",161"x +",162"x *",163"3 *",164"int",165"for (int i = 0; i < lines.length(); ++i) {",166"new",167"new C(",168"new int[",169"new int[] {1, 2,3",170"new int[] {",171"while (ct == null) {",172"while (ct == null) { switch (current.kind) {",173"while (ct == null) { switch (current.kind) { case EOF: {",174"while (ct == null) { switch (current.kind) { case EOF: { } }",175"enum TK {",176"enum TK { EOF(TokenKind.EOF, 0),",177"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM)",178"enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); ",179"enum Tt { FOO, BAR, BAZ,;",180"class C",181"class C extends D",182"class C implements D",183"class C implements D, E",184"interface I extends D",185"interface I extends D, E",186"enum E",187"enum E implements I1",188"enum E implements I1, I2",189"@interface Anno",190"void f()",191"void f() throws E",192"@A(",193"int n = 4,",194"int n,",195"int[] m = {1, 2},",196"int[] m = {1, 2}, n = {3, 4},",197"Map<String,",198"switch (x) {",199"var v = switch (x) {",200"var v = switch (x) { case ",201"var v = switch (x) { case 0:",202"var v = switch (x) { case 0: break 12; ",203"record D",204"record D(",205"record D(String",206"record D(String i",207"record D(String i,",208"record D(String i, String",209"record D(String i, String j",210"record D(String i)",211"record D(String i, String j)",212"record D(String i) {",213"record D(String i, String j) {",214"static record D",215"static record D(",216"static record D(String",217"static record D(String i",218"static record D(String i,",219"static record D(String i, String",220"static record D(String i, String j",221"static record D(String i)",222"static record D(String i, String j)",223"static record D(String i) {",224"static record D(String i, String j) {",225};226227static final String[] unknown = new String[] {228"new ;"229};230231static final Map<Completeness, String[]> statusToCases = new HashMap<>();232static {233statusToCases.put(COMPLETE, complete);234statusToCases.put(COMPLETE_WITH_SEMI, complete_with_semi);235statusToCases.put(CONSIDERED_INCOMPLETE, considered_incomplete);236statusToCases.put(DEFINITELY_INCOMPLETE, definitely_incomplete);237}238239private void assertStatus(String input, Completeness status, String source) {240String augSrc;241switch (status) {242case COMPLETE_WITH_SEMI:243augSrc = source + ";";244break;245246case DEFINITELY_INCOMPLETE:247augSrc = null;248break;249250case CONSIDERED_INCOMPLETE:251augSrc = source + ";";252break;253254case EMPTY:255case COMPLETE:256case UNKNOWN:257augSrc = source;258break;259260default:261throw new AssertionError();262}263assertAnalyze(input, status, augSrc);264}265266private void assertStatus(String[] ins, Completeness status) {267for (String input : ins) {268assertStatus(input, status, input);269}270}271272public void test_complete() {273assertStatus(complete, COMPLETE);274}275276public void test_expression() {277assertStatus(expression, COMPLETE);278}279280public void test_complete_with_semi() {281assertStatus(complete_with_semi, COMPLETE_WITH_SEMI);282}283284public void test_considered_incomplete() {285assertStatus(considered_incomplete, CONSIDERED_INCOMPLETE);286}287288public void test_definitely_incomplete() {289assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);290}291292public void test_unknown() {293assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);294}295296public void testCompleted_complete_with_semi() {297for (String in : complete_with_semi) {298String input = in + ";";299assertStatus(input, COMPLETE, input);300}301}302303public void testCompleted_expression_with_semi() {304for (String in : expression) {305String input = in + ";";306assertStatus(input, COMPLETE, input);307}308}309310public void testCompleted_considered_incomplete() {311for (String in : considered_incomplete) {312String input = in + ";";313assertStatus(input, COMPLETE, input);314}315}316317private void assertSourceByStatus(String first) {318for (Map.Entry<Completeness, String[]> e : statusToCases.entrySet()) {319for (String in : e.getValue()) {320String input = first + in;321assertAnalyze(input, COMPLETE, first, in, true);322}323}324}325326public void testCompleteSource_complete() {327for (String input : complete) {328assertSourceByStatus(input);329}330}331332public void testCompleteSource_complete_with_semi() {333for (String in : complete_with_semi) {334String input = in + ";";335assertSourceByStatus(input);336}337}338339public void testCompleteSource_expression() {340for (String in : expression) {341String input = in + ";";342assertSourceByStatus(input);343}344}345346public void testCompleteSource_considered_incomplete() {347for (String in : considered_incomplete) {348String input = in + ";";349assertSourceByStatus(input);350}351}352353public void testTrailingSlash() {354assertStatus("\"abc\\", UNKNOWN, "\"abc\\");355}356357public void testOpenComment() {358assertStatus("int xx; /* hello", DEFINITELY_INCOMPLETE, null);359assertStatus("/** test", DEFINITELY_INCOMPLETE, null);360}361362public void testTextBlocks() {363assertStatus("\"\"\"", DEFINITELY_INCOMPLETE, null);364assertStatus("\"\"\"broken", DEFINITELY_INCOMPLETE, null);365assertStatus("\"\"\"\ntext", DEFINITELY_INCOMPLETE, null);366assertStatus("\"\"\"\ntext\"\"", DEFINITELY_INCOMPLETE, "\"\"\"\ntext\"\"\"");367assertStatus("\"\"\"\ntext\"\"\"", COMPLETE, "\"\"\"\ntext\"\"\"");368assertStatus("\"\"\"\ntext\\\"\"\"\"", COMPLETE, "\"\"\"\ntext\\\"\"\"\"");369assertStatus("\"\"\"\ntext\\\"\"\"", DEFINITELY_INCOMPLETE, null);370assertStatus("\"\"\"\ntext\\\"\"\"\\\"\"\"", DEFINITELY_INCOMPLETE, null);371assertStatus("\"\"\"\ntext\\\"\"\"\\\"\"\"\"\"\"", COMPLETE, "\"\"\"\ntext\\\"\"\"\\\"\"\"\"\"\"");372}373374public void testMiscSource() {375assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug376assertStatus("int m() {} dfd", COMPLETE, "int m() {}");377assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug378assertStatus("int[] m = {1, 2}, n = new int[0]; int i;", COMPLETE,379"int[] m = {1, 2}, n = new int[0];");380}381}382383384