1 /*
2  * Copyright (c) 2017, 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 8182270
27  * @summary test non-eval Snippet analysis
28  * @build KullaTesting TestingInputStream
29  * @run testng AnalyzeSnippetTest
30  */
31 
32 import java.io.ByteArrayOutputStream;
33 import java.io.PrintStream;
34 import java.util.List;
35 import jdk.jshell.Snippet;
36 import jdk.jshell.DeclarationSnippet;
37 import org.testng.annotations.Test;
38 
39 import jdk.jshell.JShell;
40 import jdk.jshell.MethodSnippet;
41 import static org.testng.Assert.assertFalse;
42 import static org.testng.Assert.assertTrue;
43 import static org.testng.Assert.assertEquals;
44 import org.testng.annotations.AfterMethod;
45 import org.testng.annotations.BeforeMethod;
46 import jdk.jshell.ErroneousSnippet;
47 import jdk.jshell.ExpressionSnippet;
48 import jdk.jshell.ImportSnippet;
49 import jdk.jshell.Snippet.SubKind;
50 import jdk.jshell.SourceCodeAnalysis;
51 import jdk.jshell.StatementSnippet;
52 import jdk.jshell.TypeDeclSnippet;
53 import jdk.jshell.VarSnippet;
54 import static jdk.jshell.Snippet.SubKind.*;
55 
56 @Test
57 public class AnalyzeSnippetTest {
58 
59     JShell state;
60     SourceCodeAnalysis sca;
61 
62     @BeforeMethod
setUp()63     public void setUp() {
64         state = JShell.builder()
65                 .out(new PrintStream(new ByteArrayOutputStream()))
66                 .err(new PrintStream(new ByteArrayOutputStream()))
67                 .build();
68         sca = state.sourceCodeAnalysis();
69     }
70 
71     @AfterMethod
tearDown()72     public void tearDown() {
73         if (state != null) {
74             state.close();
75         }
76         state = null;
77         sca = null;
78     }
79 
testImport()80     public void testImport() {
81         ImportSnippet sn = (ImportSnippet) assertSnippet("import java.util.List;",
82                 SubKind.SINGLE_TYPE_IMPORT_SUBKIND);
83         assertEquals(sn.name(), "List");
84         sn = (ImportSnippet) assertSnippet("import static java.nio.file.StandardOpenOption.CREATE;",
85                 SubKind.SINGLE_STATIC_IMPORT_SUBKIND);
86         assertTrue(sn.isStatic());
87     }
88 
testClass()89     public void testClass() {
90         TypeDeclSnippet sn = (TypeDeclSnippet) assertSnippet("class C {}",
91                 SubKind.CLASS_SUBKIND);
92         assertEquals(sn.name(), "C");
93         sn = (TypeDeclSnippet) assertSnippet("enum EE {A, B , C}",
94                 SubKind.ENUM_SUBKIND);
95     }
96 
testMethod()97     public void testMethod() {
98         MethodSnippet sn = (MethodSnippet) assertSnippet("int m(int x) { return x + x; }",
99                 SubKind.METHOD_SUBKIND);
100         assertEquals(sn.name(), "m");
101         assertEquals(sn.signature(), "(int)int");
102     }
103 
testVar()104     public void testVar() {
105         VarSnippet sn = (VarSnippet) assertSnippet("int i;",
106                 SubKind.VAR_DECLARATION_SUBKIND);
107         assertEquals(sn.name(), "i");
108         assertEquals(sn.typeName(), "int");
109         sn = (VarSnippet) assertSnippet("int jj = 6;",
110                 SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND);
111         sn = (VarSnippet) assertSnippet("2 + 2",
112                 SubKind.TEMP_VAR_EXPRESSION_SUBKIND);
113     }
114 
testExpression()115     public void testExpression() {
116         state.eval("int aa = 10;");
117         ExpressionSnippet sn = (ExpressionSnippet) assertSnippet("aa",
118                 SubKind.VAR_VALUE_SUBKIND);
119         assertEquals(sn.name(), "aa");
120         assertEquals(sn.typeName(), "int");
121         sn = (ExpressionSnippet) assertSnippet("aa;",
122                 SubKind.VAR_VALUE_SUBKIND);
123         assertEquals(sn.name(), "aa");
124         assertEquals(sn.typeName(), "int");
125         sn = (ExpressionSnippet) assertSnippet("aa = 99",
126                 SubKind.ASSIGNMENT_SUBKIND);
127     }
128 
testStatement()129     public void testStatement() {
130         StatementSnippet sn = (StatementSnippet) assertSnippet("System.out.println(33)",
131                 SubKind.STATEMENT_SUBKIND);
132         sn = (StatementSnippet) assertSnippet("if (true) System.out.println(33);",
133                 SubKind.STATEMENT_SUBKIND);
134     }
135 
testErroneous()136     public void testErroneous() {
137         ErroneousSnippet sn = (ErroneousSnippet) assertSnippet("+++",
138                 SubKind.UNKNOWN_SUBKIND);
139         sn = (ErroneousSnippet) assertSnippet("abc",
140                 SubKind.UNKNOWN_SUBKIND);
141     }
142 
testNoStateChange()143     public void testNoStateChange() {
144         assertSnippet("int a = 5;", SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND);
145         assertSnippet("a", SubKind.UNKNOWN_SUBKIND);
146         VarSnippet vsn = (VarSnippet) state.eval("int aa = 10;").get(0).snippet();
147         assertSnippet("++aa;", SubKind.TEMP_VAR_EXPRESSION_SUBKIND);
148         assertEquals(state.varValue(vsn), "10");
149         assertSnippet("class CC {}", SubKind.CLASS_SUBKIND);
150         assertSnippet("new CC();", SubKind.UNKNOWN_SUBKIND);
151     }
152 
assertSnippet(String input, SubKind sk)153     private Snippet assertSnippet(String input, SubKind sk) {
154         List<Snippet> sns = sca.sourceToSnippets(input);
155         assertEquals(sns.size(), 1, "snippet count");
156         Snippet sn = sns.get(0);
157         assertEquals(sn.id(), "*UNASSOCIATED*");
158         assertEquals(sn.subKind(), sk);
159         return sn;
160     }
161 }
162