Filter diagnostics in the CLI compiler, as well as in the IDE
This commit is contained in:
+5
-1
@@ -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;
|
||||
|
||||
+47
-37
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user