[FIR] Add diagnostic collection to KotlinToJVMBytecodeCompiler
This commit is contained in:
+42
-2
@@ -52,8 +52,12 @@ import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
|
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
|
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmClassCodegen
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmClassCodegen
|
||||||
@@ -83,6 +87,7 @@ import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
|||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
||||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||||
@@ -356,17 +361,28 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
val firProvider = (session.firProvider as FirProviderImpl)
|
val firProvider = (session.firProvider as FirProviderImpl)
|
||||||
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
|
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
|
||||||
val resolveTransformer = FirTotalResolveProcessor(session)
|
val resolveTransformer = FirTotalResolveProcessor(session)
|
||||||
|
val collector = FirDiagnosticsCollector.create(session)
|
||||||
|
val diagnostics = mutableListOf<FirDiagnostic<*>>()
|
||||||
val firFiles = ktFiles.map {
|
val firFiles = ktFiles.map {
|
||||||
val firFile = builder.buildFirFile(it)
|
val firFile = builder.buildFirFile(it)
|
||||||
firProvider.recordFile(firFile)
|
firProvider.recordFile(firFile)
|
||||||
firFile
|
firFile
|
||||||
}.also {
|
}.also { firFiles ->
|
||||||
try {
|
try {
|
||||||
resolveTransformer.process(it)
|
resolveTransformer.process(firFiles)
|
||||||
|
firFiles.forEach {
|
||||||
|
diagnostics += collector.collectDiagnostics(it)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||||
|
SimpleDiagnostics(
|
||||||
|
diagnostics.map { it.toRegularDiagnostic() }
|
||||||
|
),
|
||||||
|
environment.messageCollector
|
||||||
|
)
|
||||||
|
|
||||||
val debugTargetDescription = "target " + module.getModuleName() + "-" + module.getModuleType() + " "
|
val debugTargetDescription = "target " + module.getModuleName() + "-" + module.getModuleType() + " "
|
||||||
val codeLines = environment.countLinesOfCode(ktFiles)
|
val codeLines = environment.countLinesOfCode(ktFiles)
|
||||||
@@ -442,6 +458,30 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
return writeOutputs(environment, projectConfiguration, chunk, outputs)
|
return writeOutputs(environment, projectConfiguration, chunk, outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirDiagnostic<*>.toRegularDiagnostic(): Diagnostic {
|
||||||
|
val psiSource = element as FirPsiSourceElement<*>
|
||||||
|
@Suppress("TYPE_MISMATCH")
|
||||||
|
when (this) {
|
||||||
|
is FirSimpleDiagnostic ->
|
||||||
|
return SimpleDiagnostic(
|
||||||
|
psiSource.psi, factory.psiDiagnosticFactory, severity
|
||||||
|
)
|
||||||
|
is FirDiagnosticWithParameters1<*, *> ->
|
||||||
|
return DiagnosticWithParameters1(
|
||||||
|
psiSource.psi, this.a, factory.psiDiagnosticFactory, severity
|
||||||
|
)
|
||||||
|
is FirDiagnosticWithParameters2<*, *, *> ->
|
||||||
|
return DiagnosticWithParameters2(
|
||||||
|
psiSource.psi, this.a, this.b, factory.psiDiagnosticFactory, severity
|
||||||
|
)
|
||||||
|
is FirDiagnosticWithParameters3<*, *, *, *> ->
|
||||||
|
return DiagnosticWithParameters3(
|
||||||
|
psiSource.psi, this.a, this.b, this.c, factory.psiDiagnosticFactory, severity
|
||||||
|
)
|
||||||
|
}
|
||||||
|
throw IllegalArgumentException("Unknown diagnostics: $this")
|
||||||
|
}
|
||||||
|
|
||||||
private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
||||||
if (buildFile == null) sourceFilePaths
|
if (buildFile == null) sourceFilePaths
|
||||||
else sourceFilePaths.map { path ->
|
else sourceFilePaths.map { path ->
|
||||||
|
|||||||
+10
-6
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
||||||
@@ -22,6 +24,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_RECEIVER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_RECEIVER_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
|
||||||
@@ -79,14 +82,15 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
||||||
|
|
||||||
// Exposed visibility group
|
// Exposed visibility group
|
||||||
map.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "{0} typealias exposes {2} in expanded type{1}", TO_STRING, TO_STRING, TO_STRING)
|
map.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "{0} typealias exposes {2} in expanded type {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type{1}", TO_STRING, TO_STRING, TO_STRING)
|
map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
map.put(EXPOSED_FUNCTION_RETURN_TYPE, "{0} function exposes its {2} return type{1}", TO_STRING, TO_STRING, TO_STRING)
|
map.put(EXPOSED_FUNCTION_RETURN_TYPE, "{0} function exposes its {2} return type {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
map.put(EXPOSED_RECEIVER_TYPE, "{0} member exposes its {2} receiver type{1}", TO_STRING, TO_STRING, TO_STRING)
|
map.put(EXPOSED_RECEIVER_TYPE, "{0} member exposes its {2} receiver type {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
map.put(EXPOSED_PARAMETER_TYPE, "{0} function exposes its {2} parameter type{1}", TO_STRING, TO_STRING, TO_STRING)
|
map.put(EXPOSED_PARAMETER_TYPE, "{0} function exposes its {2} parameter type {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
|
map.put(EXPOSED_SUPER_CLASS, "{0} subclass exposes its {2} supertype {1}", TO_STRING, DECLARATION_NAME, TO_STRING)
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
map.put(UNINITIALIZED_VARIABLE, "{2} must be initialized before access", PROPERTY_NAME)
|
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -6,6 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
@@ -35,4 +38,22 @@ object FirDiagnosticRenderers {
|
|||||||
val PROPERTY_NAME = Renderer { symbol: FirPropertySymbol ->
|
val PROPERTY_NAME = Renderer { symbol: FirPropertySymbol ->
|
||||||
symbol.fir.name.asString()
|
symbol.fir.name.asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val FIR = Renderer { element: FirElement ->
|
||||||
|
element.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
val DECLARATION_NAME = Renderer { declaration: FirMemberDeclaration ->
|
||||||
|
val name = when (declaration) {
|
||||||
|
is FirProperty -> declaration.name
|
||||||
|
is FirSimpleFunction -> declaration.name
|
||||||
|
is FirRegularClass -> declaration.name
|
||||||
|
is FirTypeAlias -> declaration.name
|
||||||
|
is FirEnumEntry -> declaration.name
|
||||||
|
is FirField -> declaration.name
|
||||||
|
is FirConstructor -> return@Renderer "constructor"
|
||||||
|
else -> return@Renderer "???"
|
||||||
|
}
|
||||||
|
name.asString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -3,4 +3,10 @@ fun println(val x: Int) {}
|
|||||||
fun main() {
|
fun main() {
|
||||||
val x: Int
|
val x: Int
|
||||||
println(x)
|
println(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Private
|
||||||
|
|
||||||
|
class Public : Private() {
|
||||||
|
val x: Private
|
||||||
}
|
}
|
||||||
+10
-1
@@ -1 +1,10 @@
|
|||||||
OK
|
compiler/testData/cli/jvm/firError.kt:5:13: error: x must be initialized before access
|
||||||
|
println(x)
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/firError.kt:10:16: error: public subclass exposes its private supertype Private
|
||||||
|
class Public : Private() {
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/firError.kt:11:9: error: public property exposes its private type Private
|
||||||
|
val x: Private
|
||||||
|
^
|
||||||
|
COMPILATION_ERROR
|
||||||
|
|||||||
Reference in New Issue
Block a user