1 /* 2 * Copyright (c) 2016, 2019, 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 8159111 8159740 27 * @summary test wrappers and dependencies 28 * @modules jdk.jshell/jdk.jshell 29 * @build KullaTesting 30 * @run testng WrapperTest 31 */ 32 33 import java.util.Collection; 34 import java.util.List; 35 import org.testng.annotations.Test; 36 import jdk.jshell.ErroneousSnippet; 37 import jdk.jshell.Snippet; 38 import jdk.jshell.Snippet.Kind; 39 import jdk.jshell.SourceCodeAnalysis.SnippetWrapper; 40 import static org.testng.Assert.assertEquals; 41 import static org.testng.Assert.assertTrue; 42 import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED; 43 import static jdk.jshell.Snippet.Status.VALID; 44 45 @Test 46 public class WrapperTest extends KullaTesting { 47 testMethod()48 public void testMethod() { 49 String src = "void glib() { System.out.println(\"hello\"); }"; 50 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 51 assertEquals(swl.size(), 1, "unexpected list length"); 52 assertWrapperHas(swl.get(0), src, Kind.METHOD, "void", "glib", "println"); 53 assertPosition(swl.get(0), src, 0, 4); 54 assertPosition(swl.get(0), src, 5, 4); 55 assertPosition(swl.get(0), src, 15, 6); 56 57 Snippet g = methodKey(assertEval(src, added(VALID))); 58 SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g); 59 assertWrapperHas(swg, src, Kind.METHOD, "void", "glib", "println"); 60 assertPosition(swg, src, 0, 4); 61 assertPosition(swg, src, 5, 4); 62 assertPosition(swg, src, 15, 6); 63 } 64 65 // test 8159740 testMethodCorralled()66 public void testMethodCorralled() { 67 String src = "void glib() { f(); }"; 68 // _123456789_123456789 69 Snippet g = methodKey(assertEval(src, added(RECOVERABLE_DEFINED))); 70 SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g); 71 assertWrapperHas(swg, src, Kind.METHOD, "SPIResolutionException", 72 "void", "glib"); 73 assertPosition(swg, src, 0, 4); 74 assertPosition(swg, src, 5, 4); 75 } 76 77 // test 8159740 testClassCorralled0()78 public void testClassCorralled0() { 79 String src = "class AAA { float mmm(double d1234) { return (float) (f0 * d1234); } }"; 80 // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 81 Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); 82 SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); 83 assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", 84 "class", "AAA", "float", "mmm", "double", "d1234"); 85 assertPosition(swa, src, 0, 5); 86 assertPosition(swa, src, 6, 3); 87 assertPosition(swa, src, 12, 5); 88 assertPosition(swa, src, 18, 3); 89 assertPosition(swa, src, 22, 6); 90 assertPosition(swa, src, 29, 5); 91 } 92 93 // test 8159740 testClassCorralled()94 public void testClassCorralled() { 95 String src = "class AAA { int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }"; 96 // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 97 Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); 98 SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); 99 assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", 100 "class", "AAA", "int", "xxx", "float", "mmm", "ffff"); 101 assertPosition(swa, src, 0, 5); 102 assertPosition(swa, src, 6, 3); 103 assertPosition(swa, src, 12, 3); 104 assertPosition(swa, src, 16, 3); 105 assertPosition(swa, src, 30, 5); 106 assertPosition(swa, src, 36, 3); 107 assertPosition(swa, src, 40, 5); 108 assertPosition(swa, src, 46, 4); 109 } 110 111 // test 8159740 testClassWithConstructorCorralled()112 public void testClassWithConstructorCorralled() { 113 String src = "public class AAA { AAA(String b) {} int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }"; 114 // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 115 Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); 116 SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); 117 assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", 118 "class", "AAA", "String", "int", "xxx", "float", "mmm", "ffff"); 119 assertPosition(swa, src, 7, 5); 120 assertPosition(swa, src, 13, 3); 121 assertPosition(swa, src, 19, 3); 122 assertPosition(swa, src, 23, 5); 123 assertPosition(swa, src, 30, 1); 124 assertPosition(swa, src, 36, 3); 125 assertPosition(swa, src, 40, 3); 126 assertPosition(swa, src, 54, 5); 127 assertPosition(swa, src, 60, 3); 128 assertPosition(swa, src, 64, 5); 129 assertPosition(swa, src, 70, 4); 130 } 131 132 // test 8159740 testInterfaceCorralled()133 public void testInterfaceCorralled() { 134 String src = "interface AAA { default float mmm(double d1234) { return (float) (f0 * d1234); } }"; 135 // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 136 Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); 137 SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); 138 assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", 139 "interface", "AAA", "float", "mmm", "double", "d1234"); 140 assertPosition(swa, src, 0, 9); 141 assertPosition(swa, src, 10, 3); 142 assertPosition(swa, src, 16, 7); 143 assertPosition(swa, src, 24, 5); 144 assertPosition(swa, src, 30, 3); 145 assertPosition(swa, src, 34, 6); 146 assertPosition(swa, src, 41, 5); 147 } 148 149 // test 8159740 testEnumCorralled()150 public void testEnumCorralled() { 151 String src = 152 "public enum Planet {\n" + 153 " MERCURY (3.303e+23, 2.4397e6),\n" + 154 " VENUS (4.869e+24, 6.0518e6),\n" + 155 " EARTH (5.976e+24, 6.37814e6),\n" + 156 " MARS (6.421e+23, 3.3972e6),\n" + 157 " JUPITER (1.9e+27, 7.1492e7),\n" + 158 " SATURN (5.688e+26, 6.0268e7),\n" + 159 " URANUS (8.686e+25, 2.5559e7),\n" + 160 " NEPTUNE (1.024e+26, 2.4746e7);\n" + 161 "\n" + 162 " private final double mass; // in kilograms\n" + 163 " private final double radius; // in meters\n" + 164 " Planet(double mass, double radius) {\n" + 165 " this.mass = mass;\n" + 166 " this.radius = radius;\n" + 167 " }\n" + 168 " private double mass() { return mass; }\n" + 169 " private double radius() { return radius; }\n" + 170 "\n" + 171 " double surfaceGravity() {\n" + 172 " return GRAVITATIONAL_CONSTANT * mass / (radius * radius);\n" + 173 " }\n" + 174 " double surfaceWeight(double otherMass) {\n" + 175 " return otherMass * surfaceGravity();\n" + 176 " }\n" + 177 "}\n"; 178 Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); 179 SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); 180 assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", 181 "enum", "Planet", "double", "mass", "EARTH", "NEPTUNE", "MERCURY", 182 "radius", "surfaceGravity", "surfaceWeight"); 183 } 184 testMethodBad()185 public void testMethodBad() { 186 String src = "void flob() { ?????; }"; 187 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 188 assertEquals(swl.size(), 1, "unexpected list length"); 189 assertWrapperHas(swl.get(0), src, Kind.METHOD, "void", "flob", "?????"); 190 assertPosition(swl.get(0), src, 9, 2); 191 192 Snippet f = key(assertEvalFail(src)); 193 assertEquals(f.kind(), Kind.ERRONEOUS); 194 assertEquals(((ErroneousSnippet)f).probableKind(), Kind.METHOD); 195 SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f); 196 assertWrapperHas(sw, src, Kind.METHOD, "void", "flob", "?????"); 197 assertPosition(swl.get(0), src, 14, 5); 198 } 199 testVar()200 public void testVar() { 201 String src = "int gx = 1234;"; 202 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 203 assertEquals(swl.size(), 1, "unexpected list length"); 204 assertWrapperHas(swl.get(0), src, Kind.VAR, "int", "gx", "1234"); 205 assertPosition(swl.get(0), src, 4, 2); 206 207 Snippet g = varKey(assertEval(src, added(VALID))); 208 SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g); 209 assertWrapperHas(swg, src, Kind.VAR, "int", "gx", "1234"); 210 assertPosition(swg, src, 0, 3); 211 } 212 testVarBad()213 public void testVarBad() { 214 String src = "double dd = ?????;"; 215 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 216 assertEquals(swl.size(), 1, "unexpected list length"); 217 assertWrapperHas(swl.get(0), src, Kind.VAR, "double", "dd", "?????"); 218 assertPosition(swl.get(0), src, 9, 2); 219 220 Snippet f = key(assertEvalFail(src)); 221 assertEquals(f.kind(), Kind.ERRONEOUS); 222 assertEquals(((ErroneousSnippet)f).probableKind(), Kind.VAR); 223 SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f); 224 assertWrapperHas(sw, src, Kind.VAR, "double", "dd", "?????"); 225 assertPosition(swl.get(0), src, 12, 5); 226 } 227 testImport()228 public void testImport() { 229 String src = "import java.lang.*;"; 230 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 231 assertEquals(swl.size(), 1, "unexpected list length"); 232 assertWrapperHas(swl.get(0), src, Kind.IMPORT, "import", "java.lang"); 233 assertPosition(swl.get(0), src, 7, 4); 234 235 Snippet g = key(assertEval(src, added(VALID))); 236 SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g); 237 assertWrapperHas(swg, src, Kind.IMPORT, "import", "java.lang"); 238 assertPosition(swg, src, 0, 6); 239 } 240 testImportBad()241 public void testImportBad() { 242 String src = "import java.?????;"; 243 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 244 assertEquals(swl.size(), 1, "unexpected list length"); 245 assertWrapperHas(swl.get(0), src, Kind.IMPORT, "import", "?????"); 246 assertPosition(swl.get(0), src, 7, 4); 247 248 Snippet f = key(assertEvalFail(src)); 249 assertEquals(f.kind(), Kind.ERRONEOUS); 250 assertEquals(((ErroneousSnippet)f).probableKind(), Kind.IMPORT); 251 SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f); 252 assertWrapperHas(sw, src, Kind.IMPORT, "import", "?????"); 253 assertPosition(swl.get(0), src, 0, 6); 254 } 255 testErroneous()256 public void testErroneous() { 257 String src = "@@@@@@@@@@"; 258 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 259 assertEquals(swl.size(), 1, "unexpected list length"); 260 assertWrapperHas(swl.get(0), src, Kind.ERRONEOUS, "@@@@@@@@@@"); 261 assertPosition(swl.get(0), src, 0, 10); 262 263 Snippet f = key(assertEvalFail(src)); 264 assertEquals(f.kind(), Kind.ERRONEOUS); 265 assertEquals(((ErroneousSnippet)f).probableKind(), Kind.ERRONEOUS); 266 SnippetWrapper sw = getState().sourceCodeAnalysis().wrapper(f); 267 assertWrapperHas(sw, src, Kind.ERRONEOUS, "@@@@@@@@@@"); 268 assertPosition(swl.get(0), src, 0, 10); 269 } 270 testEmpty()271 public void testEmpty() { 272 String src = ""; 273 List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); 274 assertEquals(swl.size(), 0, "expected empty list"); 275 } 276 testDependencies()277 public void testDependencies() { 278 Snippet a = key(assertEval("int aaa = 6;", added(VALID))); 279 Snippet b = key(assertEval("class B { B(int x) { aaa = x; } }", added(VALID))); 280 Snippet c = key(assertEval("B ccc() { return new B(aaa); }", added(VALID))); 281 Collection<Snippet> dep; 282 dep = getState().sourceCodeAnalysis().dependents(c); 283 assertEquals(dep.size(), 0); 284 dep = getState().sourceCodeAnalysis().dependents(b); 285 assertEquals(dep.size(), 1); 286 assertTrue(dep.contains(c)); 287 dep = getState().sourceCodeAnalysis().dependents(a); 288 assertEquals(dep.size(), 2); 289 assertTrue(dep.contains(c)); 290 assertTrue(dep.contains(b)); 291 } 292 assertWrapperHas(SnippetWrapper sw, String source, Kind kind, String... has)293 private void assertWrapperHas(SnippetWrapper sw, String source, Kind kind, String... has) { 294 assertEquals(sw.source(), source); 295 assertEquals(sw.kind(), kind); 296 String s = sw.wrapped(); 297 if (kind == Kind.IMPORT) { 298 assertHas(s, "import"); 299 } else { 300 String cn = sw.fullClassName(); 301 int idx = cn.lastIndexOf("."); 302 assertHas(s, cn.substring(idx+1)); 303 assertHas(s, "class"); 304 } 305 for (String hx : has) { 306 assertHas(s, hx); 307 } 308 } 309 assertHas(String s, String has)310 private void assertHas(String s, String has) { 311 assertTrue(s.contains(has), "Expected to find '" + has + "' in: '" + s + "'"); 312 } 313 assertPosition(SnippetWrapper sw, String source, int start, int length)314 private void assertPosition(SnippetWrapper sw, String source, int start, int length) { 315 //System.err.printf("\n#assertPosition:\n# debug-source: %s\n# SnippetWrapper --\n# source: %s\n# wrapped: %s\n", 316 // source, sw.source(), sw.wrapped()); 317 //System.err.printf("# start: %d length: %d\n", start, length); 318 int wpg = sw.sourceToWrappedPosition(start); 319 //System.err.printf("# wrappedPos: %d\n", wpg); 320 String wrappedPart = sw.wrapped().substring(wpg, wpg+length); 321 String sourcePart = source.substring(start, start+length); 322 //System.err.printf("# wrapped @ wrappedPos: %s\n", wrappedPart); 323 //System.err.printf("# source @ start: %s\n", sourcePart); 324 325 assertEquals(wrappedPart, sourcePart, 326 "position " + wpg + " in " + sw.wrapped()); 327 assertEquals(sw.wrappedToSourcePosition(wpg), start); 328 } 329 } 330