diff --git a/idea/resources/postfixTemplates/KtAssertPostfixTemplate/after.kt.template b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/after.kt.template new file mode 100644 index 00000000000..51d130fa0e8 --- /dev/null +++ b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/after.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + assert(x) { "" } +} diff --git a/idea/resources/postfixTemplates/KtAssertPostfixTemplate/before.kt.template b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/before.kt.template new file mode 100644 index 00000000000..854b83b9867 --- /dev/null +++ b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/before.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + x$key +} diff --git a/idea/resources/postfixTemplates/KtAssertPostfixTemplate/description.html b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/description.html new file mode 100644 index 00000000000..2a472356ab7 --- /dev/null +++ b/idea/resources/postfixTemplates/KtAssertPostfixTemplate/description.html @@ -0,0 +1,5 @@ + + +Creates assertion from boolean expression. + + diff --git a/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/after.kt.template b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/after.kt.template new file mode 100644 index 00000000000..e4fd8912a93 --- /dev/null +++ b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/after.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any) { + (x) +} diff --git a/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/before.kt.template b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/before.kt.template new file mode 100644 index 00000000000..e02133a444d --- /dev/null +++ b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/before.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any) { + x$key +} diff --git a/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/description.html b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/description.html new file mode 100644 index 00000000000..f3effd96dd9 --- /dev/null +++ b/idea/resources/postfixTemplates/KtParenthesizedPostfixTemplate/description.html @@ -0,0 +1,5 @@ + + +Parenthesizes expression. + + diff --git a/idea/resources/postfixTemplates/KtReturnPostfixTemplate/after.kt.template b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/after.kt.template new file mode 100644 index 00000000000..758b7a8796a --- /dev/null +++ b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/after.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any): Any { + return x +} diff --git a/idea/resources/postfixTemplates/KtReturnPostfixTemplate/before.kt.template b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/before.kt.template new file mode 100644 index 00000000000..20d13efe1b5 --- /dev/null +++ b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/before.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any): Any { + x$key +} diff --git a/idea/resources/postfixTemplates/KtReturnPostfixTemplate/description.html b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/description.html new file mode 100644 index 00000000000..0aa3f235664 --- /dev/null +++ b/idea/resources/postfixTemplates/KtReturnPostfixTemplate/description.html @@ -0,0 +1,5 @@ + + +Creates return statement. + + diff --git a/idea/resources/postfixTemplates/KtSoutPostfixTemplate/after.kt.template b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/after.kt.template new file mode 100644 index 00000000000..06b4adf6d45 --- /dev/null +++ b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/after.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any) { + println(x) +} diff --git a/idea/resources/postfixTemplates/KtSoutPostfixTemplate/before.kt.template b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/before.kt.template new file mode 100644 index 00000000000..e02133a444d --- /dev/null +++ b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/before.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Any) { + x$key +} diff --git a/idea/resources/postfixTemplates/KtSoutPostfixTemplate/description.html b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/description.html new file mode 100644 index 00000000000..6dccf2606eb --- /dev/null +++ b/idea/resources/postfixTemplates/KtSoutPostfixTemplate/description.html @@ -0,0 +1,5 @@ + + +Creates println() call. + + diff --git a/idea/resources/postfixTemplates/KtWhilePostfixTemplate/after.kt.template b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/after.kt.template new file mode 100644 index 00000000000..7f3c4aa1561 --- /dev/null +++ b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/after.kt.template @@ -0,0 +1,5 @@ +fun foo(x: Boolean) { + while(x) { + + } +} diff --git a/idea/resources/postfixTemplates/KtWhilePostfixTemplate/before.kt.template b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/before.kt.template new file mode 100644 index 00000000000..854b83b9867 --- /dev/null +++ b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/before.kt.template @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + x$key +} diff --git a/idea/resources/postfixTemplates/KtWhilePostfixTemplate/description.html b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/description.html new file mode 100644 index 00000000000..cd69eb2a83a --- /dev/null +++ b/idea/resources/postfixTemplates/KtWhilePostfixTemplate/description.html @@ -0,0 +1,5 @@ + + +Creates while statement from boolean expression. + + diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt index 6a84ad86950..3f6b81a9f01 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KtPostfixTemplateProvider.kt @@ -46,7 +46,12 @@ class KtPostfixTemplateProvider : PostfixTemplateProvider { KtIntroduceVariablePostfixTemplate("val"), KtIntroduceVariablePostfixTemplate("var"), KtForEachPostfixTemplate("for"), - KtForEachPostfixTemplate("iter") + KtForEachPostfixTemplate("iter"), + KtAssertPostfixTemplate, + KtParenthesizedPostfixTemplate, + KtSoutPostfixTemplate, + KtReturnPostfixTemplate, + KtWhilePostfixTemplate ) override fun isTerminalSymbol(currentChar: Char) = currentChar == '.' || currentChar == '!' diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/stringBasedPostfixTemplates.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/stringBasedPostfixTemplates.kt index ff2466bdde4..f44b15712cb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/stringBasedPostfixTemplates.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/postfix/stringBasedPostfixTemplates.kt @@ -19,28 +19,76 @@ package org.jetbrains.kotlin.idea.codeInsight.postfix import com.intellij.codeInsight.template.Template import com.intellij.codeInsight.template.impl.ConstantNode import com.intellij.codeInsight.template.impl.MacroCallNode +import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateExpressionSelector import com.intellij.codeInsight.template.postfix.templates.StringBasedPostfixTemplate import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.liveTemplates.macro.SuggestVariableNameMacro import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.typeUtil.isBoolean import org.jetbrains.kotlin.types.typeUtil.isIterator import org.jetbrains.kotlin.util.OperatorNameConventions +internal abstract class ConstantStringBasedPostfixTemplate( + name: String, + desc: String, + private val template: String, + selector: PostfixTemplateExpressionSelector +) : StringBasedPostfixTemplate(name, desc, selector) { + override fun getTemplateString(element: PsiElement) = template + + override fun getElementToRemove(expr: PsiElement?) = expr +} + internal class KtForEachPostfixTemplate( name: String -) : StringBasedPostfixTemplate(name, "for (item in expr)", createExpressionSelector(statementsOnly = true, predicate = KotlinType::containsIteratorMethod)) { - override fun getTemplateString(element: PsiElement) = "for (\$name$ in \$expr$) {\n \$END$\n}" - +) : ConstantStringBasedPostfixTemplate( + name, + "for (item in expr)", + "for (\$name$ in \$expr$) {\n \$END$\n}", + createExpressionSelector(statementsOnly = true, predicate = KotlinType::containsIteratorMethod) +) { override fun setVariables(template: Template, element: PsiElement) { val name = MacroCallNode(SuggestVariableNameMacro()) template.addVariable("name", name, ConstantNode("item"), true) } - - override fun getElementToRemove(expr: PsiElement?) = expr } private fun KotlinType.containsIteratorMethod() = memberScope.getContributedFunctions(OperatorNameConventions.ITERATOR, NoLookupLocation.FROM_IDE).any { it.returnType?.isIterator() ?: false && it.valueParameters.isEmpty() } + +internal object KtAssertPostfixTemplate : ConstantStringBasedPostfixTemplate( + "assert", + "assert(expr) { \"\" }", + "assert(\$expr$) { \"\$END$\" }", + createExpressionSelector(statementsOnly = false, predicate = KotlinType::isBoolean) +) + +internal object KtParenthesizedPostfixTemplate : ConstantStringBasedPostfixTemplate( + "par", "(expr)", + "(\$expr$)\$END$", + createExpressionSelector(statementsOnly = false) +) + +internal object KtSoutPostfixTemplate : ConstantStringBasedPostfixTemplate( + "sout", + "println(expr)", + "println(\$expr$)\$END$", + createExpressionSelector(statementsOnly = true) +) + +internal object KtReturnPostfixTemplate : ConstantStringBasedPostfixTemplate( + "return", + "return expr", + "return \$expr$\$END$", + createExpressionSelector(statementsOnly = false) +) + +internal object KtWhilePostfixTemplate : ConstantStringBasedPostfixTemplate( + "while", + "while (expr) {}", + "while (\$expr$) {\n\$END$\n}", + createExpressionSelector(statementsOnly = true, predicate = KotlinType::isBoolean) +) diff --git a/idea/testData/codeInsight/postfix/assert.kt b/idea/testData/codeInsight/postfix/assert.kt new file mode 100644 index 00000000000..8147a758105 --- /dev/null +++ b/idea/testData/codeInsight/postfix/assert.kt @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + x.assert +} diff --git a/idea/testData/codeInsight/postfix/assert.kt.after b/idea/testData/codeInsight/postfix/assert.kt.after new file mode 100644 index 00000000000..3eea2ce1d62 --- /dev/null +++ b/idea/testData/codeInsight/postfix/assert.kt.after @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + assert(x) { "" } +} diff --git a/idea/testData/codeInsight/postfix/par.kt b/idea/testData/codeInsight/postfix/par.kt new file mode 100644 index 00000000000..1e4b68f742c --- /dev/null +++ b/idea/testData/codeInsight/postfix/par.kt @@ -0,0 +1,3 @@ +fun foo(x: Any) { + x.par +} diff --git a/idea/testData/codeInsight/postfix/par.kt.after b/idea/testData/codeInsight/postfix/par.kt.after new file mode 100644 index 00000000000..ba2617ccc2a --- /dev/null +++ b/idea/testData/codeInsight/postfix/par.kt.after @@ -0,0 +1,3 @@ +fun foo(x: Any) { + (x) +} diff --git a/idea/testData/codeInsight/postfix/return.kt b/idea/testData/codeInsight/postfix/return.kt new file mode 100644 index 00000000000..f5b53fe3799 --- /dev/null +++ b/idea/testData/codeInsight/postfix/return.kt @@ -0,0 +1,3 @@ +fun foo(x: Any): Any { + x.return +} diff --git a/idea/testData/codeInsight/postfix/return.kt.after b/idea/testData/codeInsight/postfix/return.kt.after new file mode 100644 index 00000000000..758b7a8796a --- /dev/null +++ b/idea/testData/codeInsight/postfix/return.kt.after @@ -0,0 +1,3 @@ +fun foo(x: Any): Any { + return x +} diff --git a/idea/testData/codeInsight/postfix/sout.kt b/idea/testData/codeInsight/postfix/sout.kt new file mode 100644 index 00000000000..c0e15536581 --- /dev/null +++ b/idea/testData/codeInsight/postfix/sout.kt @@ -0,0 +1,3 @@ +fun foo(x: Any) { + x.sout +} diff --git a/idea/testData/codeInsight/postfix/sout.kt.after b/idea/testData/codeInsight/postfix/sout.kt.after new file mode 100644 index 00000000000..459bc272a05 --- /dev/null +++ b/idea/testData/codeInsight/postfix/sout.kt.after @@ -0,0 +1,3 @@ +fun foo(x: Any) { + println(x) +} diff --git a/idea/testData/codeInsight/postfix/while.kt b/idea/testData/codeInsight/postfix/while.kt new file mode 100644 index 00000000000..bb03d80c9cb --- /dev/null +++ b/idea/testData/codeInsight/postfix/while.kt @@ -0,0 +1,3 @@ +fun foo(x: Boolean) { + x.while +} diff --git a/idea/testData/codeInsight/postfix/while.kt.after b/idea/testData/codeInsight/postfix/while.kt.after new file mode 100644 index 00000000000..457cbc80849 --- /dev/null +++ b/idea/testData/codeInsight/postfix/while.kt.after @@ -0,0 +1,5 @@ +fun foo(x: Boolean) { + while (x) { + + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java index d1aef6ea8c7..d689f6f4545 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/postfix/PostfixTemplateProviderTestGenerated.java @@ -35,6 +35,12 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/codeInsight/postfix"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("assert.kt") + public void testAssert() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/assert.kt"); + doTest(fileName); + } + @TestMetadata("else.kt") public void testElse() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/else.kt"); @@ -83,6 +89,24 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat doTest(fileName); } + @TestMetadata("par.kt") + public void testPar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/par.kt"); + doTest(fileName); + } + + @TestMetadata("return.kt") + public void testReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/return.kt"); + doTest(fileName); + } + + @TestMetadata("sout.kt") + public void testSout() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/sout.kt"); + doTest(fileName); + } + @TestMetadata("try.kt") public void testTry() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/try.kt"); @@ -106,4 +130,10 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/when.kt"); doTest(fileName); } + + @TestMetadata("while.kt") + public void testWhile() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/while.kt"); + doTest(fileName); + } }