You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ge...@apache.org on 2018/05/10 14:57:00 UTC

[incubator-netbeans] branch master updated: [NETBEANS-694] : Support convert to var for diamond operator and other fixes (#533)

This is an automated email from the ASF dual-hosted git repository.

geertjan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 607dcd8  [NETBEANS-694] : Support convert to var for diamond operator and other fixes (#533)
607dcd8 is described below

commit 607dcd8ce1ea0e670a1f7de07644105ed49107d6
Author: Reema Taneja <32...@users.noreply.github.com>
AuthorDate: Thu May 10 20:26:56 2018 +0530

    [NETBEANS-694] : Support convert to var for diamond operator and other fixes (#533)
    
    * [NETBEANS-694] Allow convert to var for initializer having diamond operator
    
    * [NETBEANS-694] and refactoring in ConvertToVarHint
    
    * [NETBEANS-694] and refactoring in ConvertToVarHint
    
    * Incorporated review comments
    
    * incorporated review comments
---
 .../modules/java/hints/jdk/ConvertToVarHint.java   |  99 ++++++++++---
 .../java/hints/jdk/ConvertToVarHintTest.java       | 162 +++++++++++++++++++--
 2 files changed, 228 insertions(+), 33 deletions(-)

diff --git a/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHint.java b/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHint.java
index e5d13e2..8245d9e 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHint.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHint.java
@@ -19,7 +19,9 @@
 package org.netbeans.modules.java.hints.jdk;
 
 import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.Scope;
+import com.sun.source.tree.NewArrayTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.ParameterizedTypeTree;
 import com.sun.source.tree.Tree;
 import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
@@ -43,6 +45,8 @@ import javax.lang.model.SourceVersion;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.type.TypeMirror;
 import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+import org.netbeans.modules.java.hints.errors.Utilities;
 
 /**
  * Hint will convert explicit type of local variable to 'var'. Supported: JDK 10
@@ -67,20 +71,10 @@ public class ConvertToVarHint {
             return null;
         }
 
-        TreePath treePath = ctx.getPath();
-
-        TreePath initTreePath = ctx.getVariables().get("$init");     //NOI18N
-        ExpressionTree t = ctx.getInfo().getTreeUtilities().parseExpression(initTreePath.getLeaf().toString(), null);
-        Scope s = ctx.getInfo().getTrees().getScope(ctx.getPath());
-        TypeMirror initTypeMirror = ctx.getInfo().getTreeUtilities().attributeTree(t, s);
-
-        TypeMirror VariableTypeMiror = ctx.getInfo().getTrees().getElement(treePath).asType();
-
-        // variable initializer type should be same as variable type.
-        if (!ctx.getInfo().getTypes().isSameType(VariableTypeMiror, initTypeMirror)) {
+        if(!isValidVarType(ctx)) {
             return null;
         }
-
+        
         return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), Bundle.MSG_ConvertibleToVarType(), new JavaFixImpl(ctx.getInfo(), ctx.getPath()).toEditorFix());
     }
 
@@ -106,20 +100,36 @@ public class ConvertToVarHint {
             WorkingCopy wc = tc.getWorkingCopy();
             TreePath statementPath = tc.getPath();
             TreeMaker make = wc.getTreeMaker();
-
+              
             if (statementPath.getLeaf().getKind() == Tree.Kind.VARIABLE) {
                 VariableTree oldVariableTree = (VariableTree) statementPath.getLeaf();
-
+                ExpressionTree initializerTree = oldVariableTree.getInitializer();
+                if(initializerTree == null) {
+                    return;
+                }
+                //check if initializer with diamond operator
+                if (initializerTree.getKind() == Tree.Kind.NEW_CLASS) {
+                    NewClassTree nct = (NewClassTree)initializerTree;
+                    if (nct.getIdentifier().getKind() == Tree.Kind.PARAMETERIZED_TYPE) {                        
+                        if(oldVariableTree.getType().getKind() == Tree.Kind.PARAMETERIZED_TYPE) {
+                            ParameterizedTypeTree ptt = (ParameterizedTypeTree) oldVariableTree.getType();
+                            ParameterizedTypeTree nue = (ParameterizedTypeTree)nct.getIdentifier();
+                            if(nue.getTypeArguments().isEmpty() && ptt.getTypeArguments().size() > 0) {
+                                //replace diamond operator with type params from lhs
+                                wc.rewrite(nue, ptt);
+                            }                            
+                        }    
+                    }
+                }
                 VariableTree newVariableTree = make.Variable(
                         oldVariableTree.getModifiers(),
                         oldVariableTree.getName(),
                         make.Type("var"),
-                        oldVariableTree.getInitializer()
+                        initializerTree
                 );
-                tc.getWorkingCopy().rewrite(oldVariableTree, newVariableTree);
+                wc.rewrite(oldVariableTree, newVariableTree);
             }
         }
-
     }
 
     /**
@@ -143,7 +153,7 @@ public class ConvertToVarHint {
             return false;
         }
 
-        if (isDiagnosticCodeTobeSkipped(ctx.getInfo())) {
+        if (isDiagnosticCodeTobeSkipped(ctx.getInfo(), treePath.getLeaf())) {
             return false;
         }
 
@@ -156,8 +166,55 @@ public class ConvertToVarHint {
      * @param info : compilationInfo
      * @return true if Diagnostic Code is present in SKIPPED_ERROR_CODES
      */
-    private static boolean isDiagnosticCodeTobeSkipped(CompilationInfo info) {
+    private static boolean isDiagnosticCodeTobeSkipped(CompilationInfo info, Tree tree) {
+        long startPos = info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tree);
+        long endPos = info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tree);
+
         List<Diagnostic> diagnosticsList = info.getDiagnostics();
-        return diagnosticsList.stream().anyMatch((d) -> (SKIPPED_ERROR_CODES.contains(d.getCode())));
+        if (diagnosticsList.stream().anyMatch((d)
+                -> ((d.getKind() == Kind.ERROR) && ((d.getStartPosition() >= startPos) && (d.getEndPosition() <= endPos)) && (SKIPPED_ERROR_CODES.contains(d.getCode()))))) {
+            return true;
+        }
+        return false;
+    }
+    
+    private static boolean isValidVarType(HintContext ctx) {
+        TreePath treePath = ctx.getPath();
+        TreePath initTreePath = ctx.getVariables().get("$init");  //NOI18N
+        
+        if (initTreePath != null) {
+            Tree.Kind kind = initTreePath.getLeaf().getKind();
+            switch (kind) {
+                case NEW_CLASS:
+                    NewClassTree nct = (NewClassTree) (initTreePath.getLeaf());
+                    //anonymous class type
+                    if (nct.getClassBody() != null) {
+                        return false;
+                    }
+                    break;
+                case NEW_ARRAY:
+                    NewArrayTree nat = (NewArrayTree) ((VariableTree) treePath.getLeaf()).getInitializer();
+                    //array initializer expr type
+                    if (nat.getType() == null) {
+                        return false;
+                    }
+                    break;
+                case LAMBDA_EXPRESSION:
+                    return false;
+                default:
+                    break;
+            }
+        } else {
+            return false;
+        }
+        // variable initializer type should be same as variable type.
+        TypeMirror initTypeMirror = ctx.getInfo().getTrees().getTypeMirror(initTreePath);
+        TypeMirror variableTypeMirror = ctx.getInfo().getTrees().getElement(treePath).asType();
+
+        if ((!Utilities.isValidType(initTypeMirror)) || (!ctx.getInfo().getTypes().isSameType(variableTypeMirror, Utilities.resolveCapturedType(ctx.getInfo(), initTypeMirror)))) {
+            return false;
+        }
+                
+        return true;
     }
 }
diff --git a/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHintTest.java b/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHintTest.java
index 408bcc6..af3a659 100644
--- a/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHintTest.java
+++ b/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToVarHintTest.java
@@ -120,6 +120,22 @@ public class ConvertToVarHintTest {
                 .assertNotContainsWarnings(VAR_CONV_DESC);
 
     }
+    
+    @Test
+    public void testArrayInitializerVar() throws Exception {
+
+        HintTest.create()
+                .input("package test;\n"
+                        + "public class Test {\n"
+                        + "    void m2() {\n"
+                        + "        int[] i = {1,2,3};\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .assertNotContainsWarnings(VAR_CONV_DESC);
+
+    }
 
     @Test
     public void testAnonymusObjRefToVar() throws Exception {
@@ -191,17 +207,16 @@ public class ConvertToVarHintTest {
     @Test
     public void testDiamondInterfaceRefToVar() throws Exception {
         HintTest.create()
-                .setCaretMarker('^')
                 .input("package test;\n"
                         + "import java.util.HashMap;\n"
                         + "public class Test {\n"
                         + "    void m1() {\n"
-                        + "        final HashMap<String, String> map = new HashMap<>^();\n"
+                        + "        final HashMap<String, String> map = new HashMap<>();\n"
                         + "    }\n"
                         + "}")
                 .sourceLevel("1.10")
                 .run(ConvertToVarHint.class)
-                .assertNotContainsWarnings(VAR_CONV_DESC);
+                .assertContainsWarnings("4:8-4:60:"+VAR_CONV_WARNING);
     }
 
     @Test
@@ -326,33 +341,156 @@ public class ConvertToVarHintTest {
                         + "    }\n"
                         + "}");
     }
-
+    
     @Test
-    public void testMethod2AssignToVar() throws Exception {
+    public void testMethodAssignToVar2() throws Exception {
         HintTest.create()
                 .setCaretMarker('^')
                 .input("package test;\n"
-                        + "import java.util.Collections;\n"
-                        + "import java.util.List;\n"
                         + "import java.util.ArrayList;\n"
                         + "public class Test {\n"
                         + "    public static void main(String[] args) {\n"
-                        + "        List<String> list = Collections.unmodifiableList(new ArrayList<String>())^;\n"
+                        + "        Object obj = m1()^;\n"
+                        + "    }\n"
+                        + "    static Object m1()\n"
+                        + "    {\n"
+                        + "        return new ArrayList<String>();\n"
                         + "    }\n"
                         + "}")
                 .sourceLevel("1.10")
                 .run(ConvertToVarHint.class)
-                .findWarning("6:8-6:82:" + VAR_CONV_WARNING)
+                .findWarning("4:8-4:26:" + VAR_CONV_WARNING)
                 .applyFix()
                 .assertCompilable()
                 .assertVerbatimOutput("package test;\n"
-                        + "import java.util.Collections;\n"
-                        + "import java.util.List;\n"
                         + "import java.util.ArrayList;\n"
                         + "public class Test {\n"
                         + "    public static void main(String[] args) {\n"
-                        + "        var list = Collections.unmodifiableList(new ArrayList<String>());\n"
+                        + "        var obj = m1();\n"
+                        + "    }\n"
+                        + "    static Object m1()\n"
+                        + "    {\n"
+                        + "        return new ArrayList<String>();\n"
+                        + "    }\n"
+                        + "}");
+    }
+
+    @Test
+    public void testCapturedTypeTypeParamsAssignToVar() throws Exception {
+        HintTest.create()
+                .input("package test;\n"
+                        + "public class Test {\n"
+                        + "    public void m() {\n"
+                        + "        Class<? extends String> aClass = \"x\".getClass();\n"
+                        + "    }\n"
+                        + "}")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .findWarning("3:8-3:56:" + VAR_CONV_WARNING)
+                .applyFix()
+                .assertCompilable()
+                .assertVerbatimOutput("package test;\n"
+                        + "public class Test {\n"
+                        + "    public void m() {\n"
+                        + "        var aClass = \"x\".getClass();\n"
+                        + "    }\n"
+                        + "}");
+    }
+    
+    @Test
+    public void testConvertToVarForCapturedType() throws Exception {
+        HintTest.create()
+                .input("package test;\n"
+                        + "import java.util.List;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        List<? extends String> ls = null;\n"
+                        + "        String s = ls.get(0);\n"
+                        + "    }\n"
+                        + "}")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .findWarning("5:8-5:29:" + VAR_CONV_WARNING)
+                .applyFix()
+                .assertCompilable()
+                .assertVerbatimOutput("package test;\n"
+                        + "import java.util.List;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        List<? extends String> ls = null;\n"
+                        + "        var s = ls.get(0);\n"
+                        + "    }\n"
+                        + "}");
+    } 
+    
+    @Test
+    public void testConvertToVarWithDiamondOperator1() throws Exception {
+        HintTest.create()
+                .input("package test;\n"
+                        + "import java.util.HashMap;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        HashMap<String, String> list = new HashMap<>();\n"
+                        + "    }\n"
+                        + "}")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .findWarning("4:8-4:55:" + VAR_CONV_WARNING)
+                .applyFix()
+                .assertCompilable()
+                .assertVerbatimOutput("package test;\n"
+                        + "import java.util.HashMap;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        var list = new HashMap<String, String>();\n"
+                        + "    }\n"
+                        + "}");
+    } 
+    
+    @Test
+    public void testConvertToVarWithDiamondOperator2() throws Exception {
+        HintTest.create()
+                .input("package test;\n"
+                        + "import java.util.ArrayList;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        ArrayList<java.util.LinkedList<?>> list = new ArrayList<>();\n"
+                        + "    }\n"
+                        + "}")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .findWarning("4:8-4:68:" + VAR_CONV_WARNING)
+                .applyFix()
+                .assertCompilable()
+                .assertVerbatimOutput("package test;\n"
+                        + "import java.util.ArrayList;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        var list = new ArrayList<java.util.LinkedList<?>>();\n"
+                        + "    }\n"
+                        + "}");
+    }
+    
+    @Test
+    public void testConvertToVarWithDiamondOperator3() throws Exception {
+        HintTest.create()
+                .input("package test;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        java.util.HashMap<String, String> list = new java.util.HashMap<>();\n"
+                        + "    }\n"
+                        + "}")
+                .sourceLevel("1.10")
+                .run(ConvertToVarHint.class)
+                .findWarning("3:8-3:75:" + VAR_CONV_WARNING)
+                .applyFix()
+                .assertCompilable()
+                .assertVerbatimOutput("package test;\n"
+                        + "public class Test {\n"
+                        + "    void m1() {\n"
+                        + "        var list = new java.util.HashMap<String, String>();\n"
                         + "    }\n"
                         + "}");
     }
+    
 }

-- 
To stop receiving notification emails like this one, please contact
geertjan@apache.org.

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists