Revert "Revert "[light classes] drop old light classes and backend: iteration #9""
This reverts commit 38c623bc3a.
This commit is contained in:
-25
@@ -1,25 +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.asJava;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
||||
|
||||
public interface KotlinExtraDiagnosticsProvider {
|
||||
@NotNull
|
||||
Diagnostics forClassOrObject(@NotNull KtClassOrObject kclass);
|
||||
|
||||
@NotNull
|
||||
Diagnostics forFacade(@NotNull KtFile file, @NotNull GlobalSearchScope moduleScope);
|
||||
|
||||
static @NotNull KotlinExtraDiagnosticsProvider getInstance(@NotNull Project project) {
|
||||
return project.getService(KotlinExtraDiagnosticsProvider.class);
|
||||
}
|
||||
}
|
||||
@@ -1,130 +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.asJava
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.classes.safeIsScript
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
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.*
|
||||
|
||||
fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? {
|
||||
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
|
||||
val outermostClass = getOutermostClassOrObject(ktClassOrObject)
|
||||
return KotlinExtraDiagnosticsProvider.getInstance(ktClassOrObject.project).forClassOrObject(outermostClass)
|
||||
}
|
||||
|
||||
fun doGetDiagnostics(): Diagnostics? {
|
||||
//TODO: enable this diagnostic when light classes for scripts are ready
|
||||
if ((element.containingFile as? KtFile)?.safeIsScript() == true) return null
|
||||
|
||||
var parent = element.parent
|
||||
if (element is KtPropertyAccessor) {
|
||||
parent = parent?.parent
|
||||
}
|
||||
if (element is KtParameter && element.hasValOrVar()) {
|
||||
// property declared in constructor
|
||||
val parentClass = (parent?.parent?.parent as? KtClass)
|
||||
if (parentClass != null) {
|
||||
return getDiagnosticsForClass(parentClass)
|
||||
}
|
||||
}
|
||||
if (element is KtClassOrObject) {
|
||||
return getDiagnosticsForClass(element)
|
||||
}
|
||||
|
||||
when (parent) {
|
||||
is KtFile -> {
|
||||
return KotlinExtraDiagnosticsProvider.getInstance(parent.project).forFacade(parent, moduleScope)
|
||||
}
|
||||
|
||||
is KtClassBody -> {
|
||||
val parentsParent = parent.getParent()
|
||||
|
||||
if (parentsParent is KtClassOrObject) {
|
||||
return getDiagnosticsForClass(parentsParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
val result = doGetDiagnostics() ?: return null
|
||||
|
||||
return FilteredJvmDiagnostics(result, otherDiagnostics)
|
||||
}
|
||||
|
||||
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 -> this.classOrigin.originKind != INTERFACE_DEFAULT_IMPL
|
||||
MULTIFILE_CLASS_PART -> this.classOrigin.originKind == MULTIFILE_CLASS
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user