From f6b7a07efe7bdffcd952d6198183efd0af107b4b Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Tue, 11 Jul 2023 13:51:39 +0200 Subject: [PATCH] [JS FIR] Support EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT diagnostic ^KT-59416 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 7 ++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 5 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 6 +++ .../diagnostics/FirJsDiagnosticsList.kt | 3 ++ .../analysis/diagnostics/js/FirJsErrors.kt | 1 + .../js/FirJsErrorsDefaultMessages.kt | 6 +++ .../js/checkers/JsExpressionCheckers.kt | 1 + .../expression/FirJsReifiedExternalChecker.kt | 39 +++++++++++++++++++ ...ativeInterfaceAsReifiedTypeArgument.fir.kt | 21 ---------- .../nativeInterfaceAsReifiedTypeArgument.kt | 1 + 10 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsReifiedExternalChecker.kt delete mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.fir.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index aa17db39e76..275ed3891fd 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -5144,6 +5144,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT) { firDiagnostic -> + ExternalInterfaceAsReifiedTypeArgumentImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirJsErrors.NESTED_JS_EXPORT) { firDiagnostic -> NestedJsExportImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 697aff3202c..38b23771297 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -3580,6 +3580,11 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { val argType: KtType } + interface ExternalInterfaceAsReifiedTypeArgument : KtFirDiagnostic { + override val diagnosticClass get() = ExternalInterfaceAsReifiedTypeArgument::class + val typeArgument: KtType + } + interface NestedJsExport : KtFirDiagnostic { override val diagnosticClass get() = NestedJsExport::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 353ef7c8c44..a275a5571e4 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4329,6 +4329,12 @@ internal class JsExternalArgumentImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.JsExternalArgument +internal class ExternalInterfaceAsReifiedTypeArgumentImpl( + override val typeArgument: KtType, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.ExternalInterfaceAsReifiedTypeArgument + internal class NestedJsExportImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt index 66faf8c2f1e..a70184a468e 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt @@ -102,6 +102,9 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") { val JS_EXTERNAL_ARGUMENT by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { parameter("argType") } + val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { + parameter("typeArgument") + } } val EXPORT by object : DiagnosticGroup("Export") { diff --git a/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt b/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt index 317e0a82d91..a77e972b481 100644 --- a/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt +++ b/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt @@ -81,6 +81,7 @@ object FirJsErrors { val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error0() val JS_EXTERNAL_INHERITORS_ONLY by error2, FirClassLikeSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) val JS_EXTERNAL_ARGUMENT by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) + val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) // Export val NESTED_JS_EXPORT by error0() diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt index bbd0dd2003f..3e348991d94 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING +import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_EXTERNAL_INHERITORS_ONLY import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_EXTERNAL_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_EXTERNAL_ARGUMENT @@ -169,6 +170,11 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() { "Expected argument with external type, but type ''{0}'' is non-external", FirDiagnosticRenderers.RENDER_TYPE ) + map.put( + EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT, + "Cannot pass external interface {0} for reified type parameter", + FirDiagnosticRenderers.RENDER_TYPE + ) map.put(JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "@JsName is prohibited for extension properties") map.put(JS_NAME_IS_NOT_ON_ALL_ACCESSORS, "@JsName should be on all the property accessors") map.put(JS_NAME_PROHIBITED_FOR_NAMED_NATIVE, "@JsName is prohibited for external declaration with explicit name") diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsExpressionCheckers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsExpressionCheckers.kt index b373ff0e0aa..727bcb85525 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsExpressionCheckers.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsExpressionCheckers.kt @@ -23,6 +23,7 @@ object JsExpressionCheckers : ExpressionCheckers() { override val functionCallCheckers: Set get() = setOf( FirJsDynamicCallChecker, + FirJsReifiedExternalChecker ) override val callCheckers: Set diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsReifiedExternalChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsReifiedExternalChecker.kt new file mode 100644 index 00000000000..5418b4e6c4b --- /dev/null +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsReifiedExternalChecker.kt @@ -0,0 +1,39 @@ +/* + * 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.js.checkers.expression + +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.expression.FirFunctionCallChecker +import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors +import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface +import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.references.toResolvedFunctionSymbol +import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance +import org.jetbrains.kotlin.fir.types.coneTypeOrNull +import org.jetbrains.kotlin.fir.types.toSymbol + +object FirJsReifiedExternalChecker : FirFunctionCallChecker() { + override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { + val functionSymbol = expression.calleeReference.toResolvedFunctionSymbol() ?: return + for ((typeParameterSymbol, typeArgument) in functionSymbol.typeParameterSymbols.zip(expression.typeArguments)) { + if (typeParameterSymbol.isReified) { + val type = (typeArgument as? FirTypeProjectionWithVariance)?.typeRef?.coneTypeOrNull ?: continue + val typeSymbol = type.toSymbol(context.session) ?: continue + if (typeSymbol.isNativeInterface(context)) { + reporter.reportOn( + typeArgument.source ?: expression.source, + FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT, + type, + context + ) + } + } + } + } + +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.fir.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.fir.kt deleted file mode 100644 index 3635a691364..00000000000 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.fir.kt +++ /dev/null @@ -1,21 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER - -inline fun foo(x: T) { - println(x) -} - -external interface I - -external class C : I - -operator inline fun C.plus(other: T) = this - -fun bar() { - foo(C()) - - val c: I = C() - foo(c) - foo(C()) - - C() + c -} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.kt index 8965f25192c..e443b6a194a 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceAsReifiedTypeArgument.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER inline fun foo(x: T) {