From 9ecbeeb100f7b6f03f3db583fda074e416706c08 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 17 Jun 2014 17:40:45 +0400 Subject: [PATCH] Filter diagnostics in the CLI compiler, as well as in the IDE --- .../compiler/KotlinToJVMBytecodeCompiler.java | 6 +- .../jet/asJava/duplicateJvmSignatureUtil.kt | 84 +++++++++++-------- compiler/testData/cli/jvm/signatureClash.kt | 8 ++ compiler/testData/cli/jvm/signatureClash.out | 12 +-- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index d614ece9389..1053bd84883 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -30,6 +30,7 @@ import kotlin.modules.Module; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.analyzer.AnalyzeExhaust; +import org.jetbrains.jet.asJava.FilteredJvmDiagnostics; import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.CompilerPlugin; import org.jetbrains.jet.cli.common.CompilerPluginContext; @@ -346,7 +347,10 @@ public class KotlinToJVMBytecodeCompiler { ); KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION); AnalyzerWithCompilerReport.reportDiagnostics( - diagnosticHolder.getBindingContext().getDiagnostics(), + new FilteredJvmDiagnostics( + diagnosticHolder.getBindingContext().getDiagnostics(), + exhaust.getBindingContext().getDiagnostics() + ), environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) ); return generationState; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt index d4d6aad8852..77a68c51909 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/duplicateJvmSignatureUtil.kt @@ -66,53 +66,63 @@ public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Dia val result = doGetDiagnostics() if (result == null) return null - return object : Diagnostics by result { + return FilteredJvmDiagnostics(result, otherDiagnostics) +} - private fun alreadyReported(psiElement: PsiElement): Boolean { - return otherDiagnostics.forElement(psiElement).any { it.getFactory() in setOf(CONFLICTING_OVERLOADS, REDECLARATION) } - || psiElement is JetPropertyAccessor && alreadyReported(psiElement.getParent()!!) +class FilteredJvmDiagnostics(val jvmDiagnostics: Diagnostics, val otherDiagnostics: Diagnostics) : Diagnostics by jvmDiagnostics { + + private fun alreadyReported(psiElement: PsiElement): Boolean { + return otherDiagnostics.forElement(psiElement).any { it.getFactory() in setOf(CONFLICTING_OVERLOADS, REDECLARATION) } + || psiElement is JetPropertyAccessor && alreadyReported(psiElement.getParent()!!) + } + + override fun forElement(psiElement: PsiElement): Collection { + val jvmDiagnosticFactories = setOf(CONFLICTING_JVM_DECLARATIONS, ACCIDENTAL_OVERRIDE) + fun Diagnostic.data() = cast(this, jvmDiagnosticFactories).getA() + val (conflicting, other) = jvmDiagnostics.forElement(psiElement).partition { it.getFactory() in jvmDiagnosticFactories } + if (alreadyReported(psiElement)) { + // CONFLICTING_OVERLOADS already reported, no need to duplicate it + return other } - override fun forElement(psiElement: PsiElement): Collection { - val jvmDiagnosticFactories = setOf(CONFLICTING_JVM_DECLARATIONS, ACCIDENTAL_OVERRIDE) - fun Diagnostic.data() = cast(this, jvmDiagnosticFactories).getA() - val (conflicting, other) = result.forElement(element).partition { it.getFactory() in jvmDiagnosticFactories } - if (alreadyReported(psiElement)) { - // CONFLICTING_OVERLOADS already reported, no need to duplicate it - return other + val filtered = arrayListOf() + conflicting.groupBy { + it.data().signature.name + }.forEach { + val diagnostics = it.getValue() + if (diagnostics.size <= 1) { + filtered.addAll(diagnostics) } - - val filtered = arrayListOf() - conflicting.groupBy { - it.data().signature.name - }.forEach { - val diagnostics = it.getValue() - 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 - me.getFactory() == ACCIDENTAL_OVERRIDE && other.getFactory() == CONFLICTING_JVM_DECLARATIONS - // there are paris of corresponding signatures that frequently clash simultaneously: package facade & part, trait and trait-impl - || other.data() higherThan me.data() - ) - } + 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 + me.getFactory() == ACCIDENTAL_OVERRIDE && other.getFactory() == CONFLICTING_JVM_DECLARATIONS + // there are paris of corresponding signatures that frequently clash simultaneously: package facade & part, trait and trait-impl + || other.data() higherThan me.data() + ) } - ) - } + } + ) } - - return filtered + other } + + return filtered + other + } + + override fun all(): Collection { + return jvmDiagnostics.all() + .map { it.getPsiElement() } + .toSet() + .flatMap { forElement(it) } } } + private fun ConflictingJvmDeclarationsData.higherThan(other: ConflictingJvmDeclarationsData): Boolean { return when (other.classOrigin.originKind) { PACKAGE_PART -> this.classOrigin.originKind == PACKAGE_FACADE diff --git a/compiler/testData/cli/jvm/signatureClash.kt b/compiler/testData/cli/jvm/signatureClash.kt index 8950ade0ba9..f30912fab90 100644 --- a/compiler/testData/cli/jvm/signatureClash.kt +++ b/compiler/testData/cli/jvm/signatureClash.kt @@ -11,3 +11,11 @@ class A : B() { fun getB(): Int = 1 val b: Int = 1 + +trait Tr { + fun getTr() = 1 +} + +class SubTr : Tr { + val tr = 1 +} diff --git a/compiler/testData/cli/jvm/signatureClash.out b/compiler/testData/cli/jvm/signatureClash.out index 05743a714c9..1ec967b1da2 100644 --- a/compiler/testData/cli/jvm/signatureClash.out +++ b/compiler/testData/cli/jvm/signatureClash.out @@ -7,16 +7,16 @@ ERROR: $TESTDATA_DIR$/signatureClash.kt: (8, 5) Platform declaration clash: The ERROR: $TESTDATA_DIR$/signatureClash.kt: (9, 5) Platform declaration clash: The following declarations have the same JVM signature (getA()I): fun getA(): kotlin.Int fun (): kotlin.Int -ERROR: $TESTDATA_DIR$/signatureClash.kt: (12, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I): - fun getB(): kotlin.Int - fun (): kotlin.Int ERROR: $TESTDATA_DIR$/signatureClash.kt: (12, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I): fun (): kotlin.Int fun getB(): kotlin.Int -ERROR: $TESTDATA_DIR$/signatureClash.kt: (13, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I): - fun getB(): kotlin.Int - fun (): kotlin.Int ERROR: $TESTDATA_DIR$/signatureClash.kt: (13, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I): fun (): kotlin.Int fun getB(): kotlin.Int +ERROR: $TESTDATA_DIR$/signatureClash.kt: (16, 5) Platform declaration clash: The following declarations have the same JVM signature (getTr()I): + fun (): kotlin.Int + fun getTr(): kotlin.Int +ERROR: $TESTDATA_DIR$/signatureClash.kt: (20, 5) Platform declaration clash: The following declarations have the same JVM signature (getTr()I): + fun (): kotlin.Int + fun getTr(): kotlin.Int COMPILATION_ERROR \ No newline at end of file