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);
+ }
}