FIR: introduce MutableCheckerContext to save performance

This commit is contained in:
Mikhail Glukhikh
2021-07-08 14:12:50 +03:00
parent b547870d71
commit 3235b09a92
13 changed files with 186 additions and 42 deletions
@@ -0,0 +1,17 @@
/*
* 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.checkers.context
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
abstract class AbstractCheckerContext(
override val sessionHolder: SessionHolder,
override val returnTypeCalculator: ReturnTypeCalculator,
override val allInfosSuppressed: Boolean,
override val allWarningsSuppressed: Boolean,
override val allErrorsSuppressed: Boolean
) : CheckerContext()
@@ -14,7 +14,9 @@ import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
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
abstract class CheckerContext {
// Services
@@ -41,7 +43,21 @@ abstract class CheckerContext {
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
): PersistentCheckerContext
): CheckerContext
abstract fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): CheckerContext
abstract fun addDeclaration(declaration: FirDeclaration): CheckerContext
abstract fun dropDeclaration()
abstract fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContext
abstract fun dropQualifiedAccessOrAnnotationCall()
abstract fun addGetClassCall(getClassCall: FirGetClassCall): CheckerContext
abstract fun dropGetClassCall()
fun isDiagnosticSuppressed(diagnostic: FirDiagnostic): Boolean {
val factory = diagnostic.factory
@@ -0,0 +1,106 @@
/*
* 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.checkers.context
import kotlinx.collections.immutable.PersistentSet
import kotlinx.collections.immutable.persistentSetOf
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.PersistentImplicitReceiverStack
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
class MutableCheckerContext private constructor(
override val implicitReceiverStack: PersistentImplicitReceiverStack,
override val containingDeclarations: MutableList<FirDeclaration>,
override val qualifiedAccessOrAnnotationCalls: MutableList<FirStatement>,
override val getClassCalls: MutableList<FirGetClassCall>,
sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
) : AbstractCheckerContext(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
PersistentImplicitReceiverStack(),
mutableListOf(),
mutableListOf(),
mutableListOf(),
sessionHolder,
returnTypeCalculator,
persistentSetOf(),
allInfosSuppressed = false,
allWarningsSuppressed = false,
allErrorsSuppressed = false
)
override fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): MutableCheckerContext {
return MutableCheckerContext(
implicitReceiverStack.add(name, value),
containingDeclarations,
qualifiedAccessOrAnnotationCalls,
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
allInfosSuppressed,
allWarningsSuppressed,
allErrorsSuppressed
)
}
override fun addDeclaration(declaration: FirDeclaration): MutableCheckerContext {
containingDeclarations.add(declaration)
return this
}
override fun dropDeclaration() {
containingDeclarations.removeAt(containingDeclarations.size - 1)
}
override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): MutableCheckerContext {
qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall)
return this
}
override fun dropQualifiedAccessOrAnnotationCall() {
qualifiedAccessOrAnnotationCalls.removeAt(qualifiedAccessOrAnnotationCalls.size - 1)
}
override fun addGetClassCall(getClassCall: FirGetClassCall): MutableCheckerContext {
getClassCalls.add(getClassCall)
return this
}
override fun dropGetClassCall() {
getClassCalls.removeAt(getClassCalls.size - 1)
}
override fun addSuppressedDiagnostics(
diagnosticNames: Collection<String>,
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
): MutableCheckerContext {
if (diagnosticNames.isEmpty()) return this
return MutableCheckerContext(
implicitReceiverStack,
containingDeclarations,
qualifiedAccessOrAnnotationCalls,
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames),
this.allInfosSuppressed || allInfosSuppressed,
this.allWarningsSuppressed || allWarningsSuppressed,
this.allErrorsSuppressed || allErrorsSuppressed
)
}
}
@@ -23,13 +23,13 @@ class PersistentCheckerContext private constructor(
override val containingDeclarations: PersistentList<FirDeclaration>,
override val qualifiedAccessOrAnnotationCalls: PersistentList<FirStatement>,
override val getClassCalls: PersistentList<FirGetClassCall>,
override val sessionHolder: SessionHolder,
override val returnTypeCalculator: ReturnTypeCalculator,
sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
override val allInfosSuppressed: Boolean,
override val allWarningsSuppressed: Boolean,
override val allErrorsSuppressed: Boolean
) : CheckerContext() {
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
) : AbstractCheckerContext(sessionHolder, returnTypeCalculator, allInfosSuppressed, allWarningsSuppressed, allErrorsSuppressed) {
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
PersistentImplicitReceiverStack(),
persistentListOf(),
@@ -43,7 +43,7 @@ class PersistentCheckerContext private constructor(
allErrorsSuppressed = false
)
fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext {
override fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack.add(name, value),
containingDeclarations,
@@ -58,7 +58,7 @@ class PersistentCheckerContext private constructor(
)
}
fun addDeclaration(declaration: FirDeclaration): PersistentCheckerContext {
override fun addDeclaration(declaration: FirDeclaration): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations.add(declaration),
@@ -73,7 +73,10 @@ class PersistentCheckerContext private constructor(
)
}
fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): PersistentCheckerContext {
override fun dropDeclaration() {
}
override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations,
@@ -88,7 +91,10 @@ class PersistentCheckerContext private constructor(
)
}
fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext {
override fun dropQualifiedAccessOrAnnotationCall() {
}
override fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations,
@@ -103,6 +109,9 @@ class PersistentCheckerContext private constructor(
)
}
override fun dropGetClassCall() {
}
override fun addSuppressedDiagnostics(
diagnosticNames: Collection<String>,
allInfosSuppressed: Boolean,
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.analysis.checkers.util
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor
import org.jetbrains.kotlin.fir.visitors.FirVisitor
@@ -15,7 +14,7 @@ fun FirElement.checkChildrenWithCustomVisitor(
parentContext: CheckerContext,
visitorVoid: FirVisitor<Unit, CheckerContext>
) {
val collectingVisitor = object : AbstractDiagnosticCollectorVisitor(parentContext as PersistentCheckerContext) {
val collectingVisitor = object : AbstractDiagnosticCollectorVisitor(parentContext) {
override fun checkElement(element: FirElement) {
element.accept(visitorVoid, context)
}
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.*
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.name.Name
abstract class AbstractDiagnosticCollectorVisitor(
@set:PrivateForInline var context: PersistentCheckerContext,
@set:PrivateForInline var context: CheckerContext,
) : FirDefaultVisitor<Unit, Nothing?>() {
protected open fun shouldVisitDeclaration(declaration: FirDeclaration) = true
@@ -256,6 +256,7 @@ abstract class AbstractDiagnosticCollectorVisitor(
try {
return block()
} finally {
existingContext.dropQualifiedAccessOrAnnotationCall()
context = existingContext
}
}
@@ -268,6 +269,7 @@ abstract class AbstractDiagnosticCollectorVisitor(
try {
return block()
} finally {
existingContext.dropGetClassCall()
context = existingContext
}
}
@@ -280,6 +282,7 @@ abstract class AbstractDiagnosticCollectorVisitor(
try {
return block()
} finally {
existingContext.dropDeclaration()
context = existingContext
}
}
@@ -6,11 +6,11 @@
package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
open class CheckerRunningDiagnosticCollectorVisitor(
context: PersistentCheckerContext,
context: CheckerContext,
protected val components: List<AbstractDiagnosticCollectorComponent>
) : AbstractDiagnosticCollectorVisitor(context) {
@@ -6,15 +6,10 @@
package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.MutableCheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
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
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
class SimpleDiagnosticsCollector(
@@ -24,7 +19,7 @@ class SimpleDiagnosticsCollector(
) : AbstractDiagnosticCollector(session, scopeSession, createComponents) {
override fun createVisitor(components: List<AbstractDiagnosticCollectorComponent>): CheckerRunningDiagnosticCollectorVisitor {
return CheckerRunningDiagnosticCollectorVisitor(
PersistentCheckerContext(
MutableCheckerContext(
this,
ReturnTypeCalculatorForFullBodyResolve()
),