mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-18 20:41:22 +07:00
[python] PY-7292 folding for cython
GitOrigin-RevId: aa71655356e64e8375c74bf038ca492d787c8058
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d6d7c0c3f3
commit
0c3f10457b
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python
|
||||
|
||||
import com.intellij.codeInsight.folding.CodeFoldingSettings
|
||||
@@ -9,7 +9,7 @@ import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.FoldingGroup
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.LineTokenizer.Companion.tokenize
|
||||
import com.intellij.openapi.util.text.LineTokenizer
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
@@ -19,7 +19,7 @@ import com.jetbrains.python.ast.*
|
||||
import com.jetbrains.python.psi.PyStringLiteralCoreUtil
|
||||
import kotlin.math.max
|
||||
|
||||
class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
open class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
override fun buildLanguageFoldRegions(
|
||||
descriptors: MutableList<FoldingDescriptor?>,
|
||||
root: PsiElement,
|
||||
@@ -38,7 +38,7 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
val prefix = stringLiteralExpression.stringElements[0].prefix
|
||||
if (stringLiteralExpression.isDocString()) {
|
||||
val stringValue = stringLiteralExpression.stringValue.trim { it <= ' ' }
|
||||
val lines = tokenize(stringValue, true)
|
||||
val lines = LineTokenizer.tokenize(stringValue, true)
|
||||
if (lines.size > 2 && lines[1].trim { it <= ' ' }.isEmpty()) {
|
||||
return prefix + "\"\"\"" + lines[0].trim { it <= ' ' } + "...\"\"\""
|
||||
}
|
||||
@@ -57,11 +57,12 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
}
|
||||
val elementType = node.elementType
|
||||
if (elementType === PyElementTypes.STRING_LITERAL_EXPRESSION) {
|
||||
if (getDocStringOwnerType(node) === PyElementTypes.FUNCTION_DECLARATION && CodeFoldingSettings.getInstance().COLLAPSE_METHODS) {
|
||||
val docStringOwnerType = getDocStringOwnerType(node)
|
||||
if (isFunction(docStringOwnerType) && CodeFoldingSettings.getInstance().COLLAPSE_METHODS) {
|
||||
// method will be collapsed, no need to also collapse docstring
|
||||
return false
|
||||
}
|
||||
if (getDocStringOwnerType(node) != null) {
|
||||
if (docStringOwnerType != null) {
|
||||
return CodeFoldingSettings.getInstance().COLLAPSE_DOC_COMMENTS
|
||||
}
|
||||
return PythonFoldingSettings.getInstance().isCollapseLongStrings
|
||||
@@ -72,12 +73,15 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
if (elementType === PyElementTypes.ANNOTATION) {
|
||||
return PythonFoldingSettings.getInstance().isCollapseTypeAnnotations
|
||||
}
|
||||
if (elementType === PyElementTypes.STATEMENT_LIST && node.treeParent.elementType === PyElementTypes.FUNCTION_DECLARATION) {
|
||||
if (elementType === PyElementTypes.STATEMENT_LIST && isFunction(node.treeParent.elementType)) {
|
||||
return CodeFoldingSettings.getInstance().COLLAPSE_METHODS
|
||||
}
|
||||
if (elementType in FOLDABLE_COLLECTIONS_LITERALS) {
|
||||
return PythonFoldingSettings.getInstance().isCollapseLongCollections
|
||||
}
|
||||
if (isLanguageSpecificFoldableBlock(elementType)) {
|
||||
return CodeFoldingSettings.getInstance().COLLAPSE_METHODS
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -89,6 +93,10 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
return node.psi is PyAstFile || node.elementType === PyElementTypes.STATEMENT_LIST
|
||||
}
|
||||
|
||||
protected open fun isLanguageSpecificFoldableBlock(elementType: IElementType): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun appendDescriptors(node: ASTNode, descriptors: MutableList<FoldingDescriptor?>) {
|
||||
val elementType = node.elementType
|
||||
if (node.psi is PyAstFile) {
|
||||
@@ -122,6 +130,13 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
FoldingGroup.newGroup(PYTHON_TYPE_ANNOTATION_GROUP_NAME)))
|
||||
}
|
||||
}
|
||||
else if (isLanguageSpecificFoldableBlock(elementType)) {
|
||||
val nodeRange = node.textRange
|
||||
if (!nodeRange.isEmpty) {
|
||||
val colon = node.findChildByType(PyTokenTypes.COLON)
|
||||
foldSegment(node, descriptors, nodeRange, colon)
|
||||
}
|
||||
}
|
||||
var child = node.firstChildNode
|
||||
while (child != null) {
|
||||
appendDescriptors(child, descriptors)
|
||||
@@ -212,18 +227,20 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
return
|
||||
}
|
||||
|
||||
val elType = node.treeParent.elementType
|
||||
if (elType === PyElementTypes.FUNCTION_DECLARATION || elType === PyElementTypes.CLASS_DECLARATION || checkFoldBlocks(node, elType)) {
|
||||
val parentType = node.treeParent.elementType
|
||||
if (isFunction(parentType) || isClass(parentType) || checkFoldBlocks(node, parentType)) {
|
||||
val colon = node.treeParent.findChildByType(PyTokenTypes.COLON)
|
||||
foldSegment(node, descriptors, nodeRange, colon)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFoldBlocks(statementList: ASTNode, parentType: IElementType): Boolean {
|
||||
protected open fun checkFoldBlocks(statementList: ASTNode, parentType: IElementType): Boolean {
|
||||
val element = statementList.psi
|
||||
assert(element is PyAstStatementList)
|
||||
|
||||
return parentType in PyElementTypes.PARTS || parentType === PyElementTypes.WITH_STATEMENT || parentType === PyElementTypes.CASE_CLAUSE
|
||||
return parentType in PyElementTypes.PARTS ||
|
||||
parentType === PyElementTypes.WITH_STATEMENT ||
|
||||
parentType === PyElementTypes.CASE_CLAUSE
|
||||
}
|
||||
|
||||
private fun foldLongStrings(node: ASTNode, descriptors: MutableList<FoldingDescriptor?>) {
|
||||
@@ -235,15 +252,15 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDocStringOwnerType(node: ASTNode): IElementType? {
|
||||
protected open fun getDocStringOwnerType(node: ASTNode): IElementType? {
|
||||
val treeParent = node.treeParent
|
||||
val parentType = treeParent.elementType
|
||||
if (parentType === PyElementTypes.EXPRESSION_STATEMENT && treeParent.treeParent != null) {
|
||||
val parent2 = treeParent.treeParent
|
||||
if (parent2.elementType === PyElementTypes.STATEMENT_LIST && parent2.treeParent != null && treeParent === parent2.firstChildNode) {
|
||||
val parent3 = parent2.treeParent
|
||||
if (parent3.elementType === PyElementTypes.FUNCTION_DECLARATION || parent3.elementType === PyElementTypes.CLASS_DECLARATION) {
|
||||
return parent3.elementType
|
||||
val parent3 = parent2.treeParent.elementType
|
||||
if (isFunction(parent3) || isClass(parent3)) {
|
||||
return parent3
|
||||
}
|
||||
}
|
||||
else if (parent2 is PyAstFile) {
|
||||
@@ -262,10 +279,18 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
return "..."
|
||||
}
|
||||
|
||||
private fun isImport(node: ASTNode): Boolean {
|
||||
protected open fun isImport(node: ASTNode): Boolean {
|
||||
return node.elementType in PyElementTypes.IMPORT_STATEMENTS
|
||||
}
|
||||
|
||||
protected open fun isFunction(elementType: IElementType?): Boolean {
|
||||
return elementType === PyElementTypes.FUNCTION_DECLARATION
|
||||
}
|
||||
|
||||
protected open fun isClass(elementType: IElementType?): Boolean {
|
||||
return elementType === PyElementTypes.CLASS_DECLARATION
|
||||
}
|
||||
|
||||
companion object {
|
||||
val FOLDABLE_COLLECTIONS_LITERALS: TokenSet = TokenSet.create(
|
||||
PyElementTypes.SET_LITERAL_EXPRESSION,
|
||||
@@ -279,4 +304,4 @@ class PythonFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||
|
||||
const val PYTHON_TYPE_ANNOTATION_GROUP_NAME: String = "Python type annotation"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user