diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyEditablePostfixTemplate.kt b/python/src/com/jetbrains/python/codeInsight/postfix/PyEditablePostfixTemplate.kt index e5c604ec0a7c..1b0ab4eceaf6 100644 --- a/python/src/com/jetbrains/python/codeInsight/postfix/PyEditablePostfixTemplate.kt +++ b/python/src/com/jetbrains/python/codeInsight/postfix/PyEditablePostfixTemplate.kt @@ -8,9 +8,9 @@ import com.intellij.openapi.editor.Document import com.intellij.openapi.util.Conditions import com.intellij.psi.PsiElement -class PyEditablePostfixTemplate(templateId: String, templateName: String, liveTemplate: TemplateImpl, example: String, - conditions: Set, topmost: Boolean, provider: PostfixTemplateProvider, - private val myBuiltin: Boolean) : EditablePostfixTemplateWithMultipleExpressions( +open class PyEditablePostfixTemplate(templateId: String, templateName: String, liveTemplate: TemplateImpl, example: String, + conditions: Set, topmost: Boolean, provider: PostfixTemplateProvider, + private val builtin: Boolean) : EditablePostfixTemplateWithMultipleExpressions( templateId, templateName, liveTemplate, example, conditions, topmost, provider) { constructor(templateId: String, templateName: String, templateText: String, example: String, @@ -25,9 +25,7 @@ class PyEditablePostfixTemplate(templateId: String, templateName: String, liveTe return expressions.filter { condition.value(it) } } - override fun isBuiltin(): Boolean { - return myBuiltin - } + override fun isBuiltin(): Boolean = builtin override fun isEditable(): Boolean { return expressionConditions.all { diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyForPostfixTemplate.kt b/python/src/com/jetbrains/python/codeInsight/postfix/PyForPostfixTemplate.kt index 7847d57079e6..4ab2bb985a1d 100644 --- a/python/src/com/jetbrains/python/codeInsight/postfix/PyForPostfixTemplate.kt +++ b/python/src/com/jetbrains/python/codeInsight/postfix/PyForPostfixTemplate.kt @@ -1,32 +1,22 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.python.codeInsight.postfix +import com.intellij.codeInsight.template.Template +import com.intellij.codeInsight.template.impl.MacroCallNode +import com.intellij.codeInsight.template.impl.TextExpression +import com.intellij.codeInsight.template.impl.VariableNode import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateProvider -import com.intellij.codeInsight.template.postfix.templates.SurroundPostfixTemplateBase -import com.intellij.lang.surroundWith.Surrounder -import com.intellij.openapi.project.DumbService -import com.intellij.openapi.util.Condition import com.intellij.psi.PsiElement -import com.jetbrains.python.PyNames -import com.jetbrains.python.psi.PyExpression -import com.jetbrains.python.psi.types.PyABCUtil -import com.jetbrains.python.psi.types.TypeEvalContext -import com.jetbrains.python.refactoring.surround.surrounders.expressions.PyForExpressionSurrounder +import com.jetbrains.python.codeInsight.liveTemplates.CollectionElementNameMacro +class PyForPostfixTemplate(name: String, provider: PostfixTemplateProvider) : PyEditablePostfixTemplate( + name, name, "for \$VAR$ in \$EXPR$:\n \$END$", "for e in expr", + setOf(PyPostfixTemplateExpressionCondition.PyIterable()), false, provider, true) { -class PyForPostfixTemplate(name: String, provider: PostfixTemplateProvider) : SurroundPostfixTemplateBase( - name, "for e in expr", PyPostfixUtils.PY_PSI_INFO, PyPostfixUtils.selectorAllExpressionsWithCurrentOffset(iterableFilter), provider) { - companion object { - val iterableFilter: Condition = Condition { element -> - if (!DumbService.isDumb(element.project)) { - val expression = element as PyExpression - val context = TypeEvalContext.codeCompletion(expression.project, expression.containingFile) - val type = context.getType(expression) ?: return@Condition false - return@Condition PyABCUtil.isSubtype(type, PyNames.ITERABLE, context) - } - return@Condition false - } + override fun addTemplateVariables(element: PsiElement, template: Template) { + super.addTemplateVariables(element, template) + val name = MacroCallNode(CollectionElementNameMacro()) + name.addParameter(VariableNode("EXPR", null)) + template.addVariable("VAR", name, TextExpression("e"), true) } - - override fun getSurrounder(): Surrounder = PyForExpressionSurrounder() } diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyLenPostfixTemplate.kt b/python/src/com/jetbrains/python/codeInsight/postfix/PyLenPostfixTemplate.kt index f8ba67c3822e..2c17d24e8003 100644 --- a/python/src/com/jetbrains/python/codeInsight/postfix/PyLenPostfixTemplate.kt +++ b/python/src/com/jetbrains/python/codeInsight/postfix/PyLenPostfixTemplate.kt @@ -2,34 +2,12 @@ package com.jetbrains.python.codeInsight.postfix import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateProvider -import com.intellij.codeInsight.template.postfix.templates.SurroundPostfixTemplateBase -import com.intellij.lang.surroundWith.Surrounder -import com.intellij.openapi.project.DumbService -import com.intellij.openapi.util.Condition -import com.intellij.psi.PsiElement -import com.jetbrains.python.PyNames -import com.jetbrains.python.psi.PyExpression -import com.jetbrains.python.psi.types.PyABCUtil -import com.jetbrains.python.psi.types.TypeEvalContext -import com.jetbrains.python.refactoring.surround.surrounders.expressions.PyLenExpressionStatementSurrounder -class PyLenPostfixTemplate(provider: PostfixTemplateProvider) : SurroundPostfixTemplateBase( - "len", DESCR, PyPostfixUtils.PY_PSI_INFO, PyPostfixUtils.selectorAllExpressionsWithCurrentOffset(sizedFilter), provider) { - - override fun getSurrounder(): Surrounder = PyLenExpressionStatementSurrounder() +class PyLenPostfixTemplate(provider: PostfixTemplateProvider) : + PyEditablePostfixTemplate("len", "len", "len(\$EXPR$)\$END$", DESCR, + setOf(PyPostfixTemplateExpressionCondition.PyBuiltinLenApplicable()), false, provider, true) { companion object { const val DESCR = "len(expr)" - - val sizedFilter: Condition = Condition { element -> - - if (!DumbService.isDumb(element.project)) { - val expression = element as PyExpression - val context = TypeEvalContext.codeCompletion(expression.project, expression.containingFile) - val type = context.getType(expression) ?: return@Condition false - return@Condition PyABCUtil.isSubtype(type, PyNames.SIZED, context) - } - return@Condition false - } } } diff --git a/python/testData/postfix/for/complexExpression_after.py b/python/testData/postfix/for/complexExpression_after.py index 095f76498183..2379be64d9b3 100644 --- a/python/testData/postfix/for/complexExpression_after.py +++ b/python/testData/postfix/for/complexExpression_after.py @@ -1,3 +1,3 @@ def f(a:list, b:list, c:int): - for i in (2 * (a + b)) * c: + for e in (2 * (a + b)) * c: \ No newline at end of file diff --git a/python/testData/postfix/for/function_after.py b/python/testData/postfix/for/function_after.py index 00f85578daf0..f569ed486236 100644 --- a/python/testData/postfix/for/function_after.py +++ b/python/testData/postfix/for/function_after.py @@ -1,3 +1,3 @@ def f(a:list): - for i in a: + for e in a: \ No newline at end of file diff --git a/python/testData/postfix/for/topLevel_after.py b/python/testData/postfix/for/topLevel_after.py index 3200247ea62c..aa2aed878275 100644 --- a/python/testData/postfix/for/topLevel_after.py +++ b/python/testData/postfix/for/topLevel_after.py @@ -1,2 +1,2 @@ -for i in []: +for e in []: \ No newline at end of file diff --git a/python/testData/postfix/iter/complexExpression_after.py b/python/testData/postfix/iter/complexExpression_after.py index 095f76498183..2379be64d9b3 100644 --- a/python/testData/postfix/iter/complexExpression_after.py +++ b/python/testData/postfix/iter/complexExpression_after.py @@ -1,3 +1,3 @@ def f(a:list, b:list, c:int): - for i in (2 * (a + b)) * c: + for e in (2 * (a + b)) * c: \ No newline at end of file diff --git a/python/testData/postfix/iter/function_after.py b/python/testData/postfix/iter/function_after.py index 00f85578daf0..f569ed486236 100644 --- a/python/testData/postfix/iter/function_after.py +++ b/python/testData/postfix/iter/function_after.py @@ -1,3 +1,3 @@ def f(a:list): - for i in a: + for e in a: \ No newline at end of file diff --git a/python/testData/postfix/iter/topLevel_after.py b/python/testData/postfix/iter/topLevel_after.py index 3200247ea62c..aa2aed878275 100644 --- a/python/testData/postfix/iter/topLevel_after.py +++ b/python/testData/postfix/iter/topLevel_after.py @@ -1,2 +1,2 @@ -for i in []: +for e in []: \ No newline at end of file diff --git a/python/testData/postfix/len/asExpr.py b/python/testData/postfix/len/asExpr.py index af8589306742..1c4272544093 100644 --- a/python/testData/postfix/len/asExpr.py +++ b/python/testData/postfix/len/asExpr.py @@ -1 +1 @@ -foo = "something".len \ No newline at end of file +foo = "something".len diff --git a/python/testData/postfix/len/asExpr_after.py b/python/testData/postfix/len/asExpr_after.py index 06be9a9af121..cb8dd3cefa73 100644 --- a/python/testData/postfix/len/asExpr_after.py +++ b/python/testData/postfix/len/asExpr_after.py @@ -1 +1 @@ -foo = len("something") \ No newline at end of file +foo = len("something") diff --git a/python/testData/postfix/len/dict.py b/python/testData/postfix/len/dict.py index 1b29cfbeea73..f33e6a732237 100644 --- a/python/testData/postfix/len/dict.py +++ b/python/testData/postfix/len/dict.py @@ -1 +1 @@ -{"first": 1, "second": 2}.len \ No newline at end of file +{"first": 1, "second": 2}.len diff --git a/python/testData/postfix/len/dict_after.py b/python/testData/postfix/len/dict_after.py index 9edff2023988..c3ae34835504 100644 --- a/python/testData/postfix/len/dict_after.py +++ b/python/testData/postfix/len/dict_after.py @@ -1 +1 @@ -len({"first": 1, "second": 2}) \ No newline at end of file +len({"first": 1, "second": 2}) diff --git a/python/testData/postfix/len/list.py b/python/testData/postfix/len/list.py index 296d8fd7944a..5699b5155224 100644 --- a/python/testData/postfix/len/list.py +++ b/python/testData/postfix/len/list.py @@ -1 +1 @@ -[1, 2, 3, 4].len \ No newline at end of file +[1, 2, 3, 4].len diff --git a/python/testData/postfix/len/list_after.py b/python/testData/postfix/len/list_after.py index fbdb4f03d5b8..c29a3dce85fb 100644 --- a/python/testData/postfix/len/list_after.py +++ b/python/testData/postfix/len/list_after.py @@ -1 +1 @@ -len([1, 2, 3, 4]) \ No newline at end of file +len([1, 2, 3, 4]) diff --git a/python/testData/postfix/len/notSized.py b/python/testData/postfix/len/notSized.py index 252033ffa0e6..86a4192751ab 100644 --- a/python/testData/postfix/len/notSized.py +++ b/python/testData/postfix/len/notSized.py @@ -2,4 +2,4 @@ class MyNotSizedClass: pass -MyNotSizedClass().len \ No newline at end of file +MyNotSizedClass().len diff --git a/python/testData/postfix/len/notSized_after.py b/python/testData/postfix/len/notSized_after.py index d24b65982292..fe11e3575a7c 100644 --- a/python/testData/postfix/len/notSized_after.py +++ b/python/testData/postfix/len/notSized_after.py @@ -2,4 +2,4 @@ class MyNotSizedClass: pass -MyNotSizedClass().len \ No newline at end of file +MyNotSizedClass().len diff --git a/python/testData/postfix/len/sized.py b/python/testData/postfix/len/sized.py index 4cdbd7d0227c..8eb82f016582 100644 --- a/python/testData/postfix/len/sized.py +++ b/python/testData/postfix/len/sized.py @@ -3,4 +3,4 @@ class MySizedClass: pass -MySizedClass().len \ No newline at end of file +MySizedClass().len diff --git a/python/testData/postfix/len/sizedClassObj.py b/python/testData/postfix/len/sizedClassObj.py index cd06e9509d10..96cd6f225e58 100644 --- a/python/testData/postfix/len/sizedClassObj.py +++ b/python/testData/postfix/len/sizedClassObj.py @@ -3,4 +3,4 @@ class MySizedClass: pass -MySizedClass.len \ No newline at end of file +MySizedClass.len diff --git a/python/testData/postfix/len/sizedClassObj_after.py b/python/testData/postfix/len/sizedClassObj_after.py index 6f4fb66b3656..158bea8872c0 100644 --- a/python/testData/postfix/len/sizedClassObj_after.py +++ b/python/testData/postfix/len/sizedClassObj_after.py @@ -3,4 +3,4 @@ class MySizedClass: pass -MySizedClass.len \ No newline at end of file +MySizedClass.len diff --git a/python/testData/postfix/len/sized_after.py b/python/testData/postfix/len/sized_after.py index 5442242ca7f4..8a71461fe2f5 100644 --- a/python/testData/postfix/len/sized_after.py +++ b/python/testData/postfix/len/sized_after.py @@ -3,4 +3,4 @@ class MySizedClass: pass -len(MySizedClass()) \ No newline at end of file +len(MySizedClass()) diff --git a/python/testData/postfix/len/string.py b/python/testData/postfix/len/string.py index f2c3295699a7..637c5ec041e7 100644 --- a/python/testData/postfix/len/string.py +++ b/python/testData/postfix/len/string.py @@ -1 +1 @@ -"something".len \ No newline at end of file +"something".len diff --git a/python/testData/postfix/len/string_after.py b/python/testData/postfix/len/string_after.py index 91e17003228f..18598875f7a4 100644 --- a/python/testData/postfix/len/string_after.py +++ b/python/testData/postfix/len/string_after.py @@ -1 +1 @@ -len("something") \ No newline at end of file +len("something") diff --git a/python/testData/postfix/len/tuple.py b/python/testData/postfix/len/tuple.py index 9d244024fa0e..7a4a9aecde7e 100644 --- a/python/testData/postfix/len/tuple.py +++ b/python/testData/postfix/len/tuple.py @@ -1 +1 @@ -(1, 2, 3, 4).len \ No newline at end of file +(1, 2, 3, 4).len diff --git a/python/testData/postfix/len/tuple_after.py b/python/testData/postfix/len/tuple_after.py index 69340e93c409..d5c14e084714 100644 --- a/python/testData/postfix/len/tuple_after.py +++ b/python/testData/postfix/len/tuple_after.py @@ -1 +1 @@ -len((1, 2, 3, 4)) \ No newline at end of file +len((1, 2, 3, 4))