提交 94ddb712 编写于 作者: M Mikhail Glukhikh

[FIR] Simplify UnusedChecker & delete FirSourceChildren.kt

上级 8abf2789
/*
* Copyright 2010-2020 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
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.fir.*
fun FirSourceElement.getChild(type: IElementType, index: Int = 0, depth: Int = -1): FirSourceElement? {
return getChild(setOf(type), index, depth)
}
fun FirSourceElement.getChild(types: TokenSet, index: Int = 0, depth: Int = -1): FirSourceElement? {
return getChild(types.types.toSet(), index, depth)
}
fun FirSourceElement.getChild(types: Set<IElementType>, index: Int = 0, depth: Int = -1): FirSourceElement? {
return when (this) {
is FirPsiSourceElement<*> -> {
getChild(types, index, depth)
}
is FirLightSourceElement -> {
getChild(types, index, depth)
}
else -> null
}
}
private fun FirPsiSourceElement<*>.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
val visitor = PsiElementFinderByType(types, index, depth)
return visitor.find(psi)?.toFirPsiSourceElement()
}
private fun FirLightSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth)
return visitor.find(lighterASTNode)?.toFirLightSourceElement(treeStructure)
}
\ No newline at end of file
...@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended ...@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended
import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.analysis.cfa.* import org.jetbrains.kotlin.fir.analysis.cfa.*
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
...@@ -17,16 +17,17 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass ...@@ -17,16 +17,17 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.isIterator import org.jetbrains.kotlin.fir.analysis.checkers.isIterator
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.lexer.KtTokens
object UnusedChecker : FirControlFlowChecker() { object UnusedChecker : FirControlFlowChecker() {
override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) { override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, checkerContext: CheckerContext) {
if ((graph.declaration as? FirSymbolOwner<*>)?.getContainingClass(checkerContext)?.takeIf { !it.symbol.classId.isLocal }!= null) return if ((graph.declaration as? FirSymbolOwner<*>)?.getContainingClass(checkerContext)?.takeIf {
!it.symbol.classId.isLocal
} != null
) return
val properties = LocalPropertyCollector.collect(graph) val properties = LocalPropertyCollector.collect(graph)
if (properties.isEmpty()) return if (properties.isEmpty()) return
...@@ -55,11 +56,11 @@ object UnusedChecker : FirControlFlowChecker() { ...@@ -55,11 +56,11 @@ object UnusedChecker : FirControlFlowChecker() {
if (variableSymbol.isLoopIterator) return if (variableSymbol.isLoopIterator) return
val data = data[node]?.get(variableSymbol) ?: return val data = data[node]?.get(variableSymbol) ?: return
val variableSource = variableSymbol.fir.source.takeIf { it?.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION }
when { when {
data == VariableStatus.UNUSED -> { data == VariableStatus.UNUSED -> {
if ((node.fir.initializer as? FirFunctionCall)?.isIterator != true) { if ((node.fir.initializer as? FirFunctionCall)?.isIterator != true) {
val source = variableSymbol.identifierSource reporter.report(variableSource, FirErrors.UNUSED_VARIABLE)
reporter.report(source, FirErrors.UNUSED_VARIABLE)
} }
} }
data.isRedundantInit -> { data.isRedundantInit -> {
...@@ -67,8 +68,7 @@ object UnusedChecker : FirControlFlowChecker() { ...@@ -67,8 +68,7 @@ object UnusedChecker : FirControlFlowChecker() {
reporter.report(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT) reporter.report(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT)
} }
data == VariableStatus.ONLY_WRITTEN_NEVER_READ -> { data == VariableStatus.ONLY_WRITTEN_NEVER_READ -> {
val source = variableSymbol.identifierSource reporter.report(variableSource, FirErrors.VARIABLE_NEVER_READ)
reporter.report(source, FirErrors.VARIABLE_NEVER_READ)
} }
else -> { else -> {
} }
...@@ -203,7 +203,4 @@ object UnusedChecker : FirControlFlowChecker() { ...@@ -203,7 +203,4 @@ object UnusedChecker : FirControlFlowChecker() {
private val FirPropertySymbol.isLoopIterator private val FirPropertySymbol.isLoopIterator
get() = fir.initializer?.source?.kind == FirFakeSourceElementKind.DesugaredForLoop get() = fir.initializer?.source?.kind == FirFakeSourceElementKind.DesugaredForLoop
private val FirPropertySymbol.identifierSource: FirSourceElement?
get() = fir.source?.getChild(KtTokens.IDENTIFIER, 0, 1)
} }
...@@ -165,9 +165,9 @@ object FirErrors { ...@@ -165,9 +165,9 @@ object FirErrors {
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.OPERATOR) val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.OPERATOR)
val EMPTY_RANGE by warning0<FirSourceElement, PsiElement>() val EMPTY_RANGE by warning0<FirSourceElement, PsiElement>()
val REDUNDANT_SETTER_PARAMETER_TYPE by warning0<FirSourceElement, PsiElement>() val REDUNDANT_SETTER_PARAMETER_TYPE by warning0<FirSourceElement, PsiElement>()
val UNUSED_VARIABLE by warning0<FirSourceElement, PsiElement>() val UNUSED_VARIABLE by warning0<FirSourceElement, KtNamedDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ASSIGNED_VALUE_IS_NEVER_READ by warning0<FirSourceElement, PsiElement>() val ASSIGNED_VALUE_IS_NEVER_READ by warning0<FirSourceElement, PsiElement>()
val VARIABLE_INITIALIZER_IS_REDUNDANT by warning0<FirSourceElement, PsiElement>() val VARIABLE_INITIALIZER_IS_REDUNDANT by warning0<FirSourceElement, PsiElement>()
val VARIABLE_NEVER_READ by warning0<FirSourceElement, PsiElement>() val VARIABLE_NEVER_READ by warning0<FirSourceElement, KtNamedDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
val USELESS_CALL_ON_NOT_NULL by warning0<FirSourceElement, PsiElement>() val USELESS_CALL_ON_NOT_NULL by warning0<FirSourceElement, PsiElement>()
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册