aoqi@0: /* aoqi@0: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /** aoqi@0: * @test aoqi@0: * @bug 6550655 aoqi@0: * @summary javac crashes when compiling against an annotated class aoqi@0: */ aoqi@0: aoqi@0: import java.io.File; aoqi@0: import java.net.URI; aoqi@0: import java.util.Arrays; aoqi@0: aoqi@0: import javax.tools.Diagnostic; aoqi@0: import javax.tools.DiagnosticListener; aoqi@0: import javax.tools.JavaCompiler; aoqi@0: import javax.tools.JavaCompiler.CompilationTask; aoqi@0: import javax.tools.JavaFileObject; aoqi@0: import javax.tools.SimpleJavaFileObject; aoqi@0: import javax.tools.ToolProvider; aoqi@0: aoqi@0: public class T6550655 { aoqi@0: aoqi@0: JavaCompiler javacTool; aoqi@0: File testDir; aoqi@0: TestKind testKind; aoqi@0: EnumActionKind actionKind; aoqi@0: aoqi@0: String testSource = "enum E { NORTH, SOUTH, WEST, EAST; }\n" + aoqi@0: "@I(val = E.NORTH)class A {}\n" + aoqi@0: "@interface I { E val(); }"; aoqi@0: aoqi@0: T6550655(JavaCompiler javacTool, File testDir, TestKind testKind, EnumActionKind actionKind) { aoqi@0: this.javacTool = javacTool; aoqi@0: this.testDir = testDir; aoqi@0: this.testKind = testKind; aoqi@0: this.actionKind = actionKind; aoqi@0: } aoqi@0: aoqi@0: void test() { aoqi@0: testDir.mkdirs(); aoqi@0: compile(null, new JavaSource("Test.java", testSource)); aoqi@0: actionKind.doAction(this); aoqi@0: compile(new DiagnosticChecker(), testKind.source); aoqi@0: } aoqi@0: aoqi@0: void compile(DiagnosticChecker dc, JavaSource... sources) { aoqi@0: try { aoqi@0: CompilationTask ct = javacTool.getTask(null, null, dc, aoqi@0: Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", testDir.getAbsolutePath()), aoqi@0: null, Arrays.asList(sources)); aoqi@0: ct.call(); aoqi@0: } aoqi@0: catch (Exception e) { aoqi@0: error("Internal compilation error"); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void replaceEnum(String newSource) { aoqi@0: compile(null, new JavaSource("Replace.java", newSource)); aoqi@0: }; aoqi@0: aoqi@0: void removeEnum() { aoqi@0: File enumClass = new File(testDir, "E.class"); aoqi@0: if (!enumClass.exists()) { aoqi@0: error("Expected file E.class does not exists in folder " + testDir); aoqi@0: } aoqi@0: enumClass.delete(); aoqi@0: }; aoqi@0: aoqi@0: void error(String msg) { aoqi@0: System.err.println(msg); aoqi@0: nerrors++; aoqi@0: } aoqi@0: aoqi@0: class DiagnosticChecker implements DiagnosticListener { aoqi@0: aoqi@0: String[][] expectedKeys = new String[][] { aoqi@0: // DIRECT, INDIRECT aoqi@0: {/*REPLACE1*/ "compiler.err.cant.resolve.location" , "compiler.warn.unknown.enum.constant" }, aoqi@0: {/*REPLACE2*/ "compiler.err.cant.resolve.location.args", "compiler.warn.annotation.method.not.found" }, aoqi@0: {/*REMOVE*/ "compiler.err.cant.resolve" , "compiler.warn.unknown.enum.constant.reason" } }; aoqi@0: aoqi@0: String keyToIgnore = "compiler.err.attribute.value.must.be.constant"; aoqi@0: aoqi@0: public void report(Diagnostic diagnostic) { aoqi@0: String expectedCode = expectedKeys[actionKind.ordinal()][testKind.ordinal()]; aoqi@0: if (!diagnostic.getCode().equals(keyToIgnore) && aoqi@0: !diagnostic.getCode().equals(expectedCode)) { aoqi@0: error("Unexpected diagnostic" + aoqi@0: "\nfound " + diagnostic.getCode() + aoqi@0: "\nexpected " + expectedCode + aoqi@0: "\ntestKind " + testKind + aoqi@0: "\nactionKind " + actionKind); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: //global declarations aoqi@0: aoqi@0: enum EnumActionKind { aoqi@0: REPLACE1("enum E { SOUTH, WEST, EAST; }") { aoqi@0: @Override aoqi@0: void doAction(T6550655 test) { aoqi@0: test.replaceEnum(optionalSource); aoqi@0: } aoqi@0: }, aoqi@0: REPLACE2("@interface I { E valNew() default E.EAST; }") { aoqi@0: @Override aoqi@0: void doAction(T6550655 test) { aoqi@0: test.replaceEnum(optionalSource); aoqi@0: } aoqi@0: }, aoqi@0: REMOVE(null) { aoqi@0: @Override aoqi@0: void doAction(T6550655 test) { test.removeEnum(); } aoqi@0: }; aoqi@0: aoqi@0: String optionalSource; aoqi@0: aoqi@0: private EnumActionKind(String optionalSource) { aoqi@0: this.optionalSource = optionalSource; aoqi@0: } aoqi@0: aoqi@0: abstract void doAction(T6550655 test); aoqi@0: } aoqi@0: aoqi@0: enum TestKind { aoqi@0: DIRECT("@I(val = E.NORTH)class C1 {}"), aoqi@0: INDIRECT("class C2 { A a; }"); aoqi@0: aoqi@0: JavaSource source; aoqi@0: aoqi@0: private TestKind(final String code) { aoqi@0: this.source = new JavaSource("Test.java", code); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public static void main(String[] args) throws Exception { aoqi@0: String SCRATCH_DIR = System.getProperty("user.dir"); aoqi@0: JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler(); aoqi@0: int n = 0; aoqi@0: for (TestKind testKind : TestKind.values()) { aoqi@0: for (EnumActionKind actionKind : EnumActionKind.values()) { aoqi@0: File testDir = new File(SCRATCH_DIR, "test"+n); aoqi@0: new T6550655(javacTool, testDir, testKind, actionKind).test(); aoqi@0: n++; aoqi@0: } aoqi@0: } aoqi@0: if (nerrors > 0) { aoqi@0: throw new AssertionError("Some errors have been detected"); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: static class JavaSource extends SimpleJavaFileObject { aoqi@0: aoqi@0: String source; aoqi@0: aoqi@0: public JavaSource(String filename, String source) { aoqi@0: super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE); aoqi@0: this.source = source; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public CharSequence getCharContent(boolean ignoreEncodingErrors) { aoqi@0: return source; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: static int nerrors = 0; aoqi@0: }