Skip to content

Commit

Permalink
Add support for new headless quick fixes upstream for string concaten…
Browse files Browse the repository at this point in the history
…ation (eclipse-jdtls#3007)

* Update target to match changes
  • Loading branch information
gayanper authored Jan 8, 2024
1 parent 222f3fa commit 2b9a044
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@
import org.eclipse.jdt.internal.corext.fix.ChangeLambdaBodyToBlockFixCore;
import org.eclipse.jdt.internal.corext.fix.ChangeLambdaBodyToExpressionFixCore;
import org.eclipse.jdt.internal.corext.fix.ConvertLambdaToMethodReferenceFixCore;
import org.eclipse.jdt.internal.corext.fix.ConvertToMessageFormatFixCore;
import org.eclipse.jdt.internal.corext.fix.ConvertToStringBufferFixCore;
import org.eclipse.jdt.internal.corext.fix.ConvertToStringFormatFixCore;
import org.eclipse.jdt.internal.corext.fix.IProposableFix;
import org.eclipse.jdt.internal.corext.fix.InvertEqualsExpressionFixCore;
import org.eclipse.jdt.internal.corext.fix.JoinVariableFixCore;
Expand Down Expand Up @@ -224,7 +227,9 @@ public List<ProposalKindWrapper> getAssists(CodeActionParams params, IInvocation
// }
// getConvertEnhancedForLoopProposal(context, coveringNode, resultingCollections);
// getRemoveBlockProposals(context, coveringNode, resultingCollections);
// getConvertStringConcatenationProposals(context, resultingCollections);
getConvertToMessageFormatProposal(context, coveringNode, resultingCollections);
getConvertToStringBufferProposal(context, coveringNode, resultingCollections);
getConvertToStringFormatProposal(context, coveringNode, resultingCollections);
// getMissingCaseStatementProposals(context, coveringNode, resultingCollections);
getStringConcatToTextBlockProposal(context, coveringNode, resultingCollections);
// }
Expand Down Expand Up @@ -1765,4 +1770,52 @@ private boolean getConvertLambdaToMethodReferenceProposal(IInvocationContextCore
}
return false;
}

private boolean getConvertToMessageFormatProposal(IInvocationContextCore context, ASTNode coveringNode, ArrayList<ProposalKindWrapper> resultingCollections) {
if (resultingCollections != null) {
var fix = ConvertToMessageFormatFixCore.createConvertToMessageFormatFix(context.getASTRoot(), coveringNode);
if (fix != null) {
try {
var p = new ChangeCorrectionProposalCore(fix.getDisplayString(), fix.createChange(null), IProposalRelevance.CONVERT_TO_MESSAGE_FORMAT);
resultingCollections.add(CodeActionHandler.wrap(p, JavaCodeActionKind.QUICK_ASSIST));
return true;
} catch (CoreException e) {
// ignore
}
}
}
return false;
}

private boolean getConvertToStringBufferProposal(IInvocationContextCore context, ASTNode coveringNode, ArrayList<ProposalKindWrapper> resultingCollections) {
if (resultingCollections != null) {
var fix = ConvertToStringBufferFixCore.createConvertToStringBufferFix(context.getASTRoot(), coveringNode);
if (fix != null) {
try {
var p = new ChangeCorrectionProposalCore(fix.getDisplayString(), fix.createChange(null), IProposalRelevance.CONVERT_TO_STRING_BUFFER);
resultingCollections.add(CodeActionHandler.wrap(p, JavaCodeActionKind.QUICK_ASSIST));
return true;
} catch (CoreException e) {
// ignore
}
}
}
return false;
}

private boolean getConvertToStringFormatProposal(IInvocationContextCore context, ASTNode coveringNode, ArrayList<ProposalKindWrapper> resultingCollections) {
if (resultingCollections != null) {
var fix = ConvertToStringFormatFixCore.createConvertToStringFormatFix(context.getASTRoot(), coveringNode);
if (fix != null) {
try {
var p = new ChangeCorrectionProposalCore(fix.getDisplayString(), fix.createChange(null), IProposalRelevance.CONVERT_TO_MESSAGE_FORMAT);
resultingCollections.add(CodeActionHandler.wrap(p, JavaCodeActionKind.QUICK_ASSIST));
return true;
} catch (CoreException e) {
// ignore
}
}
}
return false;
}
}
2 changes: 1 addition & 1 deletion org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
<unit id="org.mockito.mockito-core" version="0.0.0"/>
<unit id="org.apache.commons.commons-io" version="0.0.0"/>
<repository location="https://download.eclipse.org/eclipse/updates/4.31-I-builds/I20231220-0750/"/>
<repository location="https://download.eclipse.org/eclipse/updates/4.31-I-builds/I20240103-1800/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.xtext.xbase.lib" version="0.0.0"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/

package org.eclipse.jdt.ls.core.internal.correction;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages;
import org.eclipse.jdt.ls.core.internal.CodeActionUtil;
import org.eclipse.lsp4j.Range;
import org.junit.Before;
import org.junit.Test;

public class StringConcatenationQuickFixTest extends AbstractQuickFixTest {
private IJavaProject fJProject;
private IPackageFragmentRoot fSourceFolder;

@Before
public void setup() throws Exception {
fJProject = newEmptyProject();
Map<String, String> options17 = new HashMap<>(fJProject.getOptions(false));
JavaModelUtil.setComplianceOptions(options17, JavaCore.VERSION_17);
fJProject.setOptions(options17);
fSourceFolder = fJProject.getPackageFragmentRoot(fJProject.getProject().getFolder("src"));
}

@Test
public void testConvertToStringFormat() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

String content = """
package test;
public class Test {
private void print(String name, int age) {
String value = "User name: " + name + ", age: " + age;
}
}
""";
ICompilationUnit cu = pack.createCompilationUnit("Test.java", content, false, null);

String expected = """
package test;
public class Test {
private void print(String name, int age) {
String value = String.format("User name: %s, age: %d", name, age);
}
}
""";

Expected e = new Expected(CorrectionMessages.QuickAssistProcessor_convert_to_string_format, expected);
Range selection = CodeActionUtil.getRange(cu, "User name:");
assertCodeActions(cu, selection, e);
}

@Test
public void testConvertToStringBuilder() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

String content = """
package test;
public class Test {
private void print(String name, int age) {
String value = "User name: " + name + ", age: " + age;
}
}
""";
ICompilationUnit cu = pack.createCompilationUnit("Test.java", content, false, null);

String expected = """
package test;
public class Test {
private void print(String name, int age) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("User name: ");
stringBuilder.append(name);
stringBuilder.append(", age: ");
stringBuilder.append(age);
String value = stringBuilder.toString();
}
}
""";

Expected e = new Expected(MessageFormat.format(CorrectionMessages.QuickAssistProcessor_convert_to_string_buffer_description, "StringBuilder"), expected);
Range selection = CodeActionUtil.getRange(cu, "User name:");
assertCodeActions(cu, selection, e);
}

@Test
public void testConvertToMessageFormat() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

String content = """
package test;
public class Test {
private void print(String name, int age) {
String value = "User name: " + name + ", age: " + age;
}
}
""";
ICompilationUnit cu = pack.createCompilationUnit("Test.java", content, false, null);

String expected = """
package test;
import java.text.MessageFormat;
public class Test {
private void print(String name, int age) {
String value = MessageFormat.format("User name: {0}, age: {1}", name, age);
}
}
""";

Expected e = new Expected(CorrectionMessages.QuickAssistProcessor_convert_to_message_format, expected);
Range selection = CodeActionUtil.getRange(cu, "User name:");
assertCodeActions(cu, selection, e);
}

@Test
public void testConvertToStringBuffer() throws Exception {
Map<String, String> options1_4 = new HashMap<>(fJProject.getOptions(false));
JavaModelUtil.setComplianceOptions(options1_4, JavaCore.VERSION_1_4);
fJProject.setOptions(options1_4);

try {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

String content = """
package test;
public class Test {
private void print(String name, int age) {
String value = "User name: " + name + ", age: " + age;
}
}
""";
ICompilationUnit cu = pack.createCompilationUnit("Test.java", content, false, null);

String expected = """
package test;
public class Test {
private void print(String name, int age) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("User name: ");
stringBuffer.append(name);
stringBuffer.append(", age: ");
stringBuffer.append(age);
String value = stringBuffer.toString();
}
}
""";

Expected e = new Expected(MessageFormat.format(CorrectionMessages.QuickAssistProcessor_convert_to_string_buffer_description, "StringBuffer"), expected);
Range selection = CodeActionUtil.getRange(cu, "User name:");
assertCodeActions(cu, selection, e);
} finally {
Map<String, String> options17 = new HashMap<>(fJProject.getOptions(false));
JavaModelUtil.setComplianceOptions(options17, JavaCore.VERSION_17);
fJProject.setOptions(options17);
}
}

}

0 comments on commit 2b9a044

Please sign in to comment.