Move specific diagnostics infrastructure to frontend.common-psi
This commit is contained in:
+1
-1
@@ -117,7 +117,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"
|
||||
|
||||
companion object {
|
||||
const val importToAdd = "org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies"
|
||||
const val importToAdd = "org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.config.LanguageFeature.ProhibitJvmOverloadsOnConstru
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitSpreadOnSignaturePolymorphicCall
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RepeatableAnnotationContainerConstraints
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
+1
-1
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
|
||||
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.modalityModifier
|
||||
import org.jetbrains.kotlin.diagnostics.overrideModifier
|
||||
import org.jetbrains.kotlin.diagnostics.visibilityModifier
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.diagnostics.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.KtPsiSourceElement
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.getAncestors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.nameIdentifier
|
||||
import org.jetbrains.kotlin.diagnostics.getAncestors
|
||||
import org.jetbrains.kotlin.diagnostics.nameIdentifier
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.hasValOrVar
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.hasValOrVar
|
||||
import org.jetbrains.kotlin.diagnostics.hasVar
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.hasPrimaryConstructor
|
||||
import org.jetbrains.kotlin.diagnostics.hasPrimaryConstructor
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.implicitModality
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDeclarationSyntaxChecker
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier
|
||||
import org.jetbrains.kotlin.diagnostics.modalityModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.overrideModifier
|
||||
import org.jetbrains.kotlin.diagnostics.visibilityModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.typeParametersList
|
||||
import org.jetbrains.kotlin.diagnostics.typeParametersList
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.KtLightSourceElement
|
||||
import org.jetbrains.kotlin.KtPsiSourceElement
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.nameIdentifier
|
||||
import org.jetbrains.kotlin.diagnostics.typeParametersList
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.typeParametersList
|
||||
import org.jetbrains.kotlin.diagnostics.typeParametersList
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
-1395
File diff suppressed because it is too large
Load Diff
-105
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.TokenType
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE
|
||||
|
||||
open class LightTreePositioningStrategy {
|
||||
open fun markKtDiagnostic(element: KtSourceElement, diagnostic: KtDiagnostic): List<TextRange> {
|
||||
return mark(element.lighterASTNode, element.startOffset, element.endOffset, element.treeStructure)
|
||||
}
|
||||
|
||||
open fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
return markElement(node, startOffset, endOffset, tree)
|
||||
}
|
||||
|
||||
open fun isValid(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
|
||||
return !hasSyntaxErrors(node, tree)
|
||||
}
|
||||
}
|
||||
|
||||
fun markElement(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
originalNode: LighterASTNode = node,
|
||||
): List<TextRange> = markRange(node, node, startOffset, endOffset, tree, originalNode)
|
||||
|
||||
fun markRange(
|
||||
from: LighterASTNode,
|
||||
to: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
originalNode: LighterASTNode
|
||||
): List<TextRange> {
|
||||
return listOf(markSingleElement(from, to, startOffset, endOffset, tree, originalNode))
|
||||
}
|
||||
|
||||
fun markSingleElement(
|
||||
from: LighterASTNode,
|
||||
to: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
originalNode: LighterASTNode
|
||||
): TextRange {
|
||||
val betterFrom = from.nonFillerFirstChildOrSelf(tree)
|
||||
val betterTo = to.nonFillerLastChildOrSelf(tree)
|
||||
val startDelta = tree.getStartOffset(betterFrom) - tree.getStartOffset(originalNode)
|
||||
val endDelta = tree.getEndOffset(betterTo) - tree.getEndOffset(originalNode)
|
||||
return TextRange(startDelta + startOffset, endDelta + endOffset)
|
||||
}
|
||||
|
||||
private val DOC_AND_COMMENT_TOKENS = setOf(
|
||||
WHITE_SPACE, KtTokens.IDENTIFIER,
|
||||
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.nonFillerFirstChildOrSelf(tree: FlyweightCapableTreeStructure<LighterASTNode>): LighterASTNode =
|
||||
getChildren(tree).firstOrNull { !it.isFiller() } ?: this
|
||||
|
||||
internal fun LighterASTNode.nonFillerLastChildOrSelf(tree: FlyweightCapableTreeStructure<LighterASTNode>): LighterASTNode =
|
||||
getChildren(tree).lastOrNull { !it.isFiller() } ?: this
|
||||
|
||||
internal fun LighterASTNode.isFiller() = tokenType in FILLER_TOKENS
|
||||
|
||||
private fun hasSyntaxErrors(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
|
||||
if (node.tokenType == TokenType.ERROR_ELEMENT) return true
|
||||
|
||||
val childrenRef = Ref<Array<LighterASTNode?>?>()
|
||||
tree.getChildren(node, childrenRef)
|
||||
val children = childrenRef.get() ?: return false
|
||||
return children.filterNotNull().lastOrNull {
|
||||
val tokenType = it.tokenType
|
||||
tokenType !is KtSingleValueToken && tokenType !in DOC_AND_COMMENT_TOKENS
|
||||
}?.let { hasSyntaxErrors(it, tree) } == true
|
||||
}
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.KtPsiSourceElement
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.cfg.UnreachableCode
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticMarker
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticWithParameters2
|
||||
import org.jetbrains.kotlin.diagnostics.PositioningStrategy
|
||||
import org.jetbrains.kotlin.psi
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
|
||||
|
||||
object PsiPositioningStrategies {
|
||||
val UNREACHABLE_CODE = object : PositioningStrategy<PsiElement>() {
|
||||
override fun markDiagnostic(diagnostic: DiagnosticMarker): List<TextRange> {
|
||||
//todo it is better to implement arguments extraction in KtDiagnosticFactory, but kotlin struggle with checking types in it atm
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val typed = diagnostic as KtDiagnosticWithParameters2<Set<KtSourceElement>, Set<KtSourceElement>>
|
||||
val source = diagnostic.element as KtPsiSourceElement
|
||||
return UnreachableCode.getUnreachableTextRanges(
|
||||
source.psi as KtElement,
|
||||
typed.a.mapNotNull { it.psi as? KtElement }.toSet(),
|
||||
typed.b.mapNotNull { it.psi as? KtElement }.toSet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val ACTUAL_DECLARATION_NAME = object : PositioningStrategy<PsiElement>() {
|
||||
override fun markDiagnostic(diagnostic: DiagnosticMarker): List<TextRange> {
|
||||
require(diagnostic is KtDiagnostic)
|
||||
val element = diagnostic.element.psi ?: return emptyList()
|
||||
(element as? KtNamedDeclaration)?.nameIdentifier?.let { nameIdentifier ->
|
||||
return mark(nameIdentifier)
|
||||
}
|
||||
return mark(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
-350
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.AbstractSourceElementPositioningStrategy
|
||||
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
|
||||
|
||||
object SourceElementPositioningStrategies {
|
||||
val DEFAULT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DEFAULT,
|
||||
PositioningStrategies.DEFAULT
|
||||
).also {
|
||||
AbstractSourceElementPositioningStrategy.setDefault(it)
|
||||
}
|
||||
|
||||
val VAL_OR_VAR_NODE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.VAL_OR_VAR_NODE,
|
||||
PositioningStrategies.VAL_OR_VAR_NODE
|
||||
)
|
||||
|
||||
val FUN_INTERFACE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.FUN_INTERFACE,
|
||||
PositioningStrategies.FUN_INTERFACE
|
||||
)
|
||||
|
||||
val COMPANION_OBJECT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.COMPANION_OBJECT,
|
||||
PositioningStrategies.COMPANION_OBJECT
|
||||
)
|
||||
|
||||
val SECONDARY_CONSTRUCTOR_DELEGATION_CALL = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL,
|
||||
PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL
|
||||
)
|
||||
|
||||
val DECLARATION_RETURN_TYPE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_RETURN_TYPE,
|
||||
PositioningStrategies.DECLARATION_RETURN_TYPE
|
||||
)
|
||||
|
||||
val DECLARATION_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_NAME,
|
||||
PositioningStrategies.DECLARATION_NAME
|
||||
)
|
||||
|
||||
val DECLARATION_SIGNATURE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_SIGNATURE,
|
||||
PositioningStrategies.DECLARATION_SIGNATURE
|
||||
)
|
||||
|
||||
val DECLARATION_SIGNATURE_OR_DEFAULT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT,
|
||||
PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT
|
||||
)
|
||||
|
||||
val VISIBILITY_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.VISIBILITY_MODIFIER,
|
||||
PositioningStrategies.VISIBILITY_MODIFIER
|
||||
)
|
||||
|
||||
val MODALITY_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.MODALITY_MODIFIER,
|
||||
PositioningStrategies.MODALITY_MODIFIER
|
||||
)
|
||||
|
||||
val ABSTRACT_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ABSTRACT_MODIFIER,
|
||||
PositioningStrategies.ABSTRACT_MODIFIER
|
||||
)
|
||||
|
||||
val OPEN_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.OPEN_MODIFIER,
|
||||
PositioningStrategies.OPEN_MODIFIER
|
||||
)
|
||||
|
||||
val OVERRIDE_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.OVERRIDE_MODIFIER,
|
||||
PositioningStrategies.OVERRIDE_MODIFIER
|
||||
)
|
||||
|
||||
val PRIVATE_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.PRIVATE_MODIFIER,
|
||||
PositioningStrategies.PRIVATE_MODIFIER
|
||||
)
|
||||
|
||||
val LATEINIT_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.LATEINIT_MODIFIER,
|
||||
PositioningStrategies.LATEINIT_MODIFIER
|
||||
)
|
||||
|
||||
val VARIANCE_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.VARIANCE_MODIFIER,
|
||||
PositioningStrategies.VARIANCE_MODIFIER
|
||||
)
|
||||
|
||||
val CONST_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.CONST_MODIFIER,
|
||||
PositioningStrategies.CONST_MODIFIER
|
||||
)
|
||||
|
||||
val INLINE_OR_VALUE_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.INLINE_OR_VALUE_MODIFIER,
|
||||
PositioningStrategies.INLINE_OR_VALUE_MODIFIER
|
||||
)
|
||||
|
||||
val INNER_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.INNER_MODIFIER,
|
||||
PositioningStrategies.INNER_MODIFIER
|
||||
)
|
||||
|
||||
val FUN_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.FUN_MODIFIER,
|
||||
PositioningStrategies.FUN_MODIFIER
|
||||
)
|
||||
|
||||
val SUSPEND_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SUSPEND_MODIFIER,
|
||||
PositioningStrategies.SUSPEND_MODIFIER
|
||||
)
|
||||
|
||||
val DATA_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DATA_MODIFIER,
|
||||
PositioningStrategies.DATA_MODIFIER
|
||||
)
|
||||
|
||||
val OPERATOR = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.OPERATOR,
|
||||
PositioningStrategies.OPERATOR
|
||||
)
|
||||
|
||||
val PARAMETER_DEFAULT_VALUE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.PARAMETER_DEFAULT_VALUE,
|
||||
PositioningStrategies.PARAMETER_DEFAULT_VALUE
|
||||
)
|
||||
|
||||
val PARAMETER_VARARG_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.PARAMETER_VARARG_MODIFIER,
|
||||
PositioningStrategies.PARAMETER_VARARG_MODIFIER
|
||||
)
|
||||
|
||||
val NAME_OF_NAMED_ARGUMENT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.NAME_OF_NAMED_ARGUMENT,
|
||||
PositioningStrategies.NAME_OF_NAMED_ARGUMENT
|
||||
)
|
||||
|
||||
val VALUE_ARGUMENTS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.VALUE_ARGUMENTS,
|
||||
PositioningStrategies.VALUE_ARGUMENTS
|
||||
)
|
||||
|
||||
val SUPERTYPES_LIST = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SUPERTYPES_LIST,
|
||||
PositioningStrategies.SUPERTYPES_LIST
|
||||
)
|
||||
|
||||
val DOT_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DOT_BY_QUALIFIED,
|
||||
PositioningStrategies.DOT_BY_QUALIFIED
|
||||
)
|
||||
|
||||
val SELECTOR_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SELECTOR_BY_QUALIFIED,
|
||||
PositioningStrategies.SELECTOR_BY_QUALIFIED
|
||||
)
|
||||
|
||||
val REFERENCE_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.REFERENCE_BY_QUALIFIED,
|
||||
PositioningStrategies.REFERENCE_BY_QUALIFIED
|
||||
)
|
||||
|
||||
val REFERENCED_NAME_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.REFERENCED_NAME_BY_QUALIFIED,
|
||||
PositioningStrategies.REFERENCED_NAME_BY_QUALIFIED
|
||||
)
|
||||
|
||||
val WHEN_EXPRESSION = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.WHEN_EXPRESSION,
|
||||
PositioningStrategies.WHEN_EXPRESSION
|
||||
)
|
||||
|
||||
val IF_EXPRESSION = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.IF_EXPRESSION,
|
||||
PositioningStrategies.IF_EXPRESSION
|
||||
)
|
||||
|
||||
val ELSE_ENTRY = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ELSE_ENTRY,
|
||||
PositioningStrategies.ELSE_ENTRY
|
||||
)
|
||||
|
||||
val ARRAY_ACCESS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ARRAY_ACCESS,
|
||||
PositioningStrategies.ARRAY_ACCESS
|
||||
)
|
||||
|
||||
val SAFE_ACCESS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SAFE_ACCESS,
|
||||
PositioningStrategies.SAFE_ACCESS
|
||||
)
|
||||
|
||||
val AS_TYPE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.AS_TYPE,
|
||||
PositioningStrategies.AS_TYPE
|
||||
)
|
||||
|
||||
val USELESS_ELVIS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.USELESS_ELVIS,
|
||||
PositioningStrategies.USELESS_ELVIS
|
||||
)
|
||||
|
||||
val RETURN_WITH_LABEL = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.RETURN_WITH_LABEL,
|
||||
PositioningStrategies.RETURN_WITH_LABEL
|
||||
)
|
||||
|
||||
val PROPERTY_INITIALIZER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.LAST_CHILD,
|
||||
PositioningStrategies.PROPERTY_INITIALIZER
|
||||
)
|
||||
|
||||
val WHOLE_ELEMENT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.WHOLE_ELEMENT,
|
||||
PositioningStrategies.WHOLE_ELEMENT
|
||||
)
|
||||
|
||||
val LONG_LITERAL_SUFFIX = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.LONG_LITERAL_SUFFIX,
|
||||
PositioningStrategies.LONG_LITERAL_SUFFIX
|
||||
)
|
||||
|
||||
val REIFIED_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.REIFIED_MODIFIER,
|
||||
PositioningStrategies.REIFIED_MODIFIER
|
||||
)
|
||||
|
||||
val TYPE_PARAMETERS_LIST = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.TYPE_PARAMETERS_LIST,
|
||||
PositioningStrategies.TYPE_PARAMETERS_LIST
|
||||
)
|
||||
|
||||
val NAME_IDENTIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.NAME_IDENTIFIER,
|
||||
PositioningStrategies.NAME_IDENTIFIER
|
||||
)
|
||||
|
||||
val QUESTION_MARK_BY_TYPE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.QUESTION_MARK_BY_TYPE,
|
||||
PositioningStrategies.QUESTION_MARK_BY_TYPE
|
||||
)
|
||||
|
||||
val ANNOTATION_USE_SITE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ANNOTATION_USE_SITE,
|
||||
PositioningStrategies.ANNOTATION_USE_SITE
|
||||
)
|
||||
|
||||
val ASSIGNMENT_LHS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ASSIGNMENT_LHS,
|
||||
PositioningStrategies.ASSIGNMENT_LHS
|
||||
)
|
||||
|
||||
val IMPORT_LAST_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.IMPORT_LAST_NAME,
|
||||
PositioningStrategies.IMPORT_LAST_NAME
|
||||
)
|
||||
|
||||
val SPREAD_OPERATOR = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SPREAD_OPERATOR,
|
||||
PositioningStrategies.SPREAD_OPERATOR
|
||||
)
|
||||
|
||||
val DECLARATION_WITH_BODY = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_WITH_BODY,
|
||||
PositioningStrategies.DECLARATION_WITH_BODY
|
||||
)
|
||||
val COMMAS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.COMMAS,
|
||||
PositioningStrategies.COMMAS
|
||||
)
|
||||
|
||||
val UNREACHABLE_CODE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.UNREACHABLE_CODE,
|
||||
PsiPositioningStrategies.UNREACHABLE_CODE
|
||||
)
|
||||
|
||||
val ACTUAL_DECLARATION_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ACTUAL_DECLARATION_NAME,
|
||||
PsiPositioningStrategies.ACTUAL_DECLARATION_NAME
|
||||
)
|
||||
|
||||
val LABEL = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.LABEL,
|
||||
PositioningStrategies.LABEL
|
||||
)
|
||||
|
||||
// TODO
|
||||
val INCOMPATIBLE_DECLARATION = DEFAULT
|
||||
|
||||
val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT,
|
||||
PositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT
|
||||
)
|
||||
|
||||
val INLINE_PARAMETER_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER,
|
||||
PositioningStrategies.INLINE_PARAMETER_MODIFIER
|
||||
)
|
||||
|
||||
val OPERATOR_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.OPERATOR_MODIFIER,
|
||||
PositioningStrategies.OPERATOR_MODIFIER
|
||||
)
|
||||
|
||||
val NON_FINAL_MODIFIER_OR_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.NON_FINAL_MODIFIER_OR_NAME,
|
||||
PositioningStrategies.NON_FINAL_MODIFIER_OR_NAME
|
||||
)
|
||||
|
||||
val ENUM_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ENUM_MODIFIER,
|
||||
PositioningStrategies.ENUM_MODIFIER
|
||||
)
|
||||
|
||||
val FIELD_KEYWORD = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.FIELD_KEYWORD,
|
||||
PositioningStrategies.FIELD_KEYWORD
|
||||
)
|
||||
|
||||
val TAILREC_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.TAILREC_MODIFIER,
|
||||
PositioningStrategies.TAILREC_MODIFIER
|
||||
)
|
||||
|
||||
val PROPERTY_DELEGATE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.PROPERTY_DELEGATE,
|
||||
PositioningStrategies.PROPERTY_DELEGATE
|
||||
)
|
||||
|
||||
val IMPORT_ALIAS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.IMPORT_ALIAS,
|
||||
PositioningStrategies.IMPORT_ALIAS
|
||||
)
|
||||
|
||||
val DECLARATION_START_TO_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DECLARATION_START_TO_NAME,
|
||||
PositioningStrategies.DECLARATION_START_TO_NAME
|
||||
)
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.KtLightSourceElement
|
||||
import org.jetbrains.kotlin.KtPsiSourceElement
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.AbstractSourceElementPositioningStrategy
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.PositioningStrategy
|
||||
|
||||
class SourceElementPositioningStrategy(
|
||||
private val lightTreeStrategy: LightTreePositioningStrategy,
|
||||
private val psiStrategy: PositioningStrategy<*>
|
||||
) : AbstractSourceElementPositioningStrategy() {
|
||||
override fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> {
|
||||
return when (val element = diagnostic.element) {
|
||||
is KtPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic)
|
||||
is KtLightSourceElement -> lightTreeStrategy.markKtDiagnostic(element, diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isValid(element: KtSourceElement): Boolean {
|
||||
return when (element) {
|
||||
is KtPsiSourceElement -> psiStrategy.hackyIsValid(element.psi)
|
||||
is KtLightSourceElement -> lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure)
|
||||
}
|
||||
}
|
||||
|
||||
private fun PositioningStrategy<*>.hackyIsValid(psi: PsiElement): Boolean {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (this as PositioningStrategy<PsiElement>).isValid(psi)
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
typealias Node = LighterASTNode
|
||||
|
||||
class UnreachableCodeLightTreeHelper(val tree: FlyweightCapableTreeStructure<Node>) {
|
||||
|
||||
fun Node.hasChildrenInSet(set: Set<Node>): Boolean {
|
||||
var result = false
|
||||
tree.traverseDescendants(this) {
|
||||
if (!result && it != this && it in set) {
|
||||
result = true
|
||||
}
|
||||
!result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun Node.getLeavesOrReachableChildren(reachable: Set<Node>, unreachable: Set<Node>): List<Node> {
|
||||
val result = mutableListOf<Node>()
|
||||
tree.traverseDescendants(this) { element ->
|
||||
val isReachable = element in reachable && !element.hasChildrenInSet(unreachable)
|
||||
if (isReachable || element.getChildren(tree).isEmpty()) {
|
||||
result.add(element)
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun List<Node>.removeReachableElementsWithMeaninglessSiblings(reachableElements: Set<Node>): List<Node> {
|
||||
val childrenToRemove = mutableSetOf<Node>()
|
||||
fun collectSiblingsIfMeaningless(elementIndex: Int, direction: Int) {
|
||||
val index = elementIndex + direction
|
||||
if (index !in 0 until size) return
|
||||
|
||||
val element = this[index]
|
||||
if (element.isFiller() || element.tokenType == KtTokens.COMMA) {
|
||||
childrenToRemove.add(element)
|
||||
collectSiblingsIfMeaningless(index, direction)
|
||||
}
|
||||
}
|
||||
for ((index, element) in this.withIndex()) {
|
||||
if (reachableElements.contains(element)) {
|
||||
childrenToRemove.add(element)
|
||||
collectSiblingsIfMeaningless(index, -1)
|
||||
collectSiblingsIfMeaningless(index, 1)
|
||||
}
|
||||
}
|
||||
return filter { it !in childrenToRemove }
|
||||
}
|
||||
|
||||
fun List<TextRange>.mergeAdjacentTextRanges(): List<TextRange> {
|
||||
val result = ArrayList<TextRange>()
|
||||
val lastRange = fold(null as TextRange?) { currentTextRange, elementRange ->
|
||||
when {
|
||||
currentTextRange == null -> {
|
||||
elementRange
|
||||
}
|
||||
currentTextRange.endOffset == elementRange.startOffset -> {
|
||||
currentTextRange.union(elementRange)
|
||||
}
|
||||
else -> {
|
||||
result.add(currentTextRange)
|
||||
elementRange
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastRange != null) {
|
||||
result.add(lastRange)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user