[FIR] Remove not used FirRedundantLabelChecker

This commit is contained in:
Ivan Kochurkin
2022-06-01 00:31:00 +03:00
committed by teamcity
parent 9f69ea1786
commit 0c543d65f3
@@ -1,163 +0,0 @@
/*
* 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.syntax
import com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.findChildByType
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.diagnostics.unwrapParenthesesLabelsAndAnnotations
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.buildChildSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.psi.*
object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, PsiElement>() {
override fun checkLightTree(
element: FirDeclaration,
source: KtLightSourceElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
// Local declarations are already checked when the containing declaration is checked.
if (!isRootLabelContainer(element)) return
val allTraversalRoots = mutableSetOf<KtSourceElement>()
// First collect all labels in the declaration
element.accept(object : FirVisitorVoid() {
override fun visitElement(element: FirElement) {
element.acceptChildren(this)
}
override fun visitBlock(block: FirBlock) {
markTraversalRoot(block)
super.visitBlock(block)
}
override fun visitProperty(property: FirProperty) {
markTraversalRoot(property)
super.visitProperty(property)
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
markTraversalRoot(simpleFunction)
super.visitFunction(simpleFunction)
}
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor) {
markTraversalRoot(propertyAccessor)
super.visitPropertyAccessor(propertyAccessor)
}
override fun visitConstructor(constructor: FirConstructor) {
markTraversalRoot(constructor)
super.visitConstructor(constructor)
}
private fun markTraversalRoot(elem: FirElement) {
val elemSource = elem.source
if (elemSource?.kind is KtRealSourceElementKind) {
allTraversalRoots.add(elemSource)
}
}
})
for (root in allTraversalRoots) {
root.treeStructure.reportRedundantLabels(reporter, context, root as KtLightSourceElement, allTraversalRoots)
}
}
private fun FlyweightCapableTreeStructure<LighterASTNode>.reportRedundantLabels(
reporter: DiagnosticReporter,
context: CheckerContext,
source: KtLightSourceElement,
allTraversalRoots: Set<KtSourceElement>,
isChildNode: Boolean = false,
) {
if (isChildNode && source in allTraversalRoots) return // Prevent double traversal
val node = source.lighterASTNode
if (node.tokenType == KtNodeTypes.LABELED_EXPRESSION) {
val labelQualifier = findChildByType(node, KtNodeTypes.LABEL_QUALIFIER)
if (labelQualifier != null) {
findChildByType(labelQualifier, KtNodeTypes.LABEL)?.let { labelNode ->
when (unwrapParenthesesLabelsAndAnnotations(node).tokenType) {
KtNodeTypes.LAMBDA_EXPRESSION, KtNodeTypes.FOR, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE, KtNodeTypes.FUN -> {}
else -> reporter.reportOn(
source.buildChildSourceElement(labelNode),
FirErrors.REDUNDANT_LABEL_WARNING,
context
)
}
}
}
}
val childrenRef = Ref.create<Array<LighterASTNode?>>(null)
getChildren(node, childrenRef)
for (child in childrenRef.get() ?: return) {
if (child == null) continue
reportRedundantLabels(reporter, context, source.buildChildSourceElement(child), allTraversalRoots, true)
}
}
override fun checkPsi(
element: FirDeclaration,
source: KtPsiSourceElement,
psi: PsiElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
// Local declarations are already checked when the containing declaration is checked.
if (!isRootLabelContainer(element)) return
// First collect all labels in the declaration
source.psi.accept(object : KtTreeVisitorVoid() {
override fun visitLabeledExpression(expression: KtLabeledExpression) {
val labelNameExpression = expression.getTargetLabel()
if (labelNameExpression != null) {
val deparenthesizedBaseExpression = KtPsiUtil.deparenthesize(expression)
if (deparenthesizedBaseExpression !is KtLambdaExpression &&
deparenthesizedBaseExpression !is KtLoopExpression &&
deparenthesizedBaseExpression !is KtNamedFunction
) {
reporter.reportOn(labelNameExpression.toKtPsiSourceElement(), FirErrors.REDUNDANT_LABEL_WARNING, context)
}
}
super.visitLabeledExpression(expression)
}
})
}
private fun isRootLabelContainer(element: FirDeclaration): Boolean {
if (element.source?.kind is KtFakeSourceElementKind) return false
if (element is FirCallableDeclaration && element.effectiveVisibility == EffectiveVisibility.Local) return false
return when (element) {
is FirAnonymousFunction -> false
is FirFunction -> true
is FirProperty -> true
// Consider class initializer of non local class as root label container.
is FirAnonymousInitializer -> {
val parentVisibility =
(element.getContainingClassSymbol(element.moduleData.session) as? FirRegularClassSymbol)?.effectiveVisibility
parentVisibility != null && parentVisibility != EffectiveVisibility.Local
}
else -> false
}
}
}