All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.resolve.diagnostics.OnDemandSuppressCache.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2020 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.resolve.diagnostics

import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.resolve.BindingContext

class OnDemandSuppressCache(private val context: BindingContext) : KotlinSuppressCache() {
    private val processedRoots = mutableSetOf()

    private val storage = mutableMapOf>()

    @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>,
        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 =
        storage[annotated].orEmpty()

    override fun getClosestAnnotatedAncestorElement(element: PsiElement, rootElement: PsiElement, excludeSelf: Boolean): PsiElement? {
        ensureRootProcessed(rootElement)
        return super.getClosestAnnotatedAncestorElement(element, rootElement, excludeSelf)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy