[FIR] Add separate diagnostic list for JVM specific diagnostics

This commit is contained in:
Dmitriy Novozhilov
2021-05-20 11:53:36 +03:00
committed by teamcityserver
parent 7f18d147c1
commit f3c58a1df7
9 changed files with 103 additions and 27 deletions
+7 -2
View File
@@ -35,6 +35,11 @@ dependencies {
val generationRoot = projectDir.resolve("gen")
// Add modules for js and native checkers here
val platformGenerationRoots = listOf(
"checkers.jvm"
).map { projectDir.resolve(it).resolve("gen") }
val generateCheckersComponents by tasks.registering(NoDebugJavaExec::class) {
val generatorRoot = "$projectDir/checkers-component-generator/src/"
@@ -44,9 +49,9 @@ val generateCheckersComponents by tasks.registering(NoDebugJavaExec::class) {
}
inputs.files(generatorConfigurationFiles)
outputs.dirs(generationRoot)
outputs.dirs(generationRoot, *platformGenerationRoots.toTypedArray())
args(generationRoot)
args(generationRoot, *platformGenerationRoots.toTypedArray())
workingDir = rootDir
classpath = generatorClasspath
main = "org.jetbrains.kotlin.fir.checkers.generator.MainKt"
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.checkers.generator
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DIAGNOSTICS_LIST
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.FIR_JVM_DIAGNOSTICS_LIST
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.generateDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
@@ -13,14 +14,17 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
import java.io.File
fun main(args: Array<String>) {
val generationPath = args.firstOrNull()?.let { File(it) } ?: File("compiler/fir/checkers/gen").absoluteFile
val arguments = args.toList()
val generationPath = arguments.firstOrNull()?.let { File(it) } ?: File("compiler/fir/checkers/gen").absoluteFile
val typePackage = "org.jetbrains.kotlin.fir.analysis.checkers.type"
val basePackage = "org.jetbrains.kotlin.fir.analysis"
val typePackage = "$basePackage.checkers.type"
generateCheckersComponents(generationPath, typePackage, "FirTypeChecker") {
alias<FirTypeRef>("TypeRefChecker")
}
val expressionPackage = "org.jetbrains.kotlin.fir.analysis.checkers.expression"
val expressionPackage = "$basePackage.checkers.expression"
generateCheckersComponents(generationPath, expressionPackage, "FirExpressionChecker") {
alias<FirStatement>("BasicExpressionChecker")
alias<FirQualifiedAccessExpression>("QualifiedAccessChecker")
@@ -44,7 +48,7 @@ fun main(args: Array<String>) {
alias<FirResolvedQualifier>("ResolvedQualifierChecker")
}
val declarationPackage = "org.jetbrains.kotlin.fir.analysis.checkers.declaration"
val declarationPackage = "$basePackage.checkers.declaration"
generateCheckersComponents(generationPath, declarationPackage, "FirDeclarationChecker") {
alias<FirDeclaration>("BasicDeclarationChecker")
alias<FirMemberDeclaration>("MemberDeclarationChecker")
@@ -60,17 +64,19 @@ fun main(args: Array<String>) {
additional(
fieldName = "controlFlowAnalyserCheckers",
classFqn = "org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker"
classFqn = "$basePackage.checkers.cfa.FirControlFlowChecker"
)
additional(
fieldName = "variableAssignmentCfaBasedCheckers",
classFqn = "org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker"
classFqn = "$basePackage.cfa.AbstractFirPropertyInitializationChecker"
)
}
val diagnosticsPackage = "org.jetbrains.kotlin.fir.analysis.diagnostics"
generateDiagnostics(generationPath, diagnosticsPackage, DIAGNOSTICS_LIST)
val jvmGenerationPath = File(arguments.getOrElse(1) { "compiler/fir/checkers/checkers.jvm/gen" })
generateDiagnostics(generationPath, "$basePackage.diagnostics", "FirErrors", DIAGNOSTICS_LIST)
generateDiagnostics(jvmGenerationPath, "$basePackage.diagnostics.jvm", "FirJvmErrors", FIR_JVM_DIAGNOSTICS_LIST)
}
/*
@@ -0,0 +1,18 @@
/*
* 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.checkers.generator.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
@OptIn(PrivateForInline::class)
object FIR_JVM_DIAGNOSTICS_LIST : DiagnosticList() {
val DECLARATIONS by object : DiagnosticGroup("Declarations") {
val CONFLICTING_JVM_DECLARATIONS by error<PsiElement>()
}
}
@@ -8,7 +8,12 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model
import org.jetbrains.kotlin.fir.checkers.generator.getGenerationPath
import java.io.File
fun generateDiagnostics(rootPath: File, packageName: String, diagnosticList: DiagnosticList) {
fun generateDiagnostics(rootPath: File, packageName: String, containingObjectName: String, diagnosticList: DiagnosticList) {
val generationPath = getGenerationPath(rootPath, packageName)
ErrorListDiagnosticListRenderer.render(generationPath.resolve("FirErrors.kt"), diagnosticList, packageName)
ErrorListDiagnosticListRenderer.render(
generationPath.resolve("$containingObjectName.kt"),
diagnosticList,
packageName,
containingObjectName
)
}
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model
import java.io.File
abstract class DiagnosticListRenderer {
abstract fun render(file: File, diagnosticList: DiagnosticList, packageName: String)
abstract fun render(file: File, diagnosticList: DiagnosticList, packageName: String, containingObjectName: String)
}
@@ -16,23 +16,25 @@ import kotlin.reflect.KType
import kotlin.reflect.KTypeProjection
object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
override fun render(file: File, diagnosticList: DiagnosticList, packageName: String) {
private const val BASE_PACKAGE = "org.jetbrains.kotlin.fir.analysis.diagnostics"
override fun render(file: File, diagnosticList: DiagnosticList, packageName: String, containingObjectName: String) {
file.writeToFileUsingSmartPrinterIfFileContentChanged {
render(diagnosticList, packageName)
render(diagnosticList, packageName, containingObjectName)
}
}
private fun SmartPrinter.render(diagnosticList: DiagnosticList, packageName: String) {
private fun SmartPrinter.render(diagnosticList: DiagnosticList, packageName: String, containingObjectName: String) {
printCopyright()
println("package $packageName")
println()
collectAndPrintImports(diagnosticList)
collectAndPrintImports(diagnosticList, packageName)
printGeneratedMessage()
printErrorsObject(diagnosticList)
printErrorsObject(diagnosticList, containingObjectName)
}
private fun SmartPrinter.printErrorsObject(diagnosticList: DiagnosticList) {
inBracketsWithIndent("object FirErrors") {
private fun SmartPrinter.printErrorsObject(diagnosticList: DiagnosticList, containingObjectName: String) {
inBracketsWithIndent("object $containingObjectName") {
for (group in diagnosticList.groups) {
printDiagnosticGroup(group.name, group.diagnostics)
println()
@@ -103,14 +105,17 @@ object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
}
}
private fun SmartPrinter.collectAndPrintImports(diagnosticList: DiagnosticList) {
val imports = collectImports(diagnosticList)
private fun SmartPrinter.collectAndPrintImports(diagnosticList: DiagnosticList, packageName: String) {
val imports = collectImports(diagnosticList, packageName)
printImports(imports)
println()
}
@OptIn(ExperimentalStdlibApi::class)
private fun collectImports(diagnosticList: DiagnosticList): Collection<String> = buildSet {
private fun collectImports(diagnosticList: DiagnosticList, packageName: String): Collection<String> = buildSet {
if (packageName != BASE_PACKAGE) {
add("$BASE_PACKAGE.*")
}
diagnosticList.allDiagnostics.forEach { diagnostic ->
for (typeArgument in diagnostic.getAllTypeArguments()) {
typeArgument.collectClassNamesTo(this)
@@ -0,0 +1,20 @@
/*
* 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.diagnostics.jvm
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
object FirJvmErrors {
// Declarations
val CONFLICTING_JVM_DECLARATIONS by error0<PsiElement>()
}
@@ -15,8 +15,25 @@ import java.nio.file.Path
object DiagnosticClassGenerator {
fun generate(rootPath: Path, diagnosticList: DiagnosticList, packageName: String) {
val path = getGenerationPath(rootPath.toFile(), packageName)
KtDiagnosticClassRenderer.render(path.resolve("KtFirDiagnostics.kt"), diagnosticList, packageName)
KtDiagnosticClassImplementationRenderer.render(path.resolve("KtFirDiagnosticsImpl.kt"), diagnosticList, packageName)
FirDiagnosticToKtDiagnosticConverterRenderer.render(path.resolve("KtFirDataClassConverters.kt"), diagnosticList, packageName)
KtDiagnosticClassRenderer.render(
path.resolve("KtFirDiagnostics.kt"),
diagnosticList,
packageName,
"KtFirDiagnostics"
)
KtDiagnosticClassImplementationRenderer.render(
path.resolve("KtFirDiagnosticsImpl.kt"),
diagnosticList,
packageName,
"KtFirDiagnosticsImpl"
)
FirDiagnosticToKtDiagnosticConverterRenderer.render(
path.resolve("KtFirDataClassConverters.kt"),
diagnosticList,
packageName,
"KtFirDataClassConverters"
)
}
}
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.util.SmartPrinter
import java.io.File
abstract class AbstractDiagnosticsDataClassRenderer : DiagnosticListRenderer() {
override fun render(file: File, diagnosticList: DiagnosticList, packageName: String) {
override fun render(file: File, diagnosticList: DiagnosticList, packageName: String, containingObjectName: String) {
val hlDiagnosticsList = HLDiagnosticConverter.convert(diagnosticList)
file.writeToFileUsingSmartPrinterIfFileContentChanged { render(hlDiagnosticsList, packageName) }
}