[FIR] Implement annotation checker for underscored type arguments
This commit is contained in:
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirCommaInWhenConditionChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirCommaInWhenConditionChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirConfusingWhenBranchSyntaxChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirConfusingWhenBranchSyntaxChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirUnderscoredTypeArgumentSyntaxChecker
|
||||||
|
|
||||||
object CommonExpressionCheckers : ExpressionCheckers() {
|
object CommonExpressionCheckers : ExpressionCheckers() {
|
||||||
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
||||||
@@ -59,6 +60,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirSpreadOfNullableChecker,
|
FirSpreadOfNullableChecker,
|
||||||
FirAssignmentOperatorCallChecker,
|
FirAssignmentOperatorCallChecker,
|
||||||
FirNamedVarargChecker,
|
FirNamedVarargChecker,
|
||||||
|
FirUnderscoredTypeArgumentSyntaxChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
|
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
|
||||||
|
|||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.annotations
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.diagnostics.userType
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.buildChildSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.isUnderscore
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
|
import org.jetbrains.kotlin.psi.KtTypeProjection
|
||||||
|
|
||||||
|
object FirUnderscoredTypeArgumentSyntaxChecker : FirExpressionSyntaxChecker<FirFunctionCall, PsiElement>() {
|
||||||
|
override fun isApplicable(element: FirFunctionCall, source: KtSourceElement): Boolean =
|
||||||
|
element.typeArguments.isNotEmpty()
|
||||||
|
|
||||||
|
override fun checkPsi(
|
||||||
|
element: FirFunctionCall,
|
||||||
|
source: KtPsiSourceElement,
|
||||||
|
psi: PsiElement,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
for (typeProjection in element.typeArguments) {
|
||||||
|
val psiTypeArgument = typeProjection.source?.psi as? KtTypeProjection ?: continue
|
||||||
|
val typeReference = psiTypeArgument.typeReference ?: continue
|
||||||
|
|
||||||
|
if (!typeReference.isPlaceholder) continue
|
||||||
|
|
||||||
|
for (annotation in typeReference.annotationEntries) {
|
||||||
|
reporter.reportOn(
|
||||||
|
annotation.toKtPsiSourceElement(), FirErrors.UNSUPPORTED,
|
||||||
|
"annotations on an underscored type argument", context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkLightTree(
|
||||||
|
element: FirFunctionCall,
|
||||||
|
source: KtLightSourceElement,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
) {
|
||||||
|
for (typeProjection in element.typeArguments) {
|
||||||
|
val lightTreeTypeArgument = typeProjection.source?.lighterASTNode ?: continue
|
||||||
|
|
||||||
|
if (!source.treeStructure.userType(lightTreeTypeArgument).toString().isUnderscore) continue
|
||||||
|
|
||||||
|
val annotations = source.treeStructure.annotations(lightTreeTypeArgument) ?: continue
|
||||||
|
|
||||||
|
for (annotation in annotations) {
|
||||||
|
reporter.reportOn(
|
||||||
|
source.buildChildSourceElement(annotation), FirErrors.UNSUPPORTED,
|
||||||
|
"annotations on an underscored type argument", context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -1192,6 +1192,17 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.inlineModifier(declaration: Li
|
|||||||
fun FlyweightCapableTreeStructure<LighterASTNode>.typeParametersList(declaration: LighterASTNode): LighterASTNode? =
|
fun FlyweightCapableTreeStructure<LighterASTNode>.typeParametersList(declaration: LighterASTNode): LighterASTNode? =
|
||||||
findChildByType(declaration, KtNodeTypes.TYPE_PARAMETER_LIST)
|
findChildByType(declaration, KtNodeTypes.TYPE_PARAMETER_LIST)
|
||||||
|
|
||||||
|
fun FlyweightCapableTreeStructure<LighterASTNode>.annotations(node: LighterASTNode): List<LighterASTNode>? {
|
||||||
|
val typeReference = findChildByType(node, KtNodeTypes.TYPE_REFERENCE) ?: return null
|
||||||
|
val modifiers = modifierList(typeReference) ?: return null
|
||||||
|
return collectDescendantsOfType(modifiers, KtNodeTypes.ANNOTATION_ENTRY)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FlyweightCapableTreeStructure<LighterASTNode>.userType(node: LighterASTNode): LighterASTNode? {
|
||||||
|
val typeReference = findChildByType(node, KtNodeTypes.TYPE_REFERENCE) ?: return null
|
||||||
|
return findChildByType(typeReference, KtNodeTypes.USER_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.supertypesList(node: LighterASTNode): LighterASTNode? =
|
private fun FlyweightCapableTreeStructure<LighterASTNode>.supertypesList(node: LighterASTNode): LighterASTNode? =
|
||||||
findChildByType(node, KtNodeTypes.SUPER_TYPE_LIST)
|
findChildByType(node, KtNodeTypes.SUPER_TYPE_LIST)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user