diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/CheckersComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/CheckersComponent.kt index ed35a704de1..bd6891b9c64 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/CheckersComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/CheckersComponent.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.analysis.checkers.declaration.* import org.jetbrains.kotlin.fir.analysis.checkers.expression.* +import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension class CheckersComponent : FirSessionComponent { companion object { @@ -33,6 +34,11 @@ class CheckersComponent : FirSessionComponent { fun register(checkers: ExpressionCheckers) { _expressionCheckers.register(checkers) } + + fun register(checkers: FirAdditionalCheckersExtension) { + register(checkers.declarationCheckers) + register(checkers.expressionCheckers) + } } val FirSession.checkersComponent: CheckersComponent by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/FirDiagnosticsCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/FirDiagnosticsCollector.kt index b36e842e89b..5c9be8bef7b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/FirDiagnosticsCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/FirDiagnosticsCollector.kt @@ -6,9 +6,13 @@ package org.jetbrains.kotlin.fir.analysis.collectors import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.analysis.checkersComponent +import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers +import org.jetbrains.kotlin.fir.extensions.extensionsService object FirDiagnosticsCollector { fun create(session: FirSession): AbstractDiagnosticCollector { + session.registerAdditionalCheckers() val collector = SimpleDiagnosticsCollector(session) collector.registerAllComponents() return collector @@ -17,8 +21,13 @@ object FirDiagnosticsCollector { // Use in CLI compiler @Suppress("unused") fun createParallel(session: FirSession): AbstractDiagnosticCollector { + session.registerAdditionalCheckers() val collector = ParallelDiagnosticsCollector(session, numberOfThreads = 4) collector.registerAllComponents() return collector } + + private fun FirSession.registerAdditionalCheckers() { + extensionsService.additionalCheckers.forEach(checkersComponent::register) + } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/extensions/FirAdditionalCheckersExtension.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/extensions/FirAdditionalCheckersExtension.kt new file mode 100644 index 00000000000..c20ec690bfb --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/extensions/FirAdditionalCheckersExtension.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2020 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.extensions + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers +import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers +import org.jetbrains.kotlin.fir.extensions.* +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +abstract class FirAdditionalCheckersExtension(session: FirSession) : AbstractFirAdditionalCheckersExtension(session) { + companion object { + val NAME = FirExtensionPointName("ExtensionCheckers") + } + + open val declarationCheckers: DeclarationCheckers = DeclarationCheckers.EMPTY + open val expressionCheckers: ExpressionCheckers = ExpressionCheckers.EMPTY + + final override val name: FirExtensionPointName + get() = NAME + + final override val directlyApplicableAnnotations: Set + get() = emptySet() + + final override val childrenApplicableAnnotations: Set + get() = emptySet() + + final override val metaAnnotations: Map + get() = emptyMap() + + final override val mode: Mode + get() = Mode.ALL +} + +val FirExtensionsService.additionalCheckers: List by FirExtensionsService.additionalCheckers() + +private fun FirExtensionsService.Companion.additionalCheckers(): ReadOnlyProperty> { + val accessor = generateAccessor, AbstractFirAdditionalCheckersExtension>( + AbstractFirAdditionalCheckersExtension::class + ) + return object : ReadOnlyProperty> { + override fun getValue(thisRef: FirExtensionsService, property: KProperty<*>): List { + val extensions = accessor.getValue(thisRef, property) + @Suppress("UNCHECKED_CAST") + return extensions.extensionsWithAllMode as List + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/AbstractFirAdditionalCheckersExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/AbstractFirAdditionalCheckersExtension.kt new file mode 100644 index 00000000000..d587b82a590 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/AbstractFirAdditionalCheckersExtension.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2020 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.extensions + +import org.jetbrains.kotlin.fir.FirSession +import kotlin.reflect.KClass + +abstract class AbstractFirAdditionalCheckersExtension(session: FirSession) : FirExtension(session) { + fun interface Factory : FirExtension.Factory + + final override val extensionType: KClass + get() = AbstractFirAdditionalCheckersExtension::class +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt index 3783115de5b..28775d1d73e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt @@ -25,7 +25,7 @@ abstract class FirExtension(val session: FirSession) { internal abstract val extensionType: KClass - fun interface Factory

{ + fun interface Factory { fun create(session: FirSession): P } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrar.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrar.kt index ccb6660f231..6ae4b3ae23d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrar.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrar.kt @@ -24,6 +24,11 @@ abstract class FirExtensionRegistrar { operator fun ((FirSession) -> FirClassGenerationExtension).unaryPlus() { classGenerationExtensions += FirClassGenerationExtension.Factory { this.invoke(it) } } + + @JvmName("plusAdditionalCheckersExtension") + operator fun ((FirSession) -> AbstractFirAdditionalCheckersExtension).unaryPlus() { + additionalCheckersExtensions += AbstractFirAdditionalCheckersExtension.Factory { this.invoke(it) } + } } protected abstract fun ExtensionRegistrarContext.configurePlugin() @@ -32,19 +37,22 @@ abstract class FirExtensionRegistrar { ExtensionRegistrarContext().configurePlugin() return RegisteredExtensions( statusTransformerExtensions, - classGenerationExtensions + classGenerationExtensions, + additionalCheckersExtensions, ) } private val statusTransformerExtensions: MutableList = mutableListOf() private val classGenerationExtensions: MutableList = mutableListOf() + private val additionalCheckersExtensions: MutableList = mutableListOf() class RegisteredExtensions( val statusTransformerExtensions: List, - val classGenerationExtensions: List + val classGenerationExtensions: List, + val additionalCheckersExtensions: List, ) { companion object { - val EMPTY = RegisteredExtensions(emptyList(), emptyList()) + val EMPTY = RegisteredExtensions(emptyList(), emptyList(), emptyList()) } } } @@ -52,4 +60,5 @@ abstract class FirExtensionRegistrar { fun FirExtensionsService.registerExtensions(extensions: FirExtensionRegistrar.RegisteredExtensions) { registerExtensions(FirStatusTransformerExtension::class, extensions.statusTransformerExtensions) registerExtensions(FirClassGenerationExtension::class, extensions.classGenerationExtensions) + registerExtensions(AbstractFirAdditionalCheckersExtension::class, extensions.additionalCheckersExtensions) } \ No newline at end of file