From 7084fec6513c5181bf28d9c3c36be640e936495c Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Thu, 15 Apr 2021 15:55:05 +0300 Subject: [PATCH] [FIR][LightTree] Position strategies fixes Skip leading comments in DEFAULT strategy Keep node offset 'padding' when getting child --- .../kotlin/fir/analysis/FirSourceUtils.kt | 9 ++++++++- .../LightTreePositioningStrategies.kt | 18 +++++++++--------- .../LightTreePositioningStrategy.kt | 17 ++++++++++------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceUtils.kt index c3b728ffced..a80f2af297f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceUtils.kt @@ -36,6 +36,13 @@ private fun FirPsiSourceElement<*>.getChild(types: Set, index: Int private fun FirLightSourceElement.getChild(types: Set, index: Int, depth: Int): FirSourceElement? { val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth) - return visitor.find(lighterASTNode)?.toFirLightSourceElement(treeStructure) + val childNode = visitor.find(lighterASTNode) ?: return null + //we need to keep 'padding' of parent node in child node + val offsetDelta = startOffset - lighterASTNode.startOffset + return childNode.toFirLightSourceElement( + treeStructure, + startOffset = childNode.startOffset + offsetDelta, + endOffset = childNode.endOffset + offsetDelta + ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index b19a4e37e80..bd9025e832c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -125,7 +125,12 @@ object LightTreePositioningStrategies { startOffset: Int, endOffset: Int, tree: FlyweightCapableTreeStructure - ): List { + ): List = markElement(getElementToMark(node, tree), startOffset, endOffset, tree, node) + + override fun isValid(node: LighterASTNode, tree: FlyweightCapableTreeStructure): Boolean = + super.isValid(getElementToMark(node, tree), tree) + + private fun getElementToMark(node: LighterASTNode, tree: FlyweightCapableTreeStructure): LighterASTNode { val (returnTypeRef, nameIdentifierOrPlaceHolder) = when { node.tokenType == KtNodeTypes.PROPERTY_ACCESSOR -> tree.typeReference(node) to tree.accessorNamePlaceholder(node) @@ -134,13 +139,7 @@ object LightTreePositioningStrategies { else -> null to null } - if (returnTypeRef != null) { - return markElement(returnTypeRef, startOffset, endOffset, tree, node) - } - if (nameIdentifierOrPlaceHolder != null) { - return markElement(nameIdentifierOrPlaceHolder, startOffset, endOffset, tree, node) - } - return DEFAULT.mark(node, startOffset, endOffset, tree) + return returnTypeRef ?: (nameIdentifierOrPlaceHolder ?: node) } } @@ -621,7 +620,8 @@ private fun FlyweightCapableTreeStructure.referenceExpression( getChildren(node, childrenRef) var result = childrenRef.get()?.firstOrNull { it?.tokenType == KtNodeTypes.REFERENCE_EXPRESSION || it?.tokenType == KtNodeTypes.CONSTRUCTOR_DELEGATION_REFERENCE || - it?.tokenType == KtNodeTypes.SUPER_EXPRESSION || it?.tokenType == KtNodeTypes.PARENTHESIZED + it?.tokenType == KtNodeTypes.SUPER_EXPRESSION || it?.tokenType == KtNodeTypes.PARENTHESIZED || + it?.tokenType == KtNodeTypes.ARRAY_ACCESS_EXPRESSION } while (locateReferencedName && result != null && result.tokenType == KtNodeTypes.PARENTHESIZED) { result = referenceExpression(result, locateReferencedName = true) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategy.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategy.kt index 971251f0885..93611e3d5f0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategy.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategy.kt @@ -36,12 +36,7 @@ fun markElement( endOffset: Int, tree: FlyweightCapableTreeStructure, originalNode: LighterASTNode = node, -): List { - if (node === originalNode) return listOf(TextRange(startOffset, endOffset)) - val startDelta = tree.getStartOffset(node) - tree.getStartOffset(originalNode) - val endDelta = tree.getEndOffset(node) - tree.getEndOffset(originalNode) - return listOf(TextRange(startDelta + startOffset, endDelta + endOffset)) -} +): List = markRange(node, node, startOffset, endOffset, tree, originalNode) fun markRange( from: LighterASTNode, @@ -62,8 +57,16 @@ private val DOC_AND_COMMENT_TOKENS = setOf( KtTokens.EOL_COMMENT, KtTokens.BLOCK_COMMENT, KtTokens.SHEBANG_COMMENT, KtTokens.DOC_COMMENT ) +private val FILLER_TOKENS = setOf( + KtTokens.WHITE_SPACE, + KtTokens.EOL_COMMENT, + KtTokens.BLOCK_COMMENT, + KtTokens.SHEBANG_COMMENT, + KtTokens.DOC_COMMENT, +) + private fun LighterASTNode.nonFillerChildOrSelf(tree: FlyweightCapableTreeStructure): LighterASTNode = - getChildren(tree).firstOrNull { it != null && it.tokenType !in DOC_AND_COMMENT_TOKENS } ?: this + getChildren(tree).firstOrNull { it != null && it.tokenType !in FILLER_TOKENS } ?: this private fun hasSyntaxErrors(node: LighterASTNode, tree: FlyweightCapableTreeStructure): Boolean {