[FIR JS] Support DELEGATION_BY_DYNAMIC

This commit is contained in:
Nikolay Lunyak
2023-01-04 12:29:42 +02:00
committed by Space Team
parent 95b589fd94
commit 0f876f665a
10 changed files with 61 additions and 13 deletions
@@ -4636,6 +4636,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
DelegationByDynamicImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirSyntaxErrors.SYNTAX) { firDiagnostic ->
SyntaxImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -3225,6 +3225,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = JavaSamInterfaceConstructorReference::class
}
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = DelegationByDynamic::class
}
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = Syntax::class
}
@@ -3901,6 +3901,11 @@ internal class JavaSamInterfaceConstructorReferenceImpl(
override val token: KtLifetimeToken,
) : KtFirDiagnostic.JavaSamInterfaceConstructorReference(), KtAbstractFirDiagnostic<PsiElement>
internal class DelegationByDynamicImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.DelegationByDynamic(), KtAbstractFirDiagnostic<KtElement>
internal class SyntaxImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
@@ -26,4 +26,8 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
parameter<FirCallableSymbol<*>>("symbol")
}
}
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
val DELEGATION_BY_DYNAMIC by error<KtElement>()
}
}
@@ -27,6 +27,9 @@ object FirJsErrors {
// Supertypes
val WRONG_MULTIPLE_INHERITANCE by error1<KtElement, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
// Dynamics
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
init {
RootDiagnosticRendererFactory.registerFactory(FirJsErrorsDefaultMessages)
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
import org.jetbrains.kotlin.fir.analysis.diagnostics.checkMissingMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_NON_NATIVE
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_VAR
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_MODULE_PROHIBITED
@@ -30,6 +31,7 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
"Can''t apply multiple inheritance here, since it''s impossible to generate bridge for system function {0}",
FirDiagnosticRenderers.SYMBOL
)
map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value")
map.checkMissingMessages(FirJsErrors)
}
@@ -27,5 +27,6 @@ object JsDeclarationCheckers : DeclarationCheckers() {
override val classCheckers: Set<FirClassChecker>
get() = setOf(
FirJsMultipleInheritanceChecker,
FirJsDynamicDeclarationChecker,
)
}
@@ -0,0 +1,35 @@
/*
* 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.FirClassChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType
object FirJsDynamicDeclarationChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
val delegatedFields = declaration.delegateFieldsMap ?: return
for ((_, delegate) in delegatedFields) {
@OptIn(SymbolInternals::class)
// Accessing fir here is ok, because it still
// belongs to the current `declaration: FirClass`,
// and it's a shape it couldn't have been accessed directly
val initializer = delegate.fir.initializer ?: continue
if (initializer.typeRef.coneType is ConeDynamicType) {
reporter.reportOn(initializer.source, FirJsErrors.DELEGATION_BY_DYNAMIC, context)
}
}
}
}
@@ -1,13 +0,0 @@
val x: dynamic = 23
interface I {
fun foo(): String
}
class C : I by x
object O : I by x
fun box(): String {
return object : I by x {}.foo()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
val x: dynamic = 23
interface I {