From 8a549cafecc854ced0bd0f3c781cc1f919d83cbc Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 31 Mar 2021 12:13:32 +0300 Subject: [PATCH] [FIR] Cleanup `CheckerContext.kt` --- .../checkers/context/CheckerContext.kt | 152 ++---------------- .../context/PersistentCheckerContext.kt | 126 +++++++++++++++ .../expression/FirAbstractSuperCallChecker.kt | 1 + ...rclassNotAccessibleFromInterfaceChecker.kt | 1 + ...irValReassignmentViaBackingFieldChecker.kt | 1 + .../RedundantVisibilityModifierChecker.kt | 1 + 6 files changed, 147 insertions(+), 135 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt index 85252687c83..4c18c5e9246 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt @@ -5,28 +5,26 @@ package org.jetbrains.kotlin.fir.analysis.checkers.context -import kotlinx.collections.immutable.PersistentList -import kotlinx.collections.immutable.PersistentSet -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.persistentSetOf import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack -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 abstract class CheckerContext { + // Services + abstract val sessionHolder: SessionHolder + abstract val returnTypeCalculator: ReturnTypeCalculator + + // Context abstract val implicitReceiverStack: ImplicitReceiverStack abstract val containingDeclarations: List abstract val qualifiedAccesses: List abstract val getClassCalls: List - abstract val sessionHolder: SessionHolder - abstract val returnTypeCalculator: ReturnTypeCalculator + + // Suppress abstract val suppressedDiagnostics: Set abstract val allInfosSuppressed: Boolean abstract val allWarningsSuppressed: Boolean @@ -35,30 +33,6 @@ abstract class CheckerContext { val session: FirSession get() = sessionHolder.session - /** - * Returns the closest to the end of context.containingDeclarations - * instance of type [T] or null if no such item could be found. - */ - inline fun findClosest(): T? { - for (it in containingDeclarations.asReversed()) { - return it as? T ?: continue - } - - return null - } - - /** - * Same as the one without specific [check]. For some cases, an instance of type [T] isn't good enough. E.g., property accessor is - * either getter or setter, but a type-based search could return, say, the closest setter, while we want to keep searching for a getter. - */ - inline fun findClosest(check: (T) -> Boolean): T? { - for (it in containingDeclarations.asReversed()) { - return (it as? T)?.takeIf(check) ?: continue - } - - return null - } - abstract fun addSuppressedDiagnostics( diagnosticNames: Collection, allInfosSuppressed: Boolean, @@ -67,109 +41,17 @@ abstract class CheckerContext { ): PersistentCheckerContext } -class PersistentCheckerContext private constructor( - override val implicitReceiverStack: PersistentImplicitReceiverStack, - override val containingDeclarations: PersistentList, - override val qualifiedAccesses: PersistentList, - override val getClassCalls: PersistentList, - override val sessionHolder: SessionHolder, - override val returnTypeCalculator: ReturnTypeCalculator, - override val suppressedDiagnostics: PersistentSet, - override val allInfosSuppressed: Boolean, - override val allWarningsSuppressed: Boolean, - override val allErrorsSuppressed: Boolean -) : CheckerContext() { - constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this( - PersistentImplicitReceiverStack(), - persistentListOf(), - persistentListOf(), - persistentListOf(), - sessionHolder, - returnTypeCalculator, - persistentSetOf(), - allInfosSuppressed = false, - allWarningsSuppressed = false, - allErrorsSuppressed = false - ) +/** + * Returns the closest to the end of context.containingDeclarations instance of type [T] or null if no such item could be found. + * By specifying [check] you can filter which exact declaration should be found + * E.g., property accessor is either getter or setter, but a type-based search could return, say, + * the closest setter, while we want to keep searching for a getter. + */ - fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext { - return PersistentCheckerContext( - implicitReceiverStack.add(name, value), - containingDeclarations, - qualifiedAccesses, - getClassCalls, - sessionHolder, - returnTypeCalculator, - suppressedDiagnostics, - allInfosSuppressed, - allWarningsSuppressed, - allErrorsSuppressed - ) +inline fun CheckerContext.findClosest(check: (T) -> Boolean = { true }): T? { + for (it in containingDeclarations.asReversed()) { + return (it as? T)?.takeIf(check) ?: continue } - fun addDeclaration(declaration: FirDeclaration): PersistentCheckerContext { - return PersistentCheckerContext( - implicitReceiverStack, - containingDeclarations.add(declaration), - qualifiedAccesses, - getClassCalls, - sessionHolder, - returnTypeCalculator, - suppressedDiagnostics, - allInfosSuppressed, - allWarningsSuppressed, - allErrorsSuppressed - ) - } - - fun addQualifiedAccess(qualifiedAccess: FirQualifiedAccess): PersistentCheckerContext { - return PersistentCheckerContext( - implicitReceiverStack, - containingDeclarations, - qualifiedAccesses.add(qualifiedAccess), - getClassCalls, - sessionHolder, - returnTypeCalculator, - suppressedDiagnostics, - allInfosSuppressed, - allWarningsSuppressed, - allErrorsSuppressed - ) - } - - fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext { - return PersistentCheckerContext( - implicitReceiverStack, - containingDeclarations, - qualifiedAccesses, - getClassCalls.add(getClassCall), - sessionHolder, - returnTypeCalculator, - suppressedDiagnostics, - allInfosSuppressed, - allWarningsSuppressed, - allErrorsSuppressed - ) - } - - override fun addSuppressedDiagnostics( - diagnosticNames: Collection, - allInfosSuppressed: Boolean, - allWarningsSuppressed: Boolean, - allErrorsSuppressed: Boolean - ): PersistentCheckerContext { - if (diagnosticNames.isEmpty()) return this - return PersistentCheckerContext( - implicitReceiverStack, - containingDeclarations, - qualifiedAccesses, - getClassCalls, - sessionHolder, - returnTypeCalculator, - suppressedDiagnostics.addAll(diagnosticNames), - this.allInfosSuppressed || allInfosSuppressed, - this.allWarningsSuppressed || allWarningsSuppressed, - this.allErrorsSuppressed || allErrorsSuppressed - ) - } + return null } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt new file mode 100644 index 00000000000..0b47de99cc5 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt @@ -0,0 +1,126 @@ +/* + * 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.PersistentList +import kotlinx.collections.immutable.PersistentSet +import kotlinx.collections.immutable.persistentListOf +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.FirQualifiedAccess +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 PersistentCheckerContext private constructor( + override val implicitReceiverStack: PersistentImplicitReceiverStack, + override val containingDeclarations: PersistentList, + override val qualifiedAccesses: PersistentList, + override val getClassCalls: PersistentList, + override val sessionHolder: SessionHolder, + override val returnTypeCalculator: ReturnTypeCalculator, + override val suppressedDiagnostics: PersistentSet, + override val allInfosSuppressed: Boolean, + override val allWarningsSuppressed: Boolean, + override val allErrorsSuppressed: Boolean +) : CheckerContext() { + constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this( + PersistentImplicitReceiverStack(), + persistentListOf(), + persistentListOf(), + persistentListOf(), + sessionHolder, + returnTypeCalculator, + persistentSetOf(), + allInfosSuppressed = false, + allWarningsSuppressed = false, + allErrorsSuppressed = false + ) + + fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext { + return PersistentCheckerContext( + implicitReceiverStack.add(name, value), + containingDeclarations, + qualifiedAccesses, + getClassCalls, + sessionHolder, + returnTypeCalculator, + suppressedDiagnostics, + allInfosSuppressed, + allWarningsSuppressed, + allErrorsSuppressed + ) + } + + fun addDeclaration(declaration: FirDeclaration): PersistentCheckerContext { + return PersistentCheckerContext( + implicitReceiverStack, + containingDeclarations.add(declaration), + qualifiedAccesses, + getClassCalls, + sessionHolder, + returnTypeCalculator, + suppressedDiagnostics, + allInfosSuppressed, + allWarningsSuppressed, + allErrorsSuppressed + ) + } + + fun addQualifiedAccess(qualifiedAccess: FirQualifiedAccess): PersistentCheckerContext { + return PersistentCheckerContext( + implicitReceiverStack, + containingDeclarations, + qualifiedAccesses.add(qualifiedAccess), + getClassCalls, + sessionHolder, + returnTypeCalculator, + suppressedDiagnostics, + allInfosSuppressed, + allWarningsSuppressed, + allErrorsSuppressed + ) + } + + fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext { + return PersistentCheckerContext( + implicitReceiverStack, + containingDeclarations, + qualifiedAccesses, + getClassCalls.add(getClassCall), + sessionHolder, + returnTypeCalculator, + suppressedDiagnostics, + allInfosSuppressed, + allWarningsSuppressed, + allErrorsSuppressed + ) + } + + override fun addSuppressedDiagnostics( + diagnosticNames: Collection, + allInfosSuppressed: Boolean, + allWarningsSuppressed: Boolean, + allErrorsSuppressed: Boolean + ): PersistentCheckerContext { + if (diagnosticNames.isEmpty()) return this + return PersistentCheckerContext( + implicitReceiverStack, + containingDeclarations, + qualifiedAccesses, + getClassCalls, + sessionHolder, + returnTypeCalculator, + suppressedDiagnostics.addAll(diagnosticNames), + this.allInfosSuppressed || allInfosSuppressed, + this.allWarningsSuppressed || allWarningsSuppressed, + this.allErrorsSuppressed || allErrorsSuppressed + ) + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt index c92c6c9ff00..3e415e39820 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAbstractSuperCallChecker.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass import org.jetbrains.kotlin.fir.analysis.checkers.getDeclaration import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt index 0bab6e13a60..7a6de37b642 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuperclassNotAccessibleFromInterfaceChecker.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentViaBackingFieldChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentViaBackingFieldChecker.kt index 3b397033a23..fb36f22520c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentViaBackingFieldChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentViaBackingFieldChecker.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt index 95cb2acd70a..aba710182df 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/RedundantVisibilityModifierChecker.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElement import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember import org.jetbrains.kotlin.fir.analysis.diagnostics.*