[FIR] Implement suppressing diagnostics with @Suppress

This commit is contained in:
Dmitriy Novozhilov
2021-02-01 18:34:03 +03:00
parent 459a2886a0
commit ebced14db2
20 changed files with 376 additions and 43 deletions
@@ -3103,6 +3103,39 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
} }
} }
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/suppress")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Suppress extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInSuppress() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/suppress"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("allWarnings.kt")
public void testAllWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/allWarnings.kt");
}
@TestMetadata("multipleWarnings.kt")
public void testMultipleWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/multipleWarnings.kt");
}
@TestMetadata("singleError.kt")
public void testSingleError() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleError.kt");
}
@TestMetadata("singleWarning.kt")
public void testSingleWarning() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleWarning.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/types") @TestMetadata("compiler/fir/analysis-tests/testData/resolve/types")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -0,0 +1,10 @@
FILE: allWarnings.kt
@R|kotlin/Suppress|(vararg(String(warnings))) public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
@@ -0,0 +1,6 @@
// WITH_EXTENDED_CHECKERS
@Suppress("warnings")
public class A {
final fun foo() {}
}
@@ -0,0 +1,10 @@
FILE: multipleWarnings.kt
@R|kotlin/Suppress|(vararg(String(REDUNDANT_VISIBILITY_MODIFIER))) public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
@R|kotlin/Suppress|(vararg(String(REDUNDANT_MODALITY_MODIFIER))) public final fun foo(): R|kotlin/Unit| {
}
}
@@ -0,0 +1,7 @@
// WITH_EXTENDED_CHECKERS
@Suppress("REDUNDANT_VISIBILITY_MODIFIER")
public class A {
@Suppress("REDUNDANT_MODALITY_MODIFIER")
public final fun foo() {}
}
@@ -0,0 +1,6 @@
FILE: singleError.kt
public final fun foo(x: R|kotlin/String|): R|kotlin/Unit| {
}
@R|kotlin/Suppress|(vararg(String(INAPPLICABLE_CANDIDATE))) public final fun bar(): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): /foo>#(Int(10))
}
@@ -0,0 +1,6 @@
fun foo(x: String) {}
@Suppress("INAPPLICABLE_CANDIDATE")
fun bar() {
foo(10)
}
@@ -0,0 +1,3 @@
FILE: singleWarning.kt
@R|kotlin/Suppress|(vararg(String(REDUNDANT_VISIBILITY_MODIFIER))) public final fun foo(): R|kotlin/Unit| {
}
@@ -0,0 +1,4 @@
// WITH_EXTENDED_CHECKERS
@Suppress("REDUNDANT_VISIBILITY_MODIFIER")
public fun foo() {}
@@ -3474,6 +3474,40 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
} }
} }
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/suppress")
@TestDataPath("$PROJECT_ROOT")
public class Suppress extends AbstractFirDiagnosticTest {
@Test
public void testAllFilesPresentInSuppress() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/suppress"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("allWarnings.kt")
public void testAllWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/allWarnings.kt");
}
@Test
@TestMetadata("multipleWarnings.kt")
public void testMultipleWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/multipleWarnings.kt");
}
@Test
@TestMetadata("singleError.kt")
public void testSingleError() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleError.kt");
}
@Test
@TestMetadata("singleWarning.kt")
public void testSingleWarning() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleWarning.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/types") @TestMetadata("compiler/fir/analysis-tests/testData/resolve/types")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -3520,6 +3520,41 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
} }
} }
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/suppress")
@TestDataPath("$PROJECT_ROOT")
@Execution(ExecutionMode.SAME_THREAD)
public class Suppress extends AbstractFirDiagnosticsWithLightTreeTest {
@Test
public void testAllFilesPresentInSuppress() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/suppress"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("allWarnings.kt")
public void testAllWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/allWarnings.kt");
}
@Test
@TestMetadata("multipleWarnings.kt")
public void testMultipleWarnings() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/multipleWarnings.kt");
}
@Test
@TestMetadata("singleError.kt")
public void testSingleError() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleError.kt");
}
@Test
@TestMetadata("singleWarning.kt")
public void testSingleWarning() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/singleWarning.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/types") @TestMetadata("compiler/fir/analysis-tests/testData/resolve/types")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -6,13 +6,16 @@
package org.jetbrains.kotlin.fir.analysis.checkers.context package org.jetbrains.kotlin.fir.analysis.checkers.context
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.PersistentSet
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.SessionHolder import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableArgumentDiagnostic
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -21,6 +24,10 @@ abstract class CheckerContext {
abstract val containingDeclarations: List<FirDeclaration> abstract val containingDeclarations: List<FirDeclaration>
abstract val sessionHolder: SessionHolder abstract val sessionHolder: SessionHolder
abstract val returnTypeCalculator: ReturnTypeCalculator abstract val returnTypeCalculator: ReturnTypeCalculator
abstract val suppressedDiagnostics: Set<String>
abstract val allInfosSuppressed: Boolean
abstract val allWarningsSuppressed: Boolean
abstract val allErrorsSuppressed: Boolean
val session: FirSession val session: FirSession
get() = sessionHolder.session get() = sessionHolder.session
@@ -38,17 +45,25 @@ abstract class CheckerContext {
} }
} }
class PersistentCheckerContext( class PersistentCheckerContext private constructor(
override val implicitReceiverStack: PersistentImplicitReceiverStack = PersistentImplicitReceiverStack(), override val implicitReceiverStack: PersistentImplicitReceiverStack,
override val containingDeclarations: PersistentList<FirDeclaration> = persistentListOf(), override val containingDeclarations: PersistentList<FirDeclaration>,
override val sessionHolder: SessionHolder, override val sessionHolder: SessionHolder,
override val returnTypeCalculator: ReturnTypeCalculator, override val returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
override val allInfosSuppressed: Boolean,
override val allWarningsSuppressed: Boolean,
override val allErrorsSuppressed: Boolean
) : CheckerContext() { ) : CheckerContext() {
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this( constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
PersistentImplicitReceiverStack(), PersistentImplicitReceiverStack(),
persistentListOf(), persistentListOf(),
sessionHolder, sessionHolder,
returnTypeCalculator returnTypeCalculator,
persistentSetOf(),
allInfosSuppressed = false,
allWarningsSuppressed = false,
allErrorsSuppressed = false
) )
fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext { fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext {
@@ -56,7 +71,11 @@ class PersistentCheckerContext(
implicitReceiverStack.add(name, value), implicitReceiverStack.add(name, value),
containingDeclarations, containingDeclarations,
sessionHolder, sessionHolder,
returnTypeCalculator returnTypeCalculator,
suppressedDiagnostics,
allInfosSuppressed,
allWarningsSuppressed,
allErrorsSuppressed
) )
} }
@@ -65,7 +84,30 @@ class PersistentCheckerContext(
implicitReceiverStack, implicitReceiverStack,
containingDeclarations.add(declaration), containingDeclarations.add(declaration),
sessionHolder, sessionHolder,
returnTypeCalculator returnTypeCalculator,
suppressedDiagnostics,
allInfosSuppressed,
allWarningsSuppressed,
allErrorsSuppressed
)
}
fun addSuppressedDiagnostics(
diagnosticNames: Collection<String>,
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
): PersistentCheckerContext {
if (diagnosticNames.isEmpty()) return this
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames),
this.allInfosSuppressed || allInfosSuppressed,
this.allWarningsSuppressed || allWarningsSuppressed,
this.allErrorsSuppressed || allErrorsSuppressed
) )
} }
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.collectors package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
@@ -21,11 +22,9 @@ import org.jetbrains.kotlin.fir.resolve.collectImplicitReceivers
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -34,6 +33,12 @@ abstract class AbstractDiagnosticCollector(
override val scopeSession: ScopeSession = ScopeSession(), override val scopeSession: ScopeSession = ScopeSession(),
returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve() returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve()
) : SessionHolder { ) : SessionHolder {
companion object {
private const val SUPPRESS_ALL_INFOS = "infos"
private const val SUPPRESS_ALL_WARNINGS = "warnings"
private const val SUPPRESS_ALL_ERRORS = "errors"
}
fun collectDiagnostics(firFile: FirFile): List<FirDiagnostic<*>> { fun collectDiagnostics(firFile: FirFile): List<FirDiagnostic<*>> {
if (!componentsInitialized) { if (!componentsInitialized) {
throw IllegalStateException("Components are not initialized") throw IllegalStateException("Components are not initialized")
@@ -74,13 +79,26 @@ abstract class AbstractDiagnosticCollector(
} }
override fun visitElement(element: FirElement, data: Nothing?) { override fun visitElement(element: FirElement, data: Nothing?) {
if (element is FirAnnotationContainer) {
visitAnnotationContainer(element, data)
return
}
element.runComponents() element.runComponents()
element.acceptChildren(this, null) element.acceptChildren(this, null)
} }
override fun visitAnnotationContainer(annotationContainer: FirAnnotationContainer, data: Nothing?) {
withSuppressedDiagnostics(annotationContainer) {
annotationContainer.runComponents()
annotationContainer.acceptChildren(this, null)
}
}
private fun visitJump(loopJump: FirLoopJump) { private fun visitJump(loopJump: FirLoopJump) {
loopJump.runComponents() withSuppressedDiagnostics(loopJump) {
loopJump.target.labeledElement.takeIf { it is FirErrorLoop }?.accept(this, null) loopJump.runComponents()
loopJump.target.labeledElement.takeIf { it is FirErrorLoop }?.accept(this, null)
}
} }
override fun visitBreakExpression(breakExpression: FirBreakExpression, data: Nothing?) { override fun visitBreakExpression(breakExpression: FirBreakExpression, data: Nothing?) {
@@ -96,55 +114,74 @@ abstract class AbstractDiagnosticCollector(
this.type = type this.type = type
} }
visitWithDeclarationAndReceiver(klass, (klass as? FirRegularClass)?.name, typeRef) visitWithDeclarationAndReceiver(klass, (klass as? FirRegularClass)?.name, typeRef)
} }
override fun visitRegularClass(regularClass: FirRegularClass, data: Nothing?) { override fun visitRegularClass(regularClass: FirRegularClass, data: Nothing?) {
visitClassAndChildren(regularClass, regularClass.defaultType()) withSuppressedDiagnostics(regularClass) {
visitClassAndChildren(regularClass, regularClass.defaultType())
}
} }
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Nothing?) { override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Nothing?) {
visitClassAndChildren(anonymousObject, anonymousObject.defaultType()) withSuppressedDiagnostics(anonymousObject) {
visitClassAndChildren(anonymousObject, anonymousObject.defaultType())
}
} }
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?) { override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?) {
visitWithDeclarationAndReceiver(simpleFunction, simpleFunction.name, simpleFunction.receiverTypeRef) withSuppressedDiagnostics(simpleFunction) {
visitWithDeclarationAndReceiver(simpleFunction, simpleFunction.name, simpleFunction.receiverTypeRef)
}
} }
override fun visitConstructor(constructor: FirConstructor, data: Nothing?) { override fun visitConstructor(constructor: FirConstructor, data: Nothing?) {
visitWithDeclaration(constructor) withSuppressedDiagnostics(constructor) {
visitWithDeclaration(constructor)
}
} }
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Nothing?) { override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Nothing?) {
val labelName = anonymousFunction.label?.name?.let { Name.identifier(it) } withSuppressedDiagnostics(anonymousFunction) {
visitWithDeclarationAndReceiver( val labelName = anonymousFunction.label?.name?.let { Name.identifier(it) }
anonymousFunction, visitWithDeclarationAndReceiver(
labelName, anonymousFunction,
anonymousFunction.receiverTypeRef labelName,
) anonymousFunction.receiverTypeRef
)
}
} }
override fun visitProperty(property: FirProperty, data: Nothing?) { override fun visitProperty(property: FirProperty, data: Nothing?) {
visitWithDeclaration(property) withSuppressedDiagnostics(property) {
visitWithDeclaration(property)
}
} }
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Nothing?) { override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Nothing?) {
if (propertyAccessor !is FirDefaultPropertyAccessor) { if (propertyAccessor !is FirDefaultPropertyAccessor) {
val property = context.containingDeclarations.last() as FirProperty val property = context.containingDeclarations.last() as FirProperty
visitWithDeclarationAndReceiver(propertyAccessor, property.name, property.receiverTypeRef) withSuppressedDiagnostics(propertyAccessor) {
visitWithDeclarationAndReceiver(propertyAccessor, property.name, property.receiverTypeRef)
}
} }
} }
override fun visitValueParameter(valueParameter: FirValueParameter, data: Nothing?) { override fun visitValueParameter(valueParameter: FirValueParameter, data: Nothing?) {
visitWithDeclaration(valueParameter) withSuppressedDiagnostics(valueParameter) {
visitWithDeclaration(valueParameter)
}
} }
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Nothing?) { override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Nothing?) {
visitWithDeclaration(enumEntry) withSuppressedDiagnostics(enumEntry) {
visitWithDeclaration(enumEntry)
}
} }
override fun visitFile(file: FirFile, data: Nothing?) { override fun visitFile(file: FirFile, data: Nothing?) {
visitWithDeclaration(file) withSuppressedDiagnostics(file) {
visitWithDeclaration(file)
}
} }
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Nothing?) { override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Nothing?) {
@@ -152,12 +189,17 @@ abstract class AbstractDiagnosticCollector(
} }
override fun visitBlock(block: FirBlock, data: Nothing?) { override fun visitBlock(block: FirBlock, data: Nothing?) {
visitExpression(block, data) withSuppressedDiagnostics(block) {
visitExpression(block, data)
}
} }
override fun visitTypeRef(typeRef: FirTypeRef, data: Nothing?) { override fun visitTypeRef(typeRef: FirTypeRef, data: Nothing?) {
if (typeRef.source != null && typeRef.source?.kind !is FirFakeSourceElementKind) { if (typeRef.source != null && typeRef.source?.kind !is FirFakeSourceElementKind) {
super.visitTypeRef(typeRef, null) withSuppressedDiagnostics(typeRef) {
typeRef.runComponents()
typeRef.acceptChildren(this, data)
}
} }
} }
@@ -233,6 +275,35 @@ abstract class AbstractDiagnosticCollector(
} }
} }
private inline fun <R> withSuppressedDiagnostics(annotationContainer: FirAnnotationContainer, block: () -> R): R {
val existingContext = context
addSuppressedDiagnosticsToContext(annotationContainer)
return try {
block()
} finally {
context = existingContext
}
}
private fun addSuppressedDiagnosticsToContext(annotationContainer: FirAnnotationContainer) {
val annotations = annotationContainer.annotations.filter {
val type = it.annotationTypeRef.coneType as? ConeClassLikeType ?: return@filter false
type.lookupTag.classId == StandardClassIds.Suppress
}
if (annotations.isEmpty()) return
val arguments = annotations.flatMap { annotationCall ->
annotationCall.arguments.filterIsInstance<FirVarargArgumentsExpression>().flatMap { varargArgument ->
varargArgument.arguments.mapNotNull { (it as? FirConstExpression<*>)?.value as? String? }
}
}
context = context.addSuppressedDiagnostics(
arguments,
allInfosSuppressed = SUPPRESS_ALL_INFOS in arguments,
allWarningsSuppressed = SUPPRESS_ALL_WARNINGS in arguments,
allErrorsSuppressed = SUPPRESS_ALL_ERRORS in arguments
)
}
private inline fun <R> withDiagnosticsAction(action: DiagnosticCollectorDeclarationAction, block: () -> R): R { private inline fun <R> withDiagnosticsAction(action: DiagnosticCollectorDeclarationAction, block: () -> R): R {
val oldAction = currentAction val oldAction = currentAction
currentAction = action currentAction = action
@@ -7,14 +7,24 @@ package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.SimpleDiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.BaseDiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.DiagnosticReporterWithSuppress
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.SimpleDiagnosticReporter
class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollector(session) { class SimpleDiagnosticsCollector(session: FirSession, private val disableSuppress: Boolean = false) : AbstractDiagnosticCollector(session) {
override var reporter = SimpleDiagnosticReporter() override var reporter = createDiagnosticReporter()
private set private set
private fun createDiagnosticReporter(): BaseDiagnosticReporter {
return if (disableSuppress) {
SimpleDiagnosticReporter()
} else {
DiagnosticReporterWithSuppress()
}
}
override fun initializeCollector() { override fun initializeCollector() {
reporter = SimpleDiagnosticReporter() reporter = createDiagnosticReporter()
} }
override fun getCollectedDiagnostics(): List<FirDiagnostic<*>> { override fun getCollectedDiagnostics(): List<FirDiagnostic<*>> {
@@ -51,11 +51,3 @@ inline fun <reified T : FirSourceElement, P : PsiElement, A : Any, B : Any, C :
source?.let { report(factory.on(it, a, b, c), context) } source?.let { report(factory.on(it, a, b, c), context) }
} }
class SimpleDiagnosticReporter : DiagnosticReporter() {
val diagnostics: MutableList<FirDiagnostic<*>> = mutableListOf()
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
if (diagnostic == null) return
diagnostics += diagnostic
}
}
@@ -0,0 +1,13 @@
/*
* 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.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
abstract class BaseDiagnosticReporter : DiagnosticReporter() {
abstract val diagnostics: List<FirDiagnostic<*>>
}
@@ -0,0 +1,30 @@
/*
* 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.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
class DiagnosticReporterWithSuppress : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic<*>> = mutableListOf()
override val diagnostics: List<FirDiagnostic<*>>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
if (diagnostic == null) return
val factory = diagnostic.factory
val name = factory.name
val suppressedByAll = when (factory.severity) {
Severity.INFO -> context.allInfosSuppressed
Severity.WARNING -> context.allWarningsSuppressed
Severity.ERROR -> context.allErrorsSuppressed
}
if (suppressedByAll || name in context.suppressedDiagnostics) return
_diagnostics += diagnostic
}
}
@@ -0,0 +1,20 @@
/*
* 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.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
class SimpleDiagnosticReporter : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic<*>> = mutableListOf()
override val diagnostics: List<FirDiagnostic<*>>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
if (diagnostic == null) return
_diagnostics += diagnostic
}
}
@@ -83,6 +83,8 @@ object StandardClassIds {
fun FunctionN(n: Int): ClassId { fun FunctionN(n: Int): ClassId {
return "Function$n".baseId() return "Function$n".baseId()
} }
val Suppress = "Suppress".baseId()
} }
private fun <K, V> Map<K, V>.inverseMap() = entries.associate { (k, v) -> v to k } private fun <K, V> Map<K, V>.inverseMap() = entries.associate { (k, v) -> v to k }
@@ -1,4 +1,3 @@
// IGNORE_FIR_DIAGNOSTICS
// FILE: 1.kt // FILE: 1.kt
package test package test