Fix inspections and slightly "kotlinify" KotlinSuppressCache
This commit is contained in:
committed by
Alexander Udalov
parent
9d3c9a823d
commit
61548a0a36
+29
-46
@@ -39,7 +39,7 @@ interface DiagnosticSuppressor {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val EP_NAME: ExtensionPointName<DiagnosticSuppressor> =
|
val EP_NAME: ExtensionPointName<DiagnosticSuppressor> =
|
||||||
ExtensionPointName.create<DiagnosticSuppressor>("org.jetbrains.kotlin.diagnosticSuppressor")
|
ExtensionPointName.create("org.jetbrains.kotlin.diagnosticSuppressor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,13 +49,13 @@ abstract class KotlinSuppressCache {
|
|||||||
// The cache is weak: we're OK with losing it
|
// The cache is weak: we're OK with losing it
|
||||||
private val suppressors = ContainerUtil.createConcurrentWeakValueMap<KtAnnotated, Suppressor>()
|
private val suppressors = ContainerUtil.createConcurrentWeakValueMap<KtAnnotated, Suppressor>()
|
||||||
|
|
||||||
val filter: (Diagnostic) -> Boolean = { diagnostic: Diagnostic -> !isSuppressed(diagnostic) }
|
val filter: (Diagnostic) -> Boolean = { diagnostic: Diagnostic ->
|
||||||
|
!isSuppressed(DiagnosticSuppressRequest(diagnostic))
|
||||||
|
}
|
||||||
|
|
||||||
fun isSuppressed(psiElement: PsiElement, suppressionKey: String, severity: Severity) =
|
fun isSuppressed(psiElement: PsiElement, suppressionKey: String, severity: Severity) =
|
||||||
isSuppressed(StringSuppressRequest(psiElement, severity, suppressionKey.toLowerCase()))
|
isSuppressed(StringSuppressRequest(psiElement, severity, suppressionKey.toLowerCase()))
|
||||||
|
|
||||||
fun isSuppressed(diagnostic: Diagnostic): Boolean = isSuppressed(DiagnosticSuppressRequest(diagnostic))
|
|
||||||
|
|
||||||
private fun isSuppressed(request: SuppressRequest): Boolean {
|
private fun isSuppressed(request: SuppressRequest): Boolean {
|
||||||
// If diagnostics are reported in a synthetic file generated by KtPsiFactory (dummy.kt),
|
// If diagnostics are reported in a synthetic file generated by KtPsiFactory (dummy.kt),
|
||||||
// there's no point to present such diagnostics to the user, because the user didn't write this code
|
// there's no point to present such diagnostics to the user, because the user didn't write this code
|
||||||
@@ -78,7 +78,7 @@ abstract class KotlinSuppressCache {
|
|||||||
return isSuppressedByAnnotated(request.suppressKey, request.severity, annotated, 0)
|
return isSuppressedByAnnotated(request.suppressKey, request.severity, annotated, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun isSuppressedByExtension(suppressor: DiagnosticSuppressor, diagnostic: Diagnostic): Boolean {
|
protected open fun isSuppressedByExtension(suppressor: DiagnosticSuppressor, diagnostic: Diagnostic): Boolean {
|
||||||
return suppressor.isSuppressed(diagnostic)
|
return suppressor.isSuppressed(diagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,34 +111,30 @@ abstract class KotlinSuppressCache {
|
|||||||
|
|
||||||
This way we need no more lookups than the number of suppress() annotations from here to the root.
|
This way we need no more lookups than the number of suppress() annotations from here to the root.
|
||||||
*/
|
*/
|
||||||
protected fun isSuppressedByAnnotated(suppressionKey: String, severity: Severity, annotated: KtAnnotated, debugDepth: Int): Boolean {
|
private fun isSuppressedByAnnotated(suppressionKey: String, severity: Severity, annotated: KtAnnotated, debugDepth: Int): 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 = KtStubbedPsiUtil.getPsiOrStubParent(suppressor.annotatedElement, KtAnnotated::class.java, true) ?: return false
|
val annotatedAbove = KtStubbedPsiUtil.getPsiOrStubParent(annotated, KtAnnotated::class.java, true) ?: return false
|
||||||
|
|
||||||
val suppressed = isSuppressedByAnnotated(suppressionKey, severity, annotatedAbove, debugDepth + 1)
|
val suppressed = isSuppressedByAnnotated(suppressionKey, severity, annotatedAbove, debugDepth + 1)
|
||||||
val suppressorAbove = suppressors[annotatedAbove]
|
val suppressorAbove = suppressors[annotatedAbove]
|
||||||
if (suppressorAbove != null && suppressorAbove.dominates(suppressor)) {
|
if (suppressorAbove != null && suppressorAbove.dominates(suppressor)) {
|
||||||
suppressors.put(annotated, suppressorAbove)
|
suppressors[annotated] = suppressorAbove
|
||||||
}
|
}
|
||||||
|
|
||||||
return suppressed
|
return suppressed
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrCreateSuppressor(annotated: KtAnnotated): Suppressor {
|
private fun getOrCreateSuppressor(annotated: KtAnnotated): Suppressor =
|
||||||
var suppressor: Suppressor? = suppressors[annotated]
|
suppressors.getOrPut(annotated) {
|
||||||
if (suppressor == null) {
|
|
||||||
val strings = getSuppressingStrings(annotated)
|
val strings = getSuppressingStrings(annotated)
|
||||||
suppressor = when {
|
when (strings.size) {
|
||||||
strings.isEmpty() -> EmptySuppressor(annotated)
|
0 -> EmptySuppressor
|
||||||
strings.size == 1 -> SingularSuppressor(annotated, strings.iterator().next())
|
1 -> SingularSuppressor(strings.first())
|
||||||
else -> MultiSuppressor(annotated, strings)
|
else -> MultiSuppressor(strings)
|
||||||
}
|
}
|
||||||
suppressors.put(annotated, suppressor)
|
|
||||||
}
|
}
|
||||||
return suppressor
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun getSuppressionAnnotations(annotated: KtAnnotated): List<AnnotationDescriptor>
|
abstract fun getSuppressionAnnotations(annotated: KtAnnotated): List<AnnotationDescriptor>
|
||||||
|
|
||||||
@@ -156,7 +152,7 @@ abstract class KotlinSuppressCache {
|
|||||||
|
|
||||||
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
|
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
|
||||||
for (arrayValue in annotationDescriptor.allValueArguments.values) {
|
for (arrayValue in annotationDescriptor.allValueArguments.values) {
|
||||||
if ((arrayValue is ArrayValue)) {
|
if (arrayValue is ArrayValue) {
|
||||||
for (value in arrayValue.value) {
|
for (value in arrayValue.value) {
|
||||||
if (value is StringValue) {
|
if (value is StringValue) {
|
||||||
builder.add(value.value.toLowerCase())
|
builder.add(value.value.toLowerCase())
|
||||||
@@ -167,36 +163,30 @@ abstract class KotlinSuppressCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getDiagnosticSuppressKey(diagnostic: Diagnostic): String {
|
private fun getDiagnosticSuppressKey(diagnostic: Diagnostic): String =
|
||||||
return diagnostic.factory.name.toLowerCase()
|
diagnostic.factory.name.toLowerCase()
|
||||||
}
|
|
||||||
|
|
||||||
fun isSuppressedByStrings(key: String, strings: Set<String>, severity: Severity): Boolean {
|
private fun isSuppressedByStrings(key: String, strings: Set<String>, severity: Severity): Boolean =
|
||||||
if (strings.contains("warnings") && severity == Severity.WARNING) return true
|
severity == Severity.WARNING && "warnings" in strings || key in strings
|
||||||
|
|
||||||
return strings.contains(key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class Suppressor protected constructor(val annotatedElement: KtAnnotated) {
|
private abstract class Suppressor {
|
||||||
abstract fun isSuppressed(diagnostic: Diagnostic): Boolean
|
open fun isSuppressed(diagnostic: Diagnostic): Boolean =
|
||||||
|
isSuppressed(getDiagnosticSuppressKey(diagnostic), diagnostic.severity)
|
||||||
|
|
||||||
abstract fun isSuppressed(suppressionKey: String, severity: Severity): Boolean
|
abstract fun isSuppressed(suppressionKey: String, severity: Severity): Boolean
|
||||||
|
|
||||||
// true is \forall x. other.isSuppressed(x) -> this.isSuppressed(x)
|
// true is \forall x. other.isSuppressed(x) -> this.isSuppressed(x)
|
||||||
abstract fun dominates(other: Suppressor): Boolean
|
abstract fun dominates(other: Suppressor): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EmptySuppressor(annotated: KtAnnotated) : Suppressor(annotated) {
|
private object EmptySuppressor : Suppressor() {
|
||||||
override fun isSuppressed(diagnostic: Diagnostic): Boolean = false
|
override fun isSuppressed(diagnostic: Diagnostic): Boolean = false
|
||||||
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean = false
|
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean = false
|
||||||
override fun dominates(other: Suppressor): Boolean = other is EmptySuppressor
|
override fun dominates(other: Suppressor): Boolean = this === other
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SingularSuppressor(annotated: KtAnnotated, private val string: String) : Suppressor(annotated) {
|
private class SingularSuppressor(private val string: String) : Suppressor() {
|
||||||
override fun isSuppressed(diagnostic: Diagnostic): Boolean {
|
|
||||||
return isSuppressed(getDiagnosticSuppressKey(diagnostic), diagnostic.severity)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean {
|
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean {
|
||||||
return isSuppressedByStrings(suppressionKey, ImmutableSet.of(string), severity)
|
return isSuppressedByStrings(suppressionKey, ImmutableSet.of(string), severity)
|
||||||
}
|
}
|
||||||
@@ -206,11 +196,7 @@ abstract class KotlinSuppressCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MultiSuppressor(annotated: KtAnnotated, private val strings: Set<String>) : Suppressor(annotated) {
|
private class MultiSuppressor(private val strings: Set<String>) : Suppressor() {
|
||||||
override fun isSuppressed(diagnostic: Diagnostic): Boolean {
|
|
||||||
return isSuppressed(getDiagnosticSuppressKey(diagnostic), diagnostic.severity)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean {
|
override fun isSuppressed(suppressionKey: String, severity: Severity): Boolean {
|
||||||
return isSuppressedByStrings(suppressionKey, strings, severity)
|
return isSuppressedByStrings(suppressionKey, strings, severity)
|
||||||
}
|
}
|
||||||
@@ -244,11 +230,8 @@ class BindingContextSuppressCache(val context: BindingContext) : KotlinSuppressC
|
|||||||
override fun getSuppressionAnnotations(annotated: KtAnnotated): List<AnnotationDescriptor> {
|
override fun getSuppressionAnnotations(annotated: KtAnnotated): List<AnnotationDescriptor> {
|
||||||
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, annotated)
|
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, annotated)
|
||||||
|
|
||||||
return if (descriptor != null) {
|
return descriptor?.annotations?.toList()
|
||||||
descriptor.annotations.toList()
|
?: annotated.annotationEntries.mapNotNull { context.get(BindingContext.ANNOTATION, it) }
|
||||||
} else {
|
|
||||||
annotated.annotationEntries.mapNotNull { context.get(BindingContext.ANNOTATION, it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSuppressedByExtension(suppressor: DiagnosticSuppressor, diagnostic: Diagnostic): Boolean {
|
override fun isSuppressedByExtension(suppressor: DiagnosticSuppressor, diagnostic: Diagnostic): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user