Filter diagnostics in the CLI compiler, as well as in the IDE

This commit is contained in:
Andrey Breslav
2014-06-17 17:40:45 +04:00
parent 61c7c2f1a1
commit 9ecbeeb100
4 changed files with 66 additions and 44 deletions
@@ -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;
@@ -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<Diagnostic> {
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<Diagnostic> {
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<Diagnostic>()
conflicting.groupBy {
it.data().signature.name
}.forEach {
val diagnostics = it.getValue()
if (diagnostics.size <= 1) {
filtered.addAll(diagnostics)
}
val filtered = arrayListOf<Diagnostic>()
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<Diagnostic> {
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
@@ -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
}
+6 -6
View File
@@ -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 <get-a>(): 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 <get-b>(): kotlin.Int
ERROR: $TESTDATA_DIR$/signatureClash.kt: (12, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I):
fun <get-b>(): 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 <get-b>(): kotlin.Int
ERROR: $TESTDATA_DIR$/signatureClash.kt: (13, 1) Platform declaration clash: The following declarations have the same JVM signature (getB()I):
fun <get-b>(): 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 <get-tr>(): 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 <get-tr>(): kotlin.Int
fun getTr(): kotlin.Int
COMPILATION_ERROR