Thu, 26 Sep 2013 15:04:15 -0700
8011738: Write test to check for bootstrap attributes for lambda expressions in class file
Reviewed-by: mcimadamore
test/tools/javac/lambda/ByteCodeTest.java | file | annotate | diff | comparison | revisions |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/lambda/ByteCodeTest.java Thu Sep 26 15:04:15 2013 -0700 1.3 @@ -0,0 +1,647 @@ 1.4 +/* 1.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 8011738 1.30 + * @author sogoel 1.31 + * @summary Code translation test for Lambda expressions, method references 1.32 + * @run main ByteCodeTest 1.33 + */ 1.34 + 1.35 +import com.sun.tools.classfile.Attribute; 1.36 +import com.sun.tools.classfile.BootstrapMethods_attribute; 1.37 +import com.sun.tools.classfile.ClassFile; 1.38 +import com.sun.tools.classfile.ConstantPool; 1.39 +import com.sun.tools.classfile.ConstantPoolException; 1.40 +import com.sun.tools.classfile.ConstantPool.*; 1.41 + 1.42 +import java.io.BufferedWriter; 1.43 +import java.io.File; 1.44 +import java.io.FileWriter; 1.45 +import java.io.IOException; 1.46 +import java.io.PrintWriter; 1.47 +import java.util.ArrayList; 1.48 +import java.util.Collections; 1.49 +import java.util.HashMap; 1.50 +import java.util.HashSet; 1.51 +import java.util.List; 1.52 +import java.util.Map; 1.53 + 1.54 +public class ByteCodeTest { 1.55 + 1.56 + static boolean IS_DEBUG = false; 1.57 + public static void main(String[] args) { 1.58 + File classFile = null; 1.59 + int err = 0; 1.60 + boolean verifyResult = false; 1.61 + for(TestCases tc : TestCases.values()) { 1.62 + classFile = getCompiledFile(tc.name(), tc.srcCode); 1.63 + if(classFile == null) { // either testFile or classFile was not created 1.64 + err++; 1.65 + } else { 1.66 + verifyResult = verifyClassFileAttributes(classFile, tc); 1.67 + if(!verifyResult) 1.68 + System.out.println("Bootstrap class file attributes did not match for " + tc.name()); 1.69 + } 1.70 + } 1.71 + if(err > 0) 1.72 + throw new RuntimeException("Found " + err + " found"); 1.73 + else 1.74 + System.out.println("Test passed"); 1.75 + } 1.76 + 1.77 + private static boolean verifyClassFileAttributes(File classFile, TestCases tc) { 1.78 + ClassFile c = null; 1.79 + try { 1.80 + c = ClassFile.read(classFile); 1.81 + } catch (IOException | ConstantPoolException e) { 1.82 + e.printStackTrace(); 1.83 + } 1.84 + ConstantPoolVisitor cpv = new ConstantPoolVisitor(c, c.constant_pool.size()); 1.85 + Map<Integer, String> hm = cpv.getBSMMap(); 1.86 + 1.87 + List<String> expectedValList = tc.getExpectedArgValues(); 1.88 + expectedValList.add(tc.bsmSpecifier.specifier); 1.89 + if(!(hm.values().containsAll(new HashSet<String>(expectedValList)))) { 1.90 + System.out.println("Values do not match"); 1.91 + return false; 1.92 + } 1.93 + return true; 1.94 + } 1.95 + 1.96 + private static File getCompiledFile(String fname, String srcString) { 1.97 + File testFile = null, classFile = null; 1.98 + boolean isTestFileCreated = true; 1.99 + 1.100 + try { 1.101 + testFile = writeTestFile(fname+".java", srcString); 1.102 + } catch(IOException ioe) { 1.103 + isTestFileCreated = false; 1.104 + System.err.println("fail to write" + ioe); 1.105 + } 1.106 + 1.107 + if(isTestFileCreated) { 1.108 + try { 1.109 + classFile = compile(testFile); 1.110 + } catch (Error err) { 1.111 + System.err.println("fail compile. Source:\n" + srcString); 1.112 + throw err; 1.113 + } 1.114 + } 1.115 + return classFile; 1.116 + } 1.117 + 1.118 + static File writeTestFile(String fname, String source) throws IOException { 1.119 + File f = new File(fname); 1.120 + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); 1.121 + out.println(source); 1.122 + out.close(); 1.123 + return f; 1.124 + } 1.125 + 1.126 + static File compile(File f) { 1.127 + int rc = com.sun.tools.javac.Main.compile(new String[] { 1.128 + "-source", "1.8", "-g", f.getPath() }); 1.129 + if (rc != 0) 1.130 + throw new Error("compilation failed. rc=" + rc); 1.131 + String path = f.getPath(); 1.132 + return new File(path.substring(0, path.length() - 5) + ".class"); 1.133 + } 1.134 + 1.135 + static void debugln(String str) { 1.136 + if(IS_DEBUG) 1.137 + System.out.println(str); 1.138 + } 1.139 + 1.140 + enum BSMSpecifier { 1.141 + SPECIFIER1("REF_invokeStatic java/lang/invoke/LambdaMetafactory metaFactory " + 1.142 + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;" + 1.143 + "Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)" + 1.144 + "Ljava/lang/invoke/CallSite;"), 1.145 + SPECIFIER2("REF_invokeStatic java/lang/invoke/LambdaMetafactory altMetaFactory " + 1.146 + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;" + 1.147 + "[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"); 1.148 + 1.149 + String specifier; 1.150 + private BSMSpecifier(String specifier) { 1.151 + this.specifier = specifier; 1.152 + } 1.153 + } 1.154 + 1.155 + enum TestCases { 1.156 + // Single line lambda expression 1.157 + TC1("class TC1 {\n" + 1.158 + " public static void main(String[] args) {\n" + 1.159 + " Object o = (Runnable) () -> { System.out.println(\"hi\");};\n" + 1.160 + " }\n"+ 1.161 + "}", BSMSpecifier.SPECIFIER1) { 1.162 + 1.163 + @Override 1.164 + List<String> getExpectedArgValues() { 1.165 + List<String> valList = new ArrayList<>(); 1.166 + valList.add("REF_invokeInterface java/lang/Runnable run ()V"); 1.167 + valList.add("REF_invokeStatic TC1 lambda$0 ()V"); 1.168 + valList.add("()V"); 1.169 + return valList; 1.170 + } 1.171 + }, 1.172 + 1.173 + // Lambda expression in a for loop 1.174 + TC2("import java.util.*;\n" + 1.175 + "public class TC2 {\n" + 1.176 + " void TC2_test() {\n" + 1.177 + " List<String> list = new ArrayList<>();\n" + 1.178 + " list.add(\"A\");\n" + 1.179 + " list.add(\"B\");\n" + 1.180 + " list.stream().forEach( s -> { System.out.println(s); } );\n" + 1.181 + " }\n" + 1.182 + " public static void main(String[] args) {\n" + 1.183 + " new TC2().TC2_test();\n" + 1.184 + " }\n" + 1.185 + "}", BSMSpecifier.SPECIFIER1) { 1.186 + 1.187 + @Override 1.188 + List<String> getExpectedArgValues() { 1.189 + List<String> valList = new ArrayList<>(); 1.190 + valList.add("REF_invokeInterface java/util/function/Consumer accept (Ljava/lang/Object;)V"); 1.191 + valList.add("REF_invokeStatic TC2 lambda$0 (Ljava/lang/String;)V"); 1.192 + valList.add("(Ljava/lang/String;)V"); 1.193 + return valList; 1.194 + } 1.195 + }, 1.196 + 1.197 + // Lambda initializer 1.198 + TC3("class TC3 {\n" + 1.199 + " interface SAM {\n" + 1.200 + " void m(int i);\n" + 1.201 + " }\n" + 1.202 + " SAM lambda_03 = (int pos) -> { };\n" + 1.203 + "}", BSMSpecifier.SPECIFIER1) { 1.204 + 1.205 + @Override 1.206 + List<String> getExpectedArgValues() { 1.207 + List<String> valList = new ArrayList<>(); 1.208 + valList.add("REF_invokeInterface TC3$SAM m (I)V"); 1.209 + valList.add("REF_invokeStatic TC3 lambda$0 (I)V"); 1.210 + valList.add("(I)V"); 1.211 + return valList; 1.212 + } 1.213 + }, 1.214 + 1.215 + // Array initializer 1.216 + TC4("class TC4 {\n" + 1.217 + " interface Block<T> {\n" + 1.218 + " void m(T t);\n" + 1.219 + " }\n" + 1.220 + " void test1() {\n" + 1.221 + " Block<?>[] arr1 = { t -> { }, t -> { } };\n" + 1.222 + " }\n" + 1.223 + "}", BSMSpecifier.SPECIFIER1) { 1.224 + 1.225 + @Override 1.226 + List<String> getExpectedArgValues() { 1.227 + List<String> valList = new ArrayList<>(); 1.228 + valList.add("REF_invokeInterface TC4$Block m (Ljava/lang/Object;)V"); 1.229 + valList.add("REF_invokeStatic TC4 lambda$0 (Ljava/lang/Object;)V"); 1.230 + valList.add("(Ljava/lang/Object;)V"); 1.231 + valList.add("REF_invokeStatic TC4 lambda$1 (Ljava/lang/Object;)V"); 1.232 + return valList; 1.233 + } 1.234 + }, 1.235 + 1.236 + //Lambda expression as a method arg 1.237 + TC5("class TC5 {\n"+ 1.238 + " interface MapFun<T,R> { R m( T n); }\n" + 1.239 + " void meth( MapFun<String,Integer> mf ) {\n" + 1.240 + " assert( mf.m(\"four\") == 4);\n" + 1.241 + " }\n"+ 1.242 + " void test(Integer i) {\n" + 1.243 + " meth(s -> { Integer len = s.length(); return len; } );\n" + 1.244 + " }\n"+ 1.245 + "}", BSMSpecifier.SPECIFIER1) { 1.246 + 1.247 + @Override 1.248 + List<String> getExpectedArgValues() { 1.249 + List<String> valList = new ArrayList<>(); 1.250 + valList.add("REF_invokeInterface TC5$MapFun m (Ljava/lang/Object;)Ljava/lang/Object;"); 1.251 + valList.add("REF_invokeStatic TC5 lambda$0 (Ljava/lang/String;)Ljava/lang/Integer;"); 1.252 + valList.add("(Ljava/lang/String;)Ljava/lang/Integer;"); 1.253 + return valList; 1.254 + } 1.255 + }, 1.256 + 1.257 + //Inner class of Lambda expression 1.258 + TC6("class TC6 {\n" + 1.259 + " interface MapFun<T, R> { R m( T n); }\n" + 1.260 + " MapFun<Class<?>,String> cs;\n" + 1.261 + " void test() {\n" + 1.262 + " cs = c -> {\n" + 1.263 + " class innerClass {\n" + 1.264 + " Class<?> icc;\n" + 1.265 + " innerClass(Class<?> _c) { icc = _c; }\n" + 1.266 + " String getString() { return icc.toString(); }\n" + 1.267 + " }\n" + 1.268 + " return new innerClass(c).getString();\n"+ 1.269 + " };\n" + 1.270 + " }\n" + 1.271 + "}\n", BSMSpecifier.SPECIFIER1) { 1.272 + 1.273 + @Override 1.274 + List<String> getExpectedArgValues() { 1.275 + List<String> valList = new ArrayList<>(); 1.276 + valList.add("REF_invokeInterface TC6$MapFun m (Ljava/lang/Object;)Ljava/lang/Object;"); 1.277 + valList.add("REF_invokeSpecial TC6 lambda$0 (Ljava/lang/Class;)Ljava/lang/String;"); 1.278 + valList.add("(Ljava/lang/Class;)Ljava/lang/String;"); 1.279 + return valList; 1.280 + } 1.281 + }, 1.282 + 1.283 + // Method reference 1.284 + TC7("class TC7 {\n" + 1.285 + " static interface SAM {\n" + 1.286 + " void m(Integer i);\n" + 1.287 + " }\n" + 1.288 + " void m(Integer i) {}\n" + 1.289 + " SAM s = this::m;\n" + 1.290 + "}\n", BSMSpecifier.SPECIFIER1) { 1.291 + 1.292 + @Override 1.293 + List<String> getExpectedArgValues() { 1.294 + List<String> valList = new ArrayList<>(); 1.295 + valList.add("REF_invokeInterface TC7$SAM m (Ljava/lang/Integer;)V"); 1.296 + valList.add("REF_invokeVirtual TC7 m (Ljava/lang/Integer;)V"); 1.297 + valList.add("(Ljava/lang/Integer;)V"); 1.298 + return valList; 1.299 + } 1.300 + }, 1.301 + 1.302 + // Constructor reference 1.303 + TC8("public class TC8 {\n" + 1.304 + " static interface A {Fee<String> m();}\n" + 1.305 + " static class Fee<T> {\n" + 1.306 + " private T t;\n" + 1.307 + " public Fee() {}\n" + 1.308 + " }\n" + 1.309 + " public static void main(String[] args) {\n" + 1.310 + " A a = Fee<String>::new; \n" + 1.311 + " }\n" + 1.312 + "}\n", BSMSpecifier.SPECIFIER1) { 1.313 + 1.314 + @Override 1.315 + List<String> getExpectedArgValues() { 1.316 + List<String> valList = new ArrayList<>(); 1.317 + valList.add("REF_invokeInterface TC8$A m ()LTC8$Fee;"); 1.318 + valList.add("REF_newInvokeSpecial TC8$Fee <init> ()V"); 1.319 + valList.add("()LTC8$Fee;"); 1.320 + return valList; 1.321 + } 1.322 + }, 1.323 + 1.324 + // Recursive lambda expression 1.325 + TC9("class TC9 {\n" + 1.326 + " interface Recursive<T, R> { T apply(R n); };\n" + 1.327 + " Recursive<Integer,Integer> factorial;\n" + 1.328 + " void test(Integer j) {\n" + 1.329 + " factorial = i -> { return i == 0 ? 1 : i * factorial.apply( i - 1 ); };\n" + 1.330 + " }\n" + 1.331 + "}\n", BSMSpecifier.SPECIFIER1) { 1.332 + 1.333 + @Override 1.334 + List<String> getExpectedArgValues() { 1.335 + List<String> valList = new ArrayList<>(); 1.336 + valList.add("REF_invokeInterface TC9$Recursive apply (Ljava/lang/Object;)Ljava/lang/Object;"); 1.337 + valList.add("REF_invokeSpecial TC9 lambda$0 (Ljava/lang/Integer;)Ljava/lang/Integer;"); 1.338 + valList.add("(Ljava/lang/Integer;)Ljava/lang/Integer;"); 1.339 + return valList; 1.340 + } 1.341 + }, 1.342 + 1.343 + //Serializable Lambda 1.344 + TC10("import java.io.Serializable;\n" + 1.345 + "class TC10 {\n" + 1.346 + " interface Foo { int m(); }\n" + 1.347 + " public static void main(String[] args) {\n" + 1.348 + " Foo f1 = (Foo & Serializable)() -> 3;\n" + 1.349 + " }\n" + 1.350 + "}\n", BSMSpecifier.SPECIFIER2) { 1.351 + 1.352 + @Override 1.353 + List<String> getExpectedArgValues() { 1.354 + List<String> valList = new ArrayList<>(); 1.355 + valList.add("REF_invokeStatic java/lang/invoke/LambdaMetafactory altMetaFactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"); 1.356 + valList.add("REF_invokeInterface TC10$Foo m ()I"); 1.357 + valList.add("REF_invokeStatic TC10 lambda$main$3231c38a$0 ()I"); 1.358 + valList.add("()I"); 1.359 + valList.add("1"); 1.360 + return valList; 1.361 + } 1.362 + }; 1.363 + 1.364 + String srcCode; 1.365 + BSMSpecifier bsmSpecifier; 1.366 + 1.367 + TestCases(String src, BSMSpecifier bsmSpecifier) { 1.368 + this.srcCode = src; 1.369 + // By default, all test cases will have bootstrap method specifier as Lambda.MetaFactory 1.370 + // For serializable lambda test cases, bootstrap method specifier changed to altMetaFactory 1.371 + this.bsmSpecifier = bsmSpecifier; 1.372 + } 1.373 + 1.374 + List<String> getExpectedArgValues() { 1.375 + return null; 1.376 + } 1.377 + 1.378 + void setSrcCode(String src) { 1.379 + srcCode = src; 1.380 + } 1.381 + } 1.382 + 1.383 + static class ConstantPoolVisitor implements ConstantPool.Visitor<String, Integer> { 1.384 + final List<String> slist; 1.385 + final ClassFile cf; 1.386 + final ConstantPool cfpool; 1.387 + final Map<Integer, String> bsmMap; 1.388 + 1.389 + 1.390 + public ConstantPoolVisitor(ClassFile cf, int size) { 1.391 + slist = new ArrayList<>(size); 1.392 + for (int i = 0 ; i < size; i++) { 1.393 + slist.add(null); 1.394 + } 1.395 + this.cf = cf; 1.396 + this.cfpool = cf.constant_pool; 1.397 + bsmMap = readBSM(); 1.398 + } 1.399 + 1.400 + public Map<Integer, String> getBSMMap() { 1.401 + return Collections.unmodifiableMap(bsmMap); 1.402 + } 1.403 + 1.404 + public String visit(CPInfo c, int index) { 1.405 + return c.accept(this, index); 1.406 + } 1.407 + 1.408 + private Map<Integer, String> readBSM() { 1.409 + BootstrapMethods_attribute bsmAttr = 1.410 + (BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods); 1.411 + if (bsmAttr != null) { 1.412 + Map<Integer, String> out = 1.413 + new HashMap<>(bsmAttr.bootstrap_method_specifiers.length); 1.414 + for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms : 1.415 + bsmAttr.bootstrap_method_specifiers) { 1.416 + int index = bsms.bootstrap_method_ref; 1.417 + try { 1.418 + String value = slist.get(index); 1.419 + if (value == null) { 1.420 + value = visit(cfpool.get(index), index); 1.421 + debugln("[SG]: index " + index); 1.422 + debugln("[SG]: value " + value); 1.423 + slist.set(index, value); 1.424 + out.put(index, value); 1.425 + } 1.426 + for (int idx : bsms.bootstrap_arguments) { 1.427 + value = slist.get(idx); 1.428 + if (value == null) { 1.429 + value = visit(cfpool.get(idx), idx); 1.430 + debugln("[SG]: idx " + idx); 1.431 + debugln("[SG]: value " + value); 1.432 + slist.set(idx, value); 1.433 + out.put(idx, value); 1.434 + } 1.435 + } 1.436 + } catch (InvalidIndex ex) { 1.437 + ex.printStackTrace(); 1.438 + } 1.439 + } 1.440 + return out; 1.441 + } 1.442 + return new HashMap<>(0); 1.443 + } 1.444 + 1.445 + @Override 1.446 + public String visitClass(CONSTANT_Class_info c, Integer p) { 1.447 + 1.448 + String value = slist.get(p); 1.449 + if (value == null) { 1.450 + try { 1.451 + value = visit(cfpool.get(c.name_index), c.name_index); 1.452 + slist.set(p, value); 1.453 + } catch (ConstantPoolException ex) { 1.454 + ex.printStackTrace(); 1.455 + } 1.456 + } 1.457 + return value; 1.458 + } 1.459 + 1.460 + @Override 1.461 + public String visitDouble(CONSTANT_Double_info c, Integer p) { 1.462 + 1.463 + String value = slist.get(p); 1.464 + if (value == null) { 1.465 + value = Double.toString(c.value); 1.466 + slist.set(p, value); 1.467 + } 1.468 + return value; 1.469 + } 1.470 + 1.471 + @Override 1.472 + public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) { 1.473 + 1.474 + String value = slist.get(p); 1.475 + if (value == null) { 1.476 + try { 1.477 + value = visit(cfpool.get(c.class_index), c.class_index); 1.478 + value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), 1.479 + c.name_and_type_index)); 1.480 + slist.set(p, value); 1.481 + } catch (ConstantPoolException ex) { 1.482 + ex.printStackTrace(); 1.483 + } 1.484 + } 1.485 + return value; 1.486 + } 1.487 + 1.488 + @Override 1.489 + public String visitFloat(CONSTANT_Float_info c, Integer p) { 1.490 + 1.491 + String value = slist.get(p); 1.492 + if (value == null) { 1.493 + value = Float.toString(c.value); 1.494 + slist.set(p, value); 1.495 + } 1.496 + return value; 1.497 + } 1.498 + 1.499 + @Override 1.500 + public String visitInteger(CONSTANT_Integer_info cnstnt, Integer p) { 1.501 + 1.502 + String value = slist.get(p); 1.503 + if (value == null) { 1.504 + value = Integer.toString(cnstnt.value); 1.505 + slist.set(p, value); 1.506 + } 1.507 + return value; 1.508 + } 1.509 + 1.510 + @Override 1.511 + public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c, 1.512 + Integer p) { 1.513 + 1.514 + String value = slist.get(p); 1.515 + if (value == null) { 1.516 + try { 1.517 + value = visit(cfpool.get(c.class_index), c.class_index); 1.518 + value = value.concat(" " + 1.519 + visit(cfpool.get(c.name_and_type_index), 1.520 + c.name_and_type_index)); 1.521 + slist.set(p, value); 1.522 + } catch (ConstantPoolException ex) { 1.523 + ex.printStackTrace(); 1.524 + } 1.525 + } 1.526 + return value; 1.527 + } 1.528 + 1.529 + @Override 1.530 + public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) { 1.531 + 1.532 + String value = slist.get(p); 1.533 + if (value == null) { 1.534 + try { 1.535 + value = bsmMap.get(c.bootstrap_method_attr_index) + " " 1.536 + + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); 1.537 + slist.set(p, value); 1.538 + } catch (ConstantPoolException ex) { 1.539 + ex.printStackTrace(); 1.540 + } 1.541 + } 1.542 + return value; 1.543 + } 1.544 + 1.545 + @Override 1.546 + public String visitLong(CONSTANT_Long_info c, Integer p) { 1.547 + 1.548 + String value = slist.get(p); 1.549 + if (value == null) { 1.550 + value = Long.toString(c.value); 1.551 + slist.set(p, value); 1.552 + } 1.553 + return value; 1.554 + } 1.555 + 1.556 + @Override 1.557 + public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) { 1.558 + 1.559 + String value = slist.get(p); 1.560 + if (value == null) { 1.561 + try { 1.562 + value = visit(cfpool.get(c.name_index), c.name_index); 1.563 + value = value.concat(" " + 1.564 + visit(cfpool.get(c.type_index), c.type_index)); 1.565 + slist.set(p, value); 1.566 + } catch (InvalidIndex ex) { 1.567 + ex.printStackTrace(); 1.568 + } 1.569 + } 1.570 + return value; 1.571 + } 1.572 + 1.573 + @Override 1.574 + public String visitMethodref(CONSTANT_Methodref_info c, Integer p) { 1.575 + 1.576 + String value = slist.get(p); 1.577 + if (value == null) { 1.578 + try { 1.579 + value = visit(cfpool.get(c.class_index), c.class_index); 1.580 + value = value.concat(" " + 1.581 + visit(cfpool.get(c.name_and_type_index), 1.582 + c.name_and_type_index)); 1.583 + slist.set(p, value); 1.584 + } catch (ConstantPoolException ex) { 1.585 + ex.printStackTrace(); 1.586 + } 1.587 + } 1.588 + return value; 1.589 + } 1.590 + 1.591 + @Override 1.592 + public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) { 1.593 + 1.594 + String value = slist.get(p); 1.595 + if (value == null) { 1.596 + try { 1.597 + value = c.reference_kind.name(); 1.598 + value = value.concat(" " 1.599 + + visit(cfpool.get(c.reference_index), c.reference_index)); 1.600 + slist.set(p, value); 1.601 + } catch (ConstantPoolException ex) { 1.602 + ex.printStackTrace(); 1.603 + } 1.604 + } 1.605 + return value; 1.606 + } 1.607 + 1.608 + @Override 1.609 + public String visitMethodType(CONSTANT_MethodType_info c, Integer p) { 1.610 + 1.611 + String value = slist.get(p); 1.612 + if (value == null) { 1.613 + try { 1.614 + value = visit(cfpool.get(c.descriptor_index), c.descriptor_index); 1.615 + slist.set(p, value); 1.616 + } catch (ConstantPoolException ex) { 1.617 + ex.printStackTrace(); 1.618 + } 1.619 + } 1.620 + return value; 1.621 + } 1.622 + 1.623 + @Override 1.624 + public String visitString(CONSTANT_String_info c, Integer p) { 1.625 + 1.626 + try { 1.627 + String value = slist.get(p); 1.628 + if (value == null) { 1.629 + value = c.getString(); 1.630 + slist.set(p, value); 1.631 + } 1.632 + return value; 1.633 + } catch (ConstantPoolException ex) { 1.634 + throw new RuntimeException("Fatal error", ex); 1.635 + } 1.636 + } 1.637 + 1.638 + @Override 1.639 + public String visitUtf8(CONSTANT_Utf8_info cnstnt, Integer p) { 1.640 + 1.641 + String value = slist.get(p); 1.642 + if (value == null) { 1.643 + value = cnstnt.value; 1.644 + slist.set(p, value); 1.645 + } 1.646 + return value; 1.647 + } 1.648 + } 1.649 +} 1.650 +