From c2cecb2818a0675f5599d1e05dcabdad9f5bbf0a Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Sat, 2 Apr 2022 00:59:02 +0300 Subject: [PATCH] [FIR JS] Add the dynamic type unsupported checker --- .../AbstractFirIdeDiagnosticsCollector.kt | 35 ++++++++++++++++--- .../analysis/jvm/checkers/JvmTypeCheckers.kt | 15 ++++++++ .../FirDynamicUnsupportedChecker.kt | 26 ++++++++++++++ .../kotlin/fir/checkers/CheckersContainers.kt | 2 ++ 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDynamicUnsupportedChecker.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/AbstractFirIdeDiagnosticsCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/AbstractFirIdeDiagnosticsCollector.kt index ff86e93304d..3f50dc67262 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/AbstractFirIdeDiagnosticsCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/AbstractFirIdeDiagnosticsCollector.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.ComposedDeclaratio import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers import org.jetbrains.kotlin.fir.analysis.checkers.expression.ComposedExpressionCheckers import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers +import org.jetbrains.kotlin.fir.analysis.checkers.type.ComposedTypeCheckers import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector import org.jetbrains.kotlin.fir.analysis.collectors.components.* @@ -21,6 +22,7 @@ import org.jetbrains.kotlin.fir.analysis.js.checkers.JsDeclarationCheckers import org.jetbrains.kotlin.fir.analysis.js.checkers.JsExpressionCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmTypeCheckers import org.jetbrains.kotlin.platform.SimplePlatform import org.jetbrains.kotlin.platform.jvm.JvmPlatform import org.jetbrains.kotlin.platform.js.JsPlatform @@ -46,7 +48,7 @@ private object CheckersFactory { val platform = module.platform.componentPlatforms.first() val declarationCheckers = createDeclarationCheckers(useExtendedCheckers, platform) val expressionCheckers = createExpressionCheckers(useExtendedCheckers, platform) - val typeCheckers = createTypeCheckers(useExtendedCheckers) + val typeCheckers = createTypeCheckers(useExtendedCheckers, platform) @OptIn(ExperimentalStdlibApi::class) return buildList { @@ -55,7 +57,7 @@ private object CheckersFactory { } add(DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers)) add(ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers)) - typeCheckers?.let { add(TypeCheckersDiagnosticComponent(session, reporter, it)) } + add(TypeCheckersDiagnosticComponent(session, reporter, typeCheckers)) add(ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers)) } } @@ -93,8 +95,18 @@ private object CheckersFactory { } } - private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers? = - if (useExtendedCheckers) ExtendedTypeCheckers else CommonTypeCheckers + private fun createTypeCheckers(useExtendedCheckers: Boolean, platform: SimplePlatform): TypeCheckers = + if (useExtendedCheckers) { + ExtendedTypeCheckers + } else { + createTypeCheckers { + add(CommonTypeCheckers) + when (platform) { + is JvmPlatform -> add(JvmTypeCheckers) + else -> {} + } + } + } @OptIn(ExperimentalStdlibApi::class) @@ -128,4 +140,19 @@ private object CheckersFactory { } } } + + @OptIn(ExperimentalStdlibApi::class) + private inline fun createTypeCheckers( + createTypeCheckers: MutableList.() -> Unit + ): TypeCheckers = createTypeCheckers(buildList(createTypeCheckers)) + + @OptIn(CheckersComponentInternal::class) + private fun createTypeCheckers(typeCheckers: List): TypeCheckers { + return when (typeCheckers.size) { + 1 -> typeCheckers.single() + else -> ComposedTypeCheckers().apply { + typeCheckers.forEach(::register) + } + } + } } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt new file mode 100644 index 00000000000..37e9daf5e56 --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmTypeCheckers.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2021 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.jvm.checkers + +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirDynamicUnsupportedChecker +import org.jetbrains.kotlin.fir.analysis.checkers.type.* + +object JvmTypeCheckers : TypeCheckers() { + override val typeRefCheckers: Set = setOf( + FirDynamicUnsupportedChecker, + ) +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDynamicUnsupportedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDynamicUnsupportedChecker.kt new file mode 100644 index 00000000000..84b152c60ea --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDynamicUnsupportedChecker.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2021 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.KtRealSourceElementKind +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.type.FirTypeRefChecker +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.types.ConeDynamicType +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.coneTypeSafe + +object FirDynamicUnsupportedChecker : FirTypeRefChecker() { + override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) { + // It's assumed this checker is only called + // by within the platform that disallows dynamics + if (typeRef.coneTypeSafe() != null) { + reporter.reportOn(typeRef.source, FirErrors.UNSUPPORTED, "dynamic type", context) + } + } +} diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt index 19a45329261..5567f878c99 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.js.checkers.JsDeclarationCheckers import org.jetbrains.kotlin.fir.analysis.js.checkers.JsExpressionCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmTypeCheckers import org.jetbrains.kotlin.fir.session.FirSessionFactory fun FirSessionFactory.FirSessionConfigurator.registerCommonCheckers() { @@ -27,6 +28,7 @@ fun FirSessionFactory.FirSessionConfigurator.registerExtendedCommonCheckers() { fun FirSessionFactory.FirSessionConfigurator.registerJvmCheckers() { useCheckers(JvmDeclarationCheckers) useCheckers(JvmExpressionCheckers) + useCheckers(JvmTypeCheckers) } fun FirSessionFactory.FirSessionConfigurator.registerJsCheckers() {