FIR checker: introduce NO_(GET|SET)_METHOD
Besides introducing new diagnostics, this commit unifies source usages for array accesses in PSI & LT.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
651fd4ad9f
commit
e1c80ac75c
+1
@@ -49,6 +49,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
PRIVATE_MODIFIER,
|
||||
COMPANION_OBJECT,
|
||||
CONST_MODIFIER,
|
||||
ARRAY_ACCESS
|
||||
|
||||
;
|
||||
|
||||
|
||||
+5
@@ -515,6 +515,11 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
}
|
||||
|
||||
val CONVENTIONS by object : DiagnosticGroup("Conventions") {
|
||||
val NO_GET_METHOD by error<FirSourceElement, KtArrayAccessExpression>(PositioningStrategy.ARRAY_ACCESS)
|
||||
val NO_SET_METHOD by error<FirSourceElement, KtArrayAccessExpression>(PositioningStrategy.ARRAY_ACCESS)
|
||||
}
|
||||
|
||||
val EXTENDED_CHECKERS by object : DiagnosticGroup("Extended checkers") {
|
||||
val REDUNDANT_VISIBILITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||
val REDUNDANT_MODALITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER)
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
@@ -307,6 +308,10 @@ object FirErrors {
|
||||
// Function contracts
|
||||
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||
|
||||
// Conventions
|
||||
val NO_GET_METHOD by error0<FirSourceElement, KtArrayAccessExpression>(SourceElementPositioningStrategies.ARRAY_ACCESS)
|
||||
val NO_SET_METHOD by error0<FirSourceElement, KtArrayAccessExpression>(SourceElementPositioningStrategies.ARRAY_ACCESS)
|
||||
|
||||
// Extended checkers
|
||||
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
object FirConventionFunctionCallChecker : FirFunctionCallChecker() {
|
||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val calleeReference = expression.calleeReference as? FirErrorNamedReference ?: return
|
||||
val diagnostic = calleeReference.diagnostic as? ConeUnresolvedNameError ?: return
|
||||
|
||||
if (expression.calleeReference.source?.kind == FirFakeSourceElementKind.ArrayAccessNameReference) {
|
||||
when (diagnostic.name) {
|
||||
OperatorNameConventions.GET -> reporter.reportOn(calleeReference.source, FirErrors.NO_GET_METHOD, context)
|
||||
OperatorNameConventions.SET -> reporter.reportOn(calleeReference.source, FirErrors.NO_SET_METHOD, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -39,6 +39,10 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
||||
?: errorNamedReference.source ?: return
|
||||
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
||||
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && errorNamedReference.diagnostic is ConeUnresolvedNameError) return
|
||||
// Already reported in FirConventionFunctionCallChecker
|
||||
if (errorNamedReference.source?.kind == FirFakeSourceElementKind.ArrayAccessNameReference &&
|
||||
errorNamedReference.diagnostic is ConeUnresolvedNameError
|
||||
) return
|
||||
reportFirDiagnostic(errorNamedReference.diagnostic, source, reporter, data)
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -139,6 +139,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_GET_METHOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SET_METHOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
|
||||
@@ -679,6 +681,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
// Function contracts
|
||||
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)
|
||||
|
||||
// Conventions
|
||||
map.put(NO_GET_METHOD, "No get method providing array access")
|
||||
map.put(NO_SET_METHOD, "No set method providing array access")
|
||||
|
||||
// Extended checkers group
|
||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
||||
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
|
||||
|
||||
+11
@@ -415,6 +415,17 @@ object LightTreePositioningStrategies {
|
||||
return markElement(tree.ifKeyword(node) ?: node, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
|
||||
val ARRAY_ACCESS = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
return markElement(tree.findChildByType(node, KtNodeTypes.INDICES)!!, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirSourceElement.hasValOrVar(): Boolean =
|
||||
|
||||
+4
@@ -143,4 +143,8 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.IF_EXPRESSION
|
||||
)
|
||||
|
||||
val ARRAY_ACCESS = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ARRAY_ACCESS,
|
||||
PositioningStrategies.ARRAY_ACCESS
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user