8075274: Compilation still depends on the order of imports
authorjlahoda
Mon, 05 Oct 2015 18:31:38 +0200
changeset 32913 586e23a1b116
parent 32912 dd06b5fd9300
child 32914 fe2f2101a692
8075274: Compilation still depends on the order of imports 8133235: Compilation depends on order of source files Summary: When analyzing type hierarchy, HierarchyPhase should process supertypes before subtypes. Reviewed-by: mcimadamore
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
langtools/test/tools/javac/importscope/T8075274/C.java
langtools/test/tools/javac/importscope/T8075274/D.java
langtools/test/tools/javac/importscope/T8075274/Outer.java
langtools/test/tools/javac/importscope/T8133235/A.java
langtools/test/tools/javac/importscope/T8133235/B.java
langtools/test/tools/javac/importscope/T8133235/C.java
langtools/test/tools/javac/importscope/T8133235/D.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Mon Oct 05 15:41:29 2015 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Mon Oct 05 18:31:38 2015 +0200
@@ -194,7 +194,7 @@
 
             dependencies.push((ClassSymbol) sym, CompletionCause.MEMBER_ENTER);
             try {
-                queue = completeClass.runPhase(List.of(typeEnvs.get((ClassSymbol) sym)));
+                queue = completeClass.completeEnvs(List.of(typeEnvs.get((ClassSymbol) sym)));
             } finally {
                 dependencies.pop();
             }
@@ -237,9 +237,22 @@
             this.next = next;
         }
 
-        public List<Env<AttrContext>> runPhase(List<Env<AttrContext>> envs) {
+        public final List<Env<AttrContext>> completeEnvs(List<Env<AttrContext>> envs) {
             boolean firstToComplete = queue.isEmpty();
 
+            doCompleteEnvs(envs);
+
+            if (firstToComplete) {
+                List<Env<AttrContext>> out = queue.toList();
+
+                queue.clear();
+                return next != null ? next.completeEnvs(out) : out;
+            } else {
+                return List.nil();
+            }
+        }
+
+        protected void doCompleteEnvs(List<Env<AttrContext>> envs) {
             for (Env<AttrContext> env : envs) {
                 JCClassDecl tree = (JCClassDecl)env.tree;
 
@@ -249,7 +262,7 @@
                 DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
                 try {
                     dependencies.push(env.enclClass.sym, phaseName);
-                    doRunPhase(env);
+                    runPhase(env);
                 } catch (CompletionFailure ex) {
                     chk.completionError(tree.pos(), ex);
                 } finally {
@@ -258,18 +271,9 @@
                     log.useSource(prev);
                 }
             }
-
-            if (firstToComplete) {
-                List<Env<AttrContext>> out = queue.toList();
+        }
 
-                queue.clear();
-                return next != null ? next.runPhase(out) : out;
-            } else {
-                return List.nil();
-            }
-       }
-
-        protected abstract void doRunPhase(Env<AttrContext> env);
+        protected abstract void runPhase(Env<AttrContext> env);
     }
 
     private final ImportsPhase completeClass = new ImportsPhase();
@@ -289,7 +293,7 @@
                 (imp, cf) -> chk.completionError(imp.pos(), cf);
 
         @Override
-        protected void doRunPhase(Env<AttrContext> env) {
+        protected void runPhase(Env<AttrContext> env) {
             JCClassDecl tree = env.enclClass;
             ClassSymbol sym = tree.sym;
 
@@ -699,14 +703,29 @@
             }
     }
 
-    private final class HierarchyPhase extends AbstractHeaderPhase {
+    private final class HierarchyPhase extends AbstractHeaderPhase implements Completer {
 
         public HierarchyPhase() {
             super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
         }
 
         @Override
-        protected void doRunPhase(Env<AttrContext> env) {
+        protected void doCompleteEnvs(List<Env<AttrContext>> envs) {
+            //The ClassSymbols in the envs list may not be in the dependency order.
+            //To get proper results, for every class or interface C, the supertypes of
+            //C must be processed by the HierarchyPhase phase before C.
+            //To achieve that, the HierarchyPhase is registered as the Completer for
+            //all the classes first, and then all the classes are completed.
+            for (Env<AttrContext> env : envs) {
+                env.enclClass.sym.completer = this;
+            }
+            for (Env<AttrContext> env : envs) {
+                env.enclClass.sym.complete();
+            }
+        }
+
+        @Override
+        protected void runPhase(Env<AttrContext> env) {
             JCClassDecl tree = env.enclClass;
             ClassSymbol sym = tree.sym;
             ClassType ct = (ClassType)sym.type;
@@ -760,6 +779,14 @@
                 }
                 return false;
             }
+
+        @Override
+        public void complete(Symbol sym) throws CompletionFailure {
+            Env<AttrContext> env = typeEnvs.get((ClassSymbol) sym);
+
+            super.doCompleteEnvs(List.of(env));
+        }
+
     }
 
     private final class HeaderPhase extends AbstractHeaderPhase {
@@ -769,7 +796,7 @@
         }
 
         @Override
-        protected void doRunPhase(Env<AttrContext> env) {
+        protected void runPhase(Env<AttrContext> env) {
             JCClassDecl tree = env.enclClass;
             ClassSymbol sym = tree.sym;
             ClassType ct = (ClassType)sym.type;
@@ -824,7 +851,7 @@
         }
 
         @Override
-        protected void doRunPhase(Env<AttrContext> env) {
+        protected void runPhase(Env<AttrContext> env) {
             JCClassDecl tree = env.enclClass;
             ClassSymbol sym = tree.sym;
             ClassType ct = (ClassType)sym.type;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8075274/C.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package P.Q;
+
+public class C extends D {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8075274/D.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package P.Q;
+
+public class D {
+  public interface I {
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8075274/Outer.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8075274
+ * @summary Ensuring order of imports or inputs does not affect compilability of the sources
+ * @compile C.java D.java Outer.java
+ * @compile C.java Outer.java D.java
+ * @compile D.java C.java Outer.java
+ * @compile D.java Outer.java C.java
+ * @compile Outer.java D.java C.java
+ * @compile Outer.java C.java D.java
+ */
+package P;
+
+import static P.Outer.Nested.*;
+import static P.Q.C.*;
+
+public class Outer {
+  public static class Nested implements I {
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8133235/A.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8133235
+ * @summary Ensuring order of inputs does not affect compilability of the sources
+ * @compile A.java B.java C.java D.java
+ * @compile A.java B.java D.java C.java
+ * @compile A.java C.java B.java D.java
+ * @compile A.java C.java D.java B.java
+ * @compile A.java D.java B.java C.java
+ * @compile A.java D.java C.java B.java
+ * @compile D.java A.java B.java C.java
+ * @compile D.java A.java C.java B.java
+ * @compile D.java B.java A.java C.java
+ * @compile D.java B.java C.java A.java
+ * @compile D.java C.java B.java A.java
+ * @compile D.java C.java A.java B.java
+ */
+package pkg;
+
+public class A {
+  public interface One {
+      public interface N2 {
+          public class N3 { }
+      }
+
+      public class Foo extends D {}
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8133235/B.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import pkg.A;
+
+public class B extends A {
+  public static interface Two {
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8133235/C.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import pkg.B.Two;
+
+public class C implements B.One {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T8133235/D.java	Mon Oct 05 18:31:38 2015 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import static pkg.C.*;
+
+public class D implements C.N2 {
+}