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 <32299405+rtane...@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 geert...@apache.org. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists