FIR IDE: add JVM checkers

This commit is contained in:
Ilya Kirillov
2021-04-26 20:03:39 +02:00
parent 81a7271009
commit cccf9b7d54
5 changed files with 55 additions and 37 deletions
@@ -94,7 +94,7 @@ class Generator(
printPackageAndCopyright()
printImports()
printGeneratedMessage()
println("internal class $composedComponentName : $checkersComponentName() {")
println("class $composedComponentName : $checkersComponentName() {")
withIndent {
// public overrides
for (alias in configuration.aliases.values) {
@@ -122,7 +122,7 @@ class Generator(
// register function
println(CHECKERS_COMPONENT_INTERNAL_ANNOTATION)
println("internal fun register(checkers: $checkersComponentName) {")
println("fun register(checkers: $checkersComponentName) {")
withIndent {
for (alias in configuration.aliases.values) {
println("_${alias.fieldName} += checkers.${alias.fieldName}")
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
* DO NOT MODIFY IT MANUALLY
*/
internal class ComposedDeclarationCheckers : DeclarationCheckers() {
class ComposedDeclarationCheckers : DeclarationCheckers() {
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
get() = _basicDeclarationCheckers
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker>
@@ -54,7 +54,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
private val _variableAssignmentCfaBasedCheckers: MutableSet<AbstractFirPropertyInitializationChecker> = mutableSetOf()
@CheckersComponentInternal
internal fun register(checkers: DeclarationCheckers) {
fun register(checkers: DeclarationCheckers) {
_basicDeclarationCheckers += checkers.basicDeclarationCheckers
_memberDeclarationCheckers += checkers.memberDeclarationCheckers
_functionCheckers += checkers.functionCheckers
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
* DO NOT MODIFY IT MANUALLY
*/
internal class ComposedExpressionCheckers : ExpressionCheckers() {
class ComposedExpressionCheckers : ExpressionCheckers() {
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
get() = _basicExpressionCheckers
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
@@ -64,7 +64,7 @@ internal class ComposedExpressionCheckers : ExpressionCheckers() {
private val _stringConcatenationCallCheckers: MutableSet<FirStringConcatenationCallChecker> = mutableSetOf()
@CheckersComponentInternal
internal fun register(checkers: ExpressionCheckers) {
fun register(checkers: ExpressionCheckers) {
_basicExpressionCheckers += checkers.basicExpressionCheckers
_qualifiedAccessCheckers += checkers.qualifiedAccessCheckers
_functionCallCheckers += checkers.functionCallCheckers
@@ -12,14 +12,14 @@ import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
* DO NOT MODIFY IT MANUALLY
*/
internal class ComposedTypeCheckers : TypeCheckers() {
class ComposedTypeCheckers : TypeCheckers() {
override val typeRefCheckers: Set<FirTypeRefChecker>
get() = _typeRefCheckers
private val _typeRefCheckers: MutableSet<FirTypeRefChecker> = mutableSetOf()
@CheckersComponentInternal
internal fun register(checkers: TypeCheckers) {
fun register(checkers: TypeCheckers) {
_typeRefCheckers += checkers.typeRefCheckers
}
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.ComposedDeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.analysis.collectors.components.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.checkers.*
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.platform.SimplePlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
internal abstract class AbstractFirIdeDiagnosticsCollector(
session: FirSession,
@@ -33,44 +36,59 @@ private object CheckersFactory {
reporter: DiagnosticReporter,
useExtendedCheckers: Boolean
): List<AbstractDiagnosticCollectorComponent> {
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers)
val moduleInfo = session.moduleInfo as ModuleSourceInfo
val platform = moduleInfo.platform.componentPlatforms.single()
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers, platform)
val expressionCheckers = createExpressionCheckers(useExtendedCheckers)
val typeCheckers = createTypeCheckers(useExtendedCheckers)
return if (useExtendedCheckers) {
listOf(
DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers),
ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers),
TypeCheckersDiagnosticComponent(session, reporter, typeCheckers),
ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers),
)
} else {
listOf(
DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers),
ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers),
TypeCheckersDiagnosticComponent(session, reporter, typeCheckers),
ErrorNodeDiagnosticCollectorComponent(session, reporter),
ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers),
)
@OptIn(ExperimentalStdlibApi::class)
return buildList {
if (!useExtendedCheckers) {
add(ErrorNodeDiagnosticCollectorComponent(session, reporter))
}
add(DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers))
add(ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers))
typeCheckers?.let { add(TypeCheckersDiagnosticComponent(session, reporter, it)) }
add(ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers))
}
}
private val extendedDeclarationCheckers = createDeclarationCheckers(ExtendedDeclarationCheckers)
private val commonDeclarationCheckers = createDeclarationCheckers(CommonDeclarationCheckers,)
private fun createDeclarationCheckers(useExtendedCheckers: Boolean): DeclarationCheckers =
if (useExtendedCheckers) extendedDeclarationCheckers else commonDeclarationCheckers
private fun createDeclarationCheckers(useExtendedCheckers: Boolean, platform: SimplePlatform): DeclarationCheckers {
return if (useExtendedCheckers) {
ExtendedDeclarationCheckers
} else {
createDeclarationCheckers {
add(CommonDeclarationCheckers)
when (platform) {
is JvmPlatform -> add(JvmDeclarationCheckers)
}
}
}
}
private fun createExpressionCheckers(useExtendedCheckers: Boolean): ExpressionCheckers =
if (useExtendedCheckers) ExtendedExpressionCheckers else CommonExpressionCheckers
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers = CommonTypeCheckers
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers? =
if (useExtendedCheckers) null else CommonTypeCheckers
// TODO hack to have all checkers present in DeclarationCheckers.memberDeclarationCheckers and similar
// If use ExtendedDeclarationCheckers directly when DeclarationCheckers.memberDeclarationCheckers will not contain basicDeclarationCheckers
@OptIn(SessionConfiguration::class)
private fun createDeclarationCheckers(vararg declarationCheckers: DeclarationCheckers): DeclarationCheckers =
CheckersComponent().apply { declarationCheckers.forEach(::register) }.declarationCheckers
@OptIn(ExperimentalStdlibApi::class)
private inline fun createDeclarationCheckers(
createDeclarationCheckers: MutableList<DeclarationCheckers>.() -> Unit
): DeclarationCheckers =
createDeclarationCheckers(buildList(createDeclarationCheckers))
@OptIn(CheckersComponentInternal::class)
private fun createDeclarationCheckers(declarationCheckers: List<DeclarationCheckers>): DeclarationCheckers {
return when (declarationCheckers.size) {
1 -> declarationCheckers.single()
else -> ComposedDeclarationCheckers().apply {
declarationCheckers.forEach(::register)
}
}
}
}