mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[python] postfix templates: make 'for' and 'len' editable (PY-30217)
GitOrigin-RevId: a92252f98e45799b03f6b39b22c3a02b5270bd0c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
56b09dadab
commit
4d0cedd933
@@ -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<PyPostfixTemplateExpressionCondition?>, topmost: Boolean, provider: PostfixTemplateProvider,
|
||||
private val myBuiltin: Boolean) : EditablePostfixTemplateWithMultipleExpressions<PyPostfixTemplateExpressionCondition?>(
|
||||
open class PyEditablePostfixTemplate(templateId: String, templateName: String, liveTemplate: TemplateImpl, example: String,
|
||||
conditions: Set<PyPostfixTemplateExpressionCondition?>, topmost: Boolean, provider: PostfixTemplateProvider,
|
||||
private val builtin: Boolean) : EditablePostfixTemplateWithMultipleExpressions<PyPostfixTemplateExpressionCondition?>(
|
||||
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 {
|
||||
|
||||
@@ -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<PsiElement> = 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()
|
||||
}
|
||||
|
||||
@@ -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<PsiElement> = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
<caret>
|
||||
@@ -1,3 +1,3 @@
|
||||
def f(a:list):
|
||||
for i in a:
|
||||
for e in a:
|
||||
<caret>
|
||||
@@ -1,2 +1,2 @@
|
||||
for i in []:
|
||||
for e in []:
|
||||
<caret>
|
||||
@@ -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:
|
||||
<caret>
|
||||
@@ -1,3 +1,3 @@
|
||||
def f(a:list):
|
||||
for i in a:
|
||||
for e in a:
|
||||
<caret>
|
||||
@@ -1,2 +1,2 @@
|
||||
for i in []:
|
||||
for e in []:
|
||||
<caret>
|
||||
@@ -1 +1 @@
|
||||
foo = "something".len<caret>
|
||||
foo = "something".len<caret>
|
||||
|
||||
@@ -1 +1 @@
|
||||
foo = len("something")
|
||||
foo = len("something")
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"first": 1, "second": 2}.len<caret>
|
||||
{"first": 1, "second": 2}.len<caret>
|
||||
|
||||
@@ -1 +1 @@
|
||||
len({"first": 1, "second": 2})
|
||||
len({"first": 1, "second": 2})
|
||||
|
||||
@@ -1 +1 @@
|
||||
[1, 2, 3, 4].len<caret>
|
||||
[1, 2, 3, 4].len<caret>
|
||||
|
||||
@@ -1 +1 @@
|
||||
len([1, 2, 3, 4])
|
||||
len([1, 2, 3, 4])
|
||||
|
||||
@@ -2,4 +2,4 @@ class MyNotSizedClass:
|
||||
pass
|
||||
|
||||
|
||||
MyNotSizedClass().len<caret>
|
||||
MyNotSizedClass().len<caret>
|
||||
|
||||
@@ -2,4 +2,4 @@ class MyNotSizedClass:
|
||||
pass
|
||||
|
||||
|
||||
MyNotSizedClass().len
|
||||
MyNotSizedClass().len
|
||||
|
||||
@@ -3,4 +3,4 @@ class MySizedClass:
|
||||
pass
|
||||
|
||||
|
||||
MySizedClass().len<caret>
|
||||
MySizedClass().len<caret>
|
||||
|
||||
@@ -3,4 +3,4 @@ class MySizedClass:
|
||||
pass
|
||||
|
||||
|
||||
MySizedClass.len<caret>
|
||||
MySizedClass.len<caret>
|
||||
|
||||
@@ -3,4 +3,4 @@ class MySizedClass:
|
||||
pass
|
||||
|
||||
|
||||
MySizedClass.len
|
||||
MySizedClass.len
|
||||
|
||||
@@ -3,4 +3,4 @@ class MySizedClass:
|
||||
pass
|
||||
|
||||
|
||||
len(MySizedClass())
|
||||
len(MySizedClass())
|
||||
|
||||
@@ -1 +1 @@
|
||||
"something".len<caret>
|
||||
"something".len<caret>
|
||||
|
||||
@@ -1 +1 @@
|
||||
len("something")
|
||||
len("something")
|
||||
|
||||
@@ -1 +1 @@
|
||||
(1, 2, 3, 4).len<caret>
|
||||
(1, 2, 3, 4).len<caret>
|
||||
|
||||
@@ -1 +1 @@
|
||||
len((1, 2, 3, 4))
|
||||
len((1, 2, 3, 4))
|
||||
|
||||
Reference in New Issue
Block a user