K2: Extract CheckerContextForProvider from CheckerContext
So, the idea is that CheckerContext should remain just read-only while the one who runs the checkers might build/modify the context. ^KT-56460 Related
This commit is contained in:
committed by
Space Team
parent
d24092e467
commit
a311d6eea0
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveCompone
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistentCheckerContextFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistentCheckerContextFactory
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
|
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
|
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
|
||||||
@@ -46,7 +46,7 @@ internal class SingleNonLocalDeclarationDiagnosticRetriever(
|
|||||||
|
|
||||||
private class Visitor(
|
private class Visitor(
|
||||||
private val structureElementDeclaration: FirDeclaration,
|
private val structureElementDeclaration: FirDeclaration,
|
||||||
context: CheckerContext,
|
context: CheckerContextForProvider,
|
||||||
components: DiagnosticCollectorComponents
|
components: DiagnosticCollectorComponents
|
||||||
) : LLFirDiagnosticVisitor(context, components) {
|
) : LLFirDiagnosticVisitor(context, components) {
|
||||||
private var insideAlwaysVisitableDeclarations = 0
|
private var insideAlwaysVisitableDeclarations = 0
|
||||||
|
|||||||
+5
-5
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.CheckerRunningDiagnosticCollectorVisitor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.collectors.CheckerRunningDiagnosticCollectorVisitor
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
|
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
|
||||||
internal open class LLFirDiagnosticVisitor(
|
internal open class LLFirDiagnosticVisitor(
|
||||||
context: CheckerContext,
|
context: CheckerContextForProvider,
|
||||||
components: DiagnosticCollectorComponents,
|
components: DiagnosticCollectorComponents,
|
||||||
) : CheckerRunningDiagnosticCollectorVisitor(context, components) {
|
) : CheckerRunningDiagnosticCollectorVisitor(context, components) {
|
||||||
private val beforeElementDiagnosticCollectionHandler = context.session.beforeElementDiagnosticCollectionHandler
|
private val beforeElementDiagnosticCollectionHandler = context.session.beforeElementDiagnosticCollectionHandler
|
||||||
|
|||||||
+5
-5
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFil
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor
|
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor
|
||||||
import org.jetbrains.kotlin.fir.containingClass
|
import org.jetbrains.kotlin.fir.containingClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -23,8 +23,8 @@ private class ContextCollectingDiagnosticCollectorVisitor private constructor(
|
|||||||
) : AbstractDiagnosticCollectorVisitor(
|
) : AbstractDiagnosticCollectorVisitor(
|
||||||
PersistentCheckerContextFactory.createEmptyPersistenceCheckerContext(sessionHolder)
|
PersistentCheckerContextFactory.createEmptyPersistenceCheckerContext(sessionHolder)
|
||||||
) {
|
) {
|
||||||
private val contextCollector = object : ContextByDesignationCollector<CheckerContext>(designation) {
|
private val contextCollector = object : ContextByDesignationCollector<CheckerContextForProvider>(designation) {
|
||||||
override fun getCurrentContext(): CheckerContext = context
|
override fun getCurrentContext(): CheckerContextForProvider = context
|
||||||
|
|
||||||
override fun goToNestedDeclaration(target: FirElementWithResolvePhase) {
|
override fun goToNestedDeclaration(target: FirElementWithResolvePhase) {
|
||||||
target.accept(this@ContextCollectingDiagnosticCollectorVisitor, null)
|
target.accept(this@ContextCollectingDiagnosticCollectorVisitor, null)
|
||||||
@@ -42,7 +42,7 @@ private class ContextCollectingDiagnosticCollectorVisitor private constructor(
|
|||||||
override fun checkElement(element: FirElement) {}
|
override fun checkElement(element: FirElement) {}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun collect(sessionHolder: SessionHolder, designation: FirDesignationWithFile): CheckerContext {
|
fun collect(sessionHolder: SessionHolder, designation: FirDesignationWithFile): CheckerContextForProvider {
|
||||||
val visitor = ContextCollectingDiagnosticCollectorVisitor(sessionHolder, designation)
|
val visitor = ContextCollectingDiagnosticCollectorVisitor(sessionHolder, designation)
|
||||||
designation.firFile.accept(visitor, null)
|
designation.firFile.accept(visitor, null)
|
||||||
return visitor.contextCollector.getCollectedContext()
|
return visitor.contextCollector.getCollectedContext()
|
||||||
@@ -55,7 +55,7 @@ internal object PersistenceContextCollector {
|
|||||||
sessionHolder: SessionHolder,
|
sessionHolder: SessionHolder,
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
declaration: FirDeclaration,
|
declaration: FirDeclaration,
|
||||||
): CheckerContext {
|
): CheckerContextForProvider {
|
||||||
val isLocal = when (declaration) {
|
val isLocal = when (declaration) {
|
||||||
is FirClassLikeDeclaration -> declaration.symbol.classId.isLocal
|
is FirClassLikeDeclaration -> declaration.symbol.classId.isLocal
|
||||||
is FirCallableDeclaration -> declaration.symbol.callableId.isLocal
|
is FirCallableDeclaration -> declaration.symbol.callableId.isLocal
|
||||||
|
|||||||
+5
-35
@@ -6,8 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.checkers.context
|
package org.jetbrains.kotlin.fir.analysis.checkers.context
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticContext
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.MutableDiagnosticContext
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
@@ -19,11 +19,12 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
|
|||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
|
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
|
||||||
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.transformers.ReturnTypeCalculator
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
abstract class CheckerContext : MutableDiagnosticContext() {
|
/**
|
||||||
|
* This class is assumed to be read-only (all the modifications are assumed to happen on CheckerContextForProvider side)
|
||||||
|
*/
|
||||||
|
abstract class CheckerContext : DiagnosticContext {
|
||||||
// Services
|
// Services
|
||||||
abstract val sessionHolder: SessionHolder
|
abstract val sessionHolder: SessionHolder
|
||||||
abstract val returnTypeCalculator: ReturnTypeCalculator
|
abstract val returnTypeCalculator: ReturnTypeCalculator
|
||||||
@@ -45,37 +46,6 @@ abstract class CheckerContext : MutableDiagnosticContext() {
|
|||||||
val session: FirSession
|
val session: FirSession
|
||||||
get() = sessionHolder.session
|
get() = sessionHolder.session
|
||||||
|
|
||||||
abstract fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): CheckerContext
|
|
||||||
|
|
||||||
abstract fun addDeclaration(declaration: FirDeclaration): CheckerContext
|
|
||||||
|
|
||||||
abstract fun dropDeclaration()
|
|
||||||
|
|
||||||
fun <T> withDeclaration(declaration: FirDeclaration, f: (CheckerContext) -> T): T {
|
|
||||||
val newContext = addDeclaration(declaration)
|
|
||||||
try {
|
|
||||||
return f(newContext)
|
|
||||||
} finally {
|
|
||||||
newContext.dropDeclaration()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContext
|
|
||||||
|
|
||||||
abstract fun dropQualifiedAccessOrAnnotationCall()
|
|
||||||
|
|
||||||
abstract fun addGetClassCall(getClassCall: FirGetClassCall): CheckerContext
|
|
||||||
|
|
||||||
abstract fun dropGetClassCall()
|
|
||||||
|
|
||||||
abstract fun addAnnotationContainer(annotationContainer: FirAnnotationContainer): CheckerContext
|
|
||||||
|
|
||||||
abstract fun dropAnnotationContainer()
|
|
||||||
|
|
||||||
abstract fun enterContractBody(): CheckerContext
|
|
||||||
|
|
||||||
abstract fun exitContractBody(): CheckerContext
|
|
||||||
|
|
||||||
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
|
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
|
||||||
val factory = diagnostic.factory
|
val factory = diagnostic.factory
|
||||||
val name = factory.name
|
val name = factory.name
|
||||||
|
|||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.checkers.context
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class should be invisible for checkers, but should be only used by DiagnosticCollectorVisitor who runs those checkers
|
||||||
|
* It contains all context-modification-related methods unlike CheckerContext that is assumed to be read-only
|
||||||
|
*/
|
||||||
|
abstract class CheckerContextForProvider(
|
||||||
|
sessionHolder: SessionHolder,
|
||||||
|
returnTypeCalculator: ReturnTypeCalculator,
|
||||||
|
allInfosSuppressed: Boolean,
|
||||||
|
allWarningsSuppressed: Boolean,
|
||||||
|
allErrorsSuppressed: Boolean
|
||||||
|
) : AbstractCheckerContext(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
|
||||||
|
|
||||||
|
abstract fun addSuppressedDiagnostics(
|
||||||
|
diagnosticNames: Collection<String>,
|
||||||
|
allInfosSuppressed: Boolean,
|
||||||
|
allWarningsSuppressed: Boolean,
|
||||||
|
allErrorsSuppressed: Boolean
|
||||||
|
): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun addDeclaration(declaration: FirDeclaration): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun dropDeclaration()
|
||||||
|
|
||||||
|
fun <T> withDeclaration(declaration: FirDeclaration, f: (CheckerContextForProvider) -> T): T {
|
||||||
|
val newContext = addDeclaration(declaration)
|
||||||
|
try {
|
||||||
|
return f(newContext)
|
||||||
|
} finally {
|
||||||
|
newContext.dropDeclaration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun dropQualifiedAccessOrAnnotationCall()
|
||||||
|
|
||||||
|
abstract fun addGetClassCall(getClassCall: FirGetClassCall): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun dropGetClassCall()
|
||||||
|
|
||||||
|
abstract fun addAnnotationContainer(annotationContainer: FirAnnotationContainer): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun dropAnnotationContainer()
|
||||||
|
|
||||||
|
abstract fun enterContractBody(): CheckerContextForProvider
|
||||||
|
|
||||||
|
abstract fun exitContractBody(): CheckerContextForProvider
|
||||||
|
|
||||||
|
}
|
||||||
+5
-5
@@ -30,7 +30,7 @@ class MutableCheckerContext private constructor(
|
|||||||
allInfosSuppressed: Boolean,
|
allInfosSuppressed: Boolean,
|
||||||
allWarningsSuppressed: Boolean,
|
allWarningsSuppressed: Boolean,
|
||||||
allErrorsSuppressed: Boolean
|
allErrorsSuppressed: Boolean
|
||||||
) : AbstractCheckerContext(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
|
) : CheckerContextForProvider(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
|
||||||
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
|
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
|
||||||
PersistentImplicitReceiverStack(),
|
PersistentImplicitReceiverStack(),
|
||||||
mutableListOf(),
|
mutableListOf(),
|
||||||
@@ -90,7 +90,7 @@ class MutableCheckerContext private constructor(
|
|||||||
getClassCalls.removeAt(getClassCalls.size - 1)
|
getClassCalls.removeAt(getClassCalls.size - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addAnnotationContainer(annotationContainer: FirAnnotationContainer): CheckerContext {
|
override fun addAnnotationContainer(annotationContainer: FirAnnotationContainer): CheckerContextForProvider {
|
||||||
annotationContainers.add(annotationContainer)
|
annotationContainers.add(annotationContainer)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ class MutableCheckerContext private constructor(
|
|||||||
allInfosSuppressed: Boolean,
|
allInfosSuppressed: Boolean,
|
||||||
allWarningsSuppressed: Boolean,
|
allWarningsSuppressed: Boolean,
|
||||||
allErrorsSuppressed: Boolean
|
allErrorsSuppressed: Boolean
|
||||||
): MutableCheckerContext {
|
): CheckerContextForProvider {
|
||||||
if (diagnosticNames.isEmpty()) return this
|
if (diagnosticNames.isEmpty()) return this
|
||||||
return MutableCheckerContext(
|
return MutableCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
@@ -122,13 +122,13 @@ class MutableCheckerContext private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enterContractBody(): CheckerContext {
|
override fun enterContractBody(): CheckerContextForProvider {
|
||||||
check(!isContractBody)
|
check(!isContractBody)
|
||||||
isContractBody = true
|
isContractBody = true
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitContractBody(): CheckerContext {
|
override fun exitContractBody(): CheckerContextForProvider {
|
||||||
check(isContractBody)
|
check(isContractBody)
|
||||||
isContractBody = false
|
isContractBody = false
|
||||||
return this
|
return this
|
||||||
|
|||||||
+5
-5
@@ -32,7 +32,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
allInfosSuppressed: Boolean,
|
allInfosSuppressed: Boolean,
|
||||||
allWarningsSuppressed: Boolean,
|
allWarningsSuppressed: Boolean,
|
||||||
allErrorsSuppressed: Boolean
|
allErrorsSuppressed: Boolean
|
||||||
) : AbstractCheckerContext(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
|
) : CheckerContextForProvider(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
|
||||||
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
|
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
|
||||||
PersistentImplicitReceiverStack(),
|
PersistentImplicitReceiverStack(),
|
||||||
persistentListOf(),
|
persistentListOf(),
|
||||||
@@ -150,7 +150,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
allInfosSuppressed: Boolean,
|
allInfosSuppressed: Boolean,
|
||||||
allWarningsSuppressed: Boolean,
|
allWarningsSuppressed: Boolean,
|
||||||
allErrorsSuppressed: Boolean
|
allErrorsSuppressed: Boolean
|
||||||
): PersistentCheckerContext {
|
): CheckerContextForProvider {
|
||||||
if (diagnosticNames.isEmpty()) return this
|
if (diagnosticNames.isEmpty()) return this
|
||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
@@ -168,7 +168,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toggleContractBody(newValue: Boolean): CheckerContext {
|
private fun toggleContractBody(newValue: Boolean): CheckerContextForProvider {
|
||||||
check(isContractBody != newValue)
|
check(isContractBody != newValue)
|
||||||
|
|
||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
@@ -187,11 +187,11 @@ class PersistentCheckerContext private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enterContractBody(): CheckerContext {
|
override fun enterContractBody(): CheckerContextForProvider {
|
||||||
return toggleContractBody(newValue = true)
|
return toggleContractBody(newValue = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitContractBody(): CheckerContext {
|
override fun exitContractBody(): CheckerContextForProvider {
|
||||||
return toggleContractBody(newValue = false)
|
return toggleContractBody(newValue = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-9
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
|
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly
|
import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||||
@@ -72,9 +73,7 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
context.session,
|
context.session,
|
||||||
reporter
|
reporter
|
||||||
)
|
)
|
||||||
context.withDeclaration(function) {
|
body.checkChildrenWithCustomVisitor(context, visitor, function)
|
||||||
body.checkChildrenWithCustomVisitor(it, visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open val inlineVisitor get() = ::BasicInlineVisitor
|
open val inlineVisitor get() = ::BasicInlineVisitor
|
||||||
@@ -538,13 +537,21 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
|
|
||||||
private fun FirElement.checkChildrenWithCustomVisitor(
|
private fun FirElement.checkChildrenWithCustomVisitor(
|
||||||
parentContext: CheckerContext,
|
parentContext: CheckerContext,
|
||||||
visitorVoid: FirVisitor<Unit, CheckerContext>
|
visitorVoid: FirVisitor<Unit, CheckerContext>,
|
||||||
|
rootFunction: FirFunction,
|
||||||
) {
|
) {
|
||||||
val collectingVisitor = object : AbstractDiagnosticCollectorVisitor(parentContext) {
|
// TODO: Get rid of this cast and the following context modification as it looks like a leaking abstraction (see KT-56460)
|
||||||
override fun checkElement(element: FirElement) {
|
require(parentContext is CheckerContextForProvider) {
|
||||||
element.accept(visitorVoid, context)
|
"This checked violates the contract for read-only checkers"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parentContext.withDeclaration(rootFunction) {
|
||||||
|
val collectingVisitor = object : AbstractDiagnosticCollectorVisitor(it) {
|
||||||
|
override fun checkElement(element: FirElement) {
|
||||||
|
element.accept(visitorVoid, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.accept(collectingVisitor, null)
|
||||||
}
|
}
|
||||||
this.accept(collectingVisitor, null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.whileAnalysing
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
abstract class AbstractDiagnosticCollectorVisitor(
|
abstract class AbstractDiagnosticCollectorVisitor(
|
||||||
@set:PrivateForInline var context: CheckerContext,
|
@set:PrivateForInline var context: CheckerContextForProvider,
|
||||||
) : FirDefaultVisitor<Unit, Nothing?>() {
|
) : FirDefaultVisitor<Unit, Nothing?>() {
|
||||||
|
|
||||||
protected open fun shouldVisitDeclaration(declaration: FirDeclaration) = true
|
protected open fun shouldVisitDeclaration(declaration: FirDeclaration) = true
|
||||||
@@ -393,6 +393,6 @@ abstract class AbstractDiagnosticCollectorVisitor(
|
|||||||
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
|
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
|
||||||
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
|
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
|
||||||
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
|
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
|
||||||
) as CheckerContext
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -6,13 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.collectors
|
package org.jetbrains.kotlin.fir.analysis.collectors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
|
||||||
open class CheckerRunningDiagnosticCollectorVisitor(
|
open class CheckerRunningDiagnosticCollectorVisitor(
|
||||||
context: CheckerContext,
|
context: CheckerContextForProvider,
|
||||||
protected val components: DiagnosticCollectorComponents
|
protected val components: DiagnosticCollectorComponents
|
||||||
) : AbstractDiagnosticCollectorVisitor(context) {
|
) : AbstractDiagnosticCollectorVisitor(context) {
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -16,15 +16,6 @@ interface DiagnosticContext {
|
|||||||
val languageVersionSettings: LanguageVersionSettings
|
val languageVersionSettings: LanguageVersionSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MutableDiagnosticContext : DiagnosticContext {
|
|
||||||
abstract fun addSuppressedDiagnostics(
|
|
||||||
diagnosticNames: Collection<String>,
|
|
||||||
allInfosSuppressed: Boolean,
|
|
||||||
allWarningsSuppressed: Boolean,
|
|
||||||
allErrorsSuppressed: Boolean
|
|
||||||
): DiagnosticContext
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class DiagnosticReporter {
|
abstract class DiagnosticReporter {
|
||||||
abstract fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext)
|
abstract fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext)
|
||||||
|
|
||||||
@@ -97,4 +88,4 @@ open class KtDiagnosticReporterWithContext(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user