[FIR] Refactor: extract ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT checker
...into separate object. ^KT-62559
This commit is contained in:
committed by
Space Team
parent
3e88fc80d2
commit
a466b14264
+1
@@ -29,6 +29,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirExposedVisibilityDeclarationChecker,
|
||||
FirCyclicTypeBoundsChecker,
|
||||
FirExpectActualDeclarationChecker,
|
||||
FirActualAnnotationsMatchExpectChecker,
|
||||
FirAmbiguousAnonymousTypeChecker,
|
||||
FirExplicitApiDeclarationChecker,
|
||||
FirAnnotationChecker,
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.InternalDiagnosticFactoryMethod
|
||||
import org.jetbrains.kotlin.diagnostics.requireNotNull
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.getSingleMatchedExpectForActualOrNull
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.expectActualMatchingContextFactory
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
||||
|
||||
// TODO(Roman.Efremov): KT-62559 prevent reporting ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT twice in CLI mode in K2
|
||||
internal object FirActualAnnotationsMatchExpectChecker : FirBasicDeclarationChecker() {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (declaration !is FirMemberDeclaration) return
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) return
|
||||
if (!declaration.isActual) return
|
||||
|
||||
val actualSymbol = declaration.symbol
|
||||
val expectSymbol = actualSymbol.getSingleMatchedExpectForActualOrNull() ?: return
|
||||
checkAnnotationsMatch(expectSymbol, actualSymbol, context, reporter)
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun checkAnnotationsMatch(
|
||||
expectSymbol: FirBasedSymbol<*>,
|
||||
actualSymbol: FirBasedSymbol<*>,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
) {
|
||||
val matchingContext = context.session.expectActualMatchingContextFactory.create(context.session, context.scopeSession)
|
||||
val incompatibility =
|
||||
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectSymbol, actualSymbol, matchingContext) ?: return
|
||||
val actualAnnotationTargetSourceElement = (incompatibility.actualAnnotationTargetElement as FirSourceElement).element
|
||||
|
||||
reporter.report(
|
||||
FirErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on(
|
||||
actualSymbol.source.requireNotNull(),
|
||||
incompatibility.expectSymbol as FirBasedSymbol<*>,
|
||||
incompatibility.actualSymbol as FirBasedSymbol<*>,
|
||||
actualAnnotationTargetSourceElement,
|
||||
incompatibility.type.mapAnnotationType { it.annotationSymbol as FirAnnotation },
|
||||
positioningStrategy = null,
|
||||
),
|
||||
context,
|
||||
)
|
||||
}
|
||||
}
|
||||
+7
-32
@@ -8,8 +8,11 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirExpectActualMatchingContext
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
@@ -18,7 +21,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isTailRec
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expectActualMatchingContextFactory
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -28,7 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.mpp.RegularClassSymbolMarker
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
@@ -212,7 +215,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
if (expectedSingleCandidate != null) {
|
||||
checkOptInAnnotation(declaration, expectedSingleCandidate, context, reporter)
|
||||
checkAnnotationsMatch(expectedSingleCandidate, symbol, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,33 +272,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(Roman.Efremov): KT-62559 prevent reporting ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT twice in CLI mode in K2
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun checkAnnotationsMatch(
|
||||
expectSymbol: FirBasedSymbol<*>,
|
||||
actualSymbol: FirBasedSymbol<*>,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) return
|
||||
val matchingContext = context.session.expectActualMatchingContextFactory.create(context.session, context.scopeSession)
|
||||
val incompatibility =
|
||||
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectSymbol, actualSymbol, matchingContext) ?: return
|
||||
val actualAnnotationTargetSourceElement = (incompatibility.actualAnnotationTargetElement as FirSourceElement).element
|
||||
|
||||
reporter.report(
|
||||
FirErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on(
|
||||
actualSymbol.source.requireNotNull(),
|
||||
incompatibility.expectSymbol as FirBasedSymbol<*>,
|
||||
incompatibility.actualSymbol as FirBasedSymbol<*>,
|
||||
actualAnnotationTargetSourceElement,
|
||||
incompatibility.type.mapAnnotationType { it.annotationSymbol as FirAnnotation },
|
||||
positioningStrategy = null,
|
||||
),
|
||||
context,
|
||||
)
|
||||
}
|
||||
|
||||
// we don't require `actual` modifier on
|
||||
// - annotation constructors, because annotation classes can only have one constructor
|
||||
// - value class primary constructors, because value class must have primary constructor
|
||||
|
||||
Reference in New Issue
Block a user