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 c62487d [NETBEANS-481] JDK10-LVTI: Added new ErrorRule to fix compiler error on initialization of var type variable with array (#519) c62487d is described below commit c62487d4e2d02723ac4e44e87429d16ca9757ffe Author: Arunava Sinha <arunava.si...@oracle.com> AuthorDate: Tue May 29 18:02:11 2018 +0530 [NETBEANS-481] JDK10-LVTI: Added new ErrorRule to fix compiler error on initialization of var type variable with array (#519) * netbeans-481: Added new ErrorRule to fix compiler error on initialization of var type variable with array * netbeans-481: Added setup() method in ConvertInvalidVarToExplicitArrayTypeTest * netbeans-481: Refactored code of CasualDiff class * netbeans-481: Refactored code of ConvertInvalidVarToExplicitArrayType class * [NETBEANS-481] Refactored code of ConvertInvalidVarToExplicitArrayType class * [NETBEANS-481] JDK10-LVTI: Added tests for CasualDiff class changes * [NETBEANS-481] JDK10-LVTI: Refactored Test class for CasualDiff changes * [NETBEANS-481] JDK10-LVTI: 1.Refactored Test File for CasualDiff changes 2. Corrected Code for Skipping hint for Parameterized type array members * [NETBEANS-481] JDK10-LVTI: Corrected fix label text * [NETBEANS-481] JDK10-LVTI: Refactored CasualDiff to handle any tokensequence overshoot scenario * [NETBEANS-481] JDK10-LVTI: Handled scenarios related to empty array/invalid array as var initializer --- .../ConvertInvalidVarToExplicitArrayType.java | 172 +++++++++++++++ .../modules/java/hints/resources/layer.xml | 1 + .../ConvertInvalidVarToExplicitArrayTypeTest.java | 235 +++++++++++++++++++++ .../modules/java/source/save/CasualDiff.java | 67 +++++- .../api/java/source/SourceUtilsTestUtil.java | 11 +- .../InvalidVarToExplicitArrayConversionTest.java | 199 +++++++++++++++++ 6 files changed, 681 insertions(+), 4 deletions(-) diff --git a/java.hints/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayType.java b/java.hints/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayType.java new file mode 100644 index 0000000..428cb05 --- /dev/null +++ b/java.hints/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayType.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.java.hints.errors; + +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.NewArrayTree; +import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import com.sun.source.tree.VariableTree; +import com.sun.source.util.Trees; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.TreeMaker; +import org.netbeans.api.java.source.WorkingCopy; +import org.netbeans.modules.java.hints.spi.ErrorRule; +import org.netbeans.spi.editor.hints.Fix; +import org.netbeans.spi.java.hints.JavaFix; +import org.openide.util.NbBundle.Messages; +import javax.lang.model.util.Types; + +/** + * + * @author arusinha + */ +@Messages({ + "DN_ConvertVarToExplicitType=Replace var with explicit type" +}) +public class ConvertInvalidVarToExplicitArrayType implements ErrorRule<Void> { + + private static final Set<String> CODES; + + static { + Set<String> codes = new HashSet<>(); + codes.add("compiler.err.cant.infer.local.var.type"); // NOI18N + CODES = Collections.unmodifiableSet(codes); + } + + @Override + public Set<String> getCodes() { + return CODES; + } + + @Override + public List<Fix> run(CompilationInfo compilationInfo, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) { + + if (treePath.getParentPath() == null) { + return null; + } + + TypeMirror arrayType = null; + if (treePath.getLeaf().getKind() == Tree.Kind.VARIABLE) { + VariableTree oldVariableTree = (VariableTree) treePath.getLeaf(); + + ExpressionTree init = oldVariableTree.getInitializer(); + + if (init == null || init.getKind() != Tree.Kind.NEW_ARRAY) { + return null; + } + + NewArrayTree arrayTree = (NewArrayTree) oldVariableTree.getInitializer(); + List<? extends ExpressionTree> currentValues = arrayTree.getInitializers(); + + if (currentValues.isEmpty()) { + return null; + } + + TreePath initArrayTreePath = new TreePath(treePath, arrayTree); + Types types = compilationInfo.getTypes(); + Trees trees = compilationInfo.getTrees(); + + for (ExpressionTree tree : currentValues) { + + TypeMirror etType = trees.getTypeMirror(new TreePath(initArrayTreePath, tree)); + + //skipped fix for invalid array member and for parameterized array member. + if (etType == null || etType.getKind() == TypeKind.ERROR || (etType.getKind() == TypeKind.DECLARED + && !((DeclaredType) etType).getTypeArguments().isEmpty())) { + return null; + } + + if (arrayType == null) { + arrayType = etType; + } else if (!types.isAssignable(etType, arrayType)) { + if (types.isAssignable(arrayType, etType)) { + arrayType = etType; + } else { + return null; //the array is not sufficiently homogeneous. + } + } + } + return Collections.<Fix>singletonList(new FixImpl(compilationInfo, treePath, arrayType).toEditorFix()); + } + return Collections.<Fix>emptyList(); + + } + + @Override + public String getId() { + return ConvertInvalidVarToExplicitArrayType.class.getName(); + } + + @Override + public String getDisplayName() { + return Bundle.DN_ConvertVarToExplicitType(); + } + + @Override + public void cancel() { + } + + private static final class FixImpl extends JavaFix { + + private TypeMirror arrayTypeMirror; + + public FixImpl(CompilationInfo info, TreePath tp, TypeMirror arrayType) { + super(info, tp); + this.arrayTypeMirror = arrayType; + } + + @Override + protected String getText() { + return Bundle.DN_ConvertVarToExplicitType(); + } + + @Override + protected void performRewrite(TransformationContext tc) throws Exception { + WorkingCopy wc = tc.getWorkingCopy(); + wc.toPhase(JavaSource.Phase.RESOLVED); + TreePath statementPath = tc.getPath(); + TreeMaker make = wc.getTreeMaker(); + VariableTree oldVariableTree = null; + + if (statementPath.getLeaf().getKind() == Tree.Kind.VARIABLE) { + oldVariableTree = (VariableTree) statementPath.getLeaf(); + + arrayTypeMirror = Utilities.resolveCapturedType(wc, arrayTypeMirror); + + VariableTree newVariableTree = make.Variable( + oldVariableTree.getModifiers(), + oldVariableTree.getName(), + make.ArrayType(make.Type(arrayTypeMirror)), + oldVariableTree.getInitializer() + ); + tc.getWorkingCopy().rewrite(oldVariableTree, newVariableTree); + } + } + } +} diff --git a/java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml b/java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml index 6f98b8f..aa9d4e9 100644 --- a/java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml +++ b/java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml @@ -182,6 +182,7 @@ <file name="org-netbeans-modules-java-hints-errors-ExtraCatch.instance"/> <file name="org-netbeans-modules-java-hints-errors-TypeErroneous.instance"/> <file name="org-netbeans-modules-java-hints-project-IncompleteClassPath.instance"/> + <file name="org-netbeans-modules-java-hints-errors-ConvertInvalidVarToExplicitArrayType.instance"/> <folder name="text"> <folder name="x-jsp"> <file name="org-netbeans-modules-java-hints-errors-ImportClass.instance"/> diff --git a/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayTypeTest.java b/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayTypeTest.java new file mode 100644 index 0000000..a36d16f --- /dev/null +++ b/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/ConvertInvalidVarToExplicitArrayTypeTest.java @@ -0,0 +1,235 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.java.hints.errors; + +import com.sun.source.util.TreePath; +import java.util.LinkedList; +import java.util.List; +import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase; +import org.netbeans.spi.editor.hints.Fix; +import org.openide.util.NbBundle; +import org.netbeans.modules.java.source.parsing.JavacParser; +import org.netbeans.api.java.source.CompilationInfo; + +/** + * + * @author arusinha + */ +public class ConvertInvalidVarToExplicitArrayTypeTest extends ErrorHintsTestBase { + + private static final String FIX_MSG = "Replace var with explicit type"; // NOI18N + + public ConvertInvalidVarToExplicitArrayTypeTest(String name) throws Exception { + super(name, ConvertInvalidVarToExplicitArrayType.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + sourceLevel = "1.10"; + JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true; + } + + @Override + protected void tearDown() throws Exception { + JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = false; + super.tearDown(); + } + + public void testEmptyArrayAsInitializer() throws Exception { + performAnalysisTest("test/Test.java", + "package test; public class Test {{final var j = {};}}", + -1); + } + + public void testInvalidArrayAsInitializer() throws Exception { + performAnalysisTest("test/Test.java", + "package test; public class Test {{final var j = {int1,var1,\"hello\"};}}", + -1); + } + + public void testParameterizedElements() throws Exception { + performAnalysisTest("test/Test.java", + "package test; public class Test {{final var j = {new java.util.ArrayList<String>(),new java.util.ArrayList<String>()};}}", + -1); + } + + public void testParameterizedElements2() throws Exception { + performAnalysisTest("test/Test.java", + "package test; import java.util.ArrayList; import java.util.Arrays; public class Test" + + "{{ \n" + + " ArrayList<ArrayList<String>> l = new ArrayList<ArrayList<String>>(); \n" + + " ArrayList<String> places = new ArrayList<String>(Arrays.asList(\"New York\", \"Tokyo\"));\n" + + " l.add(places); " + + " final var j = {l.get(0)};" + + "}}", + -1); + } + + public void testMethodInvocation() throws Exception { + performAnalysisTest("test/Test.java", + "package test; import java.util.ArrayList; import java.util.Arrays; public class Test" + + " {{ \n" + + " ArrayList<String> places = new ArrayList<String>(Arrays.asList(\"New York\", \"Tokyo\"));\n" + + " final var j = {places.get(0)};\n" + + "}}", + -1, FIX_MSG); + } + + public void testMethodInvocation2() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test" + + " {{ \n" + + " final var arr = {m3()};}" + + " static String m3(){ return new String(\"hello\") ;}" + + "}", + -1, FIX_MSG, "package test; public class Test {{ final String[] arr = {m3()};} static String m3(){ return new String(\"hello\") ;}}"); + } + + public void testArrayHetrogeneousElements() throws Exception { + performAnalysisTest("test/Test.java", + "package test; public class Test {{final/*comment1*/ var/**comment2**/ j/*comment3*/ = /*comment4*/{new java.util.ArrayList(),new java.util.HashMap()};}}", + -1); + } + + public void testArrayObjectElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final/*comment1*/ var/**comment2**/ j/*comment3*/ = /*comment4*/{new java.util.ArrayList(),new java.util.ArrayList()};}}", + -1, FIX_MSG, + "package test; import java.util.ArrayList; public class Test {{final/*comment1*/ ArrayList[]/**comment2**/ j/*comment3*/ = /*comment4*/{new java.util.ArrayList(),new java.util.ArrayList()};}}"); + } + + public void testArrayPrimitiveNumericElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final var j = {1,2.1,3f};}}", + -1, + FIX_MSG, + "package test; public class Test {{final double[] j = {1,2.1,3f};}}"); + } + + public void testArrayPrimitiveNumeric2ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final var j = {(short)1,(byte)2};}}", + -1, + FIX_MSG, + "package test; public class Test {{final short[] j = {(short)1,(byte)2};}}"); + } + + public void testArrayStringElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{/*comment1*/ /*comment2*/@NotNull final var j = {\"hello\",\"world\"};}}", + -1, + FIX_MSG, + "package test; public class Test {{/*comment1*/ /*comment2*/@NotNull final String[] j = {\"hello\",\"world\"};}}"); + } + + public void testArrayObject1ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{@NotNull final var j = {new Object(),new Object()};}}", + -1, + FIX_MSG, + "package test; public class Test {{@NotNull final Object[] j = {new Object(),new Object()};}}"); + } + + public void testArrayObject2ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{@NotNull var j = {new Object(),new Object()};}}", + -1, + FIX_MSG, + "package test; public class Test {{@NotNull Object[] j = {new Object(),new Object()};}}"); + } + + public void testArrayObject3ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final @NotNull var j = {new Object(),new Object()};}}", + -1, + FIX_MSG, + "package test; public class Test {{final @NotNull Object[] j = {new Object(),new Object()};}}"); + } + + public void testArrayObject4ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final/*comment1*/var a = {new Object(),new Object()};}}", + -1, + FIX_MSG, + "package test; public class Test {{final/*comment1*/Object[] a = {new Object(),new Object()};}}"); + } + + public void testArrayObject5ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{final/*comment1*/var /*comment2*/ a = {2,3.1f};}}", + -1, + FIX_MSG, + "package test; public class Test {{final/*comment1*/float[] /*comment2*/ a = {2,3.1f};}}"); + } + + public void testArrayObject6ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{/*comment1*/var/*comment2*/ a = {2,3.1f};}}", + -1, + FIX_MSG, + "package test; public class Test {{/*comment1*/float[]/*comment2*/ a = {2,3.1f};}}"); + } + + public void testArrayObject7ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{var/*comment1*/ a = {2,3.1f};}}", + -1, + FIX_MSG, + "package test; public class Test {{float[]/*comment1*/ a = {2,3.1f};}}"); + } + + public void testArrayObject8ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{@NotNull var j = {new Object(),new Object()};}}", + -1, + FIX_MSG, + "package test; public class Test {{@NotNull Object[] j = {new Object(),new Object()};}}"); + } + + public void testArrayObject9ElementsFix() throws Exception { + performFixTest("test/Test.java", + "package test; public class Test {{var/*comment1*/ k = {1,'c'};}}", + -1, FIX_MSG, + "package test; public class Test {{int[]/*comment1*/ k = {1,'c'};}}"); + } + + protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) { + List<Fix> fixes = new ConvertInvalidVarToExplicitArrayType().run(info, null, pos, path, null); + List<Fix> result = new LinkedList<Fix>(); + + for (Fix f : fixes) { + if (f instanceof Fix) { + result.add(f); + } + } + + return result; + } + + @Override + protected String toDebugString(CompilationInfo info, Fix f) { + return (f.getText()); + } + + static { + NbBundle.setBranding("test"); + } + +} diff --git a/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java b/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java index 4cef162..b5cb6bf 100644 --- a/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java +++ b/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java @@ -166,6 +166,7 @@ import org.netbeans.modules.java.source.transform.FieldGroupTree; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbCollections; +import javax.lang.model.type.TypeKind; public class CasualDiff { @@ -1469,8 +1470,72 @@ public class CasualDiff { addDimensions = dimension(newT.vartype, -1); cLikeArray = vartypeBounds[1] > oldT.pos; cLikeArrayChange = cLikeArray && dimension(oldT.vartype, oldT.pos) > addDimensions; - copyTo(localPointer, vartypeBounds[0]); + + /** + * Extracting modifier from oldTree using symbol position and + * modifier positions when oldT.type is error and vartype + * upperbound is not proper. + */ + if (oldT.type.getKind() == TypeKind.ERROR && vartypeBounds[1] == -1) { + + // returns -1 if modifiers not present. + int modsUpperBound = getCommentCorrectedEndPos(oldT.mods); + if (modsUpperBound > -1) { + tokenSequence.move(modsUpperBound); + + // copying modifiers from oldTree + if (tokenSequence.moveNext()) { + copyTo(localPointer, localPointer = modsUpperBound); + } + + } + int offset = localPointer; + JavaTokenId tokenId = null; + tokenSequence.move(localPointer); + + //adding back all whitespaces/block-comment/javadoc-comments present in OldTree before variable type token. + while (tokenSequence.moveNext()) { + offset = tokenSequence.offset(); + tokenId = tokenSequence.token().id(); + + if (!((tokenId == JavaTokenId.WHITESPACE || tokenId == JavaTokenId.BLOCK_COMMENT || tokenId == JavaTokenId.JAVADOC_COMMENT) && offset < oldT.sym.pos)) { + break; + } + + } + copyTo(localPointer, localPointer = offset); + + // Correcting lower/upper bounds for oldT.vartype tree. + vartypeBounds[1] = oldT.sym.pos; + vartypeBounds[0] = offset; + + } else { + copyTo(localPointer, vartypeBounds[0]); + + } + localPointer = diffTree(oldT.vartype, newT.vartype, vartypeBounds); + + /** + * For erroneous variable type sometime diffTree function return + * wrong position. In that scenario only old variable type will + * be replaced with new variable type leaving out succeeding + * comments tokens present(if any). Below code copies successive + * tokens after excluding variable type token which will be the + * first token. + */ + if (oldT.type.getKind() == TypeKind.ERROR && localPointer == -1) { + // moving to variable type token + tokenSequence.move(vartypeBounds[0]); + tokenSequence.moveNext(); + + //moving to first token after variable type token. + if (tokenSequence.moveNext()) { + // copying tokens from vartype bounds after excluding variable type token. + int offset = tokenSequence.offset(); + copyTo(offset, localPointer = vartypeBounds[1]); + } + } } } if (nameChanged(oldT.name, newT.name)) { diff --git a/java.source.base/test/unit/src/org/netbeans/api/java/source/SourceUtilsTestUtil.java b/java.source.base/test/unit/src/org/netbeans/api/java/source/SourceUtilsTestUtil.java index 8768ba0..f8214d5 100644 --- a/java.source.base/test/unit/src/org/netbeans/api/java/source/SourceUtilsTestUtil.java +++ b/java.source.base/test/unit/src/org/netbeans/api/java/source/SourceUtilsTestUtil.java @@ -40,6 +40,7 @@ import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.editor.BaseDocument; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.java.JavaDataLoader; +import org.netbeans.modules.java.source.BootClassPathUtil; import org.netbeans.modules.java.source.TestUtil; import org.netbeans.modules.java.source.indexing.JavaCustomIndexer; import org.netbeans.modules.java.source.parsing.JavacParser; @@ -280,9 +281,13 @@ public final class SourceUtilsTestUtil extends ProxyLookup { public ClassPath findClassPath(FileObject file, String type) { try { - if (ClassPath.BOOT == type || JavaClassPathConstants.MODULE_BOOT_PATH.equals(type)) { - return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0])); - } + if (ClassPath.BOOT == type) { + return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0])); + } + + if (JavaClassPathConstants.MODULE_BOOT_PATH == type) { + return BootClassPathUtil.getModuleBootPath(); + } if (ClassPath.SOURCE == type) { return ClassPathSupport.createClassPath(new FileObject[] { diff --git a/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InvalidVarToExplicitArrayConversionTest.java b/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InvalidVarToExplicitArrayConversionTest.java new file mode 100644 index 0000000..c2c5d98 --- /dev/null +++ b/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InvalidVarToExplicitArrayConversionTest.java @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.api.java.source.gen; + +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.VariableTree; +import java.io.IOException; +import static junit.framework.TestCase.assertNotNull; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.Task; +import org.netbeans.api.java.source.TestUtilities; +import org.netbeans.api.java.source.TreeMaker; +import org.netbeans.api.java.source.WorkingCopy; +import org.netbeans.junit.NbTestSuite; +import org.netbeans.modules.java.source.parsing.JavacParser; + +/** + * Tests conversion of invalid var type variable to explicit array type. + * + * @author arusinha + */ +public class InvalidVarToExplicitArrayConversionTest extends TreeRewriteTestBase { + + public InvalidVarToExplicitArrayConversionTest(String testName) { + super(testName); + } + + public static NbTestSuite suite() { + NbTestSuite suite = new NbTestSuite(); + suite.addTestSuite(InvalidVarToExplicitArrayConversionTest.class); + return suite; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + sourceLevel = "1.10"; + JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true; + + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = false; + + } + + public void testInvalidVarToExplicitArrayConversion() throws Exception { + + String code = "package test;\n" + + "public class Test {\n" + + " void m1() {\n" + + " final /*comment1*/ var/*comment2*/ k = {1, 'C'};\n" + + " }\n" + + "}\n"; + String golden = "package test;\n" + + "public class Test {\n" + + " void m1() {\n" + + " final /*comment1*/ int[]/*comment2*/ k = {1, 'C'};\n" + + " }\n" + + "}\n"; + + prepareTest("Test", code); + + rewriteStatement("int"); + String res = TestUtilities.copyFileToString(getTestFile()); + System.err.println(res); + assertEquals(golden, res); + + } + + public void testInvalidVarToExplicitArray2Conversion() throws Exception { + + String code = "package test;\n" + + "import java.util.ArrayList;\n" + + "public class Test {\n" + + " void m1() {\n" + + " /*comment1*/var k = {new ArrayList(), new ArrayList()};\n" + + " }\n" + + "}\n"; + + String golden = "package test;\n" + + "import java.util.ArrayList;\n" + + "public class Test {\n" + + " void m1() {\n" + + " /*comment1*/ArrayList[] k = {new ArrayList(), new ArrayList()};\n" + + " }\n" + + "}\n"; + + prepareTest("Test", code); + + rewriteStatement("ArrayList"); + String res = TestUtilities.copyFileToString(getTestFile()); + System.err.println(res); + assertEquals(golden, res); + } + + public void testInvalidVarToExplicitArray3Conversion() throws Exception { + String code = "package test;\n" + + "import java.util.ArrayList;\n" + + "public class Test {\n" + + " void m1() {\n" + + " @NotNull final var j = {\"hello\", \"world\"};\n" + + " }\n" + + "}\n"; + String golden = "package test;\n" + + "import java.util.ArrayList;\n" + + "public class Test {\n" + + " void m1() {\n" + + " @NotNull final String[] j = {\"hello\", \"world\"};\n" + + " }\n" + + "}\n"; + + prepareTest("Test", code); + + rewriteStatement("String"); + String res = TestUtilities.copyFileToString(getTestFile()); + System.err.println(res); + assertEquals(golden, res); + } + + public void testInvalidVarToExplicitArray4Conversion() throws Exception { + + String code = "package test;\n" + + "public class Test {\n" + + " void m1() {\n" + + " var/*comment2*/ k = {1, 'C'};\n" + + " }\n" + + "}\n"; + String golden = "package test;\n" + + "public class Test {\n" + + " void m1() {\n" + + " int[]/*comment2*/ k = {1, 'C'};\n" + + " }\n" + + "}\n"; + + prepareTest("Test", code); + + rewriteStatement("int"); + String res = TestUtilities.copyFileToString(getTestFile()); + System.err.println(res); + assertEquals(golden, res); + } + + /** + * Replaces invalid var type array initialization statement with explicit + * array type. + * + * @param arrayType : target explicit array type. + * @throws IOException + */ + private void rewriteStatement(String arrayType) throws IOException { + + JavaSource js = getJavaSource(); + assertNotNull(js); + + Task<WorkingCopy> task = new Task<WorkingCopy>() { + + public void run(WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(JavaSource.Phase.RESOLVED); + CompilationUnitTree cut = workingCopy.getCompilationUnit(); + TreeMaker make = workingCopy.getTreeMaker(); + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); + MethodTree method = (MethodTree) clazz.getMembers().get(1); + + VariableTree oldVariableTree = (VariableTree) method.getBody().getStatements().get(0); + VariableTree newVariableTree = make.Variable( + oldVariableTree.getModifiers(), + oldVariableTree.getName(), + make.ArrayType(make.Type(arrayType)), + oldVariableTree.getInitializer() + ); + // converts var type to explicit array type + workingCopy.rewrite(oldVariableTree, newVariableTree); + } + }; + js.runModificationTask(task).commit(); + } + +} -- 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