FIR: Use outer scope for annotation arguments resolution

^KT-41980 Fixed
This commit is contained in:
Denis.Zharkov
2022-06-06 15:15:05 +03:00
parent eae673233b
commit 41dd00c241
5 changed files with 41 additions and 24 deletions
@@ -11,6 +11,7 @@ import java.util.*
enum class FirTowerDataMode { enum class FirTowerDataMode {
REGULAR, REGULAR,
CLASS_HEADER_ANNOTATIONS,
NESTED_CLASS, NESTED_CLASS,
COMPANION_OBJECT, COMPANION_OBJECT,
CONSTRUCTOR_HEADER, CONSTRUCTOR_HEADER,
@@ -26,6 +27,7 @@ class FirRegularTowerDataContexts private constructor(
) { ) {
constructor( constructor(
regular: FirTowerDataContext, regular: FirTowerDataContext,
forClassHeaderAnnotations: FirTowerDataContext? = null,
forNestedClasses: FirTowerDataContext? = null, forNestedClasses: FirTowerDataContext? = null,
forCompanionObject: FirTowerDataContext? = null, forCompanionObject: FirTowerDataContext? = null,
forConstructorHeaders: FirTowerDataContext? = null, forConstructorHeaders: FirTowerDataContext? = null,
@@ -33,7 +35,7 @@ class FirRegularTowerDataContexts private constructor(
primaryConstructorPureParametersScope: FirLocalScope? = null, primaryConstructorPureParametersScope: FirLocalScope? = null,
primaryConstructorAllParametersScope: FirLocalScope? = null, primaryConstructorAllParametersScope: FirLocalScope? = null,
) : this( ) : this(
enumMap(regular, forNestedClasses, forCompanionObject, forConstructorHeaders, forEnumEntries), enumMap(regular, forClassHeaderAnnotations, forNestedClasses, forCompanionObject, forConstructorHeaders, forEnumEntries),
primaryConstructorPureParametersScope, primaryConstructorPureParametersScope,
primaryConstructorAllParametersScope, primaryConstructorAllParametersScope,
FirTowerDataMode.REGULAR FirTowerDataMode.REGULAR
@@ -68,6 +70,7 @@ class FirRegularTowerDataContexts private constructor(
companion object { companion object {
private fun enumMap( private fun enumMap(
regular: FirTowerDataContext, regular: FirTowerDataContext,
forClassHeaderAnnotations: FirTowerDataContext?,
forNestedClasses: FirTowerDataContext?, forNestedClasses: FirTowerDataContext?,
forCompanionObject: FirTowerDataContext?, forCompanionObject: FirTowerDataContext?,
forConstructorHeaders: FirTowerDataContext?, forConstructorHeaders: FirTowerDataContext?,
@@ -75,6 +78,7 @@ class FirRegularTowerDataContexts private constructor(
): EnumMap<FirTowerDataMode, FirTowerDataContext> { ): EnumMap<FirTowerDataMode, FirTowerDataContext> {
val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(FirTowerDataMode::class.java) val modeMap = EnumMap<FirTowerDataMode, FirTowerDataContext>(FirTowerDataMode::class.java)
modeMap[FirTowerDataMode.REGULAR] = regular modeMap[FirTowerDataMode.REGULAR] = regular
modeMap[FirTowerDataMode.CLASS_HEADER_ANNOTATIONS] = forClassHeaderAnnotations
modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses
modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject
modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders
@@ -478,6 +478,7 @@ class BodyResolveContext(
val newContexts = FirRegularTowerDataContexts( val newContexts = FirRegularTowerDataContexts(
forMembersResolution, forMembersResolution,
forClassHeaderAnnotations = base,
newTowerDataContextForStaticNestedClasses, newTowerDataContextForStaticNestedClasses,
statics, statics,
scopeForConstructorHeader, scopeForConstructorHeader,
@@ -655,6 +656,16 @@ class BodyResolveContext(
f: () -> T f: () -> T
): T = withTowerDataMode(FirTowerDataMode.ENUM_ENTRY, f) ): T = withTowerDataMode(FirTowerDataMode.ENUM_ENTRY, f)
@OptIn(PrivateForInline::class)
inline fun <T> forAnnotation(
f: () -> T
): T {
return when (containerIfAny) {
is FirRegularClass -> withTowerDataMode(FirTowerDataMode.CLASS_HEADER_ANNOTATIONS, f)
else -> f()
}
}
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
inline fun <T> withAnonymousInitializer( inline fun <T> withAnonymousInitializer(
anonymousInitializer: FirAnonymousInitializer, anonymousInitializer: FirAnonymousInitializer,
@@ -685,12 +685,12 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
dataFlowAnalyzer.enterFunction(constructor) dataFlowAnalyzer.enterFunction(constructor)
constructor.transformTypeParameters(transformer, data)
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
context.withConstructor(constructor) { context.withConstructor(constructor) {
constructor.transformTypeParameters(transformer, data)
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
context.forConstructorParameters(constructor, owningClass, components) { context.forConstructorParameters(constructor, owningClass, components) {
constructor.transformValueParameters(transformer, data) constructor.transformValueParameters(transformer, data)
} }
@@ -1021,15 +1021,17 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement { override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement {
if (annotationCall.resolved) return annotationCall if (annotationCall.resolved) return annotationCall
annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent) annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent)
return withFirArrayOfCallTransformer { return context.forAnnotation {
dataFlowAnalyzer.enterAnnotation(annotationCall) withFirArrayOfCallTransformer {
val result = callResolver.resolveAnnotationCall(annotationCall) dataFlowAnalyzer.enterAnnotation(annotationCall)
dataFlowAnalyzer.exitAnnotation(result ?: annotationCall) val result = callResolver.resolveAnnotationCall(annotationCall)
if (result == null) return annotationCall dataFlowAnalyzer.exitAnnotation(result ?: annotationCall)
callCompleter.completeCall(result, noExpectedType) if (result == null) return annotationCall
// TODO: FirBlackBoxCodegenTestGenerated.Annotations.testDelegatedPropertySetter, it fails with hard cast callCompleter.completeCall(result, noExpectedType)
(result.argumentList as? FirResolvedArgumentList)?.let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) } // TODO: FirBlackBoxCodegenTestGenerated.Annotations.testDelegatedPropertySetter, it fails with hard cast
annotationCall (result.argumentList as? FirResolvedArgumentList)?.let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
annotationCall
}
} }
} }
@@ -15,15 +15,15 @@ annotation class Ann(
) )
@Ann( @Ann(
Nested::class, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>Nested<!>::class<!>,
Inner::class, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>Inner<!>::class<!>,
Interface::class, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>Interface<!>::class<!>,
CONST, <!UNRESOLVED_REFERENCE!>CONST<!>,
Companion.CONST, <!UNRESOLVED_REFERENCE!>Companion<!>.CONST,
Nested.CONST, <!UNRESOLVED_REFERENCE!>Nested<!>.CONST,
Interface.CONST, <!UNRESOLVED_REFERENCE!>Interface<!>.CONST,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>a<!>, <!UNRESOLVED_REFERENCE!>a<!>,
b() <!UNRESOLVED_REFERENCE!>b<!>()
) )
class A { class A {