From 66adfbb1429a62b14d1be195c299e8791bca40da Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Thu, 5 Jul 2012 12:30:53 +0400 Subject: [PATCH] 'remove unnecessary escape characters from string' intention --- .../after.groovy.template | 1 + .../before.groovy.template | 1 + .../description.html | 5 + plugins/groovy/src/META-INF/plugin.xml | 5 + .../GroovyIntentionsBundle.properties | 2 + ...eUnnecessaryEscapeCharactersIntention.java | 126 ++++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/after.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/before.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/description.html create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/RemoveUnnecessaryEscapeCharactersIntention.java diff --git a/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/after.groovy.template new file mode 100644 index 000000000000..9925830bc471 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/after.groovy.template @@ -0,0 +1 @@ +print 'x = "abc"' \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/before.groovy.template new file mode 100644 index 000000000000..ab9fa45cb6ef --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/before.groovy.template @@ -0,0 +1 @@ +print 'x = \"abc\"' \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/description.html b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/description.html new file mode 100644 index 000000000000..6bfffe235dd2 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/RemoveUnnecessaryEscapeCharactersIntention/description.html @@ -0,0 +1,5 @@ + + +This intention removes unnecessary escape characters from a selected string. + + \ No newline at end of file diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 7bdeba76f59d..fcc2e9173aea 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1072,6 +1072,11 @@ intention.category.groovy/intention.category.conversions org.jetbrains.plugins.groovy.intentions.conversions.strings.GrConvertStringToCharIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.conversions + org.jetbrains.plugins.groovy.intentions.conversions.strings.RemoveUnnecessaryEscapeCharactersIntention + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle intention.category.groovy/intention.category.conversions diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index 6280a589d1a0..1dd19b4c38a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -165,3 +165,5 @@ gr.convert.string.to.char.intention.name=Cast to char gr.convert.string.to.char.intention.family.name=Cast to char create.field.for.parameter.0 = Create Field for Parameter {0} create.field.for.parameter=Create Field for Parameter +remove.unnecessary.escape.characters.intention.name=Remove unnecessary escape characters +remove.unnecessary.escape.characters.intention.family.name=Remove unnecessary escape characters diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/RemoveUnnecessaryEscapeCharactersIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/RemoveUnnecessaryEscapeCharactersIntention.java new file mode 100644 index 000000000000..4b5918e4524e --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/RemoveUnnecessaryEscapeCharactersIntention.java @@ -0,0 +1,126 @@ +/* + * 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.conversions.strings; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString; + +import static org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil.*; + +/** + * @author Max Medvedev + */ +public class RemoveUnnecessaryEscapeCharactersIntention extends Intention { + @Override + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { + final Document document = editor.getDocument(); + final TextRange range = element.getTextRange(); + + document.replaceString(range.getStartOffset(), range.getEndOffset(), removeUnnecessaryEscapeSymbols(((GrLiteral)element))); + } + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new PsiElementPredicate() { + @Override + public boolean satisfiedBy(PsiElement element) { + final String text = element.getText(); + return element instanceof GrLiteral && + getStartQuote(text) != null && + !removeUnnecessaryEscapeSymbols((GrLiteral)element).equals(text); + } + }; + } + + private static String removeUnnecessaryEscapeSymbols(final GrLiteral literal) { + final String text = literal.getText(); + final String quote = getStartQuote(text); + final String value = removeQuotes(text); + + final StringBuilder buffer = new StringBuilder(); + buffer.append(quote); + + if (quote == "'") { + escapeAndUnescapeSymbols(value, "", "\"$", buffer); + } + else if (quote == "'''") { + int position = buffer.length(); + escapeAndUnescapeSymbols(value, "", "\"'$n", buffer); + fixAllTripleQuotes(buffer, position); + } + else if (quote == "\"") { + if (literal instanceof GrString) { + final ASTNode node = literal.getNode(); + for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) { + final IElementType type = child.getElementType(); + if (type == GroovyTokenTypes.mGSTRING_BEGIN || type == GroovyTokenTypes.mGSTRING_END) continue; + if (type == GroovyElementTypes.GSTRING_INJECTION) { + buffer.append(child.getText()); + } + else { + escapeAndUnescapeSymbols(child.getText(), "", "'", buffer); + } + } + } + else { + escapeAndUnescapeSymbols(value, "", "'", buffer); + } + } + else if (quote == "\"\"\"") { + if (literal instanceof GrString) { + final ASTNode node = literal.getNode(); + for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) { + final IElementType type = child.getElementType(); + if (type == GroovyTokenTypes.mGSTRING_BEGIN || type == GroovyTokenTypes.mGSTRING_END) continue; + if (type == GroovyElementTypes.GSTRING_INJECTION) { + buffer.append(child.getText()); + } + else { + final int position = buffer.length(); + escapeAndUnescapeSymbols(value, "", "\"'n", buffer); + fixAllTripleDoubleQuotes(buffer, position); + } + } + } + else { + final int position = buffer.length(); + escapeAndUnescapeSymbols(value, "", "\"'n", buffer); + fixAllTripleDoubleQuotes(buffer, position); + } + } + else { + return text; + } + + buffer.append(quote); + + return buffer.toString(); + } +}