2 Intentions for string templates:

the first removes curly braces from a simple name variable, ${x} -> $x
and the second does the opposite $x -> ${x}
This commit is contained in:
Tal Man
2014-02-08 19:20:25 -05:00
committed by Andrey Breslav
parent 559ea28a6b
commit 89779b5013
41 changed files with 342 additions and 6 deletions
@@ -350,6 +350,8 @@ fun main(args: Array<String>) {
model("intentions/removeUnnecessaryParentheses", testMethod = "doTestRemoveUnnecessaryParentheses")
model("intentions/replaceWithDotQualifiedMethodCall", testMethod = "doTestReplaceWithDotQualifiedMethodCall")
model("intentions/replaceWithInfixFunctionCall", testMethod = "doTestReplaceWithInfixFunctionCall")
model("intentions/removeCurlyBracesFromTemplate", testMethod = "doTestRemoveCurlyFromTemplate")
model("intentions/insertCurlyBracestsToTemplate", testMethod = "doTestInsertCurlyToTemplate")
}
testClass(javaClass<AbstractHierarchyTest>()) {
@@ -0,0 +1,3 @@
fun foo() {
val y = <spot>"${x}"</spot>
}
@@ -0,0 +1,3 @@
fun foo() {
val y = <spot>"$x"</spot>
}
@@ -0,0 +1,5 @@
<html>
<body>
This intention inserts curly braces around simple names in string templates
</body>
</html>
@@ -0,0 +1,3 @@
fun foo() {
val y = <spot>"$x"</spot>
}
@@ -0,0 +1,3 @@
fun foo() {
val y = <spot>"${x}"</spot>
}
@@ -0,0 +1,5 @@
<html>
<body>
This intention removes the unnecessary curly braces around simple names in string templates
</body>
</html>
+10
View File
@@ -475,6 +475,16 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.RemoveCurlyBracesFromTemplateIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.InsertCurlyBracesToTemplateIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.declarations.SplitPropertyDeclarationIntention</className>
<category>Kotlin</category>
@@ -217,6 +217,10 @@ change.function.signature.chooser.title=Choose signature
change.function.signature.action=Change function signature
remove.unnecessary.parentheses=Remove unnecessary parentheses
remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses
remove.unnecessary.curly.brackets.from.string.template=Remove curly braces from variable
remove.unnecessary.curly.brackets.from.string.template.family=Remove curly braces from variable
insert.curly.brackets.to.string.template=Insert curly braces around variable
insert.curly.brackets.to.string.template.family=Insert curly braces around variable
add.name.to.argument.family=Add Name to Argument
add.name.to.argument.single=Add name to argument\: ''{0}''
add.name.to.argument.multiple=Add name to argument...
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetSimpleNameStringTemplateEntry
import org.jetbrains.jet.lang.psi.JetPsiFactory
public class InsertCurlyBracesToTemplateIntention : JetSelfTargetingIntention<JetSimpleNameStringTemplateEntry>(
"insert.curly.brackets.to.string.template", javaClass()) {
override fun isApplicableTo(element: JetSimpleNameStringTemplateEntry): Boolean = true
override fun applyTo(element: JetSimpleNameStringTemplateEntry, editor: Editor) {
val expression = element.getExpression()
if (expression == null) return
element.replace(JetPsiFactory.createBlockStringTemplateEntry(element.getProject(), expression))
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetBlockStringTemplateEntry
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
import org.jetbrains.jet.lang.psi.JetPsiFactory
import java.util.regex.*
public class RemoveCurlyBracesFromTemplateIntention : JetSelfTargetingIntention<JetBlockStringTemplateEntry>(
"remove.unnecessary.curly.brackets.from.string.template", javaClass()) {
class object {
val pattern = Pattern.compile("[a-zA-Z0-9_].*")
}
override fun isApplicableTo(element: JetBlockStringTemplateEntry): Boolean {
val nextSiblingText = element.getNextSibling()?.getText()
if (nextSiblingText != null && pattern.matcher(nextSiblingText).matches()) return false
return element.getExpression()?.getOriginalElement() is JetSimpleNameExpression
}
override fun applyTo(element: JetBlockStringTemplateEntry, editor: Editor) {
val parent = element.getParent()
if (parent == null) return
val sb = StringBuilder()
for (ch in parent.getChildren()) {
val newText = if (ch == element) "\$${element.getExpression()?.getText()}" else "${ch.getText()}"
sb.append(newText)
}
val tripleQuotes = parent.getFirstChild()?.getText()?.startsWith("\"\"\"")
if (tripleQuotes == null) return
val newExpression = if (tripleQuotes) "\"\"\"${sb.toString()}\"\"\"" else "\"${sb.toString()}\""
parent.replace(JetPsiFactory.createExpression(element.getProject(), newExpression))
}
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
fun foo() {
val x = 4
val y = "<caret>hello"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>x"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "${x}"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "something$<caret>x.somethingelse"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "something${x}.somethingelse"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>x\n"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "${x}\n"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$x$<caret>x$x"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$x${x}$x"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = """$x$<caret>x$x"""
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = """$x${x}$x"""
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
fun foo() {
val x = "x"
val y = "$<caret>{x.length}"
}
@@ -0,0 +1,9 @@
// IS_APPLICABLE: false
fun foo() {
val x = X()
val y = "$<caret>{x.bar()}"
}
public class X() {
fun bar() : String = "bar"
}
@@ -0,0 +1,6 @@
// IS_APPLICABLE: false
fun foo() {
val x = 3
val z = 4
val y = "$<caret>{x + z}"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
fun foo() {
val x = 3
val y = "$<caret>{x}y"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
fun foo() {
val x = 3
val y = "$<caret>{x}_y"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>{x}"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$x"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>{x}.moretext"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>x.moretext"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>{x}\n"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$x\n"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$<caret>{x}() this is okay, x will not be thought of as a function call"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "$x() this is okay, x will not be thought of as a function call"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "text$<caret>{x} moretext"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = "text$x moretext"
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = """text$<caret>{x} moretext"""
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: true
fun foo() {
val x = 4
val y = """text$x moretext"""
}
@@ -110,6 +110,14 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes
doTestIntention(path, new RemoveUnnecessaryParenthesesIntention());
}
public void doTestRemoveCurlyFromTemplate(@NotNull String path) throws Exception {
doTestIntention(path, new RemoveCurlyBracesFromTemplateIntention());
}
public void doTestInsertCurlyToTemplate(@NotNull String path) throws Exception {
doTestIntention(path, new InsertCurlyBracesToTemplateIntention());
}
public void doTestConvertMemberToExtension(@NotNull String path) throws Exception {
doTestIntention(path, new ConvertMemberToExtension());
}
@@ -16,21 +16,18 @@
package org.jetbrains.jet.plugin.intentions;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import java.io.File;
import java.util.regex.Pattern;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@InnerTestClasses({CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class})
@InnerTestClasses({CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class, CodeTransformationTestGenerated.RemoveCurlyBracesFromTemplate.class})
public class CodeTransformationTestGenerated extends AbstractCodeTransformationTest {
@TestMetadata("idea/testData/intentions/branched/folding/ifToAssignment")
public static class IfToAssignment extends AbstractCodeTransformationTest {
@@ -1299,6 +1296,69 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT
}
@TestMetadata("idea/testData/intentions/removeCurlyBracesFromTemplate")
public static class RemoveCurlyBracesFromTemplate extends AbstractCodeTransformationTest {
public void testAllFilesPresentInRemoveCurlyBracesFromTemplate() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/removeCurlyBracesFromTemplate"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("necessaryBrackets1.kt")
public void testNecessaryBrackets1() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/necessaryBrackets1.kt");
}
@TestMetadata("necessaryBrackets2.kt")
public void testNecessaryBrackets2() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/necessaryBrackets2.kt");
}
@TestMetadata("necessaryBrackets3.kt")
public void testNecessaryBrackets3() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/necessaryBrackets3.kt");
}
@TestMetadata("necessaryBrackets4.kt")
public void testNecessaryBrackets4() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/necessaryBrackets4.kt");
}
@TestMetadata("necessaryBrackets5.kt")
public void testNecessaryBrackets5() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/necessaryBrackets5.kt");
}
@TestMetadata("unnecessaryBrackets1.kt")
public void testUnnecessaryBrackets1() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets1.kt");
}
@TestMetadata("unnecessaryBrackets2.kt")
public void testUnnecessaryBrackets2() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets2.kt");
}
@TestMetadata("unnecessaryBrackets3.kt")
public void testUnnecessaryBrackets3() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets3.kt");
}
@TestMetadata("unnecessaryBrackets4.kt")
public void testUnnecessaryBrackets4() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets4.kt");
}
@TestMetadata("unnecessaryBrackets5.kt")
public void testUnnecessaryBrackets5() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets5.kt");
}
@TestMetadata("unnecessaryBrackets6.kt")
public void testUnnecessaryBrackets6() throws Exception {
doTestRemoveCurlyFromTemplate("idea/testData/intentions/removeCurlyBracesFromTemplate/unnecessaryBrackets6.kt");
}
}
public static Test suite() {
TestSuite suite = new TestSuite("CodeTransformationTestGenerated");
suite.addTestSuite(IfToAssignment.class);
@@ -1325,6 +1385,7 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT
suite.addTestSuite(RemoveUnnecessaryParentheses.class);
suite.addTestSuite(ReplaceWithDotQualifiedMethodCall.class);
suite.addTestSuite(ReplaceWithInfixFunctionCall.class);
suite.addTestSuite(RemoveCurlyBracesFromTemplate.class);
return suite;
}
}