[FIR] KT-53371, KT-53519: Fix annotations arguments mapping

See: compiler/testData/asJava/lightClasses/
AnnotatedParameterInInnerClassConstructor.kt

The muted tests don't work with the (KT-53371, KT-53519)-related
changes. During this test happens an attempt to access unresolved
annotations via CustomAnnotationTypeAttribute.
Discussion: KTIJ-23547
This commit is contained in:
Nikolay Lunyak
2022-09-30 19:06:16 +03:00
parent 6653f654ec
commit 89f8821d0a
50 changed files with 670 additions and 186 deletions
@@ -304,6 +304,10 @@ class FirCallCompletionResultsWriterTransformer(
return annotationCall
}
override fun transformErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: ExpectedArgumentType?): FirStatement {
return transformAnnotationCall(errorAnnotationCall, data)
}
private fun Candidate.handleVarargs() {
val argumentMapping = this.argumentMapping
val varargParameter = argumentMapping?.values?.firstOrNull { it.isVararg }
@@ -79,6 +79,7 @@ fun FirResolvePhase.createCompilerProcessorByPhase(
ARGUMENTS_OF_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession)
ANNOTATIONS_ARGUMENTS_MAPPING -> FirAnnotationArgumentsMappingProcessor(session, scopeSession)
BODY_RESOLVE -> FirBodyResolveProcessor(session, scopeSession)
EXPECT_ACTUAL_MATCHING -> FirExpectActualMatcherProcessor(session, scopeSession)
}
@@ -220,7 +220,7 @@ open class FirBodyResolveTransformer(
}
override fun transformErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: ResolutionMode): FirStatement {
return transformAnnotationCall(errorAnnotationCall, data)
return expressionsTransformer.transformErrorAnnotationCall(errorAnnotationCall, data)
}
override fun transformDelegatedConstructorCall(
@@ -68,7 +68,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
}
}
private fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration {
protected fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration {
transformer.firTowerDataContextCollector?.addDeclarationContext(declaration, context.towerDataContext)
return transformer.transformDeclarationContent(declaration, data)
}
@@ -97,7 +97,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
return FirMemberTypeParameterScope(declaration)
}
private fun doTransformTypeParameters(declaration: FirMemberDeclaration) {
protected fun doTransformTypeParameters(declaration: FirMemberDeclaration) {
for (typeParameter in declaration.typeParameters) {
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
}
@@ -1103,7 +1103,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
private val FirVariable.initializerResolved: Boolean
get() = initializer?.typeRef is FirResolvedTypeRef
private val FirFunction.bodyResolved: Boolean
protected val FirFunction.bodyResolved: Boolean
get() = body !is FirLazyBlock && body?.typeRef is FirResolvedTypeRef
}
@@ -1059,14 +1059,17 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
dataFlowAnalyzer.exitAnnotation(result ?: annotationCall)
if (result == null) return annotationCall
callCompleter.completeCall(result, noExpectedType)
// TODO: FirBlackBoxCodegenTestGenerated.Annotations.testDelegatedPropertySetter, it fails with hard cast
(result.argumentList as? FirResolvedArgumentList)?.let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
(result.argumentList as FirResolvedArgumentList).let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
annotationCall
}
}
}
private inline fun <T> withFirArrayOfCallTransformer(block: () -> T): T {
override fun transformErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: ResolutionMode): FirStatement {
return transformAnnotationCall(errorAnnotationCall, data)
}
protected inline fun <T> withFirArrayOfCallTransformer(block: () -> T): T {
enableArrayOfCallTransformation = true
return try {
block()
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2022 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.resolve.transformers.plugin
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@OptIn(AdapterForResolveProcessor::class)
class FirAnnotationArgumentsMappingProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
override val transformer: FirTransformer<Any?> = FirAnnotationArgumentsMappingTransformerAdapter(session, scopeSession)
}
@AdapterForResolveProcessor
class FirAnnotationArgumentsMappingTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer<Any?>() {
private val transformer = FirAnnotationArgumentsMappingTransformer(session, scopeSession, FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
error("Should only be called via transformFile()")
}
override fun transformFile(file: FirFile, data: Any?): FirFile {
return file.transform(transformer, ResolutionMode.ContextIndependent)
}
}
@@ -0,0 +1,162 @@
/*
* Copyright 2010-2022 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.resolve.transformers.plugin
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
open class FirAnnotationArgumentsMappingTransformer(
session: FirSession,
scopeSession: ScopeSession,
resolvePhase: FirResolvePhase,
outerBodyResolveContext: BodyResolveContext? = null
) : FirBodyResolveTransformer(
session,
resolvePhase,
implicitTypeOnly = false,
scopeSession,
outerBodyResolveContext = outerBodyResolveContext
) {
override val declarationsTransformer: FirDeclarationsResolveTransformer =
FirDeclarationsResolveTransformerForAnnotationArgumentsMapping(this)
}
private class FirDeclarationsResolveTransformerForAnnotationArgumentsMapping(
transformer: FirBodyResolveTransformer
) : FirDeclarationsResolveTransformer(transformer) {
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
regularClass.transformAnnotations(this, data)
doTransformTypeParameters(regularClass)
context.withContainingClass(regularClass) {
context.withRegularClass(regularClass, components) {
transformDeclarationContent(regularClass, data) as FirRegularClass
}
}
return regularClass
}
override fun transformAnonymousInitializer(
anonymousInitializer: FirAnonymousInitializer,
data: ResolutionMode
): FirAnonymousInitializer {
return anonymousInitializer
}
override fun transformSimpleFunction(
simpleFunction: FirSimpleFunction,
data: ResolutionMode
): FirSimpleFunction {
if (simpleFunction.bodyResolved) {
return simpleFunction
}
doTransformTypeParameters(simpleFunction)
context.withSimpleFunction(simpleFunction, session) {
simpleFunction
.transformReturnTypeRef(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformValueParameters(transformer, data)
.transformAnnotations(transformer, data)
}
return simpleFunction
}
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
val containingClass = context.containerIfAny as? FirRegularClass
doTransformTypeParameters(constructor)
context.withConstructor(constructor) {
constructor
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
context.forConstructorParameters(constructor, containingClass, components) {
constructor.transformValueParameters(transformer, data)
}
}
return constructor
}
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): FirStatement {
context.withValueParameter(valueParameter, session) {
valueParameter
.transformAnnotations(transformer, data)
.transformReturnTypeRef(transformer, data)
}
return valueParameter
}
override fun transformProperty(property: FirProperty, data: ResolutionMode): FirProperty {
property.transformReceiverTypeRef(transformer, ResolutionMode.ContextIndependent)
doTransformTypeParameters(property)
context.withProperty(property) {
property
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformGetter(transformer, data)
.transformSetter(transformer, data)
}
return property
}
override fun transformPropertyAccessor(
propertyAccessor: FirPropertyAccessor,
data: ResolutionMode
): FirPropertyAccessor {
propertyAccessor
.transformValueParameters(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformAnnotations(transformer, data)
return propertyAccessor
}
override fun transformDeclarationStatus(declarationStatus: FirDeclarationStatus, data: ResolutionMode): FirDeclarationStatus {
return declarationStatus
}
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
context.forEnumEntry {
enumEntry
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformTypeParameters(transformer, data)
}
return enumEntry
}
override fun transformField(field: FirField, data: ResolutionMode): FirField {
context.withField(field) {
field.transformAnnotations(transformer, data)
}
return field
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias {
doTransformTypeParameters(typeAlias)
typeAlias.transformAnnotations(transformer, data)
return typeAlias
}
}
@@ -148,6 +148,10 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations(
return transformAnnotation(annotationCall, data)
}
override fun transformErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: ResolutionMode): FirStatement {
return transformAnnotation(errorAnnotationCall, data)
}
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
return expression.transformChildren(transformer, data) as FirStatement
}
@@ -17,6 +17,7 @@ enum class FirResolvePhase(val noProcessor: Boolean = false) {
ARGUMENTS_OF_ANNOTATIONS,
CONTRACTS,
IMPLICIT_TYPES_BODY_RESOLVE,
ANNOTATIONS_ARGUMENTS_MAPPING,
EXPECT_ACTUAL_MATCHING,
BODY_RESOLVE;
@@ -43,10 +43,7 @@ abstract class FirBasedSymbol<E : FirDeclaration> {
val resolvedAnnotationsWithArguments: List<FirAnnotation>
get() {
// NB: annotation argument mapping (w/ vararg) are built/replaced during call completion, hence BODY_RESOLVE.
// TODO(KT-53371): optimize ARGUMENTS_OF_ANNOTATIONS to build annotation argument mapping too.
// TODO(KT-53519): Even with BODY_RESOLVE, argument mapping for annotations on [FirValueParameter] is not properly built.
lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
lazyResolveToPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
return fir.annotations
}
@@ -71,7 +71,6 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>
else -> lazyResolveToPhase(FirResolvePhase.TYPES)
}
}
override fun toString(): String = "${this::class.simpleName} $callableId"
}
@@ -42,7 +42,7 @@ public static final class Companion /* AnnoWithCompanion.Companion*/ {
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface Anno /* Anno*/ {
public abstract Anno[] x();// x()
public abstract Anno[] x() default {Anno(p = "a"), Anno(p = "b")};// x()
public abstract java.lang.String p() default "";// p()
@@ -71,7 +71,7 @@ public abstract @interface AnnotatedAttribute /* AnnotatedAttribute*/ {
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface Deprecated /* Deprecated*/ {
public abstract ReplaceWith replaceWith();// replaceWith()
public abstract ReplaceWith replaceWith() default @ReplaceWith(expression = "");// replaceWith()
public abstract java.lang.String message();// message()
@@ -43,7 +43,7 @@ public final class Container /* Container*/ {
public final void deepOpen(@org.jetbrains.annotations.NotNull() Out<? extends Out<? extends Out<? extends Open>>>);// deepOpen(Out<? extends Out<? extends Out<? extends Open>>>)
@org.jetbrains.annotations.NotNull()
public final OutPair<Final, OutPair<Out<Final>, Out<Final>>> falseTrueFalse();// falseTrueFalse()
public final OutPair<Final, OutPair<Out<Final>, Out<? extends Final>>> falseTrueFalse();// falseTrueFalse()
@org.jetbrains.annotations.NotNull()
public final OutPair<Open, ? extends OutPair<Open,? extends Out<Open>>> combination();// combination()
@@ -21,7 +21,7 @@ public final class JvmWildcardAnnotationsKt /* JvmWildcardAnnotationsKt*/ {
public static final void deepOpen(@org.jetbrains.annotations.NotNull() Out<? extends Out<? extends Out<? extends Open>>>);// deepOpen(Out<? extends Out<? extends Out<? extends Open>>>)
@org.jetbrains.annotations.NotNull()
public static final OutPair<Final, OutPair<Out<Final>, Out<Final>>> falseTrueFalse();// falseTrueFalse()
public static final OutPair<Final, OutPair<Out<Final>, Out<? extends Final>>> falseTrueFalse();// falseTrueFalse()
@org.jetbrains.annotations.NotNull()
public static final OutPair<Open, ? extends OutPair<Open,? extends Out<Open>>> combination();// combination()
@@ -1,77 +0,0 @@
public final class WildcardOptimizationKt /* WildcardOptimizationKt*/ {
@org.jetbrains.annotations.NotNull()
public static final In<Final> notDeepIn();// notDeepIn()
@org.jetbrains.annotations.NotNull()
public static final Inv<? super Out<? extends Open>> skipWildcardsUntilInProjection();// skipWildcardsUntilInProjection()
@org.jetbrains.annotations.NotNull()
public static final Inv<In<Out<? extends Open>>> skipAllInvWildcards();// skipAllInvWildcards()
@org.jetbrains.annotations.NotNull()
public static final Inv<OutPair<Open, Out<Out<Open>>>> skipAllOutInvWildcards();// skipAllOutInvWildcards()
@org.jetbrains.annotations.NotNull()
public static final Out<In<Out<? extends Final>>> skipWildcardsUntilIn1();// skipWildcardsUntilIn1()
@org.jetbrains.annotations.NotNull()
public static final Out<In<Out<? extends Open>>> skipWildcardsUntilIn0();// skipWildcardsUntilIn0()
@org.jetbrains.annotations.NotNull()
public static final Out<In<OutPair<? extends Final, ? extends Out<? extends Open>>>> skipWildcardsUntilIn2();// skipWildcardsUntilIn2()
public static final <Q extends Final> void typeParameter(@org.jetbrains.annotations.NotNull() Out<? extends Q>, @org.jetbrains.annotations.NotNull() In<? super Q>);// <Q extends Final> typeParameter(Out<? extends Q>, In<? super Q>)
public static final void arrayOfOutFinal(@org.jetbrains.annotations.NotNull() Out<Final>[]);// arrayOfOutFinal(Out<Final>[])
public static final void arrayOfOutOpen(@org.jetbrains.annotations.NotNull() Out<Open>[]);// arrayOfOutOpen(Out<Open>[])
public static final void deepFinal(@org.jetbrains.annotations.NotNull() Out<? extends Out<? extends Out<? extends Final>>>);// deepFinal(Out<? extends Out<? extends Out<? extends Final>>>)
public static final void deepOpen(@org.jetbrains.annotations.NotNull() Out<? extends Out<? extends Out<? extends Open>>>);// deepOpen(Out<? extends Out<? extends Out<? extends Open>>>)
public static final void finalClassArgument(@org.jetbrains.annotations.NotNull() Out<? extends Final>, @org.jetbrains.annotations.NotNull() In<? super Final>);// finalClassArgument(Out<? extends Final>, In<? super Final>)
public static final void inAny(@org.jetbrains.annotations.NotNull() In<java.lang.Object>);// inAny(In<java.lang.Object>)
public static final void inFinal(@org.jetbrains.annotations.NotNull() In<? super Final>);// inFinal(In<? super Final>)
public static final void inOutFinal(@org.jetbrains.annotations.NotNull() In<? super Out<? extends Final>>);// inOutFinal(In<? super Out<? extends Final>>)
public static final void invFinal(@org.jetbrains.annotations.NotNull() Inv<Final>);// invFinal(Inv<Final>)
public static final void invIn(@org.jetbrains.annotations.NotNull() Out<? extends Inv<? super Final>>);// invIn(Out<? extends Inv<? super Final>>)
public static final void invInAny(@org.jetbrains.annotations.NotNull() Out<? extends Inv<? super java.lang.Object>>);// invInAny(Out<? extends Inv<? super java.lang.Object>>)
public static final void invInOutFinal(@org.jetbrains.annotations.NotNull() Inv<In<Out<? extends Final>>>);// invInOutFinal(Inv<In<Out<? extends Final>>>)
public static final void invInOutOpen(@org.jetbrains.annotations.NotNull() Inv<In<Out<? extends Open>>>);// invInOutOpen(Inv<In<Out<? extends Open>>>)
public static final void invInv(@org.jetbrains.annotations.NotNull() Out<? extends Inv<Open>>);// invInv(Out<? extends Inv<Open>>)
public static final void invOpen(@org.jetbrains.annotations.NotNull() Inv<Open>);// invOpen(Inv<Open>)
public static final void invOut(@org.jetbrains.annotations.NotNull() Out<? extends Inv<? extends Open>>);// invOut(Out<? extends Inv<? extends Open>>)
public static final void invOutFinal(@org.jetbrains.annotations.NotNull() Inv<Out<Final>>);// invOutFinal(Inv<Out<Final>>)
public static final void invOutFinal(@org.jetbrains.annotations.NotNull() Out<? extends Inv<? extends Final>>);// invOutFinal(Out<? extends Inv<? extends Final>>)
public static final void invOutOpen(@org.jetbrains.annotations.NotNull() Inv<Out<Open>>);// invOutOpen(Inv<Out<Open>>)
public static final void invOutProjectedOutFinal(@org.jetbrains.annotations.NotNull() Inv<? extends Out<? extends Final>>);// invOutProjectedOutFinal(Inv<? extends Out<? extends Final>>)
public static final void oneArgumentFinal(@org.jetbrains.annotations.NotNull() OutPair<? extends Final, ? extends Open>);// oneArgumentFinal(OutPair<? extends Final, ? extends Open>)
public static final void openClassArgument(@org.jetbrains.annotations.NotNull() Out<? extends Open>, @org.jetbrains.annotations.NotNull() In<? super Open>);// openClassArgument(Out<? extends Open>, In<? super Open>)
public static final void outIn(@org.jetbrains.annotations.NotNull() Out<? extends In<? super Final>>);// outIn(Out<? extends In<? super Final>>)
public static final void outInAny(@org.jetbrains.annotations.NotNull() Out<? extends In<java.lang.Object>>);// outInAny(Out<? extends In<java.lang.Object>>)
public static final void outOfArrayOpen(@org.jetbrains.annotations.NotNull() Out<Open[]>);// outOfArrayOpen(Out<Open[]>)
public static final void outOfArrayOutOpen(@org.jetbrains.annotations.NotNull() Out<? extends Open[]>);// outOfArrayOutOpen(Out<? extends Open[]>)
}