diff options
5 files changed, 198 insertions, 1 deletions
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java index b9eae83071..dd0aef2dc0 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java @@ -10,6 +10,8 @@ * (reports 71244 & 74746: New Quick Assist's [quick assist]) * Benjamin Muskalla (buskalla@innoopract.com) - 104021: [quick fix] Introduce * new local with casted type applied more than once + * Billy Huang (billyhuang31@gmail.com) - [quick assist] concatenate/merge + * string literals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=77632 *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; @@ -5502,4 +5504,136 @@ public class AdvancedQuickAssistTest extends QuickFixTest { assertProposalDoesNotExist(proposals, "Pick out selected part of String"); } + + public void testCombineStringsProposals1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello\" + \" World\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("\"Hello\""); + int length= "\"Hello\" + \"World\"".length(); + AssistContext context= getCorrectionContext(cu, offset, length); + List proposals= collectAssists(context, false); + + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello World\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected }); + + } + + public void testCombineStringsProposals2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello\" + \" \" + \"World\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("\"Hello\""); + int length= "\"Hello\" + \" \" + \"World\"".length(); + AssistContext context= getCorrectionContext(cu, offset, length); + List proposals= collectAssists(context, false); + + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello World\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected }); + + } + + public void testCombineStringsProposals3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello World\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("\"Hello World\""); + AssistContext context= getCorrectionContext(cu, offset, 0); + List proposals= collectAssists(context, false); + + assertProposalDoesNotExist(proposals, CorrectionMessages.AdvancedQuickAssistProcessor_combineSelectedStrings); + + } + + public void testCombineStringsProposals4() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" System.out.println(\"Hello\" + \" \" + \"World\");\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("\"Hello\""); + int length= "\"Hello\" + \" \" + \"World\"".length(); + AssistContext context= getCorrectionContext(cu, offset, length); + List proposals= collectAssists(context, false); + + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" System.out.println(\"Hello World\");\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected }); + + } + + public void testCombineStringsProposals5() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo() {\n"); + buf.append(" String string = \"Hello\" + \"World\" + 2;\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("\"Hello\" + \"World\""); + int length= "\"Hello\" + \"World\"".length(); + AssistContext context= getCorrectionContext(cu, offset, length); + List proposals= collectAssists(context, false); + + assertProposalDoesNotExist(proposals, CorrectionMessages.AdvancedQuickAssistProcessor_combineSelectedStrings); + + } } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java index 903240281a..df5ae1a93f 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java @@ -9,6 +9,7 @@ * Konstantin Scheglov (scheglov_ke@nlmk.ru) - initial API and implementation * (reports 71244 & 74746: New Quick Assist's [quick assist]) * IBM Corporation - implementation + * Billy Huang (billyhuang31@gmail.com) - [quick assist] concatenate/merge string literals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=77632 *******************************************************************************/ package org.eclipse.jdt.internal.ui.text.correction; @@ -144,6 +145,7 @@ public class AdvancedQuickAssistProcessor implements IQuickAssistProcessor { || getExchangeInnerAndOuterIfConditionsProposals(context, coveringNode, null) || getExchangeOperandsProposals(context, coveringNode, null) || getCastAndAssignIfStatementProposals(context, coveringNode, null) + || getCombineStringProposals(context, coveringNode, null) || getPickOutStringProposals(context, coveringNode, null) || getReplaceIfElseWithConditionalProposals(context, coveringNode, null) || getReplaceConditionalWithIfElseProposals(context, coveringNode, null) @@ -187,6 +189,7 @@ public class AdvancedQuickAssistProcessor implements IQuickAssistProcessor { getExchangeInnerAndOuterIfConditionsProposals(context, coveringNode, resultingCollections); getExchangeOperandsProposals(context, coveringNode, resultingCollections); getCastAndAssignIfStatementProposals(context, coveringNode, resultingCollections); + getCombineStringProposals(context, coveringNode, resultingCollections); getPickOutStringProposals(context, coveringNode, resultingCollections); getReplaceIfElseWithConditionalProposals(context, coveringNode, resultingCollections); getInverseLocalVariableProposals(context, coveringNode, resultingCollections); @@ -1527,6 +1530,60 @@ public class AdvancedQuickAssistProcessor implements IQuickAssistProcessor { return StubUtility.getVariableNameSuggestions(NamingConventions.VK_LOCAL, cu.getJavaProject(), binding, null, excluded); } + private static boolean getCombineStringProposals(IInvocationContext context, ASTNode node, Collection<ICommandAccess> resultingCollections) { + // we work with InfixExpressions + if (!(node instanceof InfixExpression)) + return false; + + InfixExpression infixExpression= (InfixExpression) node; + + // only + is valid for combining strings + if(!(infixExpression.getOperator().equals(InfixExpression.Operator.PLUS))) { + return false; + } + + // all expressions must be strings + Expression leftOperand= infixExpression.getLeftOperand(); + Expression rightOperand= infixExpression.getRightOperand(); + if(!(leftOperand instanceof StringLiteral && rightOperand instanceof StringLiteral)) { + return false; + } + + StringLiteral leftString= (StringLiteral) leftOperand; + StringLiteral rightString= (StringLiteral) rightOperand; + + if (resultingCollections == null) { + return true; + } + + // begin building combined string + StringBuilder stringBuilder= new StringBuilder(leftString.getLiteralValue()); + stringBuilder.append(rightString.getLiteralValue()); + + // append extended string literals + for (Object operand : infixExpression.extendedOperands()) { + if (!(operand instanceof StringLiteral)) + return false; + StringLiteral stringLiteral= (StringLiteral) operand; + stringBuilder.append(stringLiteral.getLiteralValue()); + } + + // prepare new string literal + AST ast= node.getAST(); + StringLiteral combinedStringLiteral= ast.newStringLiteral(); + combinedStringLiteral.setLiteralValue(stringBuilder.toString()); + + ASTRewrite rewrite= ASTRewrite.create(ast); + rewrite.replace(infixExpression, combinedStringLiteral, null); + + // add correction proposal + String label= CorrectionMessages.AdvancedQuickAssistProcessor_combineSelectedStrings; + Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); + LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.COMBINE_STRINGS, image); + resultingCollections.add(proposal); + return true; + } + private static boolean getPickOutStringProposals(IInvocationContext context, ASTNode node, Collection<ICommandAccess> resultingCollections) { // we work with String's if (!(node instanceof StringLiteral)) { diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java index 136e6f7f49..1de6cd3807 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla <b.muskalla@gmx.net> - [quick fix] Quick fix for missing synchronized modifier - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245250 + * Billy Huang (billyhuang31@gmail.com) - [quick assist] concatenate/merge string literals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=77632 *******************************************************************************/ package org.eclipse.jdt.internal.ui.text.correction; @@ -294,6 +295,7 @@ public final class CorrectionMessages extends NLS { public static String TypeChangeCompletionProposal_method_name; public static String ImplementInterfaceProposal_name; public static String AddUnimplementedMethodsOperation_AddMissingMethod_group; + public static String AdvancedQuickAssistProcessor_combineSelectedStrings; public static String AdvancedQuickAssistProcessor_convertToIfElse_description; public static String AdvancedQuickAssistProcessor_inverseIf_description; public static String AdvancedQuickAssistProcessor_inverseBooleanVariable; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties index 493383b0ed..ea69a6d6aa 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties @@ -8,6 +8,7 @@ # Contributors: # IBM Corporation - initial API and implementation # Benjamin Muskalla <b.muskalla@gmx.net> - [quick fix] Quick fix for missing synchronized modifier - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245250 +# Billy Huang (billyhuang31@gmail.com) - [quick assist] concatenate/merge string literals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=77632 ############################################################################### # ------ SerialVersionProposal @@ -374,6 +375,7 @@ TypeChangeCompletionProposal_method_name=Change return type of ''{0}(..)'' to '' ImplementInterfaceProposal_name=Let ''{0}'' implement ''{1}'' AddUnimplementedMethodsOperation_AddMissingMethod_group=Add missing method +AdvancedQuickAssistProcessor_combineSelectedStrings=Combine strings AdvancedQuickAssistProcessor_convertToIfElse_description=Convert to 'if-else' AdvancedQuickAssistProcessor_inverseIf_description=Invert 'if' statement AdvancedQuickAssistProcessor_inverseBooleanVariable=Invert local variable diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java index c37629dd94..422aead511 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Billy Huang (billyhuang31@gmail.com) - [quick assist] concatenate/merge string literals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=77632 *******************************************************************************/ package org.eclipse.jdt.internal.ui.text.correction; @@ -34,7 +35,7 @@ public interface IProposalRelevance { public static final int CREATE_LOCAL_PREFIX_OR_SUFFIX_MATCH= 10; public static final int CHANGE_NULLNESS_ANNOTATION= 10; - public static final int CHANGE_NULLNESS_ANNOTATION_IN_OVERRIDDEN_METHOD= 9; + public static final int CHANGE_NULLNESS_ANNOTATION_IN_OVERRIDDEN_METHOD= 9; public static final int REMOVE_FINAL_MODIFIER= 9; public static final int GETTER_SETTER_NOT_VISIBLE_FIELD= 9; public static final int ADD_MISSING_BODY= 9; @@ -234,6 +235,7 @@ public interface IProposalRelevance { public static final int CONVERT_IF_ELSE_TO_SWITCH= 1; public static final int DOCUMENT_UNUSED_ITEM= 1; public static final int PICK_SELECTED_STRING= 1; + public static final int COMBINE_STRINGS= 1; public static final int INVERSE_BOOLEAN_VARIABLE= 1; public static final int REMOVE_UNUSED_ALLOCATED_OBJECT= 1; public static final int UNWRAP_STATEMENTS= 1; |