From 8bf9d6c92f65d31b0858356226cd4e16ee9a3172 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sat, 11 Feb 2023 22:28:31 +0100 Subject: [PATCH] [FIR] Support of ACTUAL_TYPE_ALIAS_NOT_TO_CLASS diagnostic ^KT-56514 Fixed --- .../checkers/CommonDeclarationCheckers.kt | 3 +- .../FirActualCallableDeclarationChecker.kt | 71 ++++++++++++++++++ .../FirActualDeclarationChecker.kt | 74 ------------------- .../declaration/FirActualTypeAliasChecker.kt | 33 +++++++++ .../genericClassImplTypeAlias.fir.kt | 2 +- 5 files changed, 107 insertions(+), 76 deletions(-) delete mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualTypeAliasChecker.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 07c7970a122..73b746c6242 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -32,7 +32,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirAnnotationChecker, FirPublishedApiChecker, FirOptInMarkedDeclarationChecker, - FirActualDeclarationChecker, ) override val callableDeclarationCheckers: Set @@ -40,6 +39,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirKClassWithIncorrectTypeArgumentChecker, FirImplicitNothingReturnTypeChecker, FirDynamicReceiverChecker, + FirActualCallableDeclarationChecker, ) override val functionCheckers: Set @@ -152,6 +152,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { override val typeAliasCheckers: Set get() = setOf( FirTopLevelTypeAliasChecker, + FirActualTypeAliasChecker, ) override val anonymousFunctionCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt index e69de29bb2d..c8d1b649a5c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt @@ -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>, Collection>>, + context + ) + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt deleted file mode 100644 index 5e365fa4f3d..00000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt +++ /dev/null @@ -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>, Collection>>, - context - ) - } - } -} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualTypeAliasChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualTypeAliasChecker.kt new file mode 100644 index 00000000000..6045d5fcc8b --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualTypeAliasChecker.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.fir.kt index 25cf58a109f..3ac0caca28a 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.fir.kt @@ -27,4 +27,4 @@ actual typealias C8 = MutableList<*> actual typealias C9 = MutableList typealias Tmp = MutableList -actual typealias C10 = Tmp +actual typealias C10 = Tmp