提交 03cb0c3c 编写于 作者: J Jinseong Jeon 提交者: Mikhail Glukhikh

FIR checker: introduce PropertyChecker alias

and use it to add diagnostic
ININITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION
上级 db65c787
......@@ -27,6 +27,7 @@ fun main(args: Array<String>) {
generateCheckersComponents(generationPath, declarationPackage, "FirDeclarationChecker") {
alias<FirDeclaration>("BasicDeclarationChecker")
alias<FirMemberDeclaration>("MemberDeclarationChecker")
alias<FirProperty>("PropertyChecker")
alias<FirRegularClass>("RegularClassChecker")
alias<FirConstructor>("ConstructorChecker")
alias<FirFile>("FileChecker")
......
......@@ -19,6 +19,8 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
get() = _basicDeclarationCheckers
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker>
get() = _memberDeclarationCheckers
override val propertyCheckers: Set<FirPropertyChecker>
get() = _propertyCheckers
override val regularClassCheckers: Set<FirRegularClassChecker>
get() = _regularClassCheckers
override val constructorCheckers: Set<FirConstructorChecker>
......@@ -32,6 +34,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
private val _basicDeclarationCheckers: MutableSet<FirBasicDeclarationChecker> = mutableSetOf()
private val _memberDeclarationCheckers: MutableSet<FirMemberDeclarationChecker> = mutableSetOf()
private val _propertyCheckers: MutableSet<FirPropertyChecker> = mutableSetOf()
private val _regularClassCheckers: MutableSet<FirRegularClassChecker> = mutableSetOf()
private val _constructorCheckers: MutableSet<FirConstructorChecker> = mutableSetOf()
private val _fileCheckers: MutableSet<FirFileChecker> = mutableSetOf()
......@@ -42,6 +45,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
internal fun register(checkers: DeclarationCheckers) {
_basicDeclarationCheckers += checkers.allBasicDeclarationCheckers
_memberDeclarationCheckers += checkers.allMemberDeclarationCheckers
_propertyCheckers += checkers.allPropertyCheckers
_regularClassCheckers += checkers.allRegularClassCheckers
_constructorCheckers += checkers.allConstructorCheckers
_fileCheckers += checkers.allFileCheckers
......
......@@ -21,6 +21,7 @@ abstract class DeclarationCheckers {
open val basicDeclarationCheckers: Set<FirBasicDeclarationChecker> = emptySet()
open val memberDeclarationCheckers: Set<FirMemberDeclarationChecker> = emptySet()
open val propertyCheckers: Set<FirPropertyChecker> = emptySet()
open val regularClassCheckers: Set<FirRegularClassChecker> = emptySet()
open val constructorCheckers: Set<FirConstructorChecker> = emptySet()
open val fileCheckers: Set<FirFileChecker> = emptySet()
......@@ -30,6 +31,7 @@ abstract class DeclarationCheckers {
@CheckersComponentInternal internal val allBasicDeclarationCheckers: Set<FirBasicDeclarationChecker> get() = basicDeclarationCheckers
@CheckersComponentInternal internal val allMemberDeclarationCheckers: Set<FirMemberDeclarationChecker> get() = memberDeclarationCheckers + allBasicDeclarationCheckers
@CheckersComponentInternal internal val allPropertyCheckers: Set<FirPropertyChecker> get() = propertyCheckers + allMemberDeclarationCheckers
@CheckersComponentInternal internal val allRegularClassCheckers: Set<FirRegularClassChecker> get() = regularClassCheckers + allMemberDeclarationCheckers
@CheckersComponentInternal internal val allConstructorCheckers: Set<FirConstructorChecker> get() = constructorCheckers + allMemberDeclarationCheckers
@CheckersComponentInternal internal val allFileCheckers: Set<FirFileChecker> get() = fileCheckers + allBasicDeclarationCheckers
......
......@@ -14,10 +14,12 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
typealias FirBasicDeclarationChecker = FirDeclarationChecker<FirDeclaration>
typealias FirMemberDeclarationChecker = FirDeclarationChecker<FirMemberDeclaration>
typealias FirPropertyChecker = FirDeclarationChecker<FirProperty>
typealias FirRegularClassChecker = FirDeclarationChecker<FirRegularClass>
typealias FirConstructorChecker = FirDeclarationChecker<FirConstructor>
typealias FirFileChecker = FirDeclarationChecker<FirFile>
/*
* 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.checkers.declaration
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.extended.report
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
object FirDestructuringDeclarationInitializerChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.name.isSpecial || declaration.name.asString() != "<destruct>") return
val source = declaration.source
if (source == null || source.kind is FirFakeSourceElementKind) return
if (source.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION) return
val needToReport =
when (val initializer = declaration.initializer) {
null -> true
is FirErrorExpression -> (initializer.diagnostic as? ConeSimpleDiagnostic)?.kind == DiagnosticKind.Syntax
else -> false
}
if (needToReport) {
reporter.report(source, FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION)
}
}
}
......@@ -22,7 +22,7 @@ class DeclarationCheckersDiagnosticComponent(
}
override fun visitProperty(property: FirProperty, data: CheckerContext) {
checkers.memberDeclarationCheckers.check(property, data, reporter)
(checkers.memberDeclarationCheckers + checkers.propertyCheckers).check(property, data, reporter)
}
override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) {
......
......@@ -166,6 +166,9 @@ object FirErrors {
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error1<FirSourceElement, PsiElement, FirPropertyAccessorSymbol>()
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error1<FirSourceElement, PsiElement, FirPropertyAccessorSymbol>()
// Destructuring declaration
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, PsiElement>()
// Control flow diagnostics
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
val WRONG_INVOCATION_KIND by warning3<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>, EventOccurrencesRange, EventOccurrencesRange>()
......
......@@ -41,6 +41,10 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirInapplicableLateinitChecker,
)
override val propertyCheckers: Set<FirPropertyChecker> = setOf(
FirDestructuringDeclarationInitializerChecker,
)
override val regularClassCheckers: Set<FirRegularClassChecker> = setOf(
FirTypeMismatchOnOverrideChecker,
FirMemberPropertyChecker,
......
......@@ -1071,13 +1071,13 @@ class DeclarationsConverter(
val entries = mutableListOf<FirVariable<*>>()
val source = destructingDeclaration.toFirSourceElement()
var firExpression: FirExpression =
buildErrorExpression(null, ConeSimpleDiagnostic("Destructuring declaration without initializer", DiagnosticKind.Syntax))
buildErrorExpression(null, ConeSimpleDiagnostic("Initializer required for destructuring declaration", DiagnosticKind.Syntax))
destructingDeclaration.forEachChildren {
when (it.tokenType) {
VAR_KEYWORD -> isVar = true
DESTRUCTURING_DECLARATION_ENTRY -> entries += convertDestructingDeclarationEntry(it)
else -> if (it.isExpression()) firExpression =
expressionConverter.getAsFirExpression(it, "Destructuring declaration without initializer")
expressionConverter.getAsFirExpression(it, "Initializer required for destructuring declaration")
}
}
......
......@@ -202,10 +202,13 @@ class RawFirBuilder(
)
}
private fun KtExpression?.toFirExpression(errorReason: String): FirExpression =
private fun KtExpression?.toFirExpression(
errorReason: String,
kind: DiagnosticKind = DiagnosticKind.ExpressionRequired,
): FirExpression =
if (stubMode) buildExpressionStub()
else convertSafe() ?: buildErrorExpression(
this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionRequired),
this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, kind),
)
private fun KtExpression.toFirStatement(errorReason: String): FirStatement =
......@@ -2061,7 +2064,7 @@ class RawFirBuilder(
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Unit): FirElement {
val baseVariable = generateTemporaryVariable(
baseSession, multiDeclaration.toFirSourceElement(), "destruct",
multiDeclaration.initializer.toFirExpression("Destructuring declaration without initializer"),
multiDeclaration.initializer.toFirExpression("Initializer required for destructuring declaration", DiagnosticKind.Syntax),
)
return generateDestructuringBlock(
baseSession,
......
fun useDeclaredVariables() {
val (<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>)
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (<!UNRESOLVED_REFERENCE!>a<!>, <!UNRESOLVED_REFERENCE!>b<!>)<!>
a
b
}
fun checkersShouldRun() {
val (<!UNRESOLVED_REFERENCE!>@A a<!>, <!UNRESOLVED_REFERENCE!>_<!>)
<!INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION!>val (<!UNRESOLVED_REFERENCE!>@A a<!>, <!UNRESOLVED_REFERENCE!>_<!>)<!>
}
annotation class A
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册