FIR: introduce & use SELECTOR_BY_QUALIFIED positioning strategy
This commit is contained in:
+1
@@ -42,6 +42,7 @@ enum class PositioningStrategy(private val strategy: String) {
|
||||
IF_EXPRESSION("IF_EXPRESSION"),
|
||||
VARIANCE_MODIFIER("VARIANCE_MODIFIER"),
|
||||
LATEINIT_MODIFIER("LATEINIT_MODIFIER"),
|
||||
SELECTOR_BY_QUALIFIED("SELECTOR_BY_QUALIFIED"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
+3
-3
@@ -388,7 +388,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
|
||||
val FUNCTION_CONTRACTS by object : DiagnosticGroup("Function contracts") {
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement> {
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||
parameter<String>("reason")
|
||||
}
|
||||
}
|
||||
@@ -401,7 +401,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning<FirSourceElement, PsiElement>()
|
||||
val CAN_BE_VAL by warning<FirSourceElement, KtDeclaration>(PositioningStrategy.VAL_OR_VAR_NODE)
|
||||
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning<FirSourceElement, KtExpression>(PositioningStrategy.OPERATOR)
|
||||
val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning<FirSourceElement, PsiElement>()
|
||||
val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning<FirSourceElement, PsiElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED)
|
||||
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning<FirSourceElement, KtExpression>(PositioningStrategy.OPERATOR)
|
||||
val EMPTY_RANGE by warning<FirSourceElement, PsiElement>()
|
||||
val REDUNDANT_SETTER_PARAMETER_TYPE by warning<FirSourceElement, PsiElement>()
|
||||
@@ -409,7 +409,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val ASSIGNED_VALUE_IS_NEVER_READ by warning<FirSourceElement, PsiElement>()
|
||||
val VARIABLE_INITIALIZER_IS_REDUNDANT by warning<FirSourceElement, PsiElement>()
|
||||
val VARIABLE_NEVER_READ by warning<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
val USELESS_CALL_ON_NOT_NULL by warning<FirSourceElement, PsiElement>()
|
||||
val USELESS_CALL_ON_NOT_NULL by warning<FirSourceElement, PsiElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -244,7 +244,7 @@ object FirErrors {
|
||||
val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
|
||||
|
||||
// Function contracts
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>()
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||
|
||||
// Extended checkers
|
||||
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||
@@ -254,7 +254,7 @@ object FirErrors {
|
||||
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0<FirSourceElement, PsiElement>()
|
||||
val CAN_BE_VAL by warning0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
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>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.OPERATOR)
|
||||
val EMPTY_RANGE by warning0<FirSourceElement, PsiElement>()
|
||||
val REDUNDANT_SETTER_PARAMETER_TYPE by warning0<FirSourceElement, PsiElement>()
|
||||
@@ -262,6 +262,6 @@ object FirErrors {
|
||||
val ASSIGNED_VALUE_IS_NEVER_READ by warning0<FirSourceElement, PsiElement>()
|
||||
val VARIABLE_INITIALIZER_IS_REDUNDANT 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>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||
|
||||
}
|
||||
|
||||
+37
@@ -335,6 +335,24 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val SELECTOR_BY_QUALIFIED: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
if (node.tokenType != KtNodeTypes.DOT_QUALIFIED_EXPRESSION && node.tokenType != KtNodeTypes.SAFE_ACCESS_EXPRESSION) {
|
||||
return super.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
val selector = tree.selector(node)
|
||||
if (selector != null) {
|
||||
return markElement(selector, startOffset, endOffset, tree, node)
|
||||
}
|
||||
return super.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
}
|
||||
|
||||
val WHEN_EXPRESSION = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
@@ -448,6 +466,25 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.defaultValue(node: Lig
|
||||
return null
|
||||
}
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.selector(node: LighterASTNode): LighterASTNode? {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
val children = childrenRef.get() ?: return null
|
||||
var dotFound = false
|
||||
for (child in children) {
|
||||
if (child == null) continue
|
||||
if (child.tokenType == KtTokens.DOT) {
|
||||
dotFound = true
|
||||
continue
|
||||
}
|
||||
if (dotFound && (child.tokenType == KtNodeTypes.CALL_EXPRESSION || child.tokenType == KtNodeTypes.REFERENCE_EXPRESSION)) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: IElementType): LighterASTNode? {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
|
||||
+5
@@ -103,6 +103,11 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.DOT_BY_SELECTOR
|
||||
)
|
||||
|
||||
val SELECTOR_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SELECTOR_BY_QUALIFIED,
|
||||
PositioningStrategies.SELECTOR_BY_QUALIFIED
|
||||
)
|
||||
|
||||
val WHEN_EXPRESSION = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.WHEN_EXPRESSION,
|
||||
PositioningStrategies.WHEN_EXPRESSION
|
||||
|
||||
@@ -725,4 +725,15 @@ object PositioningStrategies {
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
val SELECTOR_BY_QUALIFIED: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is KtQualifiedExpression) {
|
||||
when (val selectorExpression = element.selectorExpression) {
|
||||
is KtCallExpression, is KtReferenceExpression -> return mark(selectorExpression)
|
||||
}
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user