[FIR] Implement suppressing diagnostics with @Suppress
This commit is contained in:
+33
@@ -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() {}
|
||||||
|
}
|
||||||
+10
@@ -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() {}
|
||||||
+34
@@ -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")
|
||||||
|
|||||||
+35
@@ -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")
|
||||||
|
|||||||
+48
-6
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+95
-24
@@ -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
|
||||||
|
|||||||
+14
-4
@@ -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<*>> {
|
||||||
|
|||||||
-8
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+13
@@ -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<*>>
|
||||||
|
}
|
||||||
+30
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user