8210197: javac can't tell during speculative attribution if a diamond expression is creating an anonymous inner class or not
authorvromero
Thu, 08 Nov 2018 10:36:06 -0500
changeset 52455 bbbc110cdffe
parent 52454 9b20fe769046
child 52456 90ff0e286a5e
8210197: javac can't tell during speculative attribution if a diamond expression is creating an anonymous inner class or not Reviewed-by: mcimadamore
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
test/langtools/tools/javac/T8210197/DiamondWithAnonymousInnerClassTest.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 08 16:23:55 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 08 10:36:06 2018 -0500
@@ -2419,7 +2419,7 @@
                                                clazztype.getMetadata());
 
                 Env<AttrContext> diamondEnv = localEnv.dup(tree);
-                diamondEnv.info.selectSuper = cdef != null;
+                diamondEnv.info.selectSuper = cdef != null || tree.classDeclRemoved();
                 diamondEnv.info.pendingResolutionPhase = null;
 
                 //if the type of the instance creation expression is a class type
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Nov 08 16:23:55 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Nov 08 10:36:06 2018 -0500
@@ -151,7 +151,7 @@
                         JCExpression clazz = copy(t.clazz, p);
                         List<JCExpression> args = copy(t.args, p);
                         JCClassDecl def = null;
-                        return make.at(t.pos).NewClass(encl, typeargs, clazz, args, def);
+                        return make.at(t.pos).SpeculativeNewClass(encl, typeargs, clazz, args, def, t.def != null);
                     } else {
                         return super.visitNewClass(node, p);
                     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Nov 08 16:23:55 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Nov 08 10:36:06 2018 -0500
@@ -1787,6 +1787,10 @@
         public Tag getTag() {
             return NEWCLASS;
         }
+
+        public boolean classDeclRemoved() {
+            return false;
+        }
     }
 
     /**
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Nov 08 16:23:55 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Nov 08 10:36:06 2018 -0500
@@ -378,7 +378,24 @@
                              List<JCExpression> args,
                              JCClassDecl def)
     {
-        JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
+        return SpeculativeNewClass(encl, typeargs, clazz, args, def, false);
+    }
+
+    public JCNewClass SpeculativeNewClass(JCExpression encl,
+                             List<JCExpression> typeargs,
+                             JCExpression clazz,
+                             List<JCExpression> args,
+                             JCClassDecl def,
+                             boolean classDefRemoved)
+    {
+        JCNewClass tree = classDefRemoved ?
+                new JCNewClass(encl, typeargs, clazz, args, def) {
+                    @Override
+                    public boolean classDeclRemoved() {
+                        return true;
+                    }
+                } :
+                new JCNewClass(encl, typeargs, clazz, args, def);
         tree.pos = pos;
         return tree;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8210197/DiamondWithAnonymousInnerClassTest.java	Thu Nov 08 10:36:06 2018 -0500
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, 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 8210197
+ * @summary javac can't tell during speculative attribution if a diamond expression is creating an anonymous inner class or not
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+            jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask
+ * @run main DiamondWithAnonymousInnerClassTest
+ */
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class DiamondWithAnonymousInnerClassTest {
+    private static final String Class1Src =
+            "package pkg1;\n" +
+            "public class MyClass<T> {\n" +
+            "    protected MyClass() {}\n" +
+            "    protected MyClass(String s) {}\n" +
+            "}";
+    private static final String Class2Src =
+            "package pkg2;\n" +
+            "import pkg1.*;\n" +
+            "class Client {\n" +
+            "    <T> void foo(MyClass<T> m) {}\n" +
+            "    void bar() {\n" +
+            "        foo(new MyClass<>(){});\n" +
+            "    }\n" +
+            "}";
+
+    public static void main(String args[]) throws Exception {
+        new DiamondWithAnonymousInnerClassTest().run();
+    }
+
+    private final ToolBox tb = new ToolBox();
+
+    void run() {
+        new JavacTask(tb).sources(Class1Src, Class2Src).run();
+    }
+}