diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 5758ea74112..eadf8d3e037 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -52,8 +52,12 @@ import org.jetbrains.kotlin.codegen.KotlinCodegenFacade import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.fir.FirPsiSourceElement 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.jvm.FirJvmBackendClassResolver 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.psi.KtFile 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.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize @@ -356,17 +361,28 @@ object KotlinToJVMBytecodeCompiler { val firProvider = (session.firProvider as FirProviderImpl) val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false) val resolveTransformer = FirTotalResolveProcessor(session) + val collector = FirDiagnosticsCollector.create(session) + val diagnostics = mutableListOf>() val firFiles = ktFiles.map { val firFile = builder.buildFirFile(it) firProvider.recordFile(firFile) firFile - }.also { + }.also { firFiles -> try { - resolveTransformer.process(it) + resolveTransformer.process(firFiles) + firFiles.forEach { + diagnostics += collector.collectDiagnostics(it) + } } catch (e: Exception) { throw e } } + AnalyzerWithCompilerReport.reportDiagnostics( + SimpleDiagnostics( + diagnostics.map { it.toRegularDiagnostic() } + ), + environment.messageCollector + ) val debugTargetDescription = "target " + module.getModuleName() + "-" + module.getModuleType() + " " val codeLines = environment.countLinesOfCode(ktFiles) @@ -442,6 +458,30 @@ object KotlinToJVMBytecodeCompiler { 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): List = if (buildFile == null) sourceFilePaths else sourceFilePaths.map { path -> diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 680282d60f5..953d5d3ef98 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages 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.PROPERTY_NAME 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_PROPERTY_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.HIDDEN 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) // 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_PROPERTY_TYPE, "{0} property exposes its {2} type{1}", TO_STRING, TO_STRING, 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_RECEIVER_TYPE, "{0} member exposes its {2} receiver type{1}", TO_STRING, TO_STRING, TO_STRING) - map.put(EXPOSED_PARAMETER_TYPE, "{0} function exposes its {2} parameter 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, DECLARATION_NAME, 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, DECLARATION_NAME, 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 - map.put(UNINITIALIZED_VARIABLE, "{2} must be initialized before access", PROPERTY_NAME) + map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index 092f24e9088..906466b40e8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -6,6 +6,9 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics 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.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol @@ -35,4 +38,22 @@ object FirDiagnosticRenderers { val PROPERTY_NAME = Renderer { symbol: FirPropertySymbol -> 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() + } } diff --git a/compiler/testData/cli/jvm/firError.kt b/compiler/testData/cli/jvm/firError.kt index 1db83d80401..0f69e68b9d8 100644 --- a/compiler/testData/cli/jvm/firError.kt +++ b/compiler/testData/cli/jvm/firError.kt @@ -3,4 +3,10 @@ fun println(val x: Int) {} fun main() { val x: Int println(x) +} + +private class Private + +class Public : Private() { + val x: Private } \ No newline at end of file diff --git a/compiler/testData/cli/jvm/firError.out b/compiler/testData/cli/jvm/firError.out index d86bac9de59..227a5ce78d0 100644 --- a/compiler/testData/cli/jvm/firError.out +++ b/compiler/testData/cli/jvm/firError.out @@ -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