[FIR] Add extension with additional checkers

This commit is contained in:
Dmitriy Novozhilov
2020-05-08 14:09:28 +03:00
parent 04a1027b39
commit f764baad82
6 changed files with 96 additions and 4 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.* import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.checkers.expression.* import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension
class CheckersComponent : FirSessionComponent { class CheckersComponent : FirSessionComponent {
companion object { companion object {
@@ -33,6 +34,11 @@ class CheckersComponent : FirSessionComponent {
fun register(checkers: ExpressionCheckers) { fun register(checkers: ExpressionCheckers) {
_expressionCheckers.register(checkers) _expressionCheckers.register(checkers)
} }
fun register(checkers: FirAdditionalCheckersExtension) {
register(checkers.declarationCheckers)
register(checkers.expressionCheckers)
}
} }
val FirSession.checkersComponent: CheckersComponent by FirSession.sessionComponentAccessor() val FirSession.checkersComponent: CheckersComponent by FirSession.sessionComponentAccessor()
@@ -6,9 +6,13 @@
package org.jetbrains.kotlin.fir.analysis.collectors package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirSession 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 { object FirDiagnosticsCollector {
fun create(session: FirSession): AbstractDiagnosticCollector { fun create(session: FirSession): AbstractDiagnosticCollector {
session.registerAdditionalCheckers()
val collector = SimpleDiagnosticsCollector(session) val collector = SimpleDiagnosticsCollector(session)
collector.registerAllComponents() collector.registerAllComponents()
return collector return collector
@@ -17,8 +21,13 @@ object FirDiagnosticsCollector {
// Use in CLI compiler // Use in CLI compiler
@Suppress("unused") @Suppress("unused")
fun createParallel(session: FirSession): AbstractDiagnosticCollector { fun createParallel(session: FirSession): AbstractDiagnosticCollector {
session.registerAdditionalCheckers()
val collector = ParallelDiagnosticsCollector(session, numberOfThreads = 4) val collector = ParallelDiagnosticsCollector(session, numberOfThreads = 4)
collector.registerAllComponents() collector.registerAllComponents()
return collector return collector
} }
private fun FirSession.registerAdditionalCheckers() {
extensionsService.additionalCheckers.forEach(checkersComponent::register)
}
} }
@@ -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<AnnotationFqn>
get() = emptySet()
final override val childrenApplicableAnnotations: Set<AnnotationFqn>
get() = emptySet()
final override val metaAnnotations: Map<AnnotationFqn, MetaAnnotationMode>
get() = emptyMap()
final override val mode: Mode
get() = Mode.ALL
}
val FirExtensionsService.additionalCheckers: List<FirAdditionalCheckersExtension> by FirExtensionsService.additionalCheckers()
private fun FirExtensionsService.Companion.additionalCheckers(): ReadOnlyProperty<FirExtensionsService, List<FirAdditionalCheckersExtension>> {
val accessor = generateAccessor<FirRegisteredExtension<AbstractFirAdditionalCheckersExtension>, AbstractFirAdditionalCheckersExtension>(
AbstractFirAdditionalCheckersExtension::class
)
return object : ReadOnlyProperty<FirExtensionsService, List<FirAdditionalCheckersExtension>> {
override fun getValue(thisRef: FirExtensionsService, property: KProperty<*>): List<FirAdditionalCheckersExtension> {
val extensions = accessor.getValue(thisRef, property)
@Suppress("UNCHECKED_CAST")
return extensions.extensionsWithAllMode as List<FirAdditionalCheckersExtension>
}
}
}
@@ -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<AbstractFirAdditionalCheckersExtension>
final override val extensionType: KClass<out FirExtension>
get() = AbstractFirAdditionalCheckersExtension::class
}
@@ -25,7 +25,7 @@ abstract class FirExtension(val session: FirSession) {
internal abstract val extensionType: KClass<out FirExtension> internal abstract val extensionType: KClass<out FirExtension>
fun interface Factory<P : FirExtension> { fun interface Factory<out P : FirExtension> {
fun create(session: FirSession): P fun create(session: FirSession): P
} }
@@ -24,6 +24,11 @@ abstract class FirExtensionRegistrar {
operator fun ((FirSession) -> FirClassGenerationExtension).unaryPlus() { operator fun ((FirSession) -> FirClassGenerationExtension).unaryPlus() {
classGenerationExtensions += FirClassGenerationExtension.Factory { this.invoke(it) } classGenerationExtensions += FirClassGenerationExtension.Factory { this.invoke(it) }
} }
@JvmName("plusAdditionalCheckersExtension")
operator fun ((FirSession) -> AbstractFirAdditionalCheckersExtension).unaryPlus() {
additionalCheckersExtensions += AbstractFirAdditionalCheckersExtension.Factory { this.invoke(it) }
}
} }
protected abstract fun ExtensionRegistrarContext.configurePlugin() protected abstract fun ExtensionRegistrarContext.configurePlugin()
@@ -32,19 +37,22 @@ abstract class FirExtensionRegistrar {
ExtensionRegistrarContext().configurePlugin() ExtensionRegistrarContext().configurePlugin()
return RegisteredExtensions( return RegisteredExtensions(
statusTransformerExtensions, statusTransformerExtensions,
classGenerationExtensions classGenerationExtensions,
additionalCheckersExtensions,
) )
} }
private val statusTransformerExtensions: MutableList<FirStatusTransformerExtension.Factory> = mutableListOf() private val statusTransformerExtensions: MutableList<FirStatusTransformerExtension.Factory> = mutableListOf()
private val classGenerationExtensions: MutableList<FirClassGenerationExtension.Factory> = mutableListOf() private val classGenerationExtensions: MutableList<FirClassGenerationExtension.Factory> = mutableListOf()
private val additionalCheckersExtensions: MutableList<AbstractFirAdditionalCheckersExtension.Factory> = mutableListOf()
class RegisteredExtensions( class RegisteredExtensions(
val statusTransformerExtensions: List<FirStatusTransformerExtension.Factory>, val statusTransformerExtensions: List<FirStatusTransformerExtension.Factory>,
val classGenerationExtensions: List<FirClassGenerationExtension.Factory> val classGenerationExtensions: List<FirClassGenerationExtension.Factory>,
val additionalCheckersExtensions: List<AbstractFirAdditionalCheckersExtension.Factory>,
) { ) {
companion object { 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) { fun FirExtensionsService.registerExtensions(extensions: FirExtensionRegistrar.RegisteredExtensions) {
registerExtensions(FirStatusTransformerExtension::class, extensions.statusTransformerExtensions) registerExtensions(FirStatusTransformerExtension::class, extensions.statusTransformerExtensions)
registerExtensions(FirClassGenerationExtension::class, extensions.classGenerationExtensions) registerExtensions(FirClassGenerationExtension::class, extensions.classGenerationExtensions)
registerExtensions(AbstractFirAdditionalCheckersExtension::class, extensions.additionalCheckersExtensions)
} }