test/langtools/jdk/jshell/CompletenessTest.java
changeset 47216 71c04702a3d5
parent 45748 0202b55d8e08
child 51563 de411d537aae
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268
       
    27  * @summary Test SourceCodeAnalysis
       
    28  * @build KullaTesting TestingInputStream
       
    29  * @run testng CompletenessTest
       
    30  */
       
    31 
       
    32 import java.util.Map;
       
    33 import java.util.HashMap;
       
    34 
       
    35 import org.testng.annotations.Test;
       
    36 import jdk.jshell.SourceCodeAnalysis.Completeness;
       
    37 
       
    38 import static jdk.jshell.SourceCodeAnalysis.Completeness.*;
       
    39 
       
    40 @Test
       
    41 public class CompletenessTest extends KullaTesting {
       
    42 
       
    43     // Add complete units that end with semicolon to complete_with_semi (without
       
    44     // the semicolon).  Both cases will be tested.
       
    45     static final String[] complete = new String[] {
       
    46         "{ x= 4; }",
       
    47         "int mm(int x) {kll}",
       
    48         "if (t) { ddd; }",
       
    49         "for (int i = 0; i < lines.length(); ++i) { foo }",
       
    50         "while (ct == null) { switch (current.kind) { case EOF: { } } }",
       
    51         "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched); }",
       
    52         "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); }",
       
    53         "List<T> f() { return null; }",
       
    54         "List<?> f() { return null; }",
       
    55         "List<? extends Object> f() { return null; }",
       
    56         "Map<? extends Object, ? super Object> f() { return null; }",
       
    57         "class C { int z; }",
       
    58         "synchronized (r) { f(); }",
       
    59         "try { } catch (Exception ex) { }",
       
    60         "try { } catch (Exception ex) { } finally { }",
       
    61         "try { } finally { }",
       
    62         "try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)) { }",
       
    63         "foo: while (true) { printf(\"Innn\"); break foo; }",
       
    64         "class Case<E1 extends Enum<E1>, E2 extends Enum<E2>, E3 extends Enum<E3>> {}",
       
    65         ";",
       
    66         "enum Tt { FOO, BAR, BAZ,; }"
       
    67     };
       
    68 
       
    69     static final String[] expression = new String[] {
       
    70         "test",
       
    71         "x + y",
       
    72         "x + y ++",
       
    73         "p = 9",
       
    74         "match(BRACKETS, TokenKind.LBRACKET)",
       
    75         "new C()",
       
    76         "new C() { public String toString() { return \"Hi\"; } }",
       
    77         "new int[]",
       
    78         "new int[] {1, 2,3}",
       
    79         "new Foo() {}",
       
    80         "i >= 0 && Character.isWhitespace(s.charAt(i))",
       
    81         "int.class",
       
    82         "String.class",
       
    83     };
       
    84 
       
    85     static final String[] complete_with_semi = new String[] {
       
    86         "int mm",
       
    87         "if (t) ddd",
       
    88         "int p = 9",
       
    89         "int p",
       
    90         "Deque<Token> stack = new ArrayDeque<>()",
       
    91         "final Deque<Token> stack = new ArrayDeque<>()",
       
    92         "java.util.Scanner input = new java.util.Scanner(System.in)",
       
    93         "java.util.Scanner input = new java.util.Scanner(System.in) { }",
       
    94         "int j = -i",
       
    95         "String[] a = { \"AAA\" }",
       
    96         "assert true",
       
    97         "int path[]",
       
    98         "int path[][]",
       
    99         "int path[][] = new int[22][]",
       
   100         "int path[] = new int[22]",
       
   101         "int path[] = new int[] {1, 2, 3}",
       
   102         "int[] path",
       
   103         "int path[] = new int[22]",
       
   104         "int path[][] = new int[22][]",
       
   105         "for (Object o : a) System.out.println(\"Yep\")",
       
   106         "while (os == null) System.out.println(\"Yep\")",
       
   107         "do f(); while (t)",
       
   108         "if (os == null) System.out.println(\"Yep\")",
       
   109         "if (t) if (!t) System.out.println(123)",
       
   110         "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else break",
       
   111         "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else continue",
       
   112         "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else return",
       
   113         "throw ex",
       
   114         "C c = new C()",
       
   115         "java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)",
       
   116         "BufferedReader br = new BufferedReader(new FileReader(path))",
       
   117         "bar: g()",
       
   118         "baz: while (true) if (t()) printf('-'); else break baz",
       
   119         "java.util.function.IntFunction<int[]> ggg = int[]::new",
       
   120         "List<? extends Object> l",
       
   121         "int[] m = {1, 2}",
       
   122         "int[] m = {1, 2}, n = null",
       
   123         "int[] m = {1, 2}, n",
       
   124         "int[] m = {1, 2}, n = {3, 4}",
       
   125     };
       
   126 
       
   127     static final String[] considered_incomplete = new String[] {
       
   128         "if (t)",
       
   129         "if (t) { } else",
       
   130         "if (t) if (!t)",
       
   131         "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE))",
       
   132         "for (int i = 0; i < 10; ++i)",
       
   133         "while (os == null)",
       
   134     };
       
   135 
       
   136     static final String[] definitely_incomplete = new String[] {
       
   137         "int mm(",
       
   138         "int mm(int x",
       
   139         "int mm(int x)",
       
   140         "int mm(int x) {",
       
   141         "int mm(int x) {kll",
       
   142         "if",
       
   143         "if (",
       
   144         "if (t",
       
   145         "if (t) {",
       
   146         "if (t) { ddd",
       
   147         "if (t) { ddd;",
       
   148         "if (t) if (",
       
   149         "if (stack.isEmpty()) {",
       
   150         "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) {",
       
   151         "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched);",
       
   152         "x +",
       
   153         "x *",
       
   154         "3 *",
       
   155         "int",
       
   156         "for (int i = 0; i < lines.length(); ++i) {",
       
   157         "new",
       
   158         "new C(",
       
   159         "new int[",
       
   160         "new int[] {1, 2,3",
       
   161         "new int[] {",
       
   162         "while (ct == null) {",
       
   163         "while (ct == null) { switch (current.kind) {",
       
   164         "while (ct == null) { switch (current.kind) { case EOF: {",
       
   165         "while (ct == null) { switch (current.kind) { case EOF: { } }",
       
   166         "enum TK {",
       
   167         "enum TK { EOF(TokenKind.EOF, 0),",
       
   168         "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM)",
       
   169         "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); ",
       
   170         "enum Tt { FOO, BAR, BAZ,;",
       
   171         "class C",
       
   172         "class C extends D",
       
   173         "class C implements D",
       
   174         "class C implements D, E",
       
   175         "interface I extends D",
       
   176         "interface I extends D, E",
       
   177         "enum E",
       
   178         "enum E implements I1",
       
   179         "enum E implements I1, I2",
       
   180         "@interface Anno",
       
   181         "void f()",
       
   182         "void f() throws E",
       
   183         "@A(",
       
   184         "int n = 4,",
       
   185         "int n,",
       
   186         "int[] m = {1, 2},",
       
   187         "int[] m = {1, 2}, n = {3, 4},",
       
   188         "Map<String,"
       
   189     };
       
   190 
       
   191     static final String[] unknown = new String[] {
       
   192         "new ;"
       
   193     };
       
   194 
       
   195     static final Map<Completeness, String[]> statusToCases = new HashMap<>();
       
   196     static {
       
   197         statusToCases.put(COMPLETE, complete);
       
   198         statusToCases.put(COMPLETE_WITH_SEMI, complete_with_semi);
       
   199         statusToCases.put(CONSIDERED_INCOMPLETE, considered_incomplete);
       
   200         statusToCases.put(DEFINITELY_INCOMPLETE, definitely_incomplete);
       
   201     }
       
   202 
       
   203     private void assertStatus(String input, Completeness status, String source) {
       
   204         String augSrc;
       
   205         switch (status) {
       
   206             case COMPLETE_WITH_SEMI:
       
   207                 augSrc = source + ";";
       
   208                 break;
       
   209 
       
   210             case DEFINITELY_INCOMPLETE:
       
   211                 augSrc = null;
       
   212                 break;
       
   213 
       
   214             case CONSIDERED_INCOMPLETE:
       
   215                 augSrc = source + ";";
       
   216                 break;
       
   217 
       
   218             case EMPTY:
       
   219             case COMPLETE:
       
   220             case UNKNOWN:
       
   221                 augSrc = source;
       
   222                 break;
       
   223 
       
   224             default:
       
   225                 throw new AssertionError();
       
   226         }
       
   227         assertAnalyze(input, status, augSrc);
       
   228     }
       
   229 
       
   230     private void assertStatus(String[] ins, Completeness status) {
       
   231         for (String input : ins) {
       
   232             assertStatus(input, status, input);
       
   233         }
       
   234     }
       
   235 
       
   236     public void test_complete() {
       
   237         assertStatus(complete, COMPLETE);
       
   238     }
       
   239 
       
   240     public void test_expression() {
       
   241         assertStatus(expression, COMPLETE);
       
   242     }
       
   243 
       
   244     public void test_complete_with_semi() {
       
   245         assertStatus(complete_with_semi, COMPLETE_WITH_SEMI);
       
   246     }
       
   247 
       
   248     public void test_considered_incomplete() {
       
   249         assertStatus(considered_incomplete, CONSIDERED_INCOMPLETE);
       
   250     }
       
   251 
       
   252     public void test_definitely_incomplete() {
       
   253         assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);
       
   254     }
       
   255 
       
   256     public void test_unknown() {
       
   257         assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);
       
   258     }
       
   259 
       
   260     public void testCompleted_complete_with_semi() {
       
   261         for (String in : complete_with_semi) {
       
   262             String input = in + ";";
       
   263             assertStatus(input, COMPLETE, input);
       
   264         }
       
   265     }
       
   266 
       
   267     public void testCompleted_expression_with_semi() {
       
   268         for (String in : expression) {
       
   269             String input = in + ";";
       
   270             assertStatus(input, COMPLETE, input);
       
   271         }
       
   272     }
       
   273 
       
   274     public void testCompleted_considered_incomplete() {
       
   275         for (String in : considered_incomplete) {
       
   276             String input = in + ";";
       
   277             assertStatus(input, COMPLETE, input);
       
   278         }
       
   279     }
       
   280 
       
   281     private void assertSourceByStatus(String first) {
       
   282         for (Map.Entry<Completeness, String[]> e : statusToCases.entrySet()) {
       
   283             for (String in : e.getValue()) {
       
   284                 String input = first + in;
       
   285                 assertAnalyze(input, COMPLETE, first, in, true);
       
   286             }
       
   287         }
       
   288     }
       
   289 
       
   290     public void testCompleteSource_complete() {
       
   291         for (String input : complete) {
       
   292             assertSourceByStatus(input);
       
   293         }
       
   294     }
       
   295 
       
   296     public void testCompleteSource_complete_with_semi() {
       
   297         for (String in : complete_with_semi) {
       
   298             String input = in + ";";
       
   299             assertSourceByStatus(input);
       
   300         }
       
   301     }
       
   302 
       
   303     public void testCompleteSource_expression() {
       
   304         for (String in : expression) {
       
   305             String input = in + ";";
       
   306             assertSourceByStatus(input);
       
   307         }
       
   308     }
       
   309 
       
   310     public void testCompleteSource_considered_incomplete() {
       
   311         for (String in : considered_incomplete) {
       
   312             String input = in + ";";
       
   313             assertSourceByStatus(input);
       
   314         }
       
   315     }
       
   316 
       
   317     public void testTrailingSlash() {
       
   318         assertStatus("\"abc\\", UNKNOWN, "\"abc\\");
       
   319     }
       
   320 
       
   321     public void testOpenComment() {
       
   322         assertStatus("int xx; /* hello", DEFINITELY_INCOMPLETE, null);
       
   323         assertStatus("/**  test", DEFINITELY_INCOMPLETE, null);
       
   324     }
       
   325 
       
   326     public void testMiscSource() {
       
   327         assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
       
   328         assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
       
   329         assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug
       
   330         assertStatus("int[] m = {1, 2}, n = new int[0];  int i;", COMPLETE,
       
   331                      "int[] m = {1, 2}, n = new int[0];");
       
   332     }
       
   333 }