[IR] Move KtDiagnosticReporterWithImplicitIrBasedContext to ir.tree
So that it could be accessible from the `ir.serialization.common` module
This commit is contained in:
committed by
Space Team
parent
6b6ed12df1
commit
f88d09a2f6
-142
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.diagnostics.AbstractKotlinSuppressCache
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticReporterWithContext
|
||||
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.path
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.hasEqualFqName
|
||||
import org.jetbrains.kotlin.ir.util.sourceElement
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.*
|
||||
|
||||
class KtDiagnosticReporterWithImplicitIrBasedContext(
|
||||
diagnosticReporter: DiagnosticReporter,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) : KtDiagnosticReporterWithContext(diagnosticReporter, languageVersionSettings), IrDiagnosticReporter {
|
||||
|
||||
private val suppressCache = IrBasedSuppressCache()
|
||||
|
||||
private fun IrElement.toSourceElement(containingIrFile: IrFile) =
|
||||
(PsiSourceManager.findPsiElement(this, containingIrFile)?.let(::KtRealPsiSourceElement)
|
||||
?: sourceElement())
|
||||
|
||||
override fun at(irElement: IrElement, containingIrDeclaration: IrDeclaration): DiagnosticContextImpl =
|
||||
at(irElement, containingIrDeclaration.file)
|
||||
|
||||
override fun at(irDeclaration: IrDeclaration): DiagnosticContextImpl =
|
||||
at(irDeclaration, irDeclaration.file)
|
||||
|
||||
override fun at(irElement: IrElement, containingIrFile: IrFile): DiagnosticContextImpl =
|
||||
at(irElement.toSourceElement(containingIrFile), irElement, containingIrFile)
|
||||
|
||||
override fun at(
|
||||
sourceElement: AbstractKtSourceElement?,
|
||||
irElement: IrElement,
|
||||
containingFile: IrFile
|
||||
): DiagnosticContextImpl =
|
||||
DiagnosticContextWithSuppressionImpl(sourceElement, irElement, containingFile)
|
||||
|
||||
override fun at(sourceElement: AbstractKtSourceElement?, containingFilePath: String): DiagnosticContextImpl {
|
||||
error("Should not be called directly")
|
||||
}
|
||||
|
||||
internal inner class DiagnosticContextWithSuppressionImpl(
|
||||
sourceElement: AbstractKtSourceElement?,
|
||||
private val irElement: IrElement,
|
||||
private val containingFile: IrFile
|
||||
) : DiagnosticContextImpl(sourceElement, containingFile.path) {
|
||||
|
||||
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean =
|
||||
suppressCache.isSuppressed(
|
||||
irElement, containingFile, diagnostic.factory.name.lowercase(), diagnostic.severity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal class IrBasedSuppressCache : AbstractKotlinSuppressCache<IrElement>() {
|
||||
|
||||
private val annotatedAncestorsPerRoot = mutableMapOf<IrElement, MutableMap<IrElement, IrElement>>()
|
||||
|
||||
private val annotationKeys = mutableMapOf<IrElement, Set<String>>()
|
||||
|
||||
@Synchronized
|
||||
private fun ensureRootProcessed(rootElement: IrElement) =
|
||||
annotatedAncestorsPerRoot.getOrPut(rootElement) {
|
||||
val visitor = AnnotatedTreeVisitor()
|
||||
rootElement.accept(visitor, Stack())
|
||||
visitor.annotatedAncestors
|
||||
}
|
||||
|
||||
private inner class AnnotatedTreeVisitor : IrElementVisitor<Unit, Stack<IrElement>> {
|
||||
|
||||
val annotatedAncestors = mutableMapOf<IrElement, IrElement>()
|
||||
|
||||
override fun visitElement(element: IrElement, data: Stack<IrElement>) {
|
||||
if (data.isNotEmpty()) {
|
||||
annotatedAncestors[element] = data.peek()
|
||||
}
|
||||
val isAnnotated = collectSuppressAnnotationKeys(element)
|
||||
if (isAnnotated) {
|
||||
data.push(element)
|
||||
}
|
||||
element.acceptChildren(this, data)
|
||||
if (isAnnotated) {
|
||||
data.pop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectSuppressAnnotationKeys(element: IrElement): Boolean =
|
||||
(element as? IrAnnotationContainer)?.annotations?.filter {
|
||||
it.type.classOrNull?.owner?.hasEqualFqName(SUPPRESS) == true
|
||||
}?.flatMap {
|
||||
buildList {
|
||||
fun addIfStringConst(irConst: IrConst<*>) {
|
||||
if (irConst.kind == IrConstKind.String) {
|
||||
add((irConst.value as String).lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
for (i in 0 until it.valueArgumentsCount) {
|
||||
when (val arg = it.getValueArgument(i)) {
|
||||
is IrConst<*> -> addIfStringConst(arg)
|
||||
is IrConstantArray -> arg.elements.filterIsInstance<IrConstantPrimitive>().forEach {
|
||||
addIfStringConst(it.value)
|
||||
}
|
||||
// TODO: consider leaving only this branch
|
||||
is IrVararg -> arg.elements.filterIsInstance<IrConst<*>>().forEach {
|
||||
addIfStringConst(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}?.takeIf { it.isNotEmpty() }?.also {
|
||||
annotationKeys[element] = it.toSet()
|
||||
} != null
|
||||
}
|
||||
|
||||
override fun getClosestAnnotatedAncestorElement(element: IrElement, rootElement: IrElement, excludeSelf: Boolean): IrElement? {
|
||||
val annotatedAncestors = ensureRootProcessed(rootElement)
|
||||
return if (!excludeSelf && annotationKeys.containsKey(element)) element else annotatedAncestors[element]
|
||||
}
|
||||
|
||||
override fun getSuppressingStrings(annotated: IrElement): Set<String> = annotationKeys[annotated].orEmpty()
|
||||
}
|
||||
|
||||
private val SUPPRESS = FqName("kotlin.Suppress")
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.backend.common.psi
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.fileOrNull
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object PsiSourceManager {
|
||||
fun <E : PsiElement> findPsiElement(irElement: IrElement, irFile: IrFile, psiElementClass: KClass<E>): E? {
|
||||
val psiFileEntry = irFile.fileEntry as? PsiIrFileEntry ?: return null
|
||||
return psiFileEntry.findPsiElement(irElement, psiElementClass)
|
||||
}
|
||||
|
||||
fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
val psiFileEntry = irFile.fileEntry as? PsiIrFileEntry ?: return null
|
||||
return psiFileEntry.findPsiElement(irElement)
|
||||
}
|
||||
|
||||
fun <E : PsiElement> findPsiElement(irElement: IrElement, irDeclaration: IrDeclaration, psiElementClass: KClass<E>): E? {
|
||||
val irFile = irDeclaration.fileOrNull ?: return null
|
||||
return findPsiElement(irElement, irFile, psiElementClass)
|
||||
}
|
||||
|
||||
fun findPsiElement(irElement: IrElement, irDeclaration: IrDeclaration): PsiElement? {
|
||||
val irFile = irDeclaration.fileOrNull ?: return null
|
||||
return findPsiElement(irElement, irFile)
|
||||
}
|
||||
|
||||
fun <E : PsiElement> findPsiElement(irDeclaration: IrDeclaration, psiElementClass: KClass<E>): E? =
|
||||
findPsiElement(irDeclaration, irDeclaration, psiElementClass)
|
||||
|
||||
fun findPsiElement(irDeclaration: IrDeclaration): PsiElement? =
|
||||
findPsiElement(irDeclaration, irDeclaration)
|
||||
}
|
||||
Reference in New Issue
Block a user