Wed, 16 Mar 2011 17:21:52 -0700
6930508: Passing nested class names on javac command line interfere with subsequent name -> class lookup
Reviewed-by: darcy
1.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Mar 16 09:41:30 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Mar 16 17:21:52 2011 -0700 1.3 @@ -638,6 +638,19 @@ 1.4 } 1.5 } 1.6 1.7 + /** Resolve an identifier which may be the binary name of a class or 1.8 + * the Java name of a class or package. 1.9 + * @param name The name to resolve 1.10 + */ 1.11 + public Symbol resolveBinaryNameOrIdent(String name) { 1.12 + try { 1.13 + Name flatname = names.fromString(name.replace("/", ".")); 1.14 + return reader.loadClass(flatname); 1.15 + } catch (CompletionFailure ignore) { 1.16 + return resolveIdent(name); 1.17 + } 1.18 + } 1.19 + 1.20 /** Resolve an identifier. 1.21 * @param name The identifier to resolve 1.22 */ 1.23 @@ -1058,7 +1071,7 @@ 1.24 } else { 1.25 boolean errors = false; 1.26 for (String nameStr : classnames) { 1.27 - Symbol sym = resolveIdent(nameStr); 1.28 + Symbol sym = resolveBinaryNameOrIdent(nameStr); 1.29 if (sym == null || (sym.kind == Kinds.PCK && !processPcks)) { 1.30 log.error("proc.cant.find.class", nameStr); 1.31 errors = true;
2.1 --- a/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Mar 16 09:41:30 2011 -0700 2.2 +++ b/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Mar 16 17:21:52 2011 -0700 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -23,7 +23,7 @@ 2.11 2.12 /* 2.13 * @test 2.14 - * @bug 6449781 2.15 + * @bug 6449781 6930508 2.16 * @summary Test that reported names of anonymous classes are non-null. 2.17 * @author Joseph D. Darcy 2.18 * @library ../../../lib 2.19 @@ -93,6 +93,7 @@ 2.20 TestAnonClassNames.class, 2.21 }; 2.22 2.23 + List<String> names = new ArrayList<String>(); 2.24 for(Class<?> clazz : classes) { 2.25 String name = clazz.getName(); 2.26 Nesting anno = clazz.getAnnotation(Nesting.class); 2.27 @@ -100,7 +101,14 @@ 2.28 clazz.getName(), 2.29 anno == null ? "(unset/ANONYMOUS)" : anno.value()); 2.30 testClassName(name); 2.31 + names.add(name); 2.32 } 2.33 + 2.34 + // test all names together 2.35 + testClassNames(names); 2.36 + 2.37 + if (errors > 0) 2.38 + throw new RuntimeException(errors + " errors occurred"); 2.39 } 2.40 2.41 /** 2.42 @@ -109,15 +117,23 @@ 2.43 * input classes are modeled as elements. 2.44 */ 2.45 static void testClassName(String className) { 2.46 - JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 2.47 - List<String> classNames = new ArrayList<String>(); 2.48 - classNames.add(className); 2.49 + testClassNames(Arrays.asList(className)); 2.50 + } 2.51 + 2.52 + /** 2.53 + * Perform annotation processing on a list of class file names and verify 2.54 + * the existence of different flavors of class names when the 2.55 + * input classes are modeled as elements. 2.56 + */ 2.57 + static void testClassNames(List<String> classNames) { 2.58 + System.out.println("test: " + classNames); 2.59 2.60 List<String> options = new ArrayList<String>(); 2.61 options.add("-proc:only"); 2.62 options.add("-classpath"); 2.63 options.add(System.getProperty("test.classes")); 2.64 2.65 + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 2.66 JavaCompiler.CompilationTask compileTask = 2.67 javaCompiler.getTask(null, // Output 2.68 null, // File manager 2.69 @@ -130,9 +146,16 @@ 2.70 compileTask.setProcessors(processors); 2.71 Boolean goodResult = compileTask.call(); 2.72 if (!goodResult) { 2.73 - throw new RuntimeException("Errors found during compile."); 2.74 + error("Errors found during compile."); 2.75 } 2.76 } 2.77 + 2.78 + static int errors = 0; 2.79 + 2.80 + static void error(String msg) { 2.81 + System.out.println("Error: " + msg); 2.82 + errors++; 2.83 + } 2.84 } 2.85 2.86 @Retention(RUNTIME)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/processing/options/testCommandLineClasses/Test.java Wed Mar 16 17:21:52 2011 -0700 3.3 @@ -0,0 +1,106 @@ 3.4 +/* 3.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/* 3.28 + * @test 3.29 + * @bug 6930508 3.30 + * @summary Passing nested class names on javac command line interfere with subsequent name -> class lookup 3.31 + * @library ../../../lib 3.32 + * @build JavacTestingAbstractProcessor p.NestedExamples Test 3.33 + * @run main Test 3.34 + */ 3.35 + 3.36 +import java.io.*; 3.37 +import java.util.*; 3.38 +import javax.annotation.processing.RoundEnvironment; 3.39 +import javax.lang.model.element.TypeElement; 3.40 +import javax.lang.model.util.ElementFilter; 3.41 +import javax.tools.*; 3.42 + 3.43 +import p.NestedExamples; 3.44 + 3.45 +public class Test extends JavacTestingAbstractProcessor { 3.46 + public static void main(String... args) throws Exception { 3.47 + new Test().run(); 3.48 + } 3.49 + 3.50 + void run() throws Exception { 3.51 + NestedExamples e = new NestedExamples(); 3.52 + List<String> names = getNames(e.getClasses()); 3.53 + test(names); 3.54 + test(reverse(names)); 3.55 + names = Arrays.asList(e.getClassNames()); 3.56 + test(names); 3.57 + test(reverse(names)); 3.58 + 3.59 + if (errors > 0) 3.60 + throw new RuntimeException(errors + " errors occurred"); 3.61 + } 3.62 + 3.63 + List<String> getNames(Class<?>[] classes) { 3.64 + List<String> names = new ArrayList<String>(); 3.65 + for (Class<?> c: classes) 3.66 + names.add(c.getName()); 3.67 + return names; 3.68 + } 3.69 + 3.70 + void test(List<String> names) throws Exception { 3.71 + System.err.println("test: " + names); 3.72 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 3.73 + StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); 3.74 + File testClasses = new File(System.getProperty("test.classes")); 3.75 + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses)); 3.76 + JavaCompiler.CompilationTask task = compiler.getTask( 3.77 + null, null, null, Arrays.asList("-proc:only"), names, null); 3.78 + task.setProcessors(Arrays.asList(new Test())); 3.79 + boolean ok = task.call(); 3.80 + if (!ok) 3.81 + error("compilation failed"); 3.82 + System.err.println(); 3.83 + } 3.84 + 3.85 + <T> List<T> reverse(List<T> list) { 3.86 + List<T> newList = new ArrayList<T>(list); 3.87 + Collections.reverse(newList); 3.88 + return newList; 3.89 + } 3.90 + 3.91 + int errors = 0; 3.92 + 3.93 + void error(String msg) { 3.94 + System.out.println("Error: " + msg); 3.95 + errors++; 3.96 + } 3.97 + 3.98 + //---------- 3.99 + 3.100 + public boolean process(Set<? extends TypeElement> annotations, 3.101 + RoundEnvironment roundEnv) { 3.102 + if (!roundEnv.processingOver()) { 3.103 + for (TypeElement typeElt : ElementFilter.typesIn(roundEnv.getRootElements())) { 3.104 + messager.printMessage(Diagnostic.Kind.NOTE, "processing " + typeElt); 3.105 + } 3.106 + } 3.107 + return true; 3.108 + } 3.109 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/processing/options/testCommandLineClasses/p/NestedExamples.java Wed Mar 16 17:21:52 2011 -0700 4.3 @@ -0,0 +1,63 @@ 4.4 +/* 4.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +package p; 4.28 + 4.29 +public class NestedExamples { 4.30 + static class MemberClass1 { } 4.31 + 4.32 + class MemberClass2 { } 4.33 + 4.34 + class Win$$AtVegas { } // Class with funny name. 4.35 + 4.36 + public Class<?>[] getClasses() { 4.37 + class LocalClass { } 4.38 + 4.39 + Object o = new Object() { // An anonymous class 4.40 + @Override 4.41 + public String toString() { 4.42 + return "I have no name!"; 4.43 + } 4.44 + }; 4.45 + 4.46 + return new Class<?>[] { 4.47 + NestedExamples.class, 4.48 + MemberClass1.class, 4.49 + MemberClass2.class, 4.50 + Win$$AtVegas.class, 4.51 + LocalClass.class, 4.52 + o.getClass() 4.53 + }; 4.54 + } 4.55 + 4.56 + public String[] getClassNames() { 4.57 + return new String[] { 4.58 + "p.NestedExamples", 4.59 + "p.NestedExamples.MemberClass1", 4.60 + "p.NestedExamples.MemberClass2", 4.61 + "p.NestedExamples.Win$$AtVegas" 4.62 + }; 4.63 + } 4.64 +} 4.65 + 4.66 +