1/*
2 * Copyright (c) 2014, 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 8139829
27 * @summary test accessors of Snippet
28 * @build KullaTesting TestingInputStream
29 * @run testng SnippetTest
30 */
31
32import jdk.jshell.Snippet;
33import jdk.jshell.DeclarationSnippet;
34import org.testng.annotations.Test;
35
36import jdk.jshell.MethodSnippet;
37import jdk.jshell.Snippet.Status;
38import static org.testng.Assert.assertFalse;
39import static org.testng.Assert.assertTrue;
40import static jdk.jshell.Snippet.Status.VALID;
41import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
42import static jdk.jshell.Snippet.Status.OVERWRITTEN;
43import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
44import static jdk.jshell.Snippet.SubKind.*;
45
46@Test
47public class SnippetTest extends KullaTesting {
48
49    public void testImportKey() {
50        assertImportKeyMatch("import java.util.List;", "List", SINGLE_TYPE_IMPORT_SUBKIND, added(VALID));
51        assertImportKeyMatch("import java.util.*;", "java.util.*", TYPE_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
52        assertImportKeyMatch("import static java.lang.String.*;", "java.lang.String.*", STATIC_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
53    }
54
55    public void testClassKey() {
56        assertDeclarationKeyMatch("class X {}", false, "X", CLASS_SUBKIND, added(VALID));
57    }
58
59    public void testInterfaceKey() {
60        assertDeclarationKeyMatch("interface I {}", false, "I", INTERFACE_SUBKIND, added(VALID));
61    }
62
63    public void testEnumKey() {
64        assertDeclarationKeyMatch("enum E {}", false, "E", ENUM_SUBKIND, added(VALID));
65    }
66
67    public void testAnnotationKey() {
68        assertDeclarationKeyMatch("@interface A {}", false, "A", ANNOTATION_TYPE_SUBKIND, added(VALID));
69    }
70
71    public void testMethodKey() {
72        assertDeclarationKeyMatch("void m() {}", false, "m", METHOD_SUBKIND, added(VALID));
73    }
74
75    public void testVarDeclarationKey() {
76        assertVarKeyMatch("int a;", false, "a", VAR_DECLARATION_SUBKIND, "int", added(VALID));
77    }
78
79    public void testVarDeclarationWithInitializerKey() {
80        assertVarKeyMatch("double b = 9.0;", true, "b", VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "double", added(VALID));
81    }
82
83    public void testTempVarExpressionKey() {
84        assertVarKeyMatch("47;", true, "$1", TEMP_VAR_EXPRESSION_SUBKIND, "int", added(VALID));
85    }
86
87    public void testVarValueKey() {
88        assertEval("double x = 4;", "4.0");
89        assertExpressionKeyMatch("x;", "x", VAR_VALUE_SUBKIND, "double");
90    }
91
92    public void testAssignmentKey() {
93        assertEval("int y;");
94        assertExpressionKeyMatch("y = 4;", "y", ASSIGNMENT_SUBKIND, "int");
95    }
96
97    public void testStatementKey() {
98        assertKeyMatch("if (true) {}", true, STATEMENT_SUBKIND, added(VALID));
99        assertKeyMatch("while (true) { break; }", true, STATEMENT_SUBKIND, added(VALID));
100        assertKeyMatch("do { } while (false);", true, STATEMENT_SUBKIND, added(VALID));
101        assertKeyMatch("for (;;) { break; }", true, STATEMENT_SUBKIND, added(VALID));
102    }
103
104    public void noKeys() {
105        assertActiveKeys(new DeclarationSnippet[0]);
106    }
107
108    public void testKeyId1() {
109        Snippet a = classKey(assertEval("class A { }"));
110        assertEval("void f() {  }");
111        assertEval("int f;");
112        assertEval("interface A { }",
113                ste(MAIN_SNIPPET, VALID, VALID, true, null),
114                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
115        assertKeys(method("()void", "f"), variable("int", "f"), clazz(KullaTesting.ClassType.INTERFACE, "A"));
116        assertActiveKeys();
117    }
118
119    @Test(enabled = false) // TODO 8081689
120    public void testKeyId2() {
121        Snippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
122        Snippet f = methodKey(assertEval("void f() { }",
123                added(VALID),
124                ste(g, RECOVERABLE_DEFINED, VALID, false, null)));
125        assertEval("int f;");
126        assertEval("interface A { }");
127        assertKeys(method("()void", "g"), method("()void", "f"), variable("int", "f"),
128                clazz(KullaTesting.ClassType.INTERFACE, "A"));
129        assertActiveKeys();
130        assertEval("double f() { return 0.0; }",
131                ste(MAIN_SNIPPET, VALID, VALID, true, null),
132                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
133                ste(g, VALID, VALID, false, MAIN_SNIPPET));
134        assertKeys(method("()void", "g"), method("()double", "f"), variable("int", "f"),
135                clazz(KullaTesting.ClassType.INTERFACE, "A"));
136        assertActiveKeys();
137    }
138
139    public void testKeyId3() {
140        Snippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
141        Snippet f = methodKey(assertEval("void f() { }",
142                added(VALID),
143                ste(g, RECOVERABLE_DEFINED, VALID, false, null)));
144        assertDeclareFail("qqqq;", "compiler.err.cant.resolve.location");
145        assertEval("interface A { }");
146        assertKeys(method("()void", "g"), method("()void", "f"),
147                clazz(KullaTesting.ClassType.INTERFACE, "A"));
148        assertActiveKeys();
149        assertEval("double f() { return 0.0; }",
150                ste(MAIN_SNIPPET, VALID, VALID, true, null),
151                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
152        assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
153                method("()double", "f"));
154        assertActiveKeys();
155    }
156
157    public void testBooleanSnippetQueries() {
158        Snippet nd = varKey(assertEval("blort x;", added(RECOVERABLE_NOT_DEFINED)));
159        assertTrue(nd.kind().isPersistent(), "nd.isPersistent");
160        Status ndstat = getState().status(nd);
161        assertTrue(ndstat.isActive(), "nd.isActive");
162        assertFalse(ndstat.isDefined(), "nd.isDefined");
163        MethodSnippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
164        assertTrue(g.kind().isPersistent(), "g.isPersistent");
165        Status gstat = getState().status(g);
166        assertTrue(gstat.isActive(), "g.isActive");
167        assertTrue(gstat.isDefined(), "g.isDefined");
168        getState().drop(g);
169        assertTrue(g.kind().isPersistent(), "drop isPersistent");
170        gstat = getState().status(g);
171        assertFalse(gstat.isActive(), "drop isActive");
172        assertFalse(gstat.isDefined(), "drop isDefined");
173        Snippet stmt = key(assertEval("if (true) {}", added(VALID)));
174        assertFalse(stmt.kind().isPersistent(), "stmt isPersistent");
175        Status stmtstat = getState().status(stmt);
176        assertTrue(stmtstat.isActive(), "stmt isActive");
177        assertTrue(stmtstat.isDefined(), "stmt isDefined");
178    }
179}
180