提交 2d55b8db 编写于 作者: J Jinseong Jeon 提交者: Mikhail Glukhikh

FIR deserializer: build property accessors if non-default ones exist

上级 369c0821
......@@ -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|
}
......@@ -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|
......
......@@ -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|
......
......@@ -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|
......
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|
......
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>|
......
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>|
......
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>|
......
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>|
......
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|
......
......@@ -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|
......
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|
......
......@@ -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|
......
......@@ -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()
......
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册