diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt index 5b2fdfd39a6..37a46ae40bc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt @@ -11,36 +11,52 @@ import org.jetbrains.kotlin.fir.FirSourceElement import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty -fun warning0(): DiagnosticFactory0DelegateProvider { - return DiagnosticFactory0DelegateProvider(Severity.WARNING) +fun warning0( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory0DelegateProvider { + return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy) } -fun warning1(): DiagnosticFactory1DelegateProvider { - return DiagnosticFactory1DelegateProvider(Severity.WARNING) +fun warning1( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy) } -fun warning2(): DiagnosticFactory2DelegateProvider { - return DiagnosticFactory2DelegateProvider(Severity.WARNING) +fun warning2( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory2DelegateProvider { + return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy) } -fun warning3(): DiagnosticFactory3DelegateProvider { - return DiagnosticFactory3DelegateProvider(Severity.WARNING) +fun warning3( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory3DelegateProvider { + return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy) } -fun error0(): DiagnosticFactory0DelegateProvider { - return DiagnosticFactory0DelegateProvider(Severity.ERROR) +fun error0( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory0DelegateProvider { + return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy) } -fun error1(): DiagnosticFactory1DelegateProvider { - return DiagnosticFactory1DelegateProvider(Severity.ERROR) +fun error1( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy) } -fun error2(): DiagnosticFactory2DelegateProvider { - return DiagnosticFactory2DelegateProvider(Severity.ERROR) +fun error2( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory2DelegateProvider { + return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy) } -fun error3(): DiagnosticFactory3DelegateProvider { - return DiagnosticFactory3DelegateProvider(Severity.ERROR) +fun error3( + positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT +): DiagnosticFactory3DelegateProvider { + return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy) } /** @@ -48,52 +64,56 @@ fun error3(): * that takes `PsiElement` as first type parameter */ fun existing0(): DiagnosticFactory0DelegateProvider { - return DiagnosticFactory0DelegateProvider(Severity.ERROR) + return DiagnosticFactory0DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) } fun existing1(): DiagnosticFactory1DelegateProvider { - return DiagnosticFactory1DelegateProvider(Severity.ERROR) + return DiagnosticFactory1DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) } fun existing2(): DiagnosticFactory2DelegateProvider { - return DiagnosticFactory2DelegateProvider(Severity.ERROR) + return DiagnosticFactory2DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) } fun existing3(): DiagnosticFactory3DelegateProvider { - return DiagnosticFactory3DelegateProvider(Severity.ERROR) + return DiagnosticFactory3DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) } // ------------------------------ Providers ------------------------------ class DiagnosticFactory0DelegateProvider( - private val severity: Severity + private val severity: Severity, + private val positioningStrategy: LightTreePositioningStrategy ) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { - return DummyDelegate(FirDiagnosticFactory0(prop.name, severity)) + return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy)) } } class DiagnosticFactory1DelegateProvider( - private val severity: Severity + private val severity: Severity, + private val positioningStrategy: LightTreePositioningStrategy ) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { - return DummyDelegate(FirDiagnosticFactory1(prop.name, severity)) + return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy)) } } class DiagnosticFactory2DelegateProvider( - private val severity: Severity + private val severity: Severity, + private val positioningStrategy: LightTreePositioningStrategy ) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { - return DummyDelegate(FirDiagnosticFactory2(prop.name, severity)) + return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy)) } } class DiagnosticFactory3DelegateProvider( - private val severity: Severity + private val severity: Severity, + private val positioningStrategy: LightTreePositioningStrategy ) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { - return DummyDelegate(FirDiagnosticFactory3(prop.name, severity)) + return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy)) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index fe86388ba59..f2756bf2506 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -91,7 +91,7 @@ object FirErrors { val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by existing0() val NOT_AN_ANNOTATION_CLASS by error1() val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing0() - val VAR_ANNOTATION_PARAMETER by existing0() + val VAR_ANNOTATION_PARAMETER by error0(LightTreePositioningStrategies.VAL_OR_VAR_NODE) // Exposed visibility group val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3() 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 new file mode 100644 index 00000000000..fe159417118 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -0,0 +1,35 @@ +/* + * 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.tree.IElementType +import com.intellij.psi.tree.TokenSet +import com.intellij.util.diff.FlyweightCapableTreeStructure +import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET + +object LightTreePositioningStrategies { + val VAL_OR_VAR_NODE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { + override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure): List { + val target = tree.findChildByType(node, VAL_VAR_TOKEN_SET) ?: node + return markElement(target, tree) + } + } +} + +fun FlyweightCapableTreeStructure.findChildByType(node: LighterASTNode, type: IElementType): LighterASTNode? { + val childrenRef = Ref>() + getChildren(node, childrenRef) + return childrenRef.get()?.firstOrNull { it.tokenType == type } +} + +fun FlyweightCapableTreeStructure.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? { + val childrenRef = Ref>() + getChildren(node, childrenRef) + return childrenRef.get()?.firstOrNull { it.tokenType in type } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSourceElement.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSourceElement.kt index 63a8fd8b640..39f672433b3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSourceElement.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSourceElement.kt @@ -188,7 +188,13 @@ sealed class FirPsiSourceElement(val psi: P) : FirSourceElem node.unwrap().psi.parent?.node?.let { TreeBackedLighterAST.wrap(it) } override fun getChildren(node: LighterASTNode, nodesRef: Ref>): Int { - val children = node.unwrap().psi.children + val psi = node.unwrap().psi + val children = mutableListOf() + var child = psi.firstChild + while (child != null) { + children += child + child = child.nextSibling + } if (children.isEmpty()) { nodesRef.set(LighterASTNode.EMPTY_ARRAY) } else { diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtParameter.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtParameter.java index d7f191b7e1a..bd49aceb1eb 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtParameter.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtParameter.java @@ -129,7 +129,7 @@ public class KtParameter extends KtNamedDeclarationStub imp return findChildByType(KtNodeTypes.DESTRUCTURING_DECLARATION); } - private static final TokenSet VAL_VAR_TOKEN_SET = TokenSet.create(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD); + public static final TokenSet VAL_VAR_TOKEN_SET = TokenSet.create(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD); @Override public ItemPresentation getPresentation() {