Skip to content

Commit

Permalink
Fix String concat to text block to properly handle spaces (#1112)
Browse files Browse the repository at this point in the history
* Fix String concat to text block to properly handle spaces

- fixes #1111
- add new tests to AssistQuickFixTest15
- Fix CleanUpTest15 expected results
  • Loading branch information
jjohnstn committed Jan 22, 2024
1 parent 6826280 commit eb1e529
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 Red Hat Inc. and others.
* Copyright (c) 2021, 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
Expand Down Expand Up @@ -27,6 +27,9 @@
import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
Expand Down Expand Up @@ -57,6 +60,7 @@
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.core.manipulation.ICleanUpFixCore;

import org.eclipse.jdt.internal.corext.dom.ASTNodes;
Expand All @@ -65,6 +69,7 @@
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;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

import org.eclipse.jdt.internal.ui.fix.MultiFixMessages;
Expand Down Expand Up @@ -200,7 +205,7 @@ private boolean isConsistent(NLSLine nlsLine, boolean isTagged) {
public static class ChangeStringConcatToTextBlock extends CompilationUnitRewriteOperation {

private final InfixExpression fInfix;
private final String fIndent;
private String fIndent;
private final boolean isTagged;

public ChangeStringConcatToTextBlock(final InfixExpression infix, boolean isTagged) {
Expand All @@ -224,6 +229,20 @@ public SourceRange computeSourceRange(final ASTNode nodeWithComment) {
}
});

IJavaElement root= cuRewrite.getRoot().getJavaElement();
if (root != null) {
IJavaProject project= root.getJavaProject();
if (project != null) {
String tab_option= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
if (JavaCore.SPACE.equals(tab_option)) {
fIndent= ""; //$NON-NLS-1$
for (int i= 0; i < CodeFormatterUtil.getTabWidth(project); ++i) {
fIndent += " "; //$NON-NLS-1$
}
}
}
}

StringBuilder buf= new StringBuilder();

Stream<Expression> expressions= Stream.concat(Stream.of(fInfix.getLeftOperand(), fInfix.getRightOperand()), ((List<Expression>) fInfix.extendedOperands()).stream());
Expand Down Expand Up @@ -330,7 +349,7 @@ private static List<String> unescapeBlock(String escapedText) {
}
if (readIndex < escapedText.length()) {
// there is text at the end of the string that is not followed by a newline
transformed.append(escapeTrailingWhitespace(escapedText.substring(readIndex)));
transformed.append(escapedText.substring(readIndex));
}
if (transformed.length() > 0) {
parts.add(transformed.toString());
Expand Down Expand Up @@ -600,7 +619,7 @@ public static class ChangeStringBufferToTextBlock extends CompilationUnitRewrite
private final List<MethodInvocation> fToStringList;
private final List<Statement> fStatements;
private final List<StringLiteral> fLiterals;
private final String fIndent;
private String fIndent;
private final Set<String> fExcludedNames;
private final boolean fNonNLS;
private ExpressionStatement fAssignmentToConvert;
Expand Down Expand Up @@ -628,6 +647,19 @@ public void resetAssignmentToConvert() {
public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException {
String DEFAULT_NAME= "str"; //$NON-NLS-1$
ASTRewrite rewrite= cuRewrite.getASTRewrite();
IJavaElement root= cuRewrite.getRoot().getJavaElement();
if (root != null) {
IJavaProject project= root.getJavaProject();
if (project != null) {
String tab_option= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
if (JavaCore.SPACE.equals(tab_option)) {
fIndent= ""; //$NON-NLS-1$
for (int i= 0; i < CodeFormatterUtil.getTabWidth(project); ++i) {
fIndent += " "; //$NON-NLS-1$
}
}
}
}
TextEditGroup group= createTextEditGroup(MultiFixMessages.StringConcatToTextBlockCleanUp_description, cuRewrite);
rewrite.setTargetSourceRangeComputer(new TargetSourceRangeComputer() {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 IBM Corporation and others.
* Copyright (c) 2021, 2024 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -15,6 +15,7 @@
package org.eclipse.jdt.ui.tests.quickfix;

import java.util.ArrayList;
import java.util.Hashtable;

import org.junit.After;
import org.junit.Before;
Expand All @@ -27,6 +28,8 @@
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.core.formatter.DefaultCodeFormatterConstants;

import org.eclipse.jdt.internal.corext.fix.FixMessages;

Expand Down Expand Up @@ -485,6 +488,103 @@ public void testConcatToTextBlock8() throws Exception {
assertExpectedExistInProposals(proposals, new String[] { expected });
}

@Test
public void testConcatToTextBlock9() throws Exception { //https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/1111
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
JavaProjectHelper.set15CompilerOptions(fJProject1, false);
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");

StringBuilder buf= new StringBuilder();
buf.append("module test {\n");
buf.append("}\n");
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
def.createCompilationUnit("module-info.java", buf.toString(), false, null);

IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
buf= new StringBuilder();
buf.append("package test;\n");
buf.append("public class Cls {\n");
buf.append(" public void foo() {\n");
buf.append(" // comment 1\n");
buf.append(" String x = \"foo \\n\" + \"bar \" + \"baz\" + \"biz\";\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);

int index= buf.indexOf("x");
IInvocationContext ctx= getCorrectionContext(cu, index, 6);
assertNoErrors(ctx);
ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);

buf= new StringBuilder();
buf.append("package test;\n");
buf.append("public class Cls {\n");
buf.append(" public void foo() {\n");
buf.append(" // comment 1\n");
buf.append(" String x = \"\"\"\n");
buf.append(" \tfoo\\s\n");
buf.append(" \tbar \\\n");
buf.append(" \tbaz\\\n");
buf.append(" \tbiz\"\"\";\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();

assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg);
assertExpectedExistInProposals(proposals, new String[] { expected });
}

@Test
public void testConcatToTextBlock10() throws Exception { //https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/1111
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
JavaProjectHelper.set15CompilerOptions(fJProject1, false);
Hashtable<String, String> hashtable= JavaCore.getOptions();
hashtable.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
JavaCore.setOptions(hashtable);
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");

StringBuilder buf= new StringBuilder();
buf.append("module test {\n");
buf.append("}\n");
IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
def.createCompilationUnit("module-info.java", buf.toString(), false, null);

IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
buf= new StringBuilder();
buf.append("package test;\n");
buf.append("public class Cls {\n");
buf.append(" public void foo() {\n");
buf.append(" // comment 1\n");
buf.append(" String x = \"foo \\n\" + \"bar \" + \"baz\" + \"biz\";\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);

int index= buf.indexOf("x");
IInvocationContext ctx= getCorrectionContext(cu, index, 6);
assertNoErrors(ctx);
ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);

buf= new StringBuilder();
buf.append("package test;\n");
buf.append("public class Cls {\n");
buf.append(" public void foo() {\n");
buf.append(" // comment 1\n");
buf.append(" String x = \"\"\"\n");
buf.append(" foo\\s\n");
buf.append(" bar \\\n");
buf.append(" baz\\\n");
buf.append(" biz\"\"\";\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();

assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg);
assertExpectedExistInProposals(proposals, new String[] { expected });
}

@Test
public void testNoConcatToTextBlock1() throws Exception {
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
Expand Down
Loading

0 comments on commit eb1e529

Please sign in to comment.