Add support for ASTs without parents to suppress cache

This commit is contained in:
Ilya Chernikov
2021-10-15 12:40:25 +02:00
parent 7ef806b2ed
commit bfe31c97ac
3 changed files with 14 additions and 10 deletions
@@ -12,18 +12,18 @@ abstract class AbstractKotlinSuppressCache<Element> {
// The cache is weak: we're OK with losing it // The cache is weak: we're OK with losing it
protected val suppressors = ContainerUtil.createConcurrentWeakValueMap<Element, Suppressor<Element>>() protected val suppressors = ContainerUtil.createConcurrentWeakValueMap<Element, Suppressor<Element>>()
fun isSuppressed(element: Element, suppressionKey: String, severity: Severity) = fun isSuppressed(element: Element, rootElement: Element, suppressionKey: String, severity: Severity) =
isSuppressed(StringSuppressRequest(element, severity, suppressionKey.lowercase())) isSuppressed(StringSuppressRequest(element, rootElement, severity, suppressionKey.lowercase()))
protected open fun isSuppressed(request: SuppressRequest<Element>): Boolean { protected open fun isSuppressed(request: SuppressRequest<Element>): Boolean {
val annotated = getParentAnnotatedElement(request.element, false) ?: return false val annotated = getClosestAnnotatedAncestorElement(request.element, request.rootElement, false) ?: return false
return isSuppressedByAnnotated(request.suppressKey, request.severity, annotated, 0) return isSuppressedByAnnotated(request.suppressKey, request.severity, annotated, request.rootElement, 0)
} }
protected abstract fun getParentAnnotatedElement(element: Element, strict: Boolean): Element? protected abstract fun getClosestAnnotatedAncestorElement(element: Element, rootElement: Element, excludeSelf: Boolean): Element?
/* /*
The cache is optimized for the case where no warnings are suppressed (most frequent one) The cache is optimized for the case where no warnings are suppressed (most frequent one)
@@ -58,14 +58,15 @@ abstract class AbstractKotlinSuppressCache<Element> {
suppressionKey: String, suppressionKey: String,
severity: Severity, severity: Severity,
annotated: Element, annotated: Element,
rootElement: Element,
debugDepth: Int debugDepth: Int
): Boolean { ): Boolean {
val suppressor = getOrCreateSuppressor(annotated) val suppressor = getOrCreateSuppressor(annotated)
if (suppressor.isSuppressed(suppressionKey, severity)) return true if (suppressor.isSuppressed(suppressionKey, severity)) return true
val annotatedAbove = getParentAnnotatedElement(suppressor.annotatedElement, true) ?: return false val annotatedAbove = getClosestAnnotatedAncestorElement(suppressor.annotatedElement, rootElement, true) ?: return false
val suppressed = isSuppressedByAnnotated(suppressionKey, severity, annotatedAbove, debugDepth + 1) val suppressed = isSuppressedByAnnotated(suppressionKey, severity, annotatedAbove, rootElement, debugDepth + 1)
val suppressorAbove = suppressors[annotatedAbove] val suppressorAbove = suppressors[annotatedAbove]
if (suppressorAbove != null && suppressorAbove.dominates(suppressor)) { if (suppressorAbove != null && suppressorAbove.dominates(suppressor)) {
suppressors[annotated] = suppressorAbove suppressors[annotated] = suppressorAbove
@@ -126,12 +127,14 @@ abstract class AbstractKotlinSuppressCache<Element> {
protected interface SuppressRequest<Element> { protected interface SuppressRequest<Element> {
val element: Element val element: Element
val rootElement: Element
val severity: Severity val severity: Severity
val suppressKey: String val suppressKey: String
} }
private class StringSuppressRequest<Element>( private class StringSuppressRequest<Element>(
override val element: Element, override val element: Element,
override val rootElement: Element,
override val severity: Severity, override val severity: Severity,
override val suppressKey: String override val suppressKey: String
) : SuppressRequest<Element> ) : SuppressRequest<Element>
@@ -35,7 +35,7 @@ open class KtDiagnosticReporterWithContext(
) : DiagnosticReporter() { ) : DiagnosticReporter() {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) = diagnosticReporter.report(diagnostic, context) override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) = diagnosticReporter.report(diagnostic, context)
fun at(sourceElement: AbstractKtSourceElement?, containingFilePath: String): DiagnosticContextImpl = open fun at(sourceElement: AbstractKtSourceElement?, containingFilePath: String): DiagnosticContextImpl =
DiagnosticContextImpl(sourceElement, containingFilePath) DiagnosticContextImpl(sourceElement, containingFilePath)
open inner class DiagnosticContextImpl( open inner class DiagnosticContextImpl(
@@ -99,11 +99,12 @@ abstract class KotlinSuppressCache : AbstractKotlinSuppressCache<PsiElement>() {
return super.isSuppressed(request) return super.isSuppressed(request)
} }
override fun getParentAnnotatedElement(element: PsiElement, strict: Boolean) = override fun getClosestAnnotatedAncestorElement(element: PsiElement, rootElement: PsiElement, excludeSelf: Boolean): PsiElement? =
KtStubbedPsiUtil.getPsiOrStubParent(element, KtAnnotated::class.java, strict) KtStubbedPsiUtil.getPsiOrStubParent(element, KtAnnotated::class.java, excludeSelf)
protected class DiagnosticSuppressRequest(val diagnostic: Diagnostic) : SuppressRequest<PsiElement> { protected class DiagnosticSuppressRequest(val diagnostic: Diagnostic) : SuppressRequest<PsiElement> {
override val element: PsiElement get() = diagnostic.psiElement override val element: PsiElement get() = diagnostic.psiElement
override val rootElement: PsiElement get() = element.containingFile
override val severity: Severity get() = diagnostic.severity override val severity: Severity get() = diagnostic.severity
override val suppressKey: String get() = getDiagnosticSuppressKey(diagnostic) override val suppressKey: String get() = getDiagnosticSuppressKey(diagnostic)
} }