From 39fba56de932c034ab6f0de62731f5ebd076e752 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Tue, 11 Jul 2023 14:44:30 +0200 Subject: [PATCH] [JS FIR] Support PROPERTY_DELEGATION_BY_DYNAMIC diagnostic ^KT-59406 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 6 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 5 ++++ .../diagnostics/FirJsDiagnosticsList.kt | 1 + .../analysis/diagnostics/js/FirJsErrors.kt | 1 + .../js/FirJsErrorsDefaultMessages.kt | 2 ++ .../js/checkers/JsDeclarationCheckers.kt | 5 ++++ ...FirJsPropertyDelegationByDynamicChecker.kt | 23 ++++++++++++++++ .../dynamicTypes/propertyDelegateBy.fir.kt | 27 ------------------- .../dynamicTypes/propertyDelegateBy.kt | 1 + 10 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsPropertyDelegationByDynamicChecker.kt delete mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.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 275ed3891fd..16d2aecd66c 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 @@ -5185,6 +5185,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJsErrors.PROPERTY_DELEGATION_BY_DYNAMIC) { firDiagnostic -> + PropertyDelegationByDynamicImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL) { firDiagnostic -> SpreadOperatorInDynamicCallImpl( 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 38b23771297..4942c532820 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 @@ -3609,6 +3609,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = DelegationByDynamic::class } + interface PropertyDelegationByDynamic : KtFirDiagnostic { + override val diagnosticClass get() = PropertyDelegationByDynamic::class + } + interface SpreadOperatorInDynamicCall : KtFirDiagnostic { override val diagnosticClass get() = SpreadOperatorInDynamicCall::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 a275a5571e4..3988386ff2b 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 @@ -4364,6 +4364,11 @@ internal class DelegationByDynamicImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.DelegationByDynamic +internal class PropertyDelegationByDynamicImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.PropertyDelegationByDynamic + internal class SpreadOperatorInDynamicCallImpl( 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 a70184a468e..1b971d4445a 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 @@ -123,6 +123,7 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") { val DYNAMICS by object : DiagnosticGroup("Dynamics") { val DELEGATION_BY_DYNAMIC by error() + val PROPERTY_DELEGATION_BY_DYNAMIC by error() val SPREAD_OPERATOR_IN_DYNAMIC_CALL by error(PositioningStrategy.SPREAD_OPERATOR) val WRONG_OPERATION_WITH_DYNAMIC by error { parameter("operation") 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 a77e972b481..5151e36bc8c 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 @@ -91,6 +91,7 @@ object FirJsErrors { // Dynamics val DELEGATION_BY_DYNAMIC by error0() + val PROPERTY_DELEGATION_BY_DYNAMIC by error0() val SPREAD_OPERATOR_IN_DYNAMIC_CALL by error0(SourceElementPositioningStrategies.SPREAD_OPERATOR) val WRONG_OPERATION_WITH_DYNAMIC by error1() 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 3e348991d94..d11ae36369f 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_DEL import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC +import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.PROPERTY_DELEGATION_BY_DYNAMIC import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_INTERFACE_AS_CLASS_LITERAL import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION @@ -82,6 +83,7 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() { FirDiagnosticRenderers.SYMBOL ) map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value") + map.put(PROPERTY_DELEGATION_BY_DYNAMIC, "Can't apply property delegation by dynamic handler") map.put(SPREAD_OPERATOR_IN_DYNAMIC_CALL, "Can't apply spread operator in dynamic call") map.put(WRONG_OPERATION_WITH_DYNAMIC, "Wrong operation with dynamic value: {0}", CommonRenderers.STRING) map.put(IMPLEMENTING_FUNCTION_INTERFACE, "Implementing function interface is prohibited in JavaScript") diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt index fbf8bc5825b..d2f2692ac81 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt @@ -39,4 +39,9 @@ object JsDeclarationCheckers : DeclarationCheckers() { FirJsNativeGetterChecker, FirJsNativeSetterChecker, ) + + override val propertyCheckers: Set + get() = setOf( + FirJsPropertyDelegationByDynamicChecker + ) } diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsPropertyDelegationByDynamicChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsPropertyDelegationByDynamicChecker.kt new file mode 100644 index 00000000000..37cc2ac1730 --- /dev/null +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsPropertyDelegationByDynamicChecker.kt @@ -0,0 +1,23 @@ +/* + * 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.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.declaration.FirPropertyChecker +import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.types.ConeDynamicType +import org.jetbrains.kotlin.fir.types.coneTypeOrNull + +object FirJsPropertyDelegationByDynamicChecker : FirPropertyChecker() { + override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration.delegate?.typeRef?.coneTypeOrNull is ConeDynamicType) { + reporter.reportOn(declaration.delegate?.source, FirJsErrors.PROPERTY_DELEGATION_BY_DYNAMIC, context) + } + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.fir.kt b/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.fir.kt deleted file mode 100644 index 6f5a5f5e4a4..00000000000 --- a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.fir.kt +++ /dev/null @@ -1,27 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_VARIABLE - -external val x: dynamic - -var y: Any? by x - -fun foo() { - val a: Any by x -} - -class C { - val a: dynamic by x -} - -class A { - operator fun provideDelegate(host: Any?, p: Any): dynamic = TODO("") -} - -val z: Any? by A() - -class DynamicHandler { - operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): dynamic = 23 -} - -class B { - val x: dynamic by DynamicHandler() -} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.kt b/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.kt index d92001ff648..779529fa00b 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/propertyDelegateBy.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VARIABLE external val x: dynamic