[FIR] Add diagnostic when annotation argument is resolved ambiguously
Annotation arguments that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase are resolved again in ANNOTATION_ARGUMENTS phase. If they resolve to a different symbol, report an error. KT-56177
This commit is contained in:
committed by
Space Team
parent
9dda5e4fcd
commit
2139914061
+9
@@ -1007,6 +1007,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT) { firDiagnostic ->
|
||||
AmbiguousAnnotationArgumentImpl(
|
||||
firDiagnostic.a.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol)
|
||||
},
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_JS_QUALIFIER) { firDiagnostic ->
|
||||
WrongJsQualifierImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+5
@@ -728,6 +728,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val typeFromTypesPhase: KtType
|
||||
}
|
||||
|
||||
abstract class AmbiguousAnnotationArgument : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = AmbiguousAnnotationArgument::class
|
||||
abstract val symbols: List<KtSymbol>
|
||||
}
|
||||
|
||||
abstract class WrongJsQualifier : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = WrongJsQualifier::class
|
||||
}
|
||||
|
||||
+6
@@ -873,6 +873,12 @@ internal class PluginAnnotationAmbiguityImpl(
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.PluginAnnotationAmbiguity(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class AmbiguousAnnotationArgumentImpl(
|
||||
override val symbols: List<KtSymbol>,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.AmbiguousAnnotationArgument(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class WrongJsQualifierImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
|
||||
+6
@@ -35874,6 +35874,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationTargetResolvedAmbiguously.kt")
|
||||
public void testAnnotationTargetResolvedAmbiguously() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsTargetingLateinitAccessors.kt")
|
||||
public void testAnnotationsTargetingLateinitAccessors() throws Exception {
|
||||
|
||||
+6
@@ -35874,6 +35874,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationTargetResolvedAmbiguously.kt")
|
||||
public void testAnnotationTargetResolvedAmbiguously() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsTargetingLateinitAccessors.kt")
|
||||
public void testAnnotationsTargetingLateinitAccessors() throws Exception {
|
||||
|
||||
+6
@@ -35970,6 +35970,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationTargetResolvedAmbiguously.kt")
|
||||
public void testAnnotationTargetResolvedAmbiguously() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsTargetingLateinitAccessors.kt")
|
||||
public void testAnnotationsTargetingLateinitAccessors() throws Exception {
|
||||
|
||||
+5
-1
@@ -309,10 +309,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val WRONG_EXTENSION_FUNCTION_TYPE_WARNING by warning<KtAnnotationEntry>()
|
||||
val ANNOTATION_IN_WHERE_CLAUSE_ERROR by error<KtAnnotationEntry>()
|
||||
|
||||
val PLUGIN_ANNOTATION_AMBIGUITY by error<PsiElement>() {
|
||||
val PLUGIN_ANNOTATION_AMBIGUITY by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("typeFromCompilerPhase")
|
||||
parameter<ConeKotlinType>("typeFromTypesPhase")
|
||||
}
|
||||
|
||||
val AMBIGUOUS_ANNOTATION_ARGUMENT by error<PsiElement> {
|
||||
parameter<List<FirBasedSymbol<*>>>("symbols")
|
||||
}
|
||||
}
|
||||
|
||||
val OPT_IN by object : DiagnosticGroup("OptIn") {
|
||||
|
||||
@@ -264,6 +264,7 @@ object FirErrors {
|
||||
val WRONG_EXTENSION_FUNCTION_TYPE_WARNING by warning0<KtAnnotationEntry>()
|
||||
val ANNOTATION_IN_WHERE_CLAUSE_ERROR by error0<KtAnnotationEntry>()
|
||||
val PLUGIN_ANNOTATION_AMBIGUITY by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val AMBIGUOUS_ANNOTATION_ARGUMENT by error1<PsiElement, List<FirBasedSymbol<*>>>()
|
||||
|
||||
// OptIn
|
||||
val OPT_IN_USAGE by warning2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+7
-1
@@ -58,6 +58,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ALTERED_ASSIGN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANONYMOUS_TYPE_INFERRED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_EXPECTS
|
||||
@@ -928,10 +929,15 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
)
|
||||
map.put(
|
||||
PLUGIN_ANNOTATION_AMBIGUITY,
|
||||
"Resolution of annotation type is ambigous between {1} and plugin annotation {0}. Please specify fully qualified name of annotation",
|
||||
"Resolution of annotation type is ambiguous between {1} and plugin annotation {0}. Please specify fully qualified name of annotation",
|
||||
RENDER_TYPE,
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
AMBIGUOUS_ANNOTATION_ARGUMENT,
|
||||
"Resolution of annotation argument is ambiguous between {0}. Please specify fully qualified name of argument",
|
||||
SYMBOLS,
|
||||
)
|
||||
|
||||
// Exposed visibility group // #
|
||||
map.put(
|
||||
|
||||
+2
@@ -132,6 +132,8 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
||||
is ConeAmbiguouslyResolvedAnnotationFromPlugin -> {
|
||||
FirErrors.PLUGIN_ANNOTATION_AMBIGUITY.createOn(source, typeFromCompilerPhase, typeFromTypesPhase)
|
||||
}
|
||||
is ConeAmbiguouslyResolvedAnnotationArgument ->
|
||||
FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT.createOn(source, listOfNotNull(symbolFromCompilerPhase, symbolFromAnnotationArgumentsPhase))
|
||||
is ConeAmbiguousFunctionTypeKinds -> FirErrors.AMBIGUOUS_FUNCTION_TYPE_KIND.createOn(source, kinds)
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ fun FirResolvedQualifier.continueQualifier(
|
||||
packageFqName = this@continueQualifier.packageFqName
|
||||
relativeClassFqName = this@continueQualifier.relativeClassFqName?.child(name)
|
||||
symbol = nestedClassSymbol as FirClassLikeSymbol<*>
|
||||
isFullyQualified = true
|
||||
|
||||
val outerTypeArguments = this.typeArguments.toList()
|
||||
this.typeArguments.clear()
|
||||
@@ -180,6 +181,7 @@ private fun FqName.continueQualifierInPackage(
|
||||
apiVersion
|
||||
)
|
||||
)
|
||||
isFullyQualified = true
|
||||
}.apply {
|
||||
resultType = components.typeForQualifier(this)
|
||||
}
|
||||
|
||||
+1
@@ -139,6 +139,7 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
||||
relativeClassFqName = symbol.classId.relativeClassName
|
||||
typeRef = FirImplicitUnitTypeRef(receiver.typeRef.source)
|
||||
this.symbol = symbol
|
||||
isFullyQualified = segments.isNotEmpty()
|
||||
}
|
||||
|
||||
// Resolve enum entry by name from the declarations of the receiver.
|
||||
|
||||
+80
-1
@@ -7,12 +7,26 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguouslyResolvedAnnotationArgument
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
|
||||
open class FirAnnotationArgumentsResolveTransformer(
|
||||
session: FirSession,
|
||||
@@ -252,9 +266,74 @@ abstract class AbstractFirExpressionsResolveTransformerForAnnotations(transforme
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of enum class IDs that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase that need to be rechecked here.
|
||||
*/
|
||||
private val classIdsToCheck: Set<ClassId> = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget)
|
||||
|
||||
private class FirExpressionsResolveTransformerForSpecificAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) :
|
||||
AbstractFirExpressionsResolveTransformerForAnnotations(transformer) {
|
||||
|
||||
override fun transformQualifiedAccessExpression(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||
data: ResolutionMode
|
||||
): FirStatement {
|
||||
val calleeReference = qualifiedAccessExpression.calleeReference
|
||||
if (calleeReference is FirResolvedNamedReference &&
|
||||
calleeReference.resolvedSymbol.let { it is FirEnumEntrySymbol && it.containingClassLookupTag()?.classId in classIdsToCheck } &&
|
||||
qualifiedAccessExpression is FirPropertyAccessExpression
|
||||
) {
|
||||
val symbolFromCompilerPhase = calleeReference.resolvedSymbol
|
||||
|
||||
(qualifiedAccessExpression.explicitReceiver as? FirResolvedQualifier)?.let {
|
||||
qualifiedAccessExpression.replaceResolvedQualifierReceiver(it)
|
||||
}
|
||||
qualifiedAccessExpression.replaceDispatchReceiver(FirNoReceiverExpression)
|
||||
qualifiedAccessExpression.replaceTypeRef(noExpectedType)
|
||||
qualifiedAccessExpression.replaceCalleeReference(buildSimpleNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
})
|
||||
|
||||
val resolved = super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
|
||||
|
||||
if (resolved is FirQualifiedAccessExpression) {
|
||||
// The initial resolution must have been to an enum entry. Report ambiguity if symbolFromArgumentsPhase is different to
|
||||
// original symbol including null (meaning we would resolve to something other than an enum entry).
|
||||
val symbolFromArgumentsPhase = resolved.calleeReference.toResolvedBaseSymbol()
|
||||
if (symbolFromCompilerPhase != symbolFromArgumentsPhase) {
|
||||
resolved.replaceCalleeReference(buildErrorNamedReference {
|
||||
source = resolved.calleeReference.source
|
||||
diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(symbolFromCompilerPhase, symbolFromArgumentsPhase)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return resolved
|
||||
}
|
||||
|
||||
return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
|
||||
}
|
||||
|
||||
private fun FirQualifiedAccessExpression.replaceResolvedQualifierReceiver(receiver: FirResolvedQualifier) {
|
||||
var lastReceiver = buildPropertyAccessExpression {
|
||||
source = receiver.source
|
||||
this.calleeReference = buildSimpleNamedReference {
|
||||
val classId = receiver.classId ?: return
|
||||
name = classId.relativeClassName.shortName()
|
||||
}
|
||||
}
|
||||
replaceExplicitReceiver(lastReceiver)
|
||||
|
||||
if (receiver.isFullyQualified) {
|
||||
for (segment in receiver.packageFqName.pathSegments().asReversed()) {
|
||||
lastReceiver.replaceExplicitReceiver(buildPropertyAccessExpression {
|
||||
this.calleeReference = buildSimpleNamedReference { name = segment }
|
||||
}.also { lastReceiver = it })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveQualifiedAccessAndSelectCandidate(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||
isUsedAsReceiver: Boolean,
|
||||
|
||||
+12
@@ -251,3 +251,15 @@ class ConeAmbiguouslyResolvedAnnotationFromPlugin(
|
||||
- types stage: $typeFromTypesPhase
|
||||
"""
|
||||
}
|
||||
|
||||
class ConeAmbiguouslyResolvedAnnotationArgument(
|
||||
val symbolFromCompilerPhase: FirBasedSymbol<*>,
|
||||
val symbolFromAnnotationArgumentsPhase: FirBasedSymbol<*>?
|
||||
) : ConeDiagnostic {
|
||||
override val reason: String
|
||||
get() = """
|
||||
Annotation symbol resolved differently on compiler annotation and symbols stages:
|
||||
- compiler annotations: $symbolFromCompilerPhase
|
||||
- compiler arguments stage: $symbolFromAnnotationArgumentsPhase
|
||||
"""
|
||||
}
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ abstract class FirErrorResolvedQualifier : FirResolvedQualifier(), FirDiagnostic
|
||||
abstract override val symbol: FirClassLikeSymbol<*>?
|
||||
abstract override val isNullableLHSForCallableReference: Boolean
|
||||
abstract override val resolvedToCompanionObject: Boolean
|
||||
abstract override val isFullyQualified: Boolean
|
||||
abstract override val nonFatalDiagnostics: List<ConeDiagnostic>
|
||||
abstract override val typeArguments: List<FirTypeProjection>
|
||||
abstract override val diagnostic: ConeDiagnostic
|
||||
|
||||
@@ -30,6 +30,7 @@ abstract class FirResolvedQualifier : FirExpression() {
|
||||
abstract val symbol: FirClassLikeSymbol<*>?
|
||||
abstract val isNullableLHSForCallableReference: Boolean
|
||||
abstract val resolvedToCompanionObject: Boolean
|
||||
abstract val isFullyQualified: Boolean
|
||||
abstract val nonFatalDiagnostics: List<ConeDiagnostic>
|
||||
abstract val typeArguments: List<FirTypeProjection>
|
||||
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ interface FirAbstractResolvedQualifierBuilder {
|
||||
abstract var symbol: FirClassLikeSymbol<*>?
|
||||
abstract var isNullableLHSForCallableReference: Boolean
|
||||
abstract var resolvedToCompanionObject: Boolean
|
||||
abstract var isFullyQualified: Boolean
|
||||
abstract val nonFatalDiagnostics: MutableList<ConeDiagnostic>
|
||||
abstract val typeArguments: MutableList<FirTypeProjection>
|
||||
|
||||
|
||||
+2
@@ -39,6 +39,7 @@ class FirErrorResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, Fi
|
||||
override var relativeClassFqName: FqName? = null
|
||||
override var symbol: FirClassLikeSymbol<*>? = null
|
||||
override var isNullableLHSForCallableReference: Boolean = false
|
||||
override var isFullyQualified: Boolean = false
|
||||
override val nonFatalDiagnostics: MutableList<ConeDiagnostic> = mutableListOf()
|
||||
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
||||
lateinit var diagnostic: ConeDiagnostic
|
||||
@@ -51,6 +52,7 @@ class FirErrorResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, Fi
|
||||
relativeClassFqName,
|
||||
symbol,
|
||||
isNullableLHSForCallableReference,
|
||||
isFullyQualified,
|
||||
nonFatalDiagnostics.toMutableOrEmpty(),
|
||||
typeArguments.toMutableOrEmpty(),
|
||||
diagnostic,
|
||||
|
||||
+2
@@ -41,6 +41,7 @@ class FirResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, FirAnno
|
||||
override var relativeClassFqName: FqName? = null
|
||||
override var symbol: FirClassLikeSymbol<*>? = null
|
||||
override var isNullableLHSForCallableReference: Boolean = false
|
||||
override var isFullyQualified: Boolean = false
|
||||
override val nonFatalDiagnostics: MutableList<ConeDiagnostic> = mutableListOf()
|
||||
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
||||
|
||||
@@ -53,6 +54,7 @@ class FirResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, FirAnno
|
||||
relativeClassFqName,
|
||||
symbol,
|
||||
isNullableLHSForCallableReference,
|
||||
isFullyQualified,
|
||||
nonFatalDiagnostics.toMutableOrEmpty(),
|
||||
typeArguments.toMutableOrEmpty(),
|
||||
)
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ internal class FirErrorResolvedQualifierImpl(
|
||||
override val relativeClassFqName: FqName?,
|
||||
override val symbol: FirClassLikeSymbol<*>?,
|
||||
override var isNullableLHSForCallableReference: Boolean,
|
||||
override val isFullyQualified: Boolean,
|
||||
override var nonFatalDiagnostics: MutableOrEmptyList<ConeDiagnostic>,
|
||||
override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
|
||||
override val diagnostic: ConeDiagnostic,
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ internal class FirResolvedQualifierImpl(
|
||||
override var relativeClassFqName: FqName?,
|
||||
override val symbol: FirClassLikeSymbol<*>?,
|
||||
override var isNullableLHSForCallableReference: Boolean,
|
||||
override val isFullyQualified: Boolean,
|
||||
override var nonFatalDiagnostics: MutableOrEmptyList<ConeDiagnostic>,
|
||||
override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
|
||||
) : FirResolvedQualifier() {
|
||||
|
||||
+2
-2
@@ -354,12 +354,12 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
|
||||
builder(resolvedQualifier) {
|
||||
parents += abstractResolvedQualifierBuilder
|
||||
defaultFalse("isNullableLHSForCallableReference")
|
||||
defaultFalse("isNullableLHSForCallableReference", "isFullyQualified")
|
||||
}
|
||||
|
||||
builder(errorResolvedQualifier) {
|
||||
parents += abstractResolvedQualifierBuilder
|
||||
defaultFalse("isNullableLHSForCallableReference")
|
||||
defaultFalse("isNullableLHSForCallableReference", "isFullyQualified")
|
||||
}
|
||||
|
||||
// builder(safeCallExpression) {
|
||||
|
||||
+1
@@ -595,6 +595,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("symbol", classLikeSymbolType, nullable = true)
|
||||
+booleanField("isNullableLHSForCallableReference", withReplace = true)
|
||||
+booleanField("resolvedToCompanionObject", withReplace = true)
|
||||
+booleanField("isFullyQualified")
|
||||
+fieldList("nonFatalDiagnostics", coneDiagnosticType, useMutableOrEmpty = true)
|
||||
+typeArguments.withTransform()
|
||||
}
|
||||
|
||||
compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
import kotlin.annotation.AnnotationTarget.FIELD
|
||||
|
||||
object Some {
|
||||
@Target(<!ARGUMENT_TYPE_MISMATCH!>AnnotationTarget.<!AMBIGUOUS_ANNOTATION_ARGUMENT!>CLASS<!><!>)
|
||||
annotation class Ann
|
||||
|
||||
enum class AnnotationTarget {
|
||||
CLASS
|
||||
}
|
||||
|
||||
@Target(<!AMBIGUOUS_ANNOTATION_ARGUMENT!>FIELD<!>)
|
||||
annotation class Ann2
|
||||
|
||||
const val FIELD = ""
|
||||
}
|
||||
|
||||
object SomeMore {
|
||||
@Target(<!ARGUMENT_TYPE_MISMATCH!>kotlin.annotation.AnnotationTarget.<!AMBIGUOUS_ANNOTATION_ARGUMENT!>FUNCTION<!><!>)
|
||||
annotation class Ann3
|
||||
|
||||
object kotlin {
|
||||
object annotation {
|
||||
enum class AnnotationTarget {
|
||||
FUNCTION
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Base {
|
||||
annotation class Target(val target: AnnotationTarget)
|
||||
|
||||
enum class AnnotationTarget {
|
||||
TYPE
|
||||
}
|
||||
}
|
||||
|
||||
class Derived : Base() {
|
||||
@<!PLUGIN_ANNOTATION_AMBIGUITY!>Target<!>(<!ARGUMENT_TYPE_MISMATCH!>AnnotationTarget.<!AMBIGUOUS_ANNOTATION_ARGUMENT!>TYPE<!><!>)
|
||||
annotation class Ann
|
||||
|
||||
fun foo(x: <!WRONG_ANNOTATION_TARGET!>@Ann<!> String) {}
|
||||
}
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
import kotlin.annotation.AnnotationTarget.FIELD
|
||||
|
||||
object Some {
|
||||
@Target(<!TYPE_MISMATCH!>AnnotationTarget.CLASS<!>)
|
||||
annotation class Ann
|
||||
|
||||
enum class AnnotationTarget {
|
||||
CLASS
|
||||
}
|
||||
|
||||
@Target(<!TYPE_MISMATCH!>FIELD<!>)
|
||||
annotation class Ann2
|
||||
|
||||
const val FIELD = ""
|
||||
}
|
||||
|
||||
object SomeMore {
|
||||
@Target(<!TYPE_MISMATCH!>kotlin.annotation.AnnotationTarget.FUNCTION<!>)
|
||||
annotation class Ann3
|
||||
|
||||
object kotlin {
|
||||
object annotation {
|
||||
enum class AnnotationTarget {
|
||||
FUNCTION
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Base {
|
||||
annotation class Target(val target: AnnotationTarget)
|
||||
|
||||
enum class AnnotationTarget {
|
||||
TYPE
|
||||
}
|
||||
}
|
||||
|
||||
class Derived : Base() {
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class Ann
|
||||
|
||||
fun foo(x: <!WRONG_ANNOTATION_TARGET!>@Ann<!> String) {}
|
||||
}
|
||||
Generated
+6
@@ -35970,6 +35970,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationTargetResolvedAmbiguously.kt")
|
||||
public void testAnnotationTargetResolvedAmbiguously() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsTargetingLateinitAccessors.kt")
|
||||
public void testAnnotationsTargetingLateinitAccessors() throws Exception {
|
||||
|
||||
@@ -136,6 +136,7 @@ object StandardClassIds {
|
||||
|
||||
val AnnotationRetention = "AnnotationRetention".annotationId()
|
||||
val AnnotationTarget = "AnnotationTarget".annotationId()
|
||||
val DeprecationLevel = "DeprecationLevel".baseId()
|
||||
|
||||
val EnumEntries = "EnumEntries".enumsId()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user