diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnwrapNewArrayOperation.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnwrapNewArrayOperation.java index 087efe9ee34..783033e83f7 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnwrapNewArrayOperation.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnwrapNewArrayOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Red Hat Inc. and others. + * Copyright (c) 2019, 2024 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,14 +13,18 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; +import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.text.edits.TextEditGroup; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.ClassInstanceCreation; +import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.SuperMethodInvocation; @@ -29,6 +33,9 @@ import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.refactoring.nls.NLSElement; +import org.eclipse.jdt.internal.corext.refactoring.nls.NLSLine; +import org.eclipse.jdt.internal.corext.refactoring.nls.NLSUtil; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; /** @@ -46,34 +53,83 @@ public UnwrapNewArrayOperation(ArrayCreation node, Expression call) { @Override public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore linkedModel) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); + List expressionsInArray= node != null && node.getInitializer() != null && node.getInitializer().expressions() != null ? + node.getInitializer().expressions() : Collections.EMPTY_LIST; + boolean isTagged[]= new boolean[expressionsInArray.size()]; + ICompilationUnit cu= cuRewrite.getCu(); - ListRewrite listRewrite; - if (call instanceof ClassInstanceCreation) { - listRewrite= rewrite.getListRewrite(call, ClassInstanceCreation.ARGUMENTS_PROPERTY); - } else if (call instanceof MethodInvocation) { - listRewrite= rewrite.getListRewrite(call, MethodInvocation.ARGUMENTS_PROPERTY); - } else if (call instanceof SuperMethodInvocation) { - listRewrite= rewrite.getListRewrite(call, SuperMethodInvocation.ARGUMENTS_PROPERTY); - } else { - return; + boolean tagged= false; + for (int i= 0; i < expressionsInArray.size(); ++i) { + Expression operand= expressionsInArray.get(i); + NLSLine nlsLine= NLSUtil.scanCurrentLine(cu, operand.getStartPosition()); + if (nlsLine != null) { + for (NLSElement element : nlsLine.getElements()) { + if (element.getPosition().getOffset() == operand.getStartPosition()) { + if (element.hasTag()) { + tagged= true; + isTagged[i]= true; + } + } + } + } } TextEditGroup group= createTextEditGroup(FixMessages.UnusedCodeFix_RemoveUnnecessaryArrayCreation_description, cuRewrite); - if (node.getInitializer() != null && node.getInitializer().expressions() != null) { - List expressionsInArray= node.getInitializer().expressions(); - - for (int i= 1; i < expressionsInArray.size(); i++) { - listRewrite.insertLast(ASTNodes.createMoveTarget(rewrite, expressionsInArray.get(i)), group); + if (!tagged) { + ListRewrite listRewrite; + if (call instanceof ClassInstanceCreation) { + listRewrite= rewrite.getListRewrite(call, ClassInstanceCreation.ARGUMENTS_PROPERTY); + } else if (call instanceof MethodInvocation) { + listRewrite= rewrite.getListRewrite(call, MethodInvocation.ARGUMENTS_PROPERTY); + } else if (call instanceof SuperMethodInvocation) { + listRewrite= rewrite.getListRewrite(call, SuperMethodInvocation.ARGUMENTS_PROPERTY); + } else { + return; } - if (expressionsInArray.isEmpty()) { - listRewrite.remove(node, group); + if (node.getInitializer() != null && node.getInitializer().expressions() != null) { + for (int i= 1; i < expressionsInArray.size(); i++) { + listRewrite.insertLast(ASTNodes.createMoveTarget(rewrite, expressionsInArray.get(i)), group); + } + + if (expressionsInArray.isEmpty()) { + listRewrite.remove(node, group); + } else { + listRewrite.replace(node, ASTNodes.createMoveTarget(rewrite, expressionsInArray.get(0)), group); + } } else { - listRewrite.replace(node, ASTNodes.createMoveTarget(rewrite, expressionsInArray.get(0)), group); + listRewrite.remove(node, group); } } else { - listRewrite.remove(node, group); + // to avoid replacing/calculating non-NLS markers, simply remove the array declaration and it's braces + // from the original call + StringBuilder buf= new StringBuilder(); + CompilationUnit comp= (CompilationUnit)call.getRoot(); + int nodeStart= comp.getExtendedStartPosition(call); + int nodeEnd= comp.getExtendedStartPosition(call) + comp.getExtendedLength(call); + int arrayStart= node.getStartPosition(); + List expressionList= node.getInitializer().expressions(); + int arrayExpressionStart= expressionList.get(0).getStartPosition(); + Expression lastExpression= expressionList.get(expressionList.size() - 1); + int arrayExpressionEnd= lastExpression.getStartPosition() + lastExpression.getLength(); + int arrayInitializerEnd= node.getInitializer().getStartPosition() + node.getInitializer().getLength(); + buf.append(cu.getBuffer().getText(nodeStart, arrayStart - nodeStart)); + buf.append(cu.getBuffer().getText(arrayExpressionStart, arrayExpressionEnd - arrayExpressionStart)); + buf.append(cu.getBuffer().getText(arrayInitializerEnd, nodeEnd - arrayInitializerEnd)); + + ASTNode replacementNode= null; + if (call instanceof ClassInstanceCreation) { + replacementNode= rewrite.createStringPlaceholder(buf.toString(), ASTNode.CLASS_INSTANCE_CREATION); + } else if (call instanceof MethodInvocation) { + replacementNode= rewrite.createStringPlaceholder(buf.toString(), ASTNode.METHOD_INVOCATION); + } else if (call instanceof SuperMethodInvocation) { + replacementNode= rewrite.createStringPlaceholder(buf.toString(), ASTNode.SUPER_METHOD_INVOCATION); + } else { + return; + } + + rewrite.replace(call, replacementNode, group); } } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java index 5b0e3fdba3a..be0856609ab 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2023 IBM Corporation and others. + * Copyright (c) 2019, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -3107,6 +3107,52 @@ public void testUnnecessaryArray_default_package() throws Exception { } } + @Test + public void testUnnecessaryArrayNLS() throws Exception { // https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/1213 + try { + // Given + IPackageFragment pack1= fSourceFolder.createPackageFragment("", false, null); + String given= "" // + + "import java.util.Arrays;\n" // + + "import java.util.List;\n" // + + "\n" // + + "public class NLS {\n" // + + " private static final List WHITELISTED_IDS = Arrays\n" // + + " .asList(new String[] { \"org.eclipse.search.text.FileSearchResultPage\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.JavaSearchResultPage\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.CodeGeneration\", \n" // + + " \"org.eclipse.jdt.ui.ISharedImages\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.IWorkingCopyManager\" }); //$NON-NLS-1$\n" // + + "}\n"; // + String expected= "" // + + "import java.util.Arrays;\n" // + + "import java.util.List;\n" // + + "\n" // + + "public class NLS {\n" // + + " private static final List WHITELISTED_IDS = Arrays\n" // + + " .asList(\"org.eclipse.search.text.FileSearchResultPage\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.JavaSearchResultPage\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.CodeGeneration\", \n" // + + " \"org.eclipse.jdt.ui.ISharedImages\", //$NON-NLS-1$\n" // + + " \"org.eclipse.jdt.ui.IWorkingCopyManager\"); //$NON-NLS-1$\n" // + + "}\n"; // + + // When + ICompilationUnit cu= pack1.createCompilationUnit("A.java", given, false, null); + enable(CleanUpConstants.REMOVE_UNNECESSARY_ARRAY_CREATION); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.UnusedCodeFix_RemoveUnnecessaryArrayCreation_description))); + } catch (Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + fail(sw.toString()); + } + } + @Test public void testUnnecessaryEmptyArray() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);