changeset 1358:a51c5f89f8af

6747671: -Xlint:rawtypes Summary: add an Xlint option for detecting all raw types usages (ccc-approved) Reviewed-by: jjg
author mcimadamore
date Mon, 29 Sep 2008 12:00:29 +0100
parents e2d4f3e1f805
children 4cba41f47776
files langtools/src/share/classes/com/sun/tools/javac/code/Lint.java langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java langtools/src/share/classes/com/sun/tools/javac/comp/Check.java langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties langtools/test/tools/javac/6304921/T6304921.out langtools/test/tools/javac/warnings/6747671/T6747671.java langtools/test/tools/javac/warnings/6747671/T6747671.out langtools/test/tools/javac/warnings/Unchecked.lintAll.out
diffstat 8 files changed, 128 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Sep 29 12:00:29 2008 +0100
@@ -183,7 +183,12 @@
         /**
          * Warn about unchecked operations on raw types.
          */
-        UNCHECKED("unchecked");
+        UNCHECKED("unchecked"),
+
+        /**
+         * Warn about unchecked operations on raw types.
+         */
+        RAW("rawtypes");
 
         LintCategory(String option) {
             this.option = option;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Sep 29 12:00:29 2008 +0100
@@ -614,14 +614,14 @@
             }
 
             // Check that type parameters are well-formed.
-            chk.validateTypeParams(tree.typarams);
+            chk.validate(tree.typarams, localEnv);
             if ((owner.flags() & ANNOTATION) != 0 &&
                 tree.typarams.nonEmpty())
                 log.error(tree.typarams.head.pos(),
                           "intf.annotation.members.cant.have.type.params");
 
             // Check that result type is well-formed.
-            chk.validate(tree.restype);
+            chk.validate(tree.restype, localEnv);
             if ((owner.flags() & ANNOTATION) != 0)
                 chk.validateAnnotationType(tree.restype);
 
@@ -707,7 +707,7 @@
         }
 
         // Check that the variable's declared type is well-formed.
-        chk.validate(tree.vartype);
+        chk.validate(tree.vartype, env);
 
         VarSymbol v = tree.sym;
         Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
@@ -1322,7 +1322,7 @@
             // current context.  Also, capture the return type
             result = check(tree, capture(restype), VAL, pkind, pt);
         }
-        chk.validate(tree.typeargs);
+        chk.validate(tree.typeargs, localEnv);
     }
     //where
         /** Check that given application node appears as first statement
@@ -1397,7 +1397,7 @@
         // symbol + type back into the attributed tree.
         Type clazztype = chk.checkClassType(
             tree.clazz.pos(), attribType(clazz, env), true);
-        chk.validate(clazz);
+        chk.validate(clazz, localEnv);
         if (tree.encl != null) {
             // We have to work in this case to store
             // symbol + type back into the attributed tree.
@@ -1533,7 +1533,7 @@
                 owntype = clazztype;
         }
         result = check(tree, owntype, VAL, pkind, pt);
-        chk.validate(tree.typeargs);
+        chk.validate(tree.typeargs, localEnv);
     }
 
     /** Make an attributed null check tree.
@@ -1555,7 +1555,7 @@
         Type elemtype;
         if (tree.elemtype != null) {
             elemtype = attribType(tree.elemtype, env);
-            chk.validate(tree.elemtype);
+            chk.validate(tree.elemtype, env);
             owntype = elemtype;
             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
                 attribExpr(l.head, env, syms.intType);
@@ -1711,6 +1711,7 @@
 
     public void visitTypeCast(JCTypeCast tree) {
         Type clazztype = attribType(tree.clazz, env);
+        chk.validate(tree.clazz, env);
         Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
         if (exprtype.constValue() != null)
@@ -1723,6 +1724,7 @@
             tree.expr.pos(), attribExpr(tree.expr, env));
         Type clazztype = chk.checkReifiableReferenceType(
             tree.clazz.pos(), attribType(tree.clazz, env));
+        chk.validate(tree.clazz, env);
         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
         result = check(tree, syms.booleanType, VAL, pkind, pt);
     }
@@ -2695,9 +2697,9 @@
 
         // Validate type parameters, supertype and interfaces.
         attribBounds(tree.typarams);
-        chk.validateTypeParams(tree.typarams);
-        chk.validate(tree.extending);
-        chk.validate(tree.implementing);
+        chk.validate(tree.typarams, env);
+        chk.validate(tree.extending, env);
+        chk.validate(tree.implementing, env);
 
         // If this is a non-abstract class, check that it has no abstract
         // methods or unimplemented methods of an implemented interface.
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Sep 29 12:00:29 2008 +0100
@@ -764,26 +764,32 @@
     /** Visitor method: Validate a type expression, if it is not null, catching
      *  and reporting any completion failures.
      */
-    void validate(JCTree tree) {
+    void validate(JCTree tree, Env<AttrContext> env) {
         try {
-            if (tree != null) tree.accept(validator);
+            if (tree != null) {
+                validator.env = env;
+                tree.accept(validator);
+                checkRaw(tree, env);
+            }
         } catch (CompletionFailure ex) {
             completionError(tree.pos(), ex);
         }
     }
+    //where
+    void checkRaw(JCTree tree, Env<AttrContext> env) {
+        if (lint.isEnabled(Lint.LintCategory.RAW) &&
+            tree.type.tag == CLASS &&
+            !env.enclClass.name.isEmpty() &&  //anonymous or intersection
+            tree.type.isRaw()) {
+            log.warning(tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
+        }
+    }
 
     /** Visitor method: Validate a list of type expressions.
      */
-    void validate(List<? extends JCTree> trees) {
+    void validate(List<? extends JCTree> trees, Env<AttrContext> env) {
         for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
-            validate(l.head);
-    }
-
-    /** Visitor method: Validate a list of type parameters.
-     */
-    void validateTypeParams(List<JCTypeParameter> trees) {
-        for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail)
-            validate(l.head);
+            validate(l.head, env);
     }
 
     /** A visitor class for type validation.
@@ -791,7 +797,7 @@
     class Validator extends JCTree.Visitor {
 
         public void visitTypeArray(JCArrayTypeTree tree) {
-            validate(tree.elemtype);
+            validate(tree.elemtype, env);
         }
 
         public void visitTypeApply(JCTypeApply tree) {
@@ -805,7 +811,7 @@
                 // For matching pairs of actual argument types `a' and
                 // formal type parameters with declared bound `b' ...
                 while (args.nonEmpty() && forms.nonEmpty()) {
-                    validate(args.head);
+                    validate(args.head, env);
 
                     // exact type arguments needs to know their
                     // bounds (for upper and lower bound
@@ -849,14 +855,14 @@
         }
 
         public void visitTypeParameter(JCTypeParameter tree) {
-            validate(tree.bounds);
+            validate(tree.bounds, env);
             checkClassBounds(tree.pos(), tree.type);
         }
 
         @Override
         public void visitWildcard(JCWildcard tree) {
             if (tree.inner != null)
-                validate(tree.inner);
+                validate(tree.inner, env);
         }
 
         public void visitSelect(JCFieldAccess tree) {
@@ -870,7 +876,7 @@
             }
         }
         public void visitSelectInternal(JCFieldAccess tree) {
-            if (tree.type.getEnclosingType().tag != CLASS &&
+            if (tree.type.tsym.isStatic() &&
                 tree.selected.type.isParameterized()) {
                 // The enclosing type is not a class, so we are
                 // looking at a static member type.  However, the
@@ -878,7 +884,7 @@
                 log.error(tree.pos(), "cant.select.static.class.from.param.type");
             } else {
                 // otherwise validate the rest of the expression
-                validate(tree.selected);
+                tree.selected.accept(this);
             }
         }
 
@@ -886,6 +892,8 @@
          */
         public void visitTree(JCTree tree) {
         }
+
+        Env<AttrContext> env;
     }
 
 /* *************************************************************************
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Sep 29 12:00:29 2008 +0100
@@ -770,6 +770,10 @@
 compiler.warn.annotation.method.not.found.reason=\
     Cannot find annotation method ''{1}()'' in type ''{0}'': {2}
 
+compiler.warn.raw.class.use=\
+    [raw-type] found raw type: {0}\n\
+    missing type parameters for generic class {1}
+
 #####
 
 ## The following are tokens which are non-terminals in the language. They should
--- a/langtools/test/tools/javac/6304921/T6304921.out	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/test/tools/javac/6304921/T6304921.out	Mon Sep 29 12:00:29 2008 +0100
@@ -1,3 +1,7 @@
+T6304921.java:671/671/680: warning: [raw-type] found raw type: java.util.ArrayList
+missing type parameters for generic class java.util.ArrayList<E>
+        List<Integer> list = new ArrayList();
+                                 ^
 T6304921.java:667/667/682: warning: [unchecked] unchecked conversion
 found   : java.util.ArrayList
 required: java.util.List<java.lang.Integer>
@@ -18,4 +22,4 @@
         return 123 + true; // bad binary expression
                    ^
 2 errors
-3 warnings
+4 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6747671/T6747671.java	Mon Sep 29 12:00:29 2008 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6747671
+ * @summary -Xlint:rawtypes
+ * @compile/ref=T6747671.out -XDrawDiagnostics -Xlint:rawtypes T6747671.java
+ */
+
+
+class T6747671<E> {
+
+    static class B<X> {}
+
+    class A<X> {
+        class X {}
+        class Z<Y> {}
+    }
+
+
+    A.X x1;//raw warning
+    A.Z z1;//raw warning
+
+    T6747671.B<Integer> b1;//ok
+    T6747671.B b2;//raw warning
+
+    A<String>.X x2;//ok
+    A<String>.Z<Integer> z2;//ok
+    A<B>.Z<A<B>> z3;//raw warning (2)
+
+    void test(Object arg1, B arg2) {//raw warning
+        boolean b = arg1 instanceof A;//raw warning
+        Object a = (A)arg1;//raw warning
+        A a2 = new A() {};//raw warning (2)
+        a2.new Z() {};//raw warning
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/6747671/T6747671.out	Mon Sep 29 12:00:29 2008 +0100
@@ -0,0 +1,12 @@
+T6747671.java:42:6: compiler.warn.raw.class.use: T6747671.A.X, T6747671<E>.A<X>.X
+T6747671.java:43:6: compiler.warn.raw.class.use: T6747671.A.Z, T6747671<E>.A<X>.Z<Y>
+T6747671.java:46:13: compiler.warn.raw.class.use: T6747671.B, T6747671.B<X>
+T6747671.java:50:14: compiler.warn.raw.class.use: T6747671.B, T6747671.B<X>
+T6747671.java:50:7: compiler.warn.raw.class.use: T6747671.B, T6747671.B<X>
+T6747671.java:52:28: compiler.warn.raw.class.use: T6747671.B, T6747671.B<X>
+T6747671.java:53:37: compiler.warn.raw.class.use: T6747671.A, T6747671<E>.A<X>
+T6747671.java:54:21: compiler.warn.raw.class.use: T6747671.A, T6747671<E>.A<X>
+T6747671.java:55:9: compiler.warn.raw.class.use: T6747671.A, T6747671<E>.A<X>
+T6747671.java:55:20: compiler.warn.raw.class.use: T6747671.A, T6747671<E>.A<X>
+T6747671.java:56:16: compiler.warn.raw.class.use: T6747671.A.Z, T6747671<E>.A<X>.Z<Y>
+11 warnings
\ No newline at end of file
--- a/langtools/test/tools/javac/warnings/Unchecked.lintAll.out	Mon Sep 29 11:48:09 2008 +0100
+++ b/langtools/test/tools/javac/warnings/Unchecked.lintAll.out	Mon Sep 29 12:00:29 2008 +0100
@@ -1,3 +1,8 @@
+Unchecked.java:16:9: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
 Unchecked.java:17:14: compiler.warn.unchecked.call.mbr.of.raw.type: add(E), java.util.List
+Unchecked.java:26:9: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
+Unchecked.java:35:9: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
+Unchecked.java:46:21: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
+Unchecked.java:57:9: compiler.warn.raw.class.use: java.util.List, java.util.List<E>
 Unchecked.java:58:14: compiler.warn.unchecked.call.mbr.of.raw.type: add(E), java.util.List
-2 warnings
+7 warnings
\ No newline at end of file