[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
@@ -20,13 +20,9 @@ import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtCallElement
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/**
* Returns `true` if the symbol is for a function named `invoke`.
@@ -72,7 +68,7 @@ internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession)
psi as? KtCallElement,
useSiteTarget,
FirAnnotationValueConverter.toNamedConstantValue(
mapAnnotationParameters(this, useSiteSession),
mapAnnotationParameters(this),
useSiteSession,
)
)
@@ -51,7 +51,7 @@ internal class KtFirAnnotationListForDeclaration private constructor(
useSiteSession: FirSession,
token: KtLifetimeToken,
): KtAnnotationsList {
return if (firSymbol.annotations.isEmpty()) {
return if (firSymbol.resolvedAnnotationsWithArguments.isEmpty()) {
KtEmptyAnnotationsList(token)
} else {
KtFirAnnotationListForDeclaration(firSymbol, useSiteSession, token)
@@ -5,88 +5,11 @@
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny
import org.jetbrains.kotlin.fir.declarations.resolved
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSession): Map<Name, FirExpression> {
// TODO: Alas, argument mapping for annotations on [FirValueParameter] is not properly built, even after BODY_RESOLVE ensured.
// Once fixed, manual building of argument mapping below is redundant. I.e., this util can be as simple as:
// return if (annotation.resolved)
// annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
// else
// emptyMap()
if (annotation.resolved) return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
if (annotation !is FirAnnotationCall) return emptyMap()
val annotationCone = (annotation.annotationTypeRef.coneType as? ConeClassLikeType)?.fullyExpandedType(session)
?: return emptyMap()
val annotationPrimaryCtor = (annotationCone.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.primaryConstructorIfAny(session)?.fir
val valueParameters = annotationPrimaryCtor?.valueParameters
val (varargValueParameters, nonVarargValueParameters) = valueParameters?.partition { it.isVararg }
?: (emptyList<FirValueParameter>() to emptyList())
val annotationCtorParameterNames = nonVarargValueParameters.map { it.name }
val resultMap = mutableMapOf<Name, FirExpression>()
val namesSequence = annotationCtorParameterNames.asSequence().iterator()
for (argument in annotation.argumentList.arguments.filterIsInstance<FirNamedArgumentExpression>()) {
resultMap[argument.name] = argument.expression
}
val argumentSequence = annotation.argumentList.arguments.asSequence().iterator()
while (namesSequence.hasNext()) {
val name = namesSequence.next()
if (name in resultMap) continue
while (argumentSequence.hasNext()) {
val argument = argumentSequence.next()
if (argument is FirNamedArgumentExpression) continue
resultMap[name] = argument
break
}
}
if (varargValueParameters.isNotEmpty() && argumentSequence.hasNext()) {
val varargValueParameter = varargValueParameters.single()
val arguments = buildList {
while (argumentSequence.hasNext()) {
val argument = argumentSequence.next()
if (argument is FirNamedArgumentExpression) continue
add(argument)
}
}
if (arguments.isNotEmpty()) {
val exp = buildVarargArgumentsExpression {
this.arguments.addAll(arguments)
val firstArgument = arguments.first()
firstArgument.source?.let { source = it.fakeElement(KtFakeSourceElementKind.VarargArgument) }
(varargValueParameter.returnTypeRef as? FirResolvedTypeRef)?.coneType?.varargElementType()?.let {
varargElementType = buildResolvedTypeRef {
source = varargValueParameter.returnTypeRef.source
type = it
}
} ?: firstArgument.typeRef.let {
varargElementType = it
}
}
resultMap[varargValueParameter.name] = exp
}
}
return resultMap
internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirExpression> {
assert(annotation.resolved) { "By now the annotations argument mapping should have been resolved" }
return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
}
@@ -1,3 +1,4 @@
// IGNORE_FIR
annotation class ReceiverAnnotation
@Target(AnnotationTarget.TYPE)
annotation class ReceiverTypeAnnotation
@@ -1,3 +1,4 @@
// IGNORE_FIR
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
annotation class ReceiverAnnotation
@Target(AnnotationTarget.TYPE)
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.KtClassBody
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirModuleResolveComponents) {
/**
@@ -308,10 +309,12 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
?: error("Container for local declaration cannot be null")
val isLocalDeclarationResolveRequested =
possiblyLocalDeclaration != nonLocalDeclaration
val isValueParameterInsidePrimaryConstructor = firDeclarationToResolve is FirValueParameter
&& possiblyLocalDeclaration is KtPrimaryConstructor
val declarationToResolve: FirDeclaration
if (isLocalDeclarationResolveRequested) {
if (isLocalDeclarationResolveRequested && !isValueParameterInsidePrimaryConstructor) {
val enumEntry = possiblyLocalDeclaration.getContainingEnumEntryAsMemberOfEnumEntry() ?: return
declarationToResolve = enumEntry.findSourceNonLocalFirDeclaration(
@@ -33,6 +33,7 @@ internal object ResolveTreeBuilder {
FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS -> "ArgumentsOfAnnotations"
FirResolvePhase.CONTRACTS -> "Contracts"
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> "ImplicitTypes"
FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING -> "AnnotationsArgumentsMapping"
FirResolvePhase.BODY_RESOLVE -> "Body"
else -> "?"
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2020 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.analysis.low.level.api.fir.transformers
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveTreeBuilder
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer.Companion.updatePhaseDeep
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkAnnotationArgumentsMappingIsResolved
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkPhase
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirAnnotationArgumentsMappingTransformer
/**
* Transform designation into ANNOTATIONS_ARGUMENTS_MAPPING declaration. Affects only for target declaration, it's children and dependents
*/
internal class LLFirDesignatedAnnotationArgumentsMappingTransformer(
private val designation: FirDeclarationDesignationWithFile,
session: FirSession,
scopeSession: ScopeSession,
) : LLFirLazyTransformer, FirAnnotationArgumentsMappingTransformer(session, scopeSession, FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) {
private val ideDeclarationTransformer = LLFirDeclarationTransformer(designation)
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration =
ideDeclarationTransformer.transformDeclarationContent(this, declaration, data) {
super.transformDeclarationContent(declaration, data)
}
override fun transformDeclaration(phaseRunner: LLFirPhaseRunner) {
if (designation.declaration.resolvePhase >= FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) return
designation.declaration.checkPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
ResolveTreeBuilder.resolvePhase(designation.declaration, FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) {
phaseRunner.runPhaseWithCustomResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) {
designation.firFile.transform<FirFile, ResolutionMode>(this, ResolutionMode.ContextIndependent)
}
}
updatePhaseDeep(designation.declaration, FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
checkIsResolved(designation.declaration)
}
override fun checkIsResolved(declaration: FirDeclaration) {
declaration.checkPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
for (annotation in declaration.annotations) {
if (annotation is FirAnnotationCall) {
checkAnnotationArgumentsMappingIsResolved(annotation, declaration)
}
}
checkNestedDeclarationsAreResolved(declaration)
}
}
@@ -67,6 +67,11 @@ internal object LazyTransformerFactory {
scopeSession,
towerDataContextCollector
)
FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING -> LLFirDesignatedAnnotationArgumentsMappingTransformer(
designation,
designation.firFile.moduleData.session,
scopeSession,
)
FirResolvePhase.BODY_RESOLVE -> LLFirDesignatedBodyResolveTransformer(
designation,
designation.firFile.moduleData.session,
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -68,3 +70,24 @@ internal fun checkDeclarationStatusIsResolved(declaration: FirMemberDeclaration)
withFirEntry("declaration", declaration)
}
}
internal inline fun checkAnnotationArgumentsMappingIsResolved(
annotation: FirAnnotationCall,
owner: FirDeclaration,
extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {}
) {
checkWithAttachmentBuilder(
condition = annotation.argumentList is FirResolvedArgumentList,
message = {
buildString {
append("Expected ${FirResolvedArgumentList::class.simpleName}")
append(" for ${annotation::class.simpleName} of ${owner::class.simpleName}(${owner.origin})")
append(" but ${annotation.argumentList::class.simpleName} found")
}
}
) {
withFirEntry("annotation", annotation)
withFirEntry("firDeclaration", owner)
extraAttachment()
}
}
@@ -381,6 +381,45 @@ FILE: annotationParameters.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: annotationParameters.kt
public final [STATUS] enum class X : R|kotlin/Enum<X>| {
private [STATUS] [ContainingClassKey=X] constructor(): R|X| {
super<R|kotlin/Enum<X>|>()
}
public final static [STATUS] [ContainingClassKey=X] enum entry A: R|X|
public final static [BODY_RESOLVE] [ContainingClassKey=X] fun values(): R|kotlin/Array<X>| {
}
public final static [BODY_RESOLVE] [ContainingClassKey=X] fun valueOf([BODY_RESOLVE] value: R|kotlin/String|): R|X| {
}
public final static [BODY_RESOLVE] [ContainingClassKey=X] val entries: R|kotlin/enums/EnumEntries<X>|
public [RAW_FIR] get(): R|kotlin/enums/EnumEntries<X>|
}
public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| {
public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: <ERROR TYPE REF: Symbol not found for A.X>): R|Anno| {
super<R|kotlin/Any|>()
}
public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|<local>/args|
public? [SUPER_TYPES] [ContainingClassKey=Anno] get(): A.X
}
public final [STATUS] class B : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=B] constructor(): R|B| {
super<R|kotlin/Any|>()
}
@R|Anno|(args = Q|X|.R|/X.A|) public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
}
@R|Anno|(X#.A#) public final [STATUS] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
}
EXPECT_ACTUAL_MATCHING:
FILE: annotationParameters.kt
public final [STATUS] enum class X : R|kotlin/Enum<X>| {
@@ -399,13 +438,13 @@ FILE: annotationParameters.kt
public [RAW_FIR] get(): R|kotlin/enums/EnumEntries<X>|
}
public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| {
public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| {
public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| {
public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: <ERROR TYPE REF: Symbol not found for A.X>): R|Anno| {
super<R|kotlin/Any|>()
}
public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|<local>/args|
public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] get(): A.X
public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|<local>/args|
public? [SUPER_TYPES] [ContainingClassKey=Anno] get(): A.X
}
public final [STATUS] class B : R|kotlin/Any| {
@@ -413,7 +452,7 @@ FILE: annotationParameters.kt
super<R|kotlin/Any|>()
}
@R|Anno|(Q|X|.R|/X.A|) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@R|Anno|(args = Q|X|.R|/X.A|) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
}
@R|Anno|(X#.A#) public final [STATUS] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
@@ -51,10 +51,16 @@ FILE: annotations.kt
@R|kotlin/Suppress|(String(2)) public final [IMPLICIT_TYPES_BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| {
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: annotations.kt
@FILE:Suppress(String(1))
@R|kotlin/Suppress|(names = vararg(String(2))) public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
}
EXPECT_ACTUAL_MATCHING:
FILE: annotations.kt
@FILE:Suppress(String(1))
@R|kotlin/Suppress|(String(2)) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@R|kotlin/Suppress|(names = vararg(String(2))) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
}
BODY_RESOLVE:
@@ -183,6 +183,26 @@ FILE: classMembers.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: classMembers.kt
public final [STATUS] class A : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=A] constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(functionWithLazyBody#())
}
public final [STATUS] val x: R|kotlin/Int| = LAZY_EXPRESSION
public [STATUS] [ContainingClassKey=A] get(): R|kotlin/Int| { LAZY_BLOCK }
public final [STATUS] fun receive([STATUS] value: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK }
public final [STATUS] fun functionWithLazyBody(): R|kotlin/String| { LAZY_BLOCK }
}
EXPECT_ACTUAL_MATCHING:
FILE: classMembers.kt
public final [STATUS] class A : R|kotlin/Any| {
@@ -89,6 +89,15 @@ FILE: classWithTypeParameters.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: classWithTypeParameters.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] class ResolveMe<[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> : R|kotlin/Any| {
public [ANNOTATIONS_ARGUMENTS_MAPPING] [ContainingClassKey=ResolveMe] constructor<[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K>(): R|ResolveMe<T, K>| {
super<R|kotlin/Any|>()
}
}
EXPECT_ACTUAL_MATCHING:
FILE: classWithTypeParameters.kt
public final [EXPECT_ACTUAL_MATCHING] class ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> : R|kotlin/Any| {
@@ -141,6 +141,21 @@ FILE: functionInValueClass.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: functionInValueClass.kt
@R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| {
super<R|kotlin/Any|>()
}
public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|<local>/value|
public [STATUS] [ContainingClassKey=Value] get(): R|kotlin/Int|
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
}
}
EXPECT_ACTUAL_MATCHING:
FILE: functionInValueClass.kt
@R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| {
@@ -299,6 +299,40 @@ FILE: delegates.kt
D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|<local>/variableWithImplicitType|)
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: delegates.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(valueWithExplicitType#)
receive#(valueWithImplicitType#)
variableWithExplicitType# = IntegerLiteral(10)
variableWithImplicitType# = IntegerLiteral(10)
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] val delegate: <implicit> = LAZY_EXPRESSION
public? [RAW_FIR] get(): <implicit>
public? final? [RAW_FIR] val valueWithExplicitType: Intby LAZY_EXPRESSION
public? [RAW_FIR] get(): <implicit> {
^ D|/valueWithExplicitType|.getValue#(Null(null), ::R|/valueWithExplicitType|)
}
public? final? [RAW_FIR] val valueWithImplicitType: <implicit>by LAZY_EXPRESSION
public? [RAW_FIR] get(): <implicit> {
^ D|/valueWithImplicitType|.getValue#(Null(null), ::R|/valueWithImplicitType|)
}
public? final? [RAW_FIR] var variableWithExplicitType: Intby LAZY_EXPRESSION
public? [RAW_FIR] get(): <implicit> {
^ D|/variableWithExplicitType|.getValue#(Null(null), ::R|/variableWithExplicitType|)
}
public? [RAW_FIR] set([RAW_FIR] <set-?>: <implicit>): R|kotlin/Unit| {
D|/variableWithExplicitType|.setValue#(Null(null), ::R|/variableWithExplicitType|, R|<local>/variableWithExplicitType|)
}
public? final? [RAW_FIR] var variableWithImplicitType: <implicit>by LAZY_EXPRESSION
public? [RAW_FIR] get(): <implicit> {
^ D|/variableWithImplicitType|.getValue#(Null(null), ::R|/variableWithImplicitType|)
}
public? [RAW_FIR] set([RAW_FIR] <set-?>: <implicit>): R|kotlin/Unit| {
D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|<local>/variableWithImplicitType|)
}
EXPECT_ACTUAL_MATCHING:
FILE: delegates.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -107,6 +107,24 @@ FILE: anonympuseObjectInInvalidPosition.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: anonympuseObjectInInvalidPosition.kt
private final [ANNOTATIONS_ARGUMENTS_MAPPING] val resolveMe: <ERROR TYPE REF: Wrong number of type arguments> = ERROR_EXPR(Should have initializer)<Unsupported LValue: NULL># = object : A<Int> {
private [RAW_FIR] [ContainingClassKey=<anonymous>] constructor(): R|<anonymous>| {
super<<implicit>>()
}
public? open? override [RAW_FIR] fun x(): R|kotlin/Unit| {
}
}
private [ANNOTATIONS_ARGUMENTS_MAPPING] get(): <ERROR TYPE REF: Wrong number of type arguments>
public? final? [COMPILER_REQUIRED_ANNOTATIONS] interface A<[COMPILER_REQUIRED_ANNOTATIONS] T> : R|kotlin/Any| {
public? final? [COMPILER_REQUIRED_ANNOTATIONS] fun x(): R|kotlin/Unit|
}
EXPECT_ACTUAL_MATCHING:
FILE: anonympuseObjectInInvalidPosition.kt
private final [EXPECT_ACTUAL_MATCHING] val resolveMe: <ERROR TYPE REF: Wrong number of type arguments> = ERROR_EXPR(Should have initializer)<Unsupported LValue: NULL># = object : A<Int> {
@@ -63,6 +63,14 @@ FILE: functionWithParameter.kt
^resolveMe Q|kotlin/Unit|
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: functionWithParameter.kt
public? final? [COMPILER_REQUIRED_ANNOTATIONS] interface I : R|kotlin/Any| {
}
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe([ANNOTATIONS_ARGUMENTS_MAPPING] param: R|I|): R|kotlin/Unit| {
^resolveMe Q|kotlin/Unit|
}
EXPECT_ACTUAL_MATCHING:
FILE: functionWithParameter.kt
public? final? [COMPILER_REQUIRED_ANNOTATIONS] interface I : R|kotlin/Any| {
@@ -41,6 +41,11 @@ FILE: functionWithTypeParameters.kt
public final [IMPLICIT_TYPES_BODY_RESOLVE] fun <[IMPLICIT_TYPES_BODY_RESOLVE] T : R|kotlin/Int|, [IMPLICIT_TYPES_BODY_RESOLVE] K> resolveMe(): R|kotlin/Unit| {
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: functionWithTypeParameters.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun <[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> resolveMe(): R|kotlin/Unit| {
}
EXPECT_ACTUAL_MATCHING:
FILE: functionWithTypeParameters.kt
public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> resolveMe(): R|kotlin/Unit| {
@@ -159,6 +159,26 @@ FILE: lambdaAsSAMInterface.kt
)
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: lambdaAsSAMInterface.kt
public? final? [RAW_FIR] class Arg : R|kotlin/Any| {
public? [RAW_FIR] [ContainingClassKey=Arg] constructor(): R|foo/Arg| {
super<R|kotlin/Any|>()
}
}
public? final? fun [RAW_FIR] interface Foo : R|kotlin/Any| {
public? final? [RAW_FIR] fun foo([RAW_FIR] a: Arg): Arg
}
public? final? [RAW_FIR] fun testMe([RAW_FIR] f: Foo): R|kotlin/Unit| { LAZY_BLOCK }
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
testMe#(<L> = [STATUS] testMe@fun <implicit>.<anonymous>([RAW_FIR] b: <implicit>): <implicit> <inline=Unknown> {
b#
}
)
}
EXPECT_ACTUAL_MATCHING:
FILE: lambdaAsSAMInterface.kt
public? final? [RAW_FIR] class Arg : R|kotlin/Any| {
@@ -133,6 +133,21 @@ FILE: parameterOfNonLocalSetter.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: parameterOfNonLocalSetter.kt
public final [STATUS] class X : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=X] constructor(): R|X| {
super<R|kotlin/Any|>()
}
public final [ANNOTATIONS_ARGUMENTS_MAPPING] var x: R|kotlin/Int| = IntegerLiteral(2)
public [ANNOTATIONS_ARGUMENTS_MAPPING] [ContainingClassKey=X] get(): R|kotlin/Int|
public [ANNOTATIONS_ARGUMENTS_MAPPING] [ContainingClassKey=X] set([ANNOTATIONS_ARGUMENTS_MAPPING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| {
^ Unit#
}
}
EXPECT_ACTUAL_MATCHING:
FILE: parameterOfNonLocalSetter.kt
public final [STATUS] class X : R|kotlin/Any| {
@@ -53,6 +53,13 @@ FILE: propertyWithTypeParameters.kt
^ TODO#()
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: propertyWithTypeParameters.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] val <[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> R|T|.resolveMe: R|K|
public [ANNOTATIONS_ARGUMENTS_MAPPING] get(): R|K| {
^ TODO#()
}
EXPECT_ACTUAL_MATCHING:
FILE: propertyWithTypeParameters.kt
public final [EXPECT_ACTUAL_MATCHING] val <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> R|T|.resolveMe: R|K|
@@ -73,6 +73,15 @@ FILE: propertyWithGetter.kt
public? final? [RAW_FIR] val withGetter: Int
public? [RAW_FIR] get(): Int { LAZY_BLOCK }
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: propertyWithGetter.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(withGetter#)
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] val withGetter: Int
public? [RAW_FIR] get(): Int { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: propertyWithGetter.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -85,6 +85,17 @@ FILE: propertyWithGetterAndSetter.kt
public? [RAW_FIR] get(): Int { LAZY_BLOCK }
public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK }
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: propertyWithGetterAndSetter.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(withGetterAndSetter#)
withGetterAndSetter# = IntegerLiteral(123)
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] var withGetterAndSetter: Int = LAZY_EXPRESSION
public? [RAW_FIR] get(): Int { LAZY_BLOCK }
public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: propertyWithGetterAndSetter.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -63,6 +63,14 @@ FILE: propertyWithInitializer.kt
public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION
public? [RAW_FIR] get(): Int
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: propertyWithInitializer.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(property#)
}
public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION
public? [RAW_FIR] get(): Int
EXPECT_ACTUAL_MATCHING:
FILE: propertyWithInitializer.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -123,6 +123,20 @@ FILE: secondaryConstructor.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: secondaryConstructor.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(A#(IntegerLiteral(42)))
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] class A : R|kotlin/Any| {
public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| {
super<R|kotlin/Any|>()
[RAW_FIR] lval a: <implicit> = x#
}
}
EXPECT_ACTUAL_MATCHING:
FILE: secondaryConstructor.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -209,6 +209,27 @@ FILE: superTypes.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: superTypes.kt
public open [TYPES] class A : R|kotlin/Any| {
public [TYPES] [ContainingClassKey=A] constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public? open [RAW_FIR] class B : A {
public? [RAW_FIR] [ContainingClassKey=B] constructor(): R|B| {
super<A>()
}
}
public open [ANNOTATIONS_ARGUMENTS_MAPPING] class resolveMe : R|A| {
public [ANNOTATIONS_ARGUMENTS_MAPPING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| {
super<R|A|>()
}
}
EXPECT_ACTUAL_MATCHING:
FILE: superTypes.kt
public open [TYPES] class A : R|kotlin/Any| {
@@ -269,6 +269,33 @@ FILE: superTypesLoop.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: superTypesLoop.kt
public open [ANNOTATIONS_ARGUMENTS_MAPPING] class resolveMe : R|C| {
public [ANNOTATIONS_ARGUMENTS_MAPPING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| {
super<R|C|>()
}
}
public? open [COMPILER_REQUIRED_ANNOTATIONS] class A : <ERROR TYPE REF: Loop in supertype: /A -> /B> {
public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=A] constructor(): R|A| {
super<B>()
}
}
public? open [COMPILER_REQUIRED_ANNOTATIONS] class B : <ERROR TYPE REF: Loop in supertype: /B -> /C> {
public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=B] constructor(): R|B| {
super<C>()
}
}
public open [TYPES] class C : <ERROR TYPE REF: Loop in supertype: /C -> /A> {
public [TYPES] [ContainingClassKey=C] constructor(): R|C| {
super<R|A|>()
}
}
EXPECT_ACTUAL_MATCHING:
FILE: superTypesLoop.kt
public open [EXPECT_ACTUAL_MATCHING] class resolveMe : R|C| {
@@ -63,6 +63,14 @@ FILE: topLevelFunctions.kt
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK }
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: topLevelFunctions.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(functionWithLazyBody#())
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: topLevelFunctions.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -63,6 +63,14 @@ FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK }
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(functionWithLazyBody#())
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -63,6 +63,14 @@ FILE: topLevelFunctionsWithImplicitType.kt
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): <implicit> { LAZY_BLOCK }
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: topLevelFunctionsWithImplicitType.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| {
receive#(functionWithLazyBody#())
}
public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK }
public? final? [RAW_FIR] fun functionWithLazyBody(): <implicit> { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: topLevelFunctionsWithImplicitType.kt
public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| {
@@ -39,6 +39,10 @@ IMPLICIT_TYPES_BODY_RESOLVE:
FILE: typeAliasWithTypeParameters.kt
public final [IMPLICIT_TYPES_BODY_RESOLVE] typealias ResolveMe<[IMPLICIT_TYPES_BODY_RESOLVE] T : R|kotlin/Int|, [IMPLICIT_TYPES_BODY_RESOLVE] K> = R|kotlin/collections/Map<T, K>|
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: typeAliasWithTypeParameters.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] typealias ResolveMe<[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> = R|kotlin/collections/Map<T, K>|
EXPECT_ACTUAL_MATCHING:
FILE: typeAliasWithTypeParameters.kt
public final [EXPECT_ACTUAL_MATCHING] typealias ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> = R|kotlin/collections/Map<T, K>|
@@ -111,6 +111,18 @@ FILE: typeParameterOfNonLocalFunction.kt
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: typeParameterOfNonLocalFunction.kt
public final [STATUS] class X : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=X] constructor(): R|X| {
super<R|kotlin/Any|>()
}
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun <[ANNOTATIONS_ARGUMENTS_MAPPING] resolveMe> ddd(): R|kotlin/Unit| {
}
}
EXPECT_ACTUAL_MATCHING:
FILE: typeParameterOfNonLocalFunction.kt
public final [STATUS] class X : R|kotlin/Any| {
@@ -41,6 +41,11 @@ FILE: typeParameterOfTopFunction.kt
public final [IMPLICIT_TYPES_BODY_RESOLVE] fun <[IMPLICIT_TYPES_BODY_RESOLVE] resolveMe> ddd(): R|kotlin/Unit| {
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: typeParameterOfTopFunction.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun <[ANNOTATIONS_ARGUMENTS_MAPPING] resolveMe> ddd(): R|kotlin/Unit| {
}
EXPECT_ACTUAL_MATCHING:
FILE: typeParameterOfTopFunction.kt
public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] resolveMe> ddd(): R|kotlin/Unit| {
@@ -63,6 +63,14 @@ FILE: typeParameterOfTopSetter.kt
^ Unit#
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: typeParameterOfTopSetter.kt
public final [ANNOTATIONS_ARGUMENTS_MAPPING] var x: R|kotlin/Int| = IntegerLiteral(2)
public [ANNOTATIONS_ARGUMENTS_MAPPING] get(): R|kotlin/Int|
public [ANNOTATIONS_ARGUMENTS_MAPPING] set([ANNOTATIONS_ARGUMENTS_MAPPING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| {
^ Unit#
}
EXPECT_ACTUAL_MATCHING:
FILE: typeParameterOfTopSetter.kt
public final [EXPECT_ACTUAL_MATCHING] var x: R|kotlin/Int| = IntegerLiteral(2)
@@ -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[]>)
}