FIR deserializer: build property accessors if non-default ones exist
This commit is contained in:
committed by
Mikhail Glukhikh
parent
369c08214b
commit
2d55b8db07
+2
-2
@@ -17,7 +17,7 @@ public final annotation class B : R|kotlin/Annotation| {
|
||||
public abstract interface I : R|kotlin/Any| {
|
||||
public abstract var getterAndSetter: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public abstract var propertyAndGetter: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
@@ -25,6 +25,6 @@ public abstract interface I : R|kotlin/Any| {
|
||||
|
||||
public abstract var propertyAndSetter: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ public final class A : R|kotlin/Any| {
|
||||
|
||||
public final var R|kotlin/String|.myLength3: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(v: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/A|
|
||||
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ public final class Test : R|kotlin/Any| {
|
||||
|
||||
public final var prop2: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
protected set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
protected set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final val prop3: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
@@ -27,7 +27,7 @@ public final class Test : R|kotlin/Any| {
|
||||
|
||||
public final var prop7: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(i: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
private constructor(): R|test/Test.Companion|
|
||||
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ public abstract interface Test : R|kotlin/Any| {
|
||||
|
||||
public final var prop2: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
protected set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
protected set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final val prop3: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
@@ -25,7 +25,7 @@ public abstract interface Test : R|kotlin/Any| {
|
||||
|
||||
public final var prop7: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(i: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
private constructor(): R|test/Test.Companion|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class ExtPropInClass : R|kotlin/Any| {
|
||||
public final var R|kotlin/Int|.itIs: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(p: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/ExtPropInClass|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class ExtValInClass<P> : R|kotlin/Any| {
|
||||
public final var R|kotlin/Int|.asas: R|P|
|
||||
public get(): R|P|
|
||||
public set(value: R|P|): R|kotlin/Unit|
|
||||
public set(p: R|P|): R|kotlin/Unit|
|
||||
|
||||
public constructor<P>(): R|test/ExtValInClass<P>|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class ExtValInClass<P> : R|kotlin/Any| {
|
||||
public final var R|kotlin/Int|.asas: R|P?|
|
||||
public get(): R|P?|
|
||||
public set(value: R|P?|): R|kotlin/Unit|
|
||||
public set(p: R|P?|): R|kotlin/Unit|
|
||||
|
||||
public constructor<P>(): R|test/ExtValInClass<P>|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class ExtValPIntInClass<P> : R|kotlin/Any| {
|
||||
public final var R|P|.asas: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(p: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor<P>(): R|test/ExtValPIntInClass<P>|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class ExtValPIntInClass<P> : R|kotlin/Any| {
|
||||
public final var R|P?|.asas: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(p: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor<P>(): R|test/ExtValPIntInClass<P>|
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public final class A : R|kotlin/Any| {
|
||||
public final var a: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/A|
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -13,7 +13,7 @@ public open class ClassVarModality : R|kotlin/Any| {
|
||||
|
||||
internal final var property4: R|kotlin/Int|
|
||||
internal get(): R|kotlin/Int|
|
||||
private set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
private set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/ClassVarModality|
|
||||
|
||||
@@ -22,7 +22,7 @@ public open class ClassVarModality : R|kotlin/Any| {
|
||||
public abstract class ClassVarModalityAbstract : R|kotlin/Any| {
|
||||
public abstract var property1: R|java/util/Date|
|
||||
public get(): R|java/util/Date|
|
||||
public set(value: R|java/util/Date|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|java/util/Date|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/ClassVarModalityAbstract|
|
||||
|
||||
|
||||
Vendored
+9
-9
@@ -1,39 +1,39 @@
|
||||
public final class ClassVal : R|kotlin/Any| {
|
||||
public final var property1: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final var property10: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
protected set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
protected set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final var property11: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
internal set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
internal set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final var property2: R|java/lang/Object|
|
||||
public get(): R|java/lang/Object|
|
||||
protected set(value: R|java/lang/Object|): R|kotlin/Unit|
|
||||
protected set(<set-?>: R|java/lang/Object|): R|kotlin/Unit|
|
||||
|
||||
public final var property3: R|java/lang/Object|
|
||||
public get(): R|java/lang/Object|
|
||||
private set(value: R|java/lang/Object|): R|kotlin/Unit|
|
||||
private set(<set-?>: R|java/lang/Object|): R|kotlin/Unit|
|
||||
|
||||
protected final var property4: R|kotlin/String|
|
||||
protected get(): R|kotlin/String|
|
||||
protected set(value: R|kotlin/String|): R|kotlin/Unit|
|
||||
protected set(<set-?>: R|kotlin/String|): R|kotlin/Unit|
|
||||
|
||||
protected final var property5: R|kotlin/String|
|
||||
protected get(): R|kotlin/String|
|
||||
private set(value: R|kotlin/String|): R|kotlin/Unit|
|
||||
private set(<set-?>: R|kotlin/String|): R|kotlin/Unit|
|
||||
|
||||
public final var property8: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final var property9: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
private set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
private set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/ClassVal|
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ public final class PrivateClassMembers : R|kotlin/Any| {
|
||||
|
||||
private final var r: R|kotlin/Int|
|
||||
private get(): R|kotlin/Int|
|
||||
private set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
private set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
private final val v: R|kotlin/Int|
|
||||
private get(): R|kotlin/Int|
|
||||
|
||||
+20
@@ -56,6 +56,26 @@ abstract class AbstractAnnotationDeserializer(
|
||||
return annotations.map { deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
|
||||
fun loadPropertyGetterAnnotations(
|
||||
propertyProto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
getterFlags: Int
|
||||
): List<FirAnnotationCall> {
|
||||
if (!Flags.HAS_ANNOTATIONS.get(getterFlags)) return emptyList()
|
||||
val annotations = propertyProto.getExtension(protocol.propertyGetterAnnotation).orEmpty()
|
||||
return annotations.map { deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
|
||||
fun loadPropertySetterAnnotations(
|
||||
propertyProto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
setterFlags: Int
|
||||
): List<FirAnnotationCall> {
|
||||
if (!Flags.HAS_ANNOTATIONS.get(setterFlags)) return emptyList()
|
||||
val annotations = propertyProto.getExtension(protocol.propertySetterAnnotation).orEmpty()
|
||||
return annotations.map { deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
|
||||
fun loadConstructorAnnotations(constructorProto: ProtoBuf.Constructor, nameResolver: NameResolver): List<FirAnnotationCall> {
|
||||
if (!Flags.HAS_ANNOTATIONS.get(constructorProto.flags)) return emptyList()
|
||||
val annotations = constructorProto.getExtension(protocol.constructorAnnotation).orEmpty()
|
||||
|
||||
+71
-8
@@ -20,15 +20,16 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
|
||||
class FirDeserializationContext(
|
||||
val nameResolver: NameResolver,
|
||||
@@ -172,13 +173,77 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
val symbol = FirPropertySymbol(CallableId(c.packageFqName, c.relativeClassName, callableName))
|
||||
val local = c.childContext(proto.typeParameterList)
|
||||
|
||||
val getterFlags = if (proto.hasGetterFlags()) proto.getterFlags else flags
|
||||
val setterFlags = if (proto.hasSetterFlags()) proto.setterFlags else flags
|
||||
// Per documentation on Property.getter_flags in metadata.proto, if an accessor flags field is absent, its value should be computed
|
||||
// by taking hasAnnotations/visibility/modality from property flags, and using false for the rest
|
||||
val defaultAccessorFlags = Flags.getAccessorFlags(
|
||||
Flags.HAS_ANNOTATIONS.get(flags),
|
||||
Flags.VISIBILITY.get(flags),
|
||||
Flags.MODALITY.get(flags),
|
||||
false, false, false
|
||||
)
|
||||
|
||||
val returnTypeRef = proto.returnType(c.typeTable).toTypeRef(local)
|
||||
|
||||
val getter = if (Flags.HAS_GETTER.get(flags)) {
|
||||
val getterFlags = if (proto.hasGetterFlags()) proto.getterFlags else defaultAccessorFlags
|
||||
val visibility = ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))
|
||||
val modality = ProtoEnumFlags.modality(Flags.MODALITY.get(getterFlags))
|
||||
if (Flags.IS_NOT_DEFAULT.get(getterFlags)) {
|
||||
buildPropertyAccessor {
|
||||
session = c.session
|
||||
origin = FirDeclarationOrigin.Library
|
||||
this.returnTypeRef = returnTypeRef
|
||||
isGetter = true
|
||||
status = FirDeclarationStatusImpl(visibility, modality)
|
||||
annotations += c.annotationDeserializer.loadPropertyGetterAnnotations(proto, local.nameResolver, getterFlags)
|
||||
this.symbol = FirPropertyAccessorSymbol()
|
||||
}
|
||||
} else {
|
||||
FirDefaultPropertyGetter(null, c.session, FirDeclarationOrigin.Library, returnTypeRef, visibility)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val setter = if (Flags.HAS_SETTER.get(flags)) {
|
||||
val setterFlags = if (proto.hasSetterFlags()) proto.setterFlags else defaultAccessorFlags
|
||||
val visibility = ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))
|
||||
val modality = ProtoEnumFlags.modality(Flags.MODALITY.get(setterFlags))
|
||||
if (Flags.IS_NOT_DEFAULT.get(setterFlags)) {
|
||||
buildPropertyAccessor {
|
||||
session = c.session
|
||||
origin = FirDeclarationOrigin.Library
|
||||
this.returnTypeRef = FirImplicitUnitTypeRef(source)
|
||||
isGetter = false
|
||||
status = FirDeclarationStatusImpl(visibility, modality)
|
||||
annotations += c.annotationDeserializer.loadPropertySetterAnnotations(proto, local.nameResolver, setterFlags)
|
||||
this.symbol = FirPropertyAccessorSymbol()
|
||||
valueParameters += proto.setterValueParameter.let {
|
||||
val parameterFlags = if (it.hasFlags()) it.flags else 0
|
||||
buildValueParameter {
|
||||
session = c.session
|
||||
origin = FirDeclarationOrigin.Library
|
||||
this.returnTypeRef = returnTypeRef
|
||||
name = if (it.hasName()) c.nameResolver.getName(it.name) else Name.special("<default-setter-parameter>")
|
||||
this.symbol = FirVariableSymbol(CallableId(FqName.ROOT, name))
|
||||
isCrossinline = Flags.IS_CROSSINLINE.get(parameterFlags)
|
||||
isNoinline = Flags.IS_NOINLINE.get(parameterFlags)
|
||||
isVararg = it.hasVarargElementType()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FirDefaultPropertySetter(null, c.session, FirDeclarationOrigin.Library, returnTypeRef, visibility)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val isVar = Flags.IS_VAR.get(flags)
|
||||
return buildProperty {
|
||||
session = c.session
|
||||
origin = FirDeclarationOrigin.Library
|
||||
returnTypeRef = proto.returnType(c.typeTable).toTypeRef(local)
|
||||
this.returnTypeRef = returnTypeRef
|
||||
receiverTypeRef = proto.receiverType(c.typeTable)?.toTypeRef(local)
|
||||
name = callableName
|
||||
this.isVar = isVar
|
||||
@@ -198,10 +263,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
|
||||
annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver)
|
||||
getter = FirDefaultPropertyGetter(null, c.session, FirDeclarationOrigin.Library, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags)))
|
||||
setter = if (isVar) {
|
||||
FirDefaultPropertySetter(null, c.session, FirDeclarationOrigin.Library, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags)))
|
||||
} else null
|
||||
this.getter = getter
|
||||
this.setter = setter
|
||||
this.containerSource = c.containerSource
|
||||
this.initializer = if (Flags.HAS_CONSTANT.get(flags)) {
|
||||
proto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue)?.let {
|
||||
|
||||
Reference in New Issue
Block a user