6fe98143bc
8159740: JShell: corralled declarations do not have correct source to wrapper mapping 8212167: JShell : Stack trace of exception has wrong line number Build corralled (recoverable undeclared definitions) declarations from position translating wraps.... Reviewed-by: jlahoda
330 lines
15 KiB
Java
330 lines
15 KiB
Java
/*
|
|
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8159111 8159740
|
|
* @summary test wrappers and dependencies
|
|
* @modules jdk.jshell/jdk.jshell
|
|
* @build KullaTesting
|
|
* @run testng WrapperTest
|
|
*/
|
|
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import org.testng.annotations.Test;
|
|
import jdk.jshell.ErroneousSnippet;
|
|
import jdk.jshell.Snippet;
|
|
import jdk.jshell.Snippet.Kind;
|
|
import jdk.jshell.SourceCodeAnalysis.SnippetWrapper;
|
|
import static org.testng.Assert.assertEquals;
|
|
import static org.testng.Assert.assertTrue;
|
|
import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
|
|
import static jdk.jshell.Snippet.Status.VALID;
|
|
|
|
@Test
|
|
public class WrapperTest extends KullaTesting {
|
|
|
|
public void testMethod() {
|
|
String src = "void glib() { System.out.println(\"hello\"); }";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.METHOD, "void", "glib", "println");
|
|
assertPosition(swl.get(0), src, 0, 4);
|
|
assertPosition(swl.get(0), src, 5, 4);
|
|
assertPosition(swl.get(0), src, 15, 6);
|
|
|
|
Snippet g = methodKey(assertEval(src, added(VALID)));
|
|
SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g);
|
|
assertWrapperHas(swg, src, Kind.METHOD, "void", "glib", "println");
|
|
assertPosition(swg, src, 0, 4);
|
|
assertPosition(swg, src, 5, 4);
|
|
assertPosition(swg, src, 15, 6);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testMethodCorralled() {
|
|
String src = "void glib() { f(); }";
|
|
// _123456789_123456789
|
|
Snippet g = methodKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g);
|
|
assertWrapperHas(swg, src, Kind.METHOD, "SPIResolutionException",
|
|
"void", "glib");
|
|
assertPosition(swg, src, 0, 4);
|
|
assertPosition(swg, src, 5, 4);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testClassCorralled0() {
|
|
String src = "class AAA { float mmm(double d1234) { return (float) (f0 * d1234); } }";
|
|
// _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a);
|
|
assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException",
|
|
"class", "AAA", "float", "mmm", "double", "d1234");
|
|
assertPosition(swa, src, 0, 5);
|
|
assertPosition(swa, src, 6, 3);
|
|
assertPosition(swa, src, 12, 5);
|
|
assertPosition(swa, src, 18, 3);
|
|
assertPosition(swa, src, 22, 6);
|
|
assertPosition(swa, src, 29, 5);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testClassCorralled() {
|
|
String src = "class AAA { int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }";
|
|
// _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a);
|
|
assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException",
|
|
"class", "AAA", "int", "xxx", "float", "mmm", "ffff");
|
|
assertPosition(swa, src, 0, 5);
|
|
assertPosition(swa, src, 6, 3);
|
|
assertPosition(swa, src, 12, 3);
|
|
assertPosition(swa, src, 16, 3);
|
|
assertPosition(swa, src, 30, 5);
|
|
assertPosition(swa, src, 36, 3);
|
|
assertPosition(swa, src, 40, 5);
|
|
assertPosition(swa, src, 46, 4);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testClassWithConstructorCorralled() {
|
|
String src = "public class AAA { AAA(String b) {} int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }";
|
|
// _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a);
|
|
assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException",
|
|
"class", "AAA", "String", "int", "xxx", "float", "mmm", "ffff");
|
|
assertPosition(swa, src, 7, 5);
|
|
assertPosition(swa, src, 13, 3);
|
|
assertPosition(swa, src, 19, 3);
|
|
assertPosition(swa, src, 23, 5);
|
|
assertPosition(swa, src, 30, 1);
|
|
assertPosition(swa, src, 36, 3);
|
|
assertPosition(swa, src, 40, 3);
|
|
assertPosition(swa, src, 54, 5);
|
|
assertPosition(swa, src, 60, 3);
|
|
assertPosition(swa, src, 64, 5);
|
|
assertPosition(swa, src, 70, 4);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testInterfaceCorralled() {
|
|
String src = "interface AAA { default float mmm(double d1234) { return (float) (f0 * d1234); } }";
|
|
// _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a);
|
|
assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException",
|
|
"interface", "AAA", "float", "mmm", "double", "d1234");
|
|
assertPosition(swa, src, 0, 9);
|
|
assertPosition(swa, src, 10, 3);
|
|
assertPosition(swa, src, 16, 7);
|
|
assertPosition(swa, src, 24, 5);
|
|
assertPosition(swa, src, 30, 3);
|
|
assertPosition(swa, src, 34, 6);
|
|
assertPosition(swa, src, 41, 5);
|
|
}
|
|
|
|
// test 8159740
|
|
public void testEnumCorralled() {
|
|
String src =
|
|
"public enum Planet {\n" +
|
|
" MERCURY (3.303e+23, 2.4397e6),\n" +
|
|
" VENUS (4.869e+24, 6.0518e6),\n" +
|
|
" EARTH (5.976e+24, 6.37814e6),\n" +
|
|
" MARS (6.421e+23, 3.3972e6),\n" +
|
|
" JUPITER (1.9e+27, 7.1492e7),\n" +
|
|
" SATURN (5.688e+26, 6.0268e7),\n" +
|
|
" URANUS (8.686e+25, 2.5559e7),\n" +
|
|
" NEPTUNE (1.024e+26, 2.4746e7);\n" +
|
|
"\n" +
|
|
" private final double mass; // in kilograms\n" +
|
|
" private final double radius; // in meters\n" +
|
|
" Planet(double mass, double radius) {\n" +
|
|
" this.mass = mass;\n" +
|
|
" this.radius = radius;\n" +
|
|
" }\n" +
|
|
" private double mass() { return mass; }\n" +
|
|
" private double radius() { return radius; }\n" +
|
|
"\n" +
|
|
" double surfaceGravity() {\n" +
|
|
" return GRAVITATIONAL_CONSTANT * mass / (radius * radius);\n" +
|
|
" }\n" +
|
|
" double surfaceWeight(double otherMass) {\n" +
|
|
" return otherMass * surfaceGravity();\n" +
|
|
" }\n" +
|
|
"}\n";
|
|
Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED)));
|
|
SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a);
|
|
assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException",
|
|
"enum", "Planet", "double", "mass", "EARTH", "NEPTUNE", "MERCURY",
|
|
"radius", "surfaceGravity", "surfaceWeight");
|
|
}
|
|
|
|
public void testMethodBad() {
|
|
String src = "void flob() { ?????; }";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.METHOD, "void", "flob", "?????");
|
|
assertPosition(swl.get(0), src, 9, 2);
|
|
|
|
Snippet f = key(assertEvalFail(src));
|
|
assertEquals(f.kind(), Kind.ERRONEOUS);
|
|
assertEquals(((ErroneousSnippet)f).probableKind(), Kind.METHOD);
|
|
SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f);
|
|
assertWrapperHas(sw, src, Kind.METHOD, "void", "flob", "?????");
|
|
assertPosition(swl.get(0), src, 14, 5);
|
|
}
|
|
|
|
public void testVar() {
|
|
String src = "int gx = 1234;";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.VAR, "int", "gx", "1234");
|
|
assertPosition(swl.get(0), src, 4, 2);
|
|
|
|
Snippet g = varKey(assertEval(src, added(VALID)));
|
|
SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g);
|
|
assertWrapperHas(swg, src, Kind.VAR, "int", "gx", "1234");
|
|
assertPosition(swg, src, 0, 3);
|
|
}
|
|
|
|
public void testVarBad() {
|
|
String src = "double dd = ?????;";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.VAR, "double", "dd", "?????");
|
|
assertPosition(swl.get(0), src, 9, 2);
|
|
|
|
Snippet f = key(assertEvalFail(src));
|
|
assertEquals(f.kind(), Kind.ERRONEOUS);
|
|
assertEquals(((ErroneousSnippet)f).probableKind(), Kind.VAR);
|
|
SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f);
|
|
assertWrapperHas(sw, src, Kind.VAR, "double", "dd", "?????");
|
|
assertPosition(swl.get(0), src, 12, 5);
|
|
}
|
|
|
|
public void testImport() {
|
|
String src = "import java.lang.*;";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.IMPORT, "import", "java.lang");
|
|
assertPosition(swl.get(0), src, 7, 4);
|
|
|
|
Snippet g = key(assertEval(src, added(VALID)));
|
|
SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g);
|
|
assertWrapperHas(swg, src, Kind.IMPORT, "import", "java.lang");
|
|
assertPosition(swg, src, 0, 6);
|
|
}
|
|
|
|
public void testImportBad() {
|
|
String src = "import java.?????;";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.IMPORT, "import", "?????");
|
|
assertPosition(swl.get(0), src, 7, 4);
|
|
|
|
Snippet f = key(assertEvalFail(src));
|
|
assertEquals(f.kind(), Kind.ERRONEOUS);
|
|
assertEquals(((ErroneousSnippet)f).probableKind(), Kind.IMPORT);
|
|
SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f);
|
|
assertWrapperHas(sw, src, Kind.IMPORT, "import", "?????");
|
|
assertPosition(swl.get(0), src, 0, 6);
|
|
}
|
|
|
|
public void testErroneous() {
|
|
String src = "@@@@@@@@@@";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 1, "unexpected list length");
|
|
assertWrapperHas(swl.get(0), src, Kind.ERRONEOUS, "@@@@@@@@@@");
|
|
assertPosition(swl.get(0), src, 0, 10);
|
|
|
|
Snippet f = key(assertEvalFail(src));
|
|
assertEquals(f.kind(), Kind.ERRONEOUS);
|
|
assertEquals(((ErroneousSnippet)f).probableKind(), Kind.ERRONEOUS);
|
|
SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f);
|
|
assertWrapperHas(sw, src, Kind.ERRONEOUS, "@@@@@@@@@@");
|
|
assertPosition(swl.get(0), src, 0, 10);
|
|
}
|
|
|
|
public void testEmpty() {
|
|
String src = "";
|
|
List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src);
|
|
assertEquals(swl.size(), 0, "expected empty list");
|
|
}
|
|
|
|
public void testDependencies() {
|
|
Snippet a = key(assertEval("int aaa = 6;", added(VALID)));
|
|
Snippet b = key(assertEval("class B { B(int x) { aaa = x; } }", added(VALID)));
|
|
Snippet c = key(assertEval("B ccc() { return new B(aaa); }", added(VALID)));
|
|
Collection<Snippet> dep;
|
|
dep = getState().sourceCodeAnalysis().dependents(c);
|
|
assertEquals(dep.size(), 0);
|
|
dep = getState().sourceCodeAnalysis().dependents(b);
|
|
assertEquals(dep.size(), 1);
|
|
assertTrue(dep.contains(c));
|
|
dep = getState().sourceCodeAnalysis().dependents(a);
|
|
assertEquals(dep.size(), 2);
|
|
assertTrue(dep.contains(c));
|
|
assertTrue(dep.contains(b));
|
|
}
|
|
|
|
private void assertWrapperHas(SnippetWrapper sw, String source, Kind kind, String... has) {
|
|
assertEquals(sw.source(), source);
|
|
assertEquals(sw.kind(), kind);
|
|
String s = sw.wrapped();
|
|
if (kind == Kind.IMPORT) {
|
|
assertHas(s, "import");
|
|
} else {
|
|
String cn = sw.fullClassName();
|
|
int idx = cn.lastIndexOf(".");
|
|
assertHas(s, cn.substring(idx+1));
|
|
assertHas(s, "class");
|
|
}
|
|
for (String hx : has) {
|
|
assertHas(s, hx);
|
|
}
|
|
}
|
|
|
|
private void assertHas(String s, String has) {
|
|
assertTrue(s.contains(has), "Expected to find '" + has + "' in: '" + s + "'");
|
|
}
|
|
|
|
private void assertPosition(SnippetWrapper sw, String source, int start, int length) {
|
|
//System.err.printf("\n#assertPosition:\n# debug-source: %s\n# SnippetWrapper --\n# source: %s\n# wrapped: %s\n",
|
|
// source, sw.source(), sw.wrapped());
|
|
//System.err.printf("# start: %d length: %d\n", start, length);
|
|
int wpg = sw.sourceToWrappedPosition(start);
|
|
//System.err.printf("# wrappedPos: %d\n", wpg);
|
|
String wrappedPart = sw.wrapped().substring(wpg, wpg+length);
|
|
String sourcePart = source.substring(start, start+length);
|
|
//System.err.printf("# wrapped @ wrappedPos: %s\n", wrappedPart);
|
|
//System.err.printf("# source @ start: %s\n", sourcePart);
|
|
|
|
assertEquals(wrappedPart, sourcePart,
|
|
"position " + wpg + " in " + sw.wrapped());
|
|
assertEquals(sw.wrappedToSourcePosition(wpg), start);
|
|
}
|
|
}
|