From 1618027e48191a93a2e3549f263fece039ce880e Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Tue, 3 Apr 2012 17:48:32 +0400 Subject: [PATCH] IDEA-83877 Broken 'Convert to GString' intention --- ...onvertConcatenationToGstringIntention.java | 24 ++++-- .../groovy/lang/psi/util/GrStringUtil.java | 10 ++- .../ConvertConcatenationToGstringTest.groovy | 81 +++++++++++++++++++ .../ConvertConcatenationToGstringTest.java | 80 ------------------ 4 files changed, 106 insertions(+), 89 deletions(-) create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.groovy delete mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java index ed5e8306e136..8e51b604fe8b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertConcatenationToGstringIntention.java @@ -35,6 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrRegex; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; @@ -87,14 +88,24 @@ public class ConvertConcatenationToGstringIntention extends Intention { } private static void getOperandText(@Nullable GrExpression operand, StringBuilder builder) { - if (operand instanceof GrString) { + if (operand instanceof GrRegex) { + StringBuilder b = new StringBuilder(); + GrStringUtil.parseRegexCharacters(GrStringUtil.removeQuotes(operand.getText()), b, null, operand.getText().startsWith("/")); + GrStringUtil.escapeSymbolsForGString(b, false, false); + } + else if (operand instanceof GrString) { builder.append(GrStringUtil.removeQuotes(operand.getText())); } else if (operand instanceof GrLiteral) { - final String text = GrStringUtil.removeQuotes(operand.getText()); + Object value = ((GrLiteral)operand).getValue(); + if (value == null) { + value = GrStringUtil.removeQuotes(operand.getText()); + } + + String text = value.toString(); StringBuilder buffer = new StringBuilder(text.length()); boolean containsLineFeeds = text.indexOf('\n') >= 0 || text.indexOf('\r') >= 0; - GrStringUtil.escapeStringCharacters(text.length(), text, "$", false, false, buffer); + GrStringUtil.escapeStringCharacters(text.length(), text, "$", false, true, buffer); GrStringUtil.unescapeCharacters(buffer, containsLineFeeds?"'\"":"'", containsLineFeeds); builder.append(buffer); } @@ -164,8 +175,10 @@ public class ConvertConcatenationToGstringIntention extends Intention { } public static boolean satisfiedBy(PsiElement element, boolean checkForParent) { - if (element instanceof GrLiteral && element.getText().startsWith("'")) return true; + if (element instanceof GrString || element instanceof GrLiteral && ((GrLiteral)element).getValue() instanceof String) return true; + if (!(element instanceof GrBinaryExpression)) return false; + GrBinaryExpression binaryExpression = (GrBinaryExpression)element; if (!GroovyTokenTypes.mPLUS.equals(binaryExpression.getOperationTokenType())) return false; @@ -180,9 +193,8 @@ public class ConvertConcatenationToGstringIntention extends Intention { final PsiType type = binaryExpression.getType(); if (type == null) return false; - final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject()); final PsiClassType stringType = TypesUtil.createType(CommonClassNames.JAVA_LANG_STRING, element); - final PsiClassType gstringType = factory.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_GSTRING, element.getResolveScope()); + final PsiClassType gstringType = TypesUtil.createType(GroovyCommonClassNames.GROOVY_LANG_GSTRING, element); if (!(TypeConversionUtil.isAssignable(stringType, type) || TypeConversionUtil.isAssignable(gstringType, type))) return false; return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java index 9658515a2ac7..7e942d05510d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java @@ -242,13 +242,17 @@ public class GrStringUtil { buffer.append(hexCode); } - public static String escapeSymbolsForGString(String s, boolean isSingleLine, boolean forInjection) { + public static String escapeSymbolsForGString(CharSequence s, boolean isSingleLine, boolean forInjection) { StringBuilder b = new StringBuilder(); + escapeSymbolsForGString(s, isSingleLine, forInjection, b); + return b.toString(); + } + + private static void escapeSymbolsForGString(CharSequence s, boolean isSingleLine, boolean forInjection, StringBuilder b) { escapeStringCharacters(s.length(), s, isSingleLine ? "$\"" : "$", isSingleLine, true, b); if (!forInjection) { unescapeCharacters(b, isSingleLine ? "'" : "'\"", true); } - return b.toString(); } public static String escapeSymbolsForString(String s, boolean isSingleLine, boolean forInjection) { @@ -262,7 +266,7 @@ public class GrStringUtil { @NotNull public static StringBuilder escapeStringCharacters(int length, - @NotNull String str, + @NotNull CharSequence str, @Nullable String additionalChars, boolean escapeLineFeeds, boolean escapeBackSlash, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.groovy new file mode 100644 index 000000000000..8ced6af5abaf --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.groovy @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.plugins.groovy.intentions; + + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author Maxim.Medvedev + */ +public class ConvertConcatenationToGstringTest extends GrIntentionTestCase { + + private static final String CONVERT_TO_GSTRING = "Convert to GString"; + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY").modifiableModel; + final VirtualFile groovyJar = JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.mockGroovy1_7LibraryName + "!/"); + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); + modifiableModel.commit(); + } + }; + } + + @Override + protected String getBasePath() { + return "${TestUtils.testDataPath}intentions/convertConcatenationToGstring/"; + } + + public void testSimpleCase() throws Exception { + doTest(CONVERT_TO_GSTRING, true); + } + + public void testVeryComplicatedCase() throws Exception { + doTest(CONVERT_TO_GSTRING, true); + } + + public void testQuotes() throws Exception { + doTest(CONVERT_TO_GSTRING, true); + } + + public void testQuotes2() throws Exception { + doTest(CONVERT_TO_GSTRING, true); + } + + public void _testQuotesInMultilineString() throws Exception { + doTest(CONVERT_TO_GSTRING, true); + } + + public void testDot() { + doTest(CONVERT_TO_GSTRING, true); + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.java deleted file mode 100644 index 6823a76f6b94..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ConvertConcatenationToGstringTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.plugins.groovy.intentions; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.util.TestUtils; - -/** - * @author Maxim.Medvedev - */ -public class ConvertConcatenationToGstringTest extends GrIntentionTestCase { - - private static final String CONVERT_TO_GSTRING = "Convert to GString"; - - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return new DefaultLightProjectDescriptor() { - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); - final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); - modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); - modifiableModel.commit(); - } - }; - } - - @Override - protected String getBasePath() { - return TestUtils.getTestDataPath() + "intentions/convertConcatenationToGstring/"; - } - - public void testSimpleCase() throws Exception { - doTest(CONVERT_TO_GSTRING, true); - } - - public void testVeryComplicatedCase() throws Exception { - doTest(CONVERT_TO_GSTRING, true); - } - - public void testQuotes() throws Exception { - doTest(CONVERT_TO_GSTRING, true); - } - - public void testQuotes2() throws Exception { - doTest(CONVERT_TO_GSTRING, true); - } - - public void testQuotesInMultilineString() throws Exception { - doTest(CONVERT_TO_GSTRING, true); - } - - public void testDot() { - doTest(CONVERT_TO_GSTRING, true); - } -}