Implement semi-lazy PSI-based suppress cache for IR
calculates suppressions per root (KtFile) basis on demand.
This commit is contained in:
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.psi.KtScript
|
|||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
|
import org.jetbrains.kotlin.resolve.diagnostics.OnDemandSuppressCache
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.PrecomputedSuppressCache
|
import org.jetbrains.kotlin.resolve.diagnostics.PrecomputedSuppressCache
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
@@ -198,7 +199,7 @@ class GenerationState private constructor(
|
|||||||
val extraJvmDiagnosticsTrace: BindingTrace =
|
val extraJvmDiagnosticsTrace: BindingTrace =
|
||||||
DelegatingBindingTrace(
|
DelegatingBindingTrace(
|
||||||
originalFrontendBindingContext, "For extra diagnostics in ${this::class.java}", false,
|
originalFrontendBindingContext, "For extra diagnostics in ${this::class.java}", false,
|
||||||
customSuppressCache = if (isIrBackend) PrecomputedSuppressCache(originalFrontendBindingContext, files) else null,
|
customSuppressCache = if (isIrBackend) OnDemandSuppressCache(originalFrontendBindingContext) else null,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val interceptedBuilderFactory: ClassBuilderFactory
|
private val interceptedBuilderFactory: ClassBuilderFactory
|
||||||
|
|||||||
+49
@@ -59,3 +59,52 @@ class PrecomputedSuppressCache(context: BindingContext, files: List<KtFile>) : K
|
|||||||
override fun getSuppressionAnnotations(annotated: PsiElement): List<AnnotationDescriptor> =
|
override fun getSuppressionAnnotations(annotated: PsiElement): List<AnnotationDescriptor> =
|
||||||
storage[annotated].orEmpty()
|
storage[annotated].orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OnDemandSuppressCache(private val context: BindingContext) : KotlinSuppressCache() {
|
||||||
|
|
||||||
|
private val processedRoots = mutableSetOf<KtFile>()
|
||||||
|
|
||||||
|
private val storage = mutableMapOf<PsiElement, List<AnnotationDescriptor>>()
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun ensureRootProcessed(rootElement: PsiElement) {
|
||||||
|
require(rootElement is KtFile)
|
||||||
|
if (!processedRoots.contains(rootElement)) {
|
||||||
|
val visitor = PrecomputingVisitor(storage, BindingContextSuppressCache(context))
|
||||||
|
rootElement.accept(visitor, null)
|
||||||
|
processedRoots.add(rootElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PrecomputingVisitor(
|
||||||
|
val storage: MutableMap<PsiElement, List<AnnotationDescriptor>>,
|
||||||
|
val computer: KotlinSuppressCache,
|
||||||
|
) : KtTreeVisitorVoid() {
|
||||||
|
override fun visitKtElement(element: KtElement) {
|
||||||
|
super.visitKtElement(element)
|
||||||
|
if (element is KtAnnotated) {
|
||||||
|
computeAnnotations(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitKtFile(file: KtFile) {
|
||||||
|
super.visitKtFile(file)
|
||||||
|
computeAnnotations(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeAnnotations(element: KtAnnotated) {
|
||||||
|
val suppressions = computer.getSuppressionAnnotations(element).filter { it.fqName == StandardNames.FqNames.suppress }
|
||||||
|
if (suppressions.isNotEmpty()) {
|
||||||
|
storage[element] = suppressions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSuppressionAnnotations(annotated: PsiElement): List<AnnotationDescriptor> =
|
||||||
|
storage[annotated].orEmpty()
|
||||||
|
|
||||||
|
override fun getClosestAnnotatedAncestorElement(element: PsiElement, rootElement: PsiElement, excludeSelf: Boolean): PsiElement? {
|
||||||
|
ensureRootProcessed(rootElement)
|
||||||
|
return super.getClosestAnnotatedAncestorElement(element, rootElement, excludeSelf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user