FIR: handle annotations on non-containers more precisely
This commit is contained in:
+2
-1
@@ -10,12 +10,13 @@ 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.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
|
||||
object FirAnnotationUsedAsAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
override fun check(expression: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val args = expression.argumentList.arguments
|
||||
for (arg in args) {
|
||||
for (ann in arg.annotations) {
|
||||
for (ann in ((arg as? FirWrappedArgumentExpression)?.expression ?: arg).annotations) {
|
||||
reporter.reportOn(ann.source, FirErrors.ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, context)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
||||
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(source, this.reason)
|
||||
is ConeTypeParameterSupertype -> FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(source, this.reason)
|
||||
is ConeTypeParameterInQualifiedAccess -> null // reported in various checkers instead
|
||||
is ConeNotAnnotationContainer -> null
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeNotAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -411,10 +412,10 @@ class ExpressionsConverter(
|
||||
}
|
||||
}
|
||||
|
||||
return firExpression?.also {
|
||||
require(it is FirAnnotationContainer)
|
||||
(it.annotations as MutableList<FirAnnotationCall>) += firAnnotationList
|
||||
} ?: buildErrorExpression(null, ConeSimpleDiagnostic("Strange annotated expression: ${firExpression?.render()}", DiagnosticKind.Syntax))
|
||||
val result = firExpression ?: buildErrorExpression(null, ConeNotAnnotationContainer(firExpression?.render() ?: "???"))
|
||||
require(result is FirAnnotationContainer)
|
||||
(result.annotations as MutableList<FirAnnotationCall>) += firAnnotationList
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeNotAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -2083,15 +2084,10 @@ open class RawFirBuilder(
|
||||
|
||||
override fun visitAnnotatedExpression(expression: KtAnnotatedExpression, data: Unit): FirElement {
|
||||
val rawResult = expression.baseExpression?.accept(this, data)
|
||||
// return rawResult ?: buildErrorExpression(
|
||||
// expression.toFirSourceElement(),
|
||||
// FirSimpleDiagnostic("Strange annotated expression: ${rawResult?.render()}", DiagnosticKind.Syntax),
|
||||
// )
|
||||
// TODO !!!!!!!!
|
||||
val result = rawResult as? FirAnnotationContainer
|
||||
?: return buildErrorExpression(
|
||||
?: buildErrorExpression(
|
||||
expression.toFirSourceElement(),
|
||||
ConeSimpleDiagnostic("Strange annotated expression: ${rawResult?.render()}", DiagnosticKind.Syntax),
|
||||
ConeNotAnnotationContainer(rawResult?.render() ?: "???")
|
||||
)
|
||||
expression.extractAnnotationsTo(result.annotations as MutableList<FirAnnotationCall>)
|
||||
return result
|
||||
|
||||
+2
-3
@@ -27,11 +27,13 @@ import org.jetbrains.kotlin.fir.visitors.*
|
||||
@FirBuilderDsl
|
||||
class FirErrorExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||
override var source: FirSourceElement? = null
|
||||
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
|
||||
lateinit var diagnostic: ConeDiagnostic
|
||||
|
||||
override fun build(): FirErrorExpression {
|
||||
return FirErrorExpressionImpl(
|
||||
source,
|
||||
annotations,
|
||||
diagnostic,
|
||||
)
|
||||
}
|
||||
@@ -43,9 +45,6 @@ class FirErrorExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBu
|
||||
set(_) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
@Deprecated("Modification of 'annotations' has no impact for FirErrorExpressionBuilder", level = DeprecationLevel.HIDDEN)
|
||||
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
|
||||
+4
-1
@@ -21,21 +21,24 @@ import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
internal class FirErrorExpressionImpl(
|
||||
override val source: FirSourceElement?,
|
||||
override val annotations: MutableList<FirAnnotationCall>,
|
||||
override val diagnostic: ConeDiagnostic,
|
||||
) : FirErrorExpression() {
|
||||
override var typeRef: FirTypeRef = FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic))
|
||||
override val annotations: List<FirAnnotationCall> get() = emptyList()
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
typeRef.accept(visitor, data)
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirErrorExpressionImpl {
|
||||
typeRef = typeRef.transform(transformer, data)
|
||||
transformAnnotations(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirErrorExpressionImpl {
|
||||
annotations.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ internal class FirErrorLoopImpl(
|
||||
override val diagnostic: ConeDiagnostic,
|
||||
) : FirErrorLoop() {
|
||||
override var block: FirBlock = FirEmptyExpressionBlock()
|
||||
override var condition: FirExpression = FirErrorExpressionImpl(source, ConeStubDiagnostic(diagnostic))
|
||||
override var condition: FirExpression = FirErrorExpressionImpl(source, mutableListOf(), ConeStubDiagnostic(diagnostic))
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
|
||||
@@ -7,6 +7,10 @@ package org.jetbrains.kotlin.fir.diagnostics
|
||||
|
||||
class ConeSimpleDiagnostic(override val reason: String, val kind: DiagnosticKind = DiagnosticKind.Other) : ConeDiagnostic()
|
||||
|
||||
class ConeNotAnnotationContainer(val text: String) : ConeDiagnostic() {
|
||||
override val reason: String get() = "Strange annotated expression: $text"
|
||||
}
|
||||
|
||||
enum class DiagnosticKind {
|
||||
Syntax,
|
||||
ExpressionExpected,
|
||||
|
||||
+1
-2
@@ -128,7 +128,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
|
||||
impl(errorLoop) {
|
||||
default("block", "FirEmptyExpressionBlock()")
|
||||
default("condition", "FirErrorExpressionImpl(source, ConeStubDiagnostic(diagnostic))")
|
||||
default("condition", "FirErrorExpressionImpl(source, mutableListOf(), ConeStubDiagnostic(diagnostic))")
|
||||
useTypes(emptyExpressionBlock, coneStubDiagnosticType)
|
||||
}
|
||||
|
||||
@@ -394,7 +394,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
|
||||
impl(errorExpression) {
|
||||
defaultEmptyList("annotations")
|
||||
default("typeRef", "FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic))")
|
||||
useTypes(errorTypeRefImpl, coneStubDiagnosticType)
|
||||
}
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
// SKIP_ERRORS_BEFORE
|
||||
|
||||
annotation class X(val value: Y, val y: Y)
|
||||
annotation class Y()
|
||||
|
||||
@X(@Y()<!SYNTAX!><!>, y = Y())
|
||||
fun foo1() {
|
||||
}
|
||||
@X(@Y()<!SYNTAX!><!>, y = @Y()<!SYNTAX!><!>)
|
||||
fun foo2() {
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// SKIP_ERRORS_BEFORE
|
||||
|
||||
annotation class X(val value: Y, val y: Y)
|
||||
|
||||
Reference in New Issue
Block a user