Skip to content

Commit

Permalink
Enhance 'Convert to multi-line string' to handle string concat sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed May 30, 2017
1 parent f64e2cc commit 9284612
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,36 @@ final class QuickAssistTests extends QuickFixTestSuite {
4, 0, new ConvertAccessorToPropertyProposal())
}

@Test
void testConvertToMultiLine0() {
assertProposalNotOffered('""', 0, 0, new ConvertToMultiLineStringProposal())
assertProposalNotOffered('""', 1, 0, new ConvertToMultiLineStringProposal())
assertProposalNotOffered('""', 2, 0, new ConvertToMultiLineStringProposal())
assertProposalNotOffered("''", 0, 0, new ConvertToMultiLineStringProposal())
assertProposalNotOffered("''", 1, 0, new ConvertToMultiLineStringProposal())
assertProposalNotOffered("''", 2, 0, new ConvertToMultiLineStringProposal())
}

@Test
void testConvertToMultiLine1() {
assertConversion(
'"fadfsad\\n\\t\' \\"\\nggggg"',
'"""fadfsad\n\t\' "\nggggg"""',
'f', new ConvertToMultiLineStringProposal())
def assertConversion = { String pre, String post ->
assertConversion("'" + pre + "'", "'''" + post + "'''", 0, 0, new ConvertToMultiLineStringProposal())
}
assertConversion('a', 'a')
assertConversion('.', '.')
assertConversion('$', '$')
assertConversion('\\"', '"')
assertConversion(" \\' ", " \' ")
//assertConversion("\\'", "\\'") // trailing single-quote is special case
//assertConversion(" ''' ", " \\'\\'\\' ") // triple-quote is special case
assertConversion('\\t', '\t')
assertConversion('\\n', '\n')
assertConversion('\\r', '\\r')
assertConversion('\\f', '\\f')
assertConversion('\\b', '\\b')
assertConversion('\\\\', '\\')
assertConversion('\u00A7', '\u00A7')
//assertConversion('\\u00A7', '\\u00A7')
}

@Test
Expand All @@ -297,9 +321,46 @@ final class QuickAssistTests extends QuickFixTestSuite {
@Test
void testConvertToMultiLine3() {
assertConversion(
'int a,b,c; def eq= "$a is\\n$b + ${c}"',
'int a,b,c; def eq= """$a is\n$b + ${c}"""',
'is', new ConvertToMultiLineStringProposal())
'int a,b,c; def eq = "$a is $b plus ${c}";',
'int a,b,c; def eq = """$a is $b plus ${c}""";',
20, 20, new ConvertToMultiLineStringProposal())
}

@Test
void testConvertToMultiLine4() {
assertConversion(
'\'$1\' + " $i \\n"',
'"""\\$1 $i \n"""',
0, 15, new ConvertToMultiLineStringProposal())
}

@Test
void testConvertToMultiLine5() {
assertConversion(
'\'one \' + { -> 2 } + " $three"',
'"""one ${ -> 2 } $three"""',
0, 29, new ConvertToMultiLineStringProposal())
}

@Test
void testConvertToMultiLine6() {
String original = $/
'A\n' +
"B\n" +
"""C\n""" +
D
/$.substring(1).stripIndent()

String expected = $/
"""A
B
C
$${D}"""
/$.substring(1).stripIndent()

assertConversion(
original, expected,
0, 29, new ConvertToMultiLineStringProposal())
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor

abstract class QuickFixTestSuite extends GroovyEclipseTestSuite {

protected GroovyCompilationUnit addGroovySource(CharSequence contents, String name = 'QuickFix', String pack = '') {
protected GroovyCompilationUnit addGroovySource(CharSequence contents, String name = "QuickFix${nextUnitName()}", String pack = '') {
super.addGroovySource(contents, name, pack)
}

protected CompilationUnit addJavaSource(CharSequence contents, String name = 'QuickFix', String pack = '') {
protected CompilationUnit addJavaSource(CharSequence contents, String name = "QuickFix${nextUnitName()}", String pack = '') {
super.addJavaSource(contents, name, pack)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@
*/
package org.codehaus.groovy.eclipse.quickassist;

import static org.eclipse.jdt.internal.corext.codemanipulation.StubUtility.getLineDelimiterPreference;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.expr.GStringExpression;
import org.codehaus.groovy.eclipse.codebrowsing.requestor.ASTNodeFinder;
import org.codehaus.groovy.eclipse.codebrowsing.requestor.Region;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.groovy.search.ITypeRequestor;
import org.eclipse.jdt.groovy.search.TypeInferencingVisitorFactory;
import org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor;
import org.eclipse.jdt.groovy.search.TypeLookupResult;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Display;
Expand Down Expand Up @@ -70,6 +75,24 @@ public void visitGStringExpression(GStringExpression expr) {
return coveredNode;
}

/**
* Returns the line delimiter of the specified line or a sensible default if
* the line is not closed with a line delimiter.
*
* @param document can be {@code null}
*/
public String getLineDelimiter(IDocument document, int line) {
if (document == null) document = newTempDocument();
String ending = null;
try {
while ((ending = document.getLineDelimiter(line)) == null && line > 1) {
line -= 1;
}
} catch (BadLocationException ignore) {
}
return ending != null ? ending : getLineDelimiterPreference(getProject());
}

public String getNodeText(ASTNode node) {
int offset = node.getStart(),
length = node.getLength();
Expand All @@ -82,6 +105,23 @@ public String getNodeText(ASTNode node) {
return null;
}

public TypeLookupResult getNodeType(final ASTNode node) {
final TypeLookupResult[] ref = new TypeLookupResult[1];
visitCompilationUnit(new ITypeRequestor() {
public ITypeRequestor.VisitStatus acceptASTNode(ASTNode n, TypeLookupResult r, IJavaElement e) {
if (n == node) {
ref[0] = r;
return ITypeRequestor.VisitStatus.STOP_VISIT;
}
return ITypeRequestor.VisitStatus.CONTINUE;
}
});
if (ref[0] != null) {
return ref[0];
}
return new TypeLookupResult(null, null, node, TypeLookupResult.TypeConfidence.UNKNOWN, null);
}

public int getSelectionOffset() {
return context.getSelectionOffset();
}
Expand Down
Loading

0 comments on commit 9284612

Please sign in to comment.