[FIR] Support of ACTUAL_TYPE_ALIAS_NOT_TO_CLASS diagnostic
^KT-56514 Fixed
This commit is contained in:
committed by
Space Team
parent
c418a7a7bf
commit
8bf9d6c92f
+2
-1
@@ -32,7 +32,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirAnnotationChecker,
|
||||
FirPublishedApiChecker,
|
||||
FirOptInMarkedDeclarationChecker,
|
||||
FirActualDeclarationChecker,
|
||||
)
|
||||
|
||||
override val callableDeclarationCheckers: Set<FirCallableDeclarationChecker>
|
||||
@@ -40,6 +39,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirKClassWithIncorrectTypeArgumentChecker,
|
||||
FirImplicitNothingReturnTypeChecker,
|
||||
FirDynamicReceiverChecker,
|
||||
FirActualCallableDeclarationChecker,
|
||||
)
|
||||
|
||||
override val functionCheckers: Set<FirFunctionChecker>
|
||||
@@ -152,6 +152,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
override val typeAliasCheckers: Set<FirTypeAliasChecker>
|
||||
get() = setOf(
|
||||
FirTopLevelTypeAliasChecker,
|
||||
FirActualTypeAliasChecker,
|
||||
)
|
||||
|
||||
override val anonymousFunctionCheckers: Set<FirAnonymousFunctionChecker>
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
|
||||
object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
||||
override fun check(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isActual) return
|
||||
|
||||
if (declaration is FirFunction) {
|
||||
checkActualFunctionWithDefaultArguments(declaration, reporter, context)
|
||||
}
|
||||
checkReturnTypes(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkActualFunctionWithDefaultArguments(function: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) {
|
||||
for (valueParameter in function.valueParameters) {
|
||||
if (valueParameter.defaultValue != null) {
|
||||
reporter.reportOn(valueParameter.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkReturnTypes(callableDeclaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val actualFunctionSymbol = callableDeclaration.symbol
|
||||
val expectFunctionSymbol = actualFunctionSymbol.getSingleCompatibleExpectForActualOrNull() as? FirCallableSymbol ?: return
|
||||
|
||||
val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session)
|
||||
?.typeParameterSymbols.orEmpty()
|
||||
val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty()
|
||||
val parentSubstitutor =
|
||||
createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session)
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
expectFunctionSymbol.typeParameterSymbols,
|
||||
actualFunctionSymbol.typeParameterSymbols,
|
||||
context.session,
|
||||
parentSubstitutor
|
||||
)
|
||||
|
||||
if (!areCompatibleExpectActualTypes(
|
||||
substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type),
|
||||
actualFunctionSymbol.resolvedReturnType.type,
|
||||
context.session
|
||||
)
|
||||
) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
reporter.reportOn(
|
||||
callableDeclaration.source,
|
||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||
actualFunctionSymbol,
|
||||
actualFunctionSymbol.expectForActual as Map<ExpectActualCompatibility.Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
|
||||
object FirActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (declaration !is FirMemberDeclaration || !declaration.isActual) return
|
||||
|
||||
if (declaration is FirCallableDeclaration) {
|
||||
if (declaration is FirFunction) {
|
||||
checkActualFunctionWithDefaultArguments(declaration, reporter, context)
|
||||
}
|
||||
checkReturnTypes(declaration, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkActualFunctionWithDefaultArguments(function: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) {
|
||||
for (valueParameter in function.valueParameters) {
|
||||
if (valueParameter.defaultValue != null) {
|
||||
reporter.reportOn(valueParameter.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkReturnTypes(callableDeclaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val actualFunctionSymbol = callableDeclaration.symbol
|
||||
val expectFunctionSymbol = actualFunctionSymbol.getSingleCompatibleExpectForActualOrNull() as? FirCallableSymbol ?: return
|
||||
|
||||
val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session)
|
||||
?.typeParameterSymbols.orEmpty()
|
||||
val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty()
|
||||
val parentSubstitutor =
|
||||
createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session)
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
expectFunctionSymbol.typeParameterSymbols,
|
||||
actualFunctionSymbol.typeParameterSymbols,
|
||||
context.session,
|
||||
parentSubstitutor
|
||||
)
|
||||
|
||||
if (!areCompatibleExpectActualTypes(
|
||||
substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type),
|
||||
actualFunctionSymbol.resolvedReturnType.type,
|
||||
expectFunctionSymbol.moduleData.session,
|
||||
context.session
|
||||
)
|
||||
) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
reporter.reportOn(
|
||||
callableDeclaration.source,
|
||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||
actualFunctionSymbol,
|
||||
actualFunctionSymbol.expectForActual as Map<ExpectActualCompatibility.Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
|
||||
object FirActualTypeAliasChecker : FirTypeAliasChecker() {
|
||||
override fun check(declaration: FirTypeAlias, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isActual) return
|
||||
|
||||
checkActualTypeAliasNotToClass(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkActualTypeAliasNotToClass(
|
||||
declaration: FirTypeAlias,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
if (declaration.expandedTypeRef.toClassLikeSymbol(context.session) is FirTypeAliasSymbol) {
|
||||
reporter.reportOn(declaration.source, FirErrors.ACTUAL_TYPE_ALIAS_NOT_TO_CLASS, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
@@ -27,4 +27,4 @@ actual typealias C8<J> = MutableList<*>
|
||||
actual typealias C9<K> = MutableList<in K>
|
||||
|
||||
typealias Tmp<K> = MutableList<K>
|
||||
actual typealias C10<L> = Tmp<L>
|
||||
<!ACTUAL_TYPE_ALIAS_NOT_TO_CLASS!>actual typealias C10<L> = Tmp<L><!>
|
||||
|
||||
Reference in New Issue
Block a user