[FIR] Introduce & use SourceElementPositioningStrategies.OPERATOR

This commit is contained in:
Mikhail Glukhikh
2020-11-24 16:09:50 +03:00
parent c9806c5af9
commit ea7d738ee1
6 changed files with 28 additions and 9 deletions
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.lexer.KtTokens
object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() { object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -29,7 +27,6 @@ object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() {
if (left.typeRef.coneType.classId != StandardClassIds.Array) return if (left.typeRef.coneType.classId != StandardClassIds.Array) return
if (right.typeRef.coneType.classId != StandardClassIds.Array) return if (right.typeRef.coneType.classId != StandardClassIds.Array) return
val source = expression.source?.getChild(setOf(KtTokens.EQEQ, KtTokens.EXCLEQ)) reporter.report(expression.source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS)
reporter.report(source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS)
} }
} }
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirExpressionChecke
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
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.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
@@ -59,8 +58,7 @@ object CanBeReplacedWithOperatorAssignmentChecker : FirExpressionChecker<FirVari
} }
if (needToReport) { if (needToReport) {
val source = expression.source?.getChild(setOf(KtTokens.EQ)) reporter.report(expression.source, FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT)
reporter.report(source, FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT)
} }
} }
@@ -160,9 +160,9 @@ object FirErrors {
val REDUNDANT_EXPLICIT_TYPE by warning0<FirSourceElement, PsiElement>() val REDUNDANT_EXPLICIT_TYPE by warning0<FirSourceElement, PsiElement>()
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0<FirSourceElement, PsiElement>() val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0<FirSourceElement, PsiElement>()
val CAN_BE_VAL by warning0<FirSourceElement, PsiElement>() val CAN_BE_VAL by warning0<FirSourceElement, PsiElement>()
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning0<FirSourceElement, PsiElement>() val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.OPERATOR)
val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning0<FirSourceElement, PsiElement>() val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning0<FirSourceElement, PsiElement>()
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, PsiElement>() 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, PsiElement>()
@@ -142,6 +142,12 @@ object LightTreePositioningStrategies {
return super.mark(node, tree) return super.mark(node, tree)
} }
} }
val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): List<TextRange> {
return markElement(tree.operationReference(node) ?: node, tree)
}
}
} }
fun FirSourceElement.hasValOrVar(): Boolean = fun FirSourceElement.hasValOrVar(): Boolean =
@@ -162,6 +168,9 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.initKeyword(node: Ligh
private fun FlyweightCapableTreeStructure<LighterASTNode>.nameIdentifier(node: LighterASTNode): LighterASTNode? = private fun FlyweightCapableTreeStructure<LighterASTNode>.nameIdentifier(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtTokens.IDENTIFIER) findChildByType(node, KtTokens.IDENTIFIER)
private fun FlyweightCapableTreeStructure<LighterASTNode>.operationReference(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtNodeTypes.OPERATION_REFERENCE)
private fun FlyweightCapableTreeStructure<LighterASTNode>.rightParenthesis(node: LighterASTNode): LighterASTNode? = private fun FlyweightCapableTreeStructure<LighterASTNode>.rightParenthesis(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtTokens.RPAR) findChildByType(node, KtTokens.RPAR)
@@ -32,4 +32,9 @@ object SourceElementPositioningStrategies {
LightTreePositioningStrategies.DECLARATION_SIGNATURE, LightTreePositioningStrategies.DECLARATION_SIGNATURE,
PositioningStrategies.DECLARATION_SIGNATURE PositioningStrategies.DECLARATION_SIGNATURE
) )
val OPERATOR = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR,
PositioningStrategies.OPERATOR
)
} }
@@ -687,4 +687,14 @@ object PositioningStrategies {
return DEFAULT.mark(element) return DEFAULT.mark(element)
} }
} }
val OPERATOR: PositioningStrategy<KtExpression> = object : PositioningStrategy<KtExpression>() {
override fun mark(element: KtExpression): List<TextRange> {
return when (element) {
is KtBinaryExpression -> mark(element.operationReference)
is KtUnaryExpression -> mark(element.operationReference)
else -> super.mark(element)
}
}
}
} }