6939780: add a warning to detect diamond sites
Summary: added hidden compiler flag '-XDfindDiamond' to detect 'diamondifiable' sites
Reviewed-by: jjg
--- 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