mcimadamore@1015: /* mcimadamore@1015: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. mcimadamore@1015: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@1015: * mcimadamore@1015: * This code is free software; you can redistribute it and/or modify it mcimadamore@1015: * under the terms of the GNU General Public License version 2 only, as mcimadamore@1015: * published by the Free Software Foundation. mcimadamore@1015: * mcimadamore@1015: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@1015: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@1015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@1015: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@1015: * accompanied this code). mcimadamore@1015: * mcimadamore@1015: * You should have received a copy of the GNU General Public License version mcimadamore@1015: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@1015: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@1015: * mcimadamore@1015: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@1015: * or visit www.oracle.com if you need additional information or have any mcimadamore@1015: * questions. mcimadamore@1015: */ mcimadamore@1015: mcimadamore@1015: /** mcimadamore@1015: * @test mcimadamore@1015: * @bug 7046348 mcimadamore@1015: * @summary Regression: javac complains of missing classfile for a seemingly unrelated interface mcimadamore@1015: */ mcimadamore@1015: mcimadamore@1015: import java.io.File; mcimadamore@1015: import java.net.URI; mcimadamore@1015: import java.util.Arrays; mcimadamore@1393: import java.util.List; mcimadamore@1015: mcimadamore@1015: import javax.tools.Diagnostic; mcimadamore@1015: import javax.tools.DiagnosticListener; mcimadamore@1015: import javax.tools.JavaCompiler; mcimadamore@1015: import javax.tools.JavaCompiler.CompilationTask; mcimadamore@1015: import javax.tools.JavaFileObject; mcimadamore@1015: import javax.tools.SimpleJavaFileObject; mcimadamore@1015: import javax.tools.ToolProvider; mcimadamore@1015: mcimadamore@1015: public class EagerInterfaceCompletionTest { mcimadamore@1015: mcimadamore@1015: JavaCompiler javacTool; mcimadamore@1015: File testDir; mcimadamore@1393: VersionKind versionKind; mcimadamore@1015: HierarchyKind hierarchyKind; mcimadamore@1015: TestKind testKind; mcimadamore@1015: ActionKind actionKind; mcimadamore@1015: mcimadamore@1393: EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir, VersionKind versionKind, mcimadamore@1015: HierarchyKind hierarchyKind, TestKind testKind, ActionKind actionKind) { mcimadamore@1015: this.javacTool = javacTool; mcimadamore@1393: this.versionKind = versionKind; mcimadamore@1015: this.hierarchyKind = hierarchyKind; mcimadamore@1015: this.testDir = testDir; mcimadamore@1015: this.testKind = testKind; mcimadamore@1015: this.actionKind = actionKind; mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: void test() { mcimadamore@1015: testDir.mkdirs(); mcimadamore@1015: compile(null, hierarchyKind.source); mcimadamore@1015: actionKind.doAction(this); mcimadamore@1015: DiagnosticChecker dc = new DiagnosticChecker(); mcimadamore@1015: compile(dc, testKind.source); mcimadamore@1393: if (testKind.completionFailure(versionKind, actionKind, hierarchyKind) != dc.errorFound) { mcimadamore@1015: if (dc.errorFound) { mcimadamore@1015: error("Unexpected completion failure" + mcimadamore@1015: "\nhierarhcyKind " + hierarchyKind + mcimadamore@1015: "\ntestKind " + testKind + mcimadamore@1015: "\nactionKind " + actionKind); mcimadamore@1015: } else { mcimadamore@1015: error("Missing completion failure " + mcimadamore@1015: "\nhierarhcyKind " + hierarchyKind + mcimadamore@1015: "\ntestKind " + testKind + mcimadamore@1015: "\nactionKind " + actionKind); mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: void compile(DiagnosticChecker dc, JavaSource... sources) { mcimadamore@1015: try { mcimadamore@1015: CompilationTask ct = javacTool.getTask(null, null, dc, mcimadamore@1393: Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", mcimadamore@1393: testDir.getAbsolutePath(), versionKind.optsArr[0], versionKind.optsArr[1]), mcimadamore@1015: null, Arrays.asList(sources)); mcimadamore@1015: ct.call(); mcimadamore@1015: } mcimadamore@1015: catch (Exception e) { mcimadamore@1015: e.printStackTrace(); mcimadamore@1015: error("Internal compilation error"); mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: void removeClass(String classToRemoveStr) { mcimadamore@1015: File classToRemove = new File(testDir, classToRemoveStr); mcimadamore@1015: if (!classToRemove.exists()) { mcimadamore@1015: error("Expected file " + classToRemove + " does not exists in folder " + testDir); mcimadamore@1015: } mcimadamore@1015: classToRemove.delete(); mcimadamore@1015: }; mcimadamore@1015: mcimadamore@1015: void error(String msg) { mcimadamore@1015: System.err.println(msg); mcimadamore@1015: nerrors++; mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: class DiagnosticChecker implements DiagnosticListener { mcimadamore@1015: mcimadamore@1015: boolean errorFound = false; mcimadamore@1015: mcimadamore@1015: public void report(Diagnostic diagnostic) { mcimadamore@1393: if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { mcimadamore@1393: errorFound = true; mcimadamore@1393: } mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: //global declarations mcimadamore@1015: mcimadamore@1393: enum VersionKind { mcimadamore@1393: PRE_LAMBDA("-source", "7"), mcimadamore@1393: LAMBDA("-source", "8"); mcimadamore@1393: mcimadamore@1393: String[] optsArr; mcimadamore@1393: mcimadamore@1393: VersionKind(String... optsArr) { mcimadamore@1393: this.optsArr = optsArr; mcimadamore@1393: } mcimadamore@1393: } mcimadamore@1393: mcimadamore@1015: enum HierarchyKind { mcimadamore@1015: INTERFACE("interface A { boolean f = false; void m(); }\n" + mcimadamore@1015: "class B implements A { public void m() {} }"), mcimadamore@1015: CLASS("class A { boolean f; void m() {} }\n" + mcimadamore@1015: "class B extends A { void m() {} }"), mcimadamore@1015: ABSTRACT_CLASS("abstract class A { boolean f; abstract void m(); }\n" + mcimadamore@1015: "class B extends A { void m() {} }"); mcimadamore@1015: mcimadamore@1015: JavaSource source; mcimadamore@1015: mcimadamore@1015: private HierarchyKind(String code) { mcimadamore@1015: this.source = new JavaSource("Test1.java", code); mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: enum ActionKind { mcimadamore@1015: REMOVE_A("A.class"), mcimadamore@1015: REMOVE_B("B.class"); mcimadamore@1015: mcimadamore@1015: String classFile; mcimadamore@1015: mcimadamore@1015: private ActionKind(String classFile) { mcimadamore@1015: this.classFile = classFile; mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: void doAction(EagerInterfaceCompletionTest test) { mcimadamore@1015: test.removeClass(classFile); mcimadamore@1015: }; mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: enum TestKind { mcimadamore@1015: ACCESS_ONLY("class C { B b; }"), mcimadamore@1015: SUPER("class C extends B {}"), mcimadamore@1015: METHOD("class C { void test(B b) { b.m(); } }"), mcimadamore@1015: FIELD("class C { void test(B b) { boolean b2 = b.f; } }"), mcimadamore@1015: CONSTR("class C { void test() { new B(); } }"); mcimadamore@1015: mcimadamore@1015: JavaSource source; mcimadamore@1015: mcimadamore@1015: private TestKind(final String code) { mcimadamore@1015: this.source = new JavaSource("Test2.java", code); mcimadamore@1015: } mcimadamore@1015: mcimadamore@1393: boolean completionFailure(VersionKind vk, ActionKind ak, HierarchyKind hk) { mcimadamore@1015: switch (this) { mcimadamore@1015: case ACCESS_ONLY: mcimadamore@1015: case CONSTR: return ak == ActionKind.REMOVE_B; mcimadamore@1015: case FIELD: mcimadamore@1015: case SUPER: return true; mcimadamore@1393: case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B || mcimadamore@1393: (hk == HierarchyKind.INTERFACE && ak == ActionKind.REMOVE_A && vk == VersionKind.LAMBDA); mcimadamore@1015: default: throw new AssertionError("Unexpected test kind " + this); mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: public static void main(String[] args) throws Exception { mcimadamore@1015: String SCRATCH_DIR = System.getProperty("user.dir"); mcimadamore@1015: JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler(); mcimadamore@1015: int n = 0; mcimadamore@1393: for (VersionKind versionKind : VersionKind.values()) { mcimadamore@1393: for (HierarchyKind hierarchyKind : HierarchyKind.values()) { mcimadamore@1393: for (TestKind testKind : TestKind.values()) { mcimadamore@1393: for (ActionKind actionKind : ActionKind.values()) { mcimadamore@1393: File testDir = new File(SCRATCH_DIR, "test"+n); mcimadamore@1393: new EagerInterfaceCompletionTest(javacTool, testDir, versionKind, mcimadamore@1393: hierarchyKind, testKind, actionKind).test(); mcimadamore@1393: n++; mcimadamore@1393: } mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: if (nerrors > 0) { mcimadamore@1015: throw new AssertionError("Some errors have been detected"); mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: static class JavaSource extends SimpleJavaFileObject { mcimadamore@1015: mcimadamore@1015: String source; mcimadamore@1015: mcimadamore@1015: public JavaSource(String filename, String source) { mcimadamore@1015: super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE); mcimadamore@1015: this.source = source; mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: @Override mcimadamore@1015: public CharSequence getCharContent(boolean ignoreEncodingErrors) { mcimadamore@1015: return source; mcimadamore@1015: } mcimadamore@1015: } mcimadamore@1015: mcimadamore@1015: static int nerrors = 0; mcimadamore@1015: }