Only allow hint when $coll is not raw and is assignable to Iterable<? extends $type>.
authorJesse Glick <jglick@netbeans.org>
Thu, 19 Apr 2012 13:03:28 -0400
changeset 178176fd564374553
parent 17816 1f86cca7a83c
child 17820 76be0d576837
child 17825 3ac0b733c804
Only allow hint when $coll is not raw and is assignable to Iterable<? extends $type>.
javahints/nbproject/project.properties
javahints/src/org/netbeans/modules/javahints/jdk5/IteratorToFor.java
javahints/test/unit/src/org/netbeans/modules/javahints/jdk5/IteratorToForTest.java
     1.1 --- a/javahints/nbproject/project.properties	Thu Apr 19 12:20:09 2012 -0400
     1.2 +++ b/javahints/nbproject/project.properties	Thu Apr 19 13:03:28 2012 -0400
     1.3 @@ -50,7 +50,7 @@
     1.4  auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width=80
     1.5  javac.compilerargs=-Xlint:unchecked
     1.6  javac.source=1.6
     1.7 -spec.version.base=2.54.0
     1.8 +spec.version.base=2.55.0
     1.9  
    1.10  nbm.needs.restart=true
    1.11  requires.nb.javac=true
     2.1 --- a/javahints/src/org/netbeans/modules/javahints/jdk5/IteratorToFor.java	Thu Apr 19 12:20:09 2012 -0400
     2.2 +++ b/javahints/src/org/netbeans/modules/javahints/jdk5/IteratorToFor.java	Thu Apr 19 13:03:28 2012 -0400
     2.3 @@ -47,6 +47,8 @@
     2.4  import com.sun.source.util.TreePathScanner;
     2.5  import java.util.Collection;
     2.6  import javax.lang.model.element.Element;
     2.7 +import javax.lang.model.element.TypeElement;
     2.8 +import javax.lang.model.type.TypeMirror;
     2.9  import org.netbeans.spi.editor.hints.ErrorDescription;
    2.10  import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
    2.11  import org.netbeans.spi.java.hints.Hint;
    2.12 @@ -69,6 +71,9 @@
    2.13          if (uses(ctx, ctx.getMultiVariables().get("$rest$"), ctx.getVariables().get("$it"))) {
    2.14              return null;
    2.15          }
    2.16 +        if (!iterable(ctx, ctx.getVariables().get("$coll"), ctx.getVariables().get("$type"))) {
    2.17 +            return null;
    2.18 +        }
    2.19          return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_IteratorToFor(),
    2.20                  JavaFixUtilities.rewriteFix(ctx, Bundle.FIX_IteratorToFor(), ctx.getPath(), "for ($type $elem : $coll) {$rest$;}"));
    2.21      }
    2.22 @@ -78,6 +83,9 @@
    2.23          if (uses(ctx, ctx.getMultiVariables().get("$rest$"), ctx.getVariables().get("$it"))) {
    2.24              return null;
    2.25          }
    2.26 +        if (!iterable(ctx, ctx.getVariables().get("$coll"), ctx.getVariables().get("$type"))) {
    2.27 +            return null;
    2.28 +        }
    2.29          return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_IteratorToFor(),
    2.30                  JavaFixUtilities.rewriteFix(ctx, Bundle.FIX_IteratorToFor(), ctx.getPath(), "for ($type $elem : $coll) {$rest$;}"));
    2.31      }
    2.32 @@ -115,4 +123,12 @@
    2.33          return false;
    2.34      }
    2.35  
    2.36 +    private static boolean iterable(HintContext ctx, TreePath collection, TreePath type) {
    2.37 +        TypeMirror collectionType = ctx.getInfo().getTrees().getTypeMirror(collection);
    2.38 +        TypeElement iterable = ctx.getInfo().getElements().getTypeElement("java.lang.Iterable");
    2.39 +        TypeMirror iterableType = ctx.getInfo().getTypes().getDeclaredType(iterable, ctx.getInfo().getTypes().getWildcardType(ctx.getInfo().getTrees().getTypeMirror(type), null));
    2.40 +        TypeMirror bogusIterableType = ctx.getInfo().getTypes().getDeclaredType(iterable, ctx.getInfo().getTypes().getNullType());
    2.41 +        return ctx.getInfo().getTypes().isAssignable(collectionType, iterableType) && !ctx.getInfo().getTypes().isAssignable(collectionType, bogusIterableType);
    2.42 +    }
    2.43 +
    2.44  }
     3.1 --- a/javahints/test/unit/src/org/netbeans/modules/javahints/jdk5/IteratorToForTest.java	Thu Apr 19 12:20:09 2012 -0400
     3.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/jdk5/IteratorToForTest.java	Thu Apr 19 13:03:28 2012 -0400
     3.3 @@ -80,6 +80,125 @@
     3.4                  + "}\n").run(IteratorToFor.class).assertWarnings();
     3.5      }
     3.6  
     3.7 +    @Test public void whileRaw() throws Exception {
     3.8 +        HintTest.create().input("package test;\n"
     3.9 +                + "import java.util.*;"
    3.10 +                + "public class Test {\n"
    3.11 +                + "    void m(List strings) {\n"
    3.12 +                + "        Iterator it = strings.iterator();\n"
    3.13 +                + "        while (it.hasNext()) {\n"
    3.14 +                + "            String s = (String) it.next();\n"
    3.15 +                + "            System.out.println(s);\n"
    3.16 +                + "            System.err.println(s);\n"
    3.17 +                + "        }\n"
    3.18 +                + "    }\n"
    3.19 +                + "}\n").run(IteratorToFor.class).assertWarnings();
    3.20 +    }
    3.21 +
    3.22 +    @Test public void whileWrongType() throws Exception {
    3.23 +        HintTest.create().input("package test;\n"
    3.24 +                + "import java.util.*;"
    3.25 +                + "public class Test {\n"
    3.26 +                + "    void m(List<java.net.URL> strings) {\n"
    3.27 +                + "        Iterator it = strings.iterator();\n"
    3.28 +                + "        while (it.hasNext()) {\n"
    3.29 +                + "            String s = (String) it.next();\n"
    3.30 +                + "            System.out.println(s);\n"
    3.31 +                + "            System.err.println(s);\n"
    3.32 +                + "        }\n"
    3.33 +                + "    }\n"
    3.34 +                + "}\n").run(IteratorToFor.class).assertWarnings();
    3.35 +    }
    3.36 +
    3.37 +    @Test public void whileNotRaw() throws Exception {
    3.38 +        HintTest.create().input("package test;\n"
    3.39 +                + "import java.util.*;"
    3.40 +                + "public class Test {\n"
    3.41 +                + "    void m(MyList strings) {\n"
    3.42 +                + "        Iterator it = strings.iterator();\n"
    3.43 +                + "        while (it.hasNext()) {\n"
    3.44 +                + "            String s = (String) it.next();\n"
    3.45 +                + "            System.out.println(s);\n"
    3.46 +                + "            System.err.println(s);\n"
    3.47 +                + "        }\n"
    3.48 +                + "    }\n"
    3.49 +                + "    static class MyList extends ArrayList<String> {}\n"
    3.50 +                + "}\n").run(IteratorToFor.class).assertWarnings("2:27-9:5:verifier:" + Bundle.ERR_IteratorToFor());
    3.51 +    }
    3.52 +
    3.53 +    @Test public void whileNotIterable() throws Exception {
    3.54 +        HintTest.create().input("package test;\n"
    3.55 +                + "import java.util.*;"
    3.56 +                + "public class Test {\n"
    3.57 +                + "    void m(MyList strings) {\n"
    3.58 +                + "        Iterator it = strings.iterator();\n"
    3.59 +                + "        while (it.hasNext()) {\n"
    3.60 +                + "            String s = (String) it.next();\n"
    3.61 +                + "            System.out.println(s);\n"
    3.62 +                + "            System.err.println(s);\n"
    3.63 +                + "        }\n"
    3.64 +                + "    }\n"
    3.65 +                + "    interface MyList {\n"
    3.66 +                + "        Iterator<String> iterator();\n"
    3.67 +                + "    }\n"
    3.68 +                + "}\n").run(IteratorToFor.class).assertWarnings();
    3.69 +    }
    3.70 +
    3.71 +    @Test public void whileSubtype() throws Exception {
    3.72 +        HintTest.create().input("package test;\n"
    3.73 +                + "import java.util.*;"
    3.74 +                + "public class Test {\n"
    3.75 +                + "    void m(List<PropertyResourceBundle> bundles) {\n"
    3.76 +                + "        Iterator it = bundles.iterator();\n"
    3.77 +                + "        while (it.hasNext()) {\n"
    3.78 +                + "            ResourceBundle bundle = (ResourceBundle) it.next();\n"
    3.79 +                + "            System.out.println(bundle);\n"
    3.80 +                + "            System.err.println(bundle);\n"
    3.81 +                + "        }\n"
    3.82 +                + "    }\n"
    3.83 +                + "}\n").run(IteratorToFor.class).assertWarnings("2:49-9:5:verifier:" + Bundle.ERR_IteratorToFor());
    3.84 +    }
    3.85 +
    3.86 +    @Test public void whileGenericSubtype() throws Exception {
    3.87 +        HintTest.create().input("package test;\n"
    3.88 +                + "import java.util.*;"
    3.89 +                + "public class Test {\n"
    3.90 +                + "    void m(List<ArrayList<String>> lists) {\n"
    3.91 +                + "        Iterator it = lists.iterator();\n"
    3.92 +                + "        while (it.hasNext()) {\n"
    3.93 +                + "            List<String> list = (List<String>) it.next();\n"
    3.94 +                + "            System.out.println(list);\n"
    3.95 +                + "        }\n"
    3.96 +                + "    }\n"
    3.97 +                + "}\n").run(IteratorToFor.class).findWarning("2:42-8:5:verifier:" + Bundle.ERR_IteratorToFor()).
    3.98 +                applyFix().
    3.99 +                assertCompilable().
   3.100 +                assertOutput("package test;\n"
   3.101 +                + "import java.util.*;"
   3.102 +                + "public class Test {\n"
   3.103 +                + "    void m(List<ArrayList<String>> lists) {\n"
   3.104 +                + "        for (List<String> list : lists) {\n"
   3.105 +                + "            System.out.println(list);\n"
   3.106 +                + "        }\n"
   3.107 +                + "    }\n"
   3.108 +                + "}\n");
   3.109 +    }
   3.110 +
   3.111 +    @Test public void whileNotSubtype() throws Exception {
   3.112 +        HintTest.create().input("package test;\n"
   3.113 +                + "import java.util.*;"
   3.114 +                + "public class Test {\n"
   3.115 +                + "    void m(List<ResourceBundle> bundles) {\n"
   3.116 +                + "        Iterator it = bundles.iterator();\n"
   3.117 +                + "        while (it.hasNext()) {\n"
   3.118 +                + "            PropertyResourceBundle bundle = (PropertyResourceBundle) it.next();\n"
   3.119 +                + "            System.out.println(bundle);\n"
   3.120 +                + "            System.err.println(bundle);\n"
   3.121 +                + "        }\n"
   3.122 +                + "    }\n"
   3.123 +                + "}\n").run(IteratorToFor.class).assertWarnings();
   3.124 +    }
   3.125 +
   3.126      @Test public void whileFix() throws Exception {
   3.127          HintTest.create().input("package test;\n"
   3.128                  + "import java.util.*;"
   3.129 @@ -144,6 +263,20 @@
   3.130                  + "}\n").run(IteratorToFor.class).assertWarnings();
   3.131      }
   3.132  
   3.133 +    @Test public void forRaw() throws Exception {
   3.134 +        HintTest.create().input("package test;\n"
   3.135 +                + "import java.util.*;"
   3.136 +                + "public class Test {\n"
   3.137 +                + "    void m(List strings) {\n"
   3.138 +                + "        for (Iterator it = strings.iterator(); it.hasNext(); ) {\n"
   3.139 +                + "            String s = (String) it.next();\n"
   3.140 +                + "            System.out.println(s);\n"
   3.141 +                + "            System.err.println(s);\n"
   3.142 +                + "        }\n"
   3.143 +                + "    }\n"
   3.144 +                + "}\n").run(IteratorToFor.class).assertWarnings();
   3.145 +    }
   3.146 +
   3.147      @Test public void forFix() throws Exception {
   3.148          HintTest.create().input("package test;\n"
   3.149                  + "import java.util.*;"