JVM: remove FilteredJvmDiagnostics

The purpose of this class was to avoid reporting conflicting JVM
signatures / accidental override errors when there's a similar (e.g.
conflicting overloads) diagnostic already reported.

It was not used meaningfully because it only affected diagnostics
reported by the old JVM backend. Also, in real life, backend diagnostics
would not be reported anyway in most cases because backend is not even
run if there's an error after frontend.
This commit is contained in:
Alexander Udalov
2024-03-12 16:58:40 +01:00
committed by Space Team
parent b4d65fe5cd
commit 5cbaf077f3
3 changed files with 8 additions and 94 deletions
@@ -10,11 +10,14 @@ package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsageForPsi
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.prepareJvmSessions
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.ModuleCompilerEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.ModuleCompilerIrBackendInput
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.convertToIrAndActualizeForJvm
@@ -52,7 +55,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -262,10 +264,7 @@ object FirKotlinToJvmBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
FilteredJvmDiagnostics(
generationState.collectedExtraJvmDiagnostics,
Diagnostics.EMPTY
),
generationState.collectedExtraJvmDiagnostics,
messageCollector,
renderDiagnosticName
)
@@ -145,7 +145,7 @@ object KotlinToJVMBytecodeCompiler {
for (input in codegenInputs) {
// Codegen (per module)
outputs += runCodegen(input, input.state, codegenFactory, bindingContext, diagnosticsReporter, compilerConfiguration)
outputs += runCodegen(input, input.state, codegenFactory, diagnosticsReporter, compilerConfiguration)
}
return writeOutputsIfNeeded(project, compilerConfiguration, messageCollector, outputs, mainClassFqName)
@@ -309,7 +309,7 @@ object KotlinToJVMBytecodeCompiler {
environment, environment.configuration, result.moduleDescriptor, result.bindingContext,
environment.getSourceFiles(), null, codegenFactory, backendInput, diagnosticsReporter
)
return runCodegen(input, input.state, codegenFactory, result.bindingContext, diagnosticsReporter, environment.configuration)
return runCodegen(input, input.state, codegenFactory, diagnosticsReporter, environment.configuration)
}
private fun convertToIr(environment: KotlinCoreEnvironment, result: AnalysisResult): Pair<CodegenFactory, CodegenFactory.BackendInput> {
@@ -468,7 +468,6 @@ object KotlinToJVMBytecodeCompiler {
codegenInput: CodegenFactory.CodegenInput,
state: GenerationState,
codegenFactory: CodegenFactory,
bindingContext: BindingContext,
diagnosticsReporter: BaseDiagnosticsCollector,
configuration: CompilerConfiguration,
): GenerationState {
@@ -489,10 +488,7 @@ object KotlinToJVMBytecodeCompiler {
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
AnalyzerWithCompilerReport.reportDiagnostics(
FilteredJvmDiagnostics(
state.collectedExtraJvmDiagnostics,
bindingContext.diagnostics
),
state.collectedExtraJvmDiagnostics,
messageCollector,
configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
)
@@ -1,81 +0,0 @@
/*
* Copyright 2010-2022 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.cli.jvm.compiler
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
class FilteredJvmDiagnostics(val jvmDiagnostics: Diagnostics, val otherDiagnostics: Diagnostics) : Diagnostics by jvmDiagnostics {
companion object {
private val higherPriorityDiagnosticFactories =
setOf(CONFLICTING_OVERLOADS, REDECLARATION, NOTHING_TO_OVERRIDE, MANY_IMPL_MEMBER_NOT_IMPLEMENTED)
private val jvmDiagnosticFactories =
setOf(CONFLICTING_JVM_DECLARATIONS, ACCIDENTAL_OVERRIDE, CONFLICTING_INHERITED_JVM_DECLARATIONS)
}
private fun alreadyReported(psiElement: PsiElement): Boolean {
return otherDiagnostics.forElement(psiElement).any { it.factory in higherPriorityDiagnosticFactories }
|| psiElement is KtPropertyAccessor && alreadyReported(psiElement.parent)
}
override fun forElement(psiElement: PsiElement): Collection<Diagnostic> {
fun Diagnostic.data() = DiagnosticFactory.cast(this, jvmDiagnosticFactories).a
val (conflicting, other) = jvmDiagnostics.forElement(psiElement).partition { it.factory in jvmDiagnosticFactories }
if (alreadyReported(psiElement)) {
// CONFLICTING_OVERLOADS already reported, no need to duplicate it
return other
}
val filtered = arrayListOf<Diagnostic>()
conflicting.groupBy {
it.data().signature.name
}.forEach {
val diagnostics = it.value
if (diagnostics.size <= 1) {
filtered.addAll(diagnostics)
} else {
filtered.addAll(
diagnostics.filter { me ->
diagnostics.none { other ->
me != other && (
// in case of implementation copied from a super trait there will be both diagnostics on the same signature
other.factory == CONFLICTING_JVM_DECLARATIONS && (me.factory == ACCIDENTAL_OVERRIDE ||
me.factory == CONFLICTING_INHERITED_JVM_DECLARATIONS)
// there are paris of corresponding signatures that frequently clash simultaneously: multifile class & part, trait and trait-impl
|| other.data().higherThan(me.data())
)
}
}
)
}
}
return filtered + other
}
override fun all(): Collection<Diagnostic> {
return jvmDiagnostics.all()
.map { it.psiElement }
.toSet()
.flatMap { forElement(it) }
}
}
private infix fun ConflictingJvmDeclarationsData.higherThan(other: ConflictingJvmDeclarationsData): Boolean {
return when (other.classOrigin?.originKind) {
INTERFACE_DEFAULT_IMPL -> classOrigin?.originKind != INTERFACE_DEFAULT_IMPL
MULTIFILE_CLASS_PART -> classOrigin?.originKind == MULTIFILE_CLASS
else -> false
}
}