[K2] Instantiation of annotations having default values for properties
This commit adds missing pieces for the puzzle: Annotation instantiation feature uses IrProperty's initializer to instantiate properties from other modules that have default values which weren't specified on call site. To support this feature properly, Fir2IrVisitor should fill LazyIrProperty's backing field initializer with information from Fir. To get this information into Fir, FirMemberDeserializer should be able to read it from KotlinJvmBinaryClass with AnnotationLoaderVisitorImpl. (klibs are unsupported for now) There's a catch with enum entries references: we can't access session.SymbolProvider to resolve it because we're still at the deserialization stage, and it can cause StackOverflow if enum is nested in the same class (see RequiresOptIn.Level). To mitigate this, a new FirEnumEntryDeserializedAccessExpression is produced instead; it is later replaced with the correct reference in the Fir2IrVisitor. ^KT-58137 Fixed Also add test to loadJava folder with annotations default values that verifies metadata loading
This commit is contained in:
committed by
Space Team
parent
d757847ed6
commit
c4255f9a9e
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.expressions
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
abstract class FirEnumEntryDeserializedAccessExpression : FirExpression() {
|
||||
abstract override val source: KtSourceElement?
|
||||
abstract override val typeRef: FirTypeRef
|
||||
abstract override val annotations: List<FirAnnotation>
|
||||
abstract val enumClassId: ClassId
|
||||
abstract val enumEntryName: Name
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitEnumEntryDeserializedAccessExpression(this, data)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||
transformer.transformEnumEntryDeserializedAccessExpression(this, data) as E
|
||||
|
||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||
|
||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirEnumEntryDeserializedAccessExpression
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.builder
|
||||
|
||||
import kotlin.contracts.*
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEnumEntryDeserializedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.constructClassType
|
||||
import org.jetbrains.kotlin.fir.types.toLookupTag
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
@FirBuilderDsl
|
||||
class FirEnumEntryDeserializedAccessExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||
lateinit var enumClassId: ClassId
|
||||
lateinit var enumEntryName: Name
|
||||
|
||||
override fun build(): FirEnumEntryDeserializedAccessExpression {
|
||||
return FirEnumEntryDeserializedAccessExpressionImpl(
|
||||
annotations.toMutableOrEmpty(),
|
||||
enumClassId,
|
||||
enumEntryName,
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("Modification of 'source' has no impact for FirEnumEntryDeserializedAccessExpressionBuilder", level = DeprecationLevel.HIDDEN)
|
||||
override var source: KtSourceElement?
|
||||
get() = throw IllegalStateException()
|
||||
set(_) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
@Deprecated("Modification of 'typeRef' has no impact for FirEnumEntryDeserializedAccessExpressionBuilder", level = DeprecationLevel.HIDDEN)
|
||||
override var typeRef: FirTypeRef
|
||||
get() = throw IllegalStateException()
|
||||
set(_) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildEnumEntryDeserializedAccessExpression(init: FirEnumEntryDeserializedAccessExpressionBuilder.() -> Unit): FirEnumEntryDeserializedAccessExpression {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return FirEnumEntryDeserializedAccessExpressionBuilder().apply(init).build()
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.constructClassType
|
||||
import org.jetbrains.kotlin.fir.types.toLookupTag
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.MutableOrEmptyList
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
internal class FirEnumEntryDeserializedAccessExpressionImpl(
|
||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||
override val enumClassId: ClassId,
|
||||
override val enumEntryName: Name,
|
||||
) : FirEnumEntryDeserializedAccessExpression() {
|
||||
override val source: KtSourceElement? get() = null
|
||||
override var typeRef: FirTypeRef = buildResolvedTypeRef { type = enumClassId.toLookupTag().constructClassType(emptyArray(), false) }
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
typeRef.accept(visitor, data)
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirEnumEntryDeserializedAccessExpressionImpl {
|
||||
typeRef = typeRef.transform(transformer, data)
|
||||
transformAnnotations(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirEnumEntryDeserializedAccessExpressionImpl {
|
||||
annotations.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||
typeRef = newTypeRef
|
||||
}
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||
annotations = newAnnotations.toMutableOrEmpty()
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -279,6 +280,8 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
|
||||
|
||||
override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): R = visitWrappedExpression(wrappedDelegateExpression, data)
|
||||
|
||||
override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): R = visitExpression(enumEntryDeserializedAccessExpression, data)
|
||||
|
||||
override fun visitNamedReference(namedReference: FirNamedReference, data: D): R = visitReference(namedReference, data)
|
||||
|
||||
override fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase, data: D): R = visitNamedReference(namedReferenceWithCandidateBase, data)
|
||||
|
||||
@@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -279,6 +280,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
|
||||
|
||||
override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression) = visitWrappedExpression(wrappedDelegateExpression)
|
||||
|
||||
override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) = visitExpression(enumEntryDeserializedAccessExpression)
|
||||
|
||||
override fun visitNamedReference(namedReference: FirNamedReference) = visitReference(namedReference)
|
||||
|
||||
override fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase) = visitNamedReference(namedReferenceWithCandidateBase)
|
||||
|
||||
@@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -652,6 +653,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformElement(wrappedDelegateExpression, data)
|
||||
}
|
||||
|
||||
open fun transformEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): FirStatement {
|
||||
return transformElement(enumEntryDeserializedAccessExpression, data)
|
||||
}
|
||||
|
||||
open fun transformNamedReference(namedReference: FirNamedReference, data: D): FirReference {
|
||||
return transformElement(namedReference, data)
|
||||
}
|
||||
@@ -1248,6 +1253,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformWrappedDelegateExpression(wrappedDelegateExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): FirStatement {
|
||||
return transformEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitNamedReference(namedReference: FirNamedReference, data: D): FirReference {
|
||||
return transformNamedReference(namedReference, data)
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -407,6 +408,8 @@ abstract class FirVisitor<out R, in D> {
|
||||
|
||||
open fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): R = visitElement(wrappedDelegateExpression, data)
|
||||
|
||||
open fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): R = visitElement(enumEntryDeserializedAccessExpression, data)
|
||||
|
||||
open fun visitNamedReference(namedReference: FirNamedReference, data: D): R = visitElement(namedReference, data)
|
||||
|
||||
open fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase, data: D): R = visitElement(namedReferenceWithCandidateBase, data)
|
||||
|
||||
@@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -651,6 +652,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitElement(wrappedDelegateExpression)
|
||||
}
|
||||
|
||||
open fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) {
|
||||
visitElement(enumEntryDeserializedAccessExpression)
|
||||
}
|
||||
|
||||
open fun visitNamedReference(namedReference: FirNamedReference) {
|
||||
visitElement(namedReference)
|
||||
}
|
||||
@@ -1247,6 +1252,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitWrappedDelegateExpression(wrappedDelegateExpression)
|
||||
}
|
||||
|
||||
final override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: Nothing?) {
|
||||
visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression)
|
||||
}
|
||||
|
||||
final override fun visitNamedReference(namedReference: FirNamedReference, data: Nothing?) {
|
||||
visitNamedReference(namedReference)
|
||||
}
|
||||
|
||||
@@ -651,6 +651,12 @@ class FirRenderer(
|
||||
wrappedDelegateExpression.expression.accept(this)
|
||||
}
|
||||
|
||||
override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) {
|
||||
with(enumEntryDeserializedAccessExpression) {
|
||||
print("$enumClassId.$enumEntryName")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression) {
|
||||
print(namedArgumentExpression.name)
|
||||
print(" = ")
|
||||
|
||||
+2
@@ -156,6 +156,8 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
||||
|
||||
val wrappedDelegateExpression by element(Expression, wrappedExpression)
|
||||
|
||||
val enumEntryDeserializedAccessExpression by element(Expression, expression)
|
||||
|
||||
val namedReference by element(Reference, reference)
|
||||
val namedReferenceWithCandidateBase by element(Reference, namedReference)
|
||||
val errorNamedReference by element(Reference, namedReference, diagnosticHolder)
|
||||
|
||||
+8
@@ -394,6 +394,14 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
}
|
||||
|
||||
impl(enumEntryDeserializedAccessExpression) {
|
||||
noSource()
|
||||
default("typeRef") {
|
||||
value = "buildResolvedTypeRef { type = enumClassId.toLookupTag().constructClassType(emptyArray(), false) }"
|
||||
useTypes(buildResolvedTypeRefImport, toLookupTagImport, constructClassTypeImport)
|
||||
}
|
||||
}
|
||||
|
||||
impl(smartCastExpression) {
|
||||
default("isStable") {
|
||||
value = "smartcastStability == SmartcastStability.STABLE_VALUE"
|
||||
|
||||
+5
@@ -644,6 +644,11 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("delegateProvider", expression).withReplace()
|
||||
}
|
||||
|
||||
enumEntryDeserializedAccessExpression.configure {
|
||||
+field("enumClassId", classIdType)
|
||||
+field("enumEntryName", nameType)
|
||||
}
|
||||
|
||||
namedReference.configure {
|
||||
+name
|
||||
}
|
||||
|
||||
+5
-1
@@ -10,4 +10,8 @@ import org.jetbrains.kotlin.fir.tree.generator.model.ArbitraryImportable
|
||||
val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState")
|
||||
val resolvePhaseExtensionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "resolvePhase")
|
||||
val resolveStateAccessImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "ResolveStateAccess")
|
||||
val resolvedDeclarationStatusImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations.impl", "FirResolvedDeclarationStatusImpl")
|
||||
val resolvedDeclarationStatusImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations.impl", "FirResolvedDeclarationStatusImpl")
|
||||
|
||||
val buildResolvedTypeRefImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types.builder", "buildResolvedTypeRef")
|
||||
val constructClassTypeImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types", "constructClassType")
|
||||
val toLookupTagImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types", "toLookupTag")
|
||||
|
||||
Reference in New Issue
Block a user