6939780: add a warning to detect diamond sites
authormcimadamore
Tue, 02 Nov 2010 12:01:35 +0000
changeset 7081 94cfc5b65bed
parent 7080 66bab13849fb
child 7082 b36c199d8de8
child 7203 1153590927f7
6939780: add a warning to detect diamond sites Summary: added hidden compiler flag '-XDfindDiamond' to detect 'diamondifiable' sites Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/test/tools/javac/diags/examples/DiamondRedundantArgs.java
langtools/test/tools/javac/diags/examples/DiamondRedundantArgs1.java
langtools/test/tools/javac/generics/diamond/T6939780.java
langtools/test/tools/javac/generics/diamond/T6939780.out
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Nov 02 12:00:54 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Nov 02 12:01:35 2010 +0000
@@ -121,6 +121,8 @@
         sourceName = source.name;
         relax = (options.isSet("-retrofit") ||
                  options.isSet("-relax"));
+        findDiamonds = options.get("findDiamond") != null &&
+                 source.allowDiamond();
         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
         enableSunApiLintControl = options.isSet("enableSunApiLintControl");
     }
@@ -154,6 +156,16 @@
      */
     boolean allowAnonOuterThis;
 
+    /** Switch: generates a warning if diamond can be safely applied
+     *  to a given new expression
+     */
+    boolean findDiamonds;
+
+    /**
+     * Internally enables/disables diamond finder feature
+     */
+    static final boolean allowDiamondFinder = true;
+
     /**
      * Switch: warn about use of variable before declaration?
      * RFE: 6425594
@@ -1572,6 +1584,24 @@
         if (TreeInfo.isDiamond(tree)) {
             clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes);
             clazz.type = clazztype;
+        } else if (allowDiamondFinder &&
+                clazztype.getTypeArguments().nonEmpty() &&
+                findDiamonds) {
+            Type inferred = attribDiamond(localEnv,
+                    tree,
+                    clazztype,
+                    mapping,
+                    argtypes,
+                    typeargtypes);
+            if (!inferred.isErroneous() &&
+                    inferred.tag == CLASS &&
+                    types.isAssignable(inferred, pt.tag == NONE ? clazztype : pt, Warner.noWarnings) &&
+                    chk.checkDiamond((ClassType)inferred).isEmpty()) {
+                String key = types.isSameType(clazztype, inferred) ?
+                    "diamond.redundant.args" :
+                    "diamond.redundant.args.1";
+                log.warning(tree.clazz.pos(), key, clazztype, inferred);
+            }
         }
 
         // If we have made no mistakes in the class type...
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Nov 02 12:00:54 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Nov 02 12:01:35 2010 +0000
@@ -873,6 +873,13 @@
     found raw type: {0}\n\
     missing type parameters for generic class {1}
 
+compiler.warn.diamond.redundant.args=\
+    redundant type arguments in new expression (use diamond operator instead).
+compiler.warn.diamond.redundant.args.1=\
+    redundant type arguments in new expression (use diamond operator instead).\n\
+    explicit: {0}\n\
+    inferred: {1}
+
 #####
 
 ## The following are tokens which are non-terminals in the language. They should
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs.java	Tue Nov 02 12:01:35 2010 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.warn.diamond.redundant.args
+// options: -XDfindDiamond
+
+class Foo<X> {
+   Foo<String> fs = new Foo<String>();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs1.java	Tue Nov 02 12:01:35 2010 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.warn.diamond.redundant.args.1
+// options: -XDfindDiamond
+
+class Foo<X> {
+   Foo<?> fs = new Foo<String>();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/T6939780.java	Tue Nov 02 12:01:35 2010 +0000
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6939780
+ *
+ * @summary  add a warning to detect diamond sites
+ * @author mcimadamore
+ * @compile/ref=T6939780.out T6939780.java -XDrawDiagnostics -XDfindDiamond
+ *
+ */
+
+class T6939780 {
+
+    void test() {
+        class Foo<X extends Number> {
+            Foo() {}
+            Foo(X x) {}
+        }
+        Foo<Number> f1 = new Foo<Number>(1);
+        Foo<?> f2 = new Foo<Number>();
+        Foo<?> f3 = new Foo<Integer>();
+        Foo<Number> f4 = new Foo<Number>(1) {};
+        Foo<?> f5 = new Foo<Number>() {};
+        Foo<?> f6 = new Foo<Integer>() {};
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/T6939780.out	Tue Nov 02 12:01:35 2010 +0000
@@ -0,0 +1,5 @@
+T6939780.java:19:28: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
+T6939780.java:20:28: compiler.warn.diamond.redundant.args.1: Foo<java.lang.Integer>, Foo<java.lang.Number>
+T6939780.java:22:28: compiler.warn.diamond.redundant.args: Foo<java.lang.Number>, Foo<java.lang.Number>
+T6939780.java:23:28: compiler.warn.diamond.redundant.args.1: Foo<java.lang.Integer>, Foo<java.lang.Number>
+4 warnings