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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
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.CLIConfigurationKeys;
|
||||||
import org.jetbrains.jet.cli.common.CompilerPlugin;
|
import org.jetbrains.jet.cli.common.CompilerPlugin;
|
||||||
import org.jetbrains.jet.cli.common.CompilerPluginContext;
|
import org.jetbrains.jet.cli.common.CompilerPluginContext;
|
||||||
@@ -346,7 +347,10 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
);
|
);
|
||||||
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION);
|
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION);
|
||||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||||
diagnosticHolder.getBindingContext().getDiagnostics(),
|
new FilteredJvmDiagnostics(
|
||||||
|
diagnosticHolder.getBindingContext().getDiagnostics(),
|
||||||
|
exhaust.getBindingContext().getDiagnostics()
|
||||||
|
),
|
||||||
environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
);
|
);
|
||||||
return generationState;
|
return generationState;
|
||||||
|
|||||||
+47
-37
@@ -66,53 +66,63 @@ public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Dia
|
|||||||
val result = doGetDiagnostics()
|
val result = doGetDiagnostics()
|
||||||
if (result == null) return null
|
if (result == null) return null
|
||||||
|
|
||||||
return object : Diagnostics by result {
|
return FilteredJvmDiagnostics(result, otherDiagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
private fun alreadyReported(psiElement: PsiElement): Boolean {
|
class FilteredJvmDiagnostics(val jvmDiagnostics: Diagnostics, val otherDiagnostics: Diagnostics) : Diagnostics by jvmDiagnostics {
|
||||||
return otherDiagnostics.forElement(psiElement).any { it.getFactory() in setOf(CONFLICTING_OVERLOADS, REDECLARATION) }
|
|
||||||
|| psiElement is JetPropertyAccessor && alreadyReported(psiElement.getParent()!!)
|
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 filtered = arrayListOf<Diagnostic>()
|
||||||
val jvmDiagnosticFactories = setOf(CONFLICTING_JVM_DECLARATIONS, ACCIDENTAL_OVERRIDE)
|
conflicting.groupBy {
|
||||||
fun Diagnostic.data() = cast(this, jvmDiagnosticFactories).getA()
|
it.data().signature.name
|
||||||
val (conflicting, other) = result.forElement(element).partition { it.getFactory() in jvmDiagnosticFactories }
|
}.forEach {
|
||||||
if (alreadyReported(psiElement)) {
|
val diagnostics = it.getValue()
|
||||||
// CONFLICTING_OVERLOADS already reported, no need to duplicate it
|
if (diagnostics.size <= 1) {
|
||||||
return other
|
filtered.addAll(diagnostics)
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
val filtered = arrayListOf<Diagnostic>()
|
filtered.addAll(
|
||||||
conflicting.groupBy {
|
diagnostics.filter {
|
||||||
it.data().signature.name
|
me ->
|
||||||
}.forEach {
|
diagnostics.none {
|
||||||
val diagnostics = it.getValue()
|
other ->
|
||||||
if (diagnostics.size <= 1) {
|
me != other && (
|
||||||
filtered.addAll(diagnostics)
|
// 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
|
||||||
else {
|
// there are paris of corresponding signatures that frequently clash simultaneously: package facade & part, trait and trait-impl
|
||||||
filtered.addAll(
|
|| other.data() higherThan me.data()
|
||||||
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 {
|
private fun ConflictingJvmDeclarationsData.higherThan(other: ConflictingJvmDeclarationsData): Boolean {
|
||||||
return when (other.classOrigin.originKind) {
|
return when (other.classOrigin.originKind) {
|
||||||
PACKAGE_PART -> this.classOrigin.originKind == PACKAGE_FACADE
|
PACKAGE_PART -> this.classOrigin.originKind == PACKAGE_FACADE
|
||||||
|
|||||||
@@ -11,3 +11,11 @@ class A : B() {
|
|||||||
|
|
||||||
fun getB(): Int = 1
|
fun getB(): Int = 1
|
||||||
val b: 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):
|
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 getA(): kotlin.Int
|
||||||
fun <get-a>(): 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):
|
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 <get-b>(): kotlin.Int
|
||||||
fun getB(): 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):
|
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 <get-b>(): kotlin.Int
|
||||||
fun getB(): 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
|
COMPILATION_ERROR
|
||||||
Reference in New Issue
Block a user