Don't read isStaticInOuter message for fields
It's only written for fields of properties of companion objects of classes; handle that case manually in deserialization
This commit is contained in:
+9
-22
@@ -91,16 +91,15 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
if (kind == AnnotatedCallableKind.PROPERTY) {
|
if (kind == AnnotatedCallableKind.PROPERTY) {
|
||||||
proto as ProtoBuf.Property
|
proto as ProtoBuf.Property
|
||||||
|
|
||||||
val nameResolver = container.nameResolver
|
val syntheticFunctionSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, synthetic = true)
|
||||||
val syntheticFunctionSignature = getPropertySignature(proto, nameResolver, container.typeTable, synthetic = true)
|
val fieldSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, field = true)
|
||||||
val fieldSignature = getPropertySignature(proto, nameResolver, container.typeTable, field = true)
|
|
||||||
|
|
||||||
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
||||||
findClassAndLoadMemberAnnotations(container, proto, sig)
|
findClassAndLoadMemberAnnotations(container, proto, sig)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
val fieldAnnotations = fieldSignature?.let { sig ->
|
val fieldAnnotations = fieldSignature?.let { sig ->
|
||||||
findClassAndLoadMemberAnnotations(container, proto, sig, isStaticFieldInOuter(proto))
|
findClassAndLoadMemberAnnotations(container, proto, sig, field = true)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
|
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
|
||||||
@@ -123,14 +122,9 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
||||||
|
|
||||||
private fun findClassAndLoadMemberAnnotations(
|
private fun findClassAndLoadMemberAnnotations(
|
||||||
container: ProtoContainer,
|
container: ProtoContainer, proto: MessageLite, signature: MemberSignature, field: Boolean = false
|
||||||
proto: MessageLite,
|
|
||||||
signature: MemberSignature,
|
|
||||||
isStaticFieldInOuter: Boolean = false
|
|
||||||
): List<A> {
|
): List<A> {
|
||||||
val kotlinClass = findClassWithAnnotationsAndInitializers(
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(proto, container.nameResolver), field)
|
||||||
container, getImplClassName(proto, container.nameResolver), isStaticFieldInOuter
|
|
||||||
)
|
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.debugFqName()}", null)
|
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.debugFqName()}", null)
|
||||||
return listOf()
|
return listOf()
|
||||||
@@ -182,9 +176,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
val nameResolver = container.nameResolver
|
val nameResolver = container.nameResolver
|
||||||
val signature = getCallableSignature(proto, nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY) ?: return null
|
val signature = getCallableSignature(proto, nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY) ?: return null
|
||||||
|
|
||||||
val kotlinClass = findClassWithAnnotationsAndInitializers(
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(proto, nameResolver), field = true)
|
||||||
container, getImplClassName(proto, nameResolver), isStaticFieldInOuter(proto)
|
|
||||||
)
|
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.debugFqName()}", null)
|
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.debugFqName()}", null)
|
||||||
return null
|
return null
|
||||||
@@ -194,7 +186,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findClassWithAnnotationsAndInitializers(
|
private fun findClassWithAnnotationsAndInitializers(
|
||||||
container: ProtoContainer, implClassName: Name?, isStaticFieldInOuter: Boolean
|
container: ProtoContainer, implClassName: Name?, field: Boolean
|
||||||
): KotlinJvmBinaryClass? = when (container) {
|
): KotlinJvmBinaryClass? = when (container) {
|
||||||
is ProtoContainer.Package -> {
|
is ProtoContainer.Package -> {
|
||||||
implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) }
|
implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) }
|
||||||
@@ -211,8 +203,8 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
ClassId(classId.packageFqName, implClassName)
|
ClassId(classId.packageFqName, implClassName)
|
||||||
kotlinClassFinder.findKotlinClass(implClassId)
|
kotlinClassFinder.findKotlinClass(implClassId)
|
||||||
}
|
}
|
||||||
else if (isStaticFieldInOuter && classId.isNestedClass) {
|
else if (field && container.isCompanionOfClass) {
|
||||||
// Backing fields of properties of a companion object are generated in the outer class
|
// Backing fields of properties of a companion object in a class are generated in the outer class
|
||||||
kotlinClassFinder.findKotlinClass(classId.outerClassId)
|
kotlinClassFinder.findKotlinClass(classId.outerClassId)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -230,11 +222,6 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isStaticFieldInOuter(proto: MessageLite): Boolean =
|
|
||||||
if (proto is ProtoBuf.Property && proto.hasExtension(propertySignature))
|
|
||||||
proto.getExtension(propertySignature).let { it.hasField() && it.field.isStaticInOuter }
|
|
||||||
else false
|
|
||||||
|
|
||||||
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage<A, C> {
|
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage<A, C> {
|
||||||
val memberAnnotations = HashMap<MemberSignature, MutableList<A>>()
|
val memberAnnotations = HashMap<MemberSignature, MutableList<A>>()
|
||||||
val propertyConstants = HashMap<MemberSignature, C>()
|
val propertyConstants = HashMap<MemberSignature, C>()
|
||||||
|
|||||||
+7
-2
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.serialization.Flags
|
import org.jetbrains.kotlin.serialization.Flags
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||||
@@ -241,9 +242,13 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when(this) {
|
private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when (this) {
|
||||||
is PackageFragmentDescriptor -> ProtoContainer.Package(fqName, c.nameResolver, c.typeTable)
|
is PackageFragmentDescriptor -> ProtoContainer.Package(fqName, c.nameResolver, c.typeTable)
|
||||||
is DeserializedClassDescriptor -> ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
|
is DeserializedClassDescriptor -> ProtoContainer.Class(
|
||||||
|
classProto, c.nameResolver, c.typeTable,
|
||||||
|
isCompanionOfClass = DescriptorUtils.isCompanionObject(this) &&
|
||||||
|
containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) }
|
||||||
|
)
|
||||||
else -> null // TODO: support annotations on lambdas and their parameters
|
else -> null // TODO: support annotations on lambdas and their parameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -26,7 +26,8 @@ sealed class ProtoContainer(
|
|||||||
class Class(
|
class Class(
|
||||||
val classProto: ProtoBuf.Class,
|
val classProto: ProtoBuf.Class,
|
||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
typeTable: TypeTable
|
typeTable: TypeTable,
|
||||||
|
val isCompanionOfClass: Boolean
|
||||||
) : ProtoContainer(nameResolver, typeTable) {
|
) : ProtoContainer(nameResolver, typeTable) {
|
||||||
override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName()
|
override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -296,7 +296,7 @@ public class DeserializedClassDescriptor(
|
|||||||
val annotations = enumEntryProtos[name]?.let { proto ->
|
val annotations = enumEntryProtos[name]?.let { proto ->
|
||||||
DeserializedAnnotations(c.storageManager) {
|
DeserializedAnnotations(c.storageManager) {
|
||||||
c.components.annotationAndConstantLoader.loadEnumEntryAnnotations(
|
c.components.annotationAndConstantLoader.loadEnumEntryAnnotations(
|
||||||
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable), proto
|
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false), proto
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: if (name in oldEnumEntryNames) Annotations.EMPTY
|
} ?: if (name in oldEnumEntryNames) Annotations.EMPTY
|
||||||
|
|||||||
+10
-5
@@ -50,9 +50,9 @@ private class ClassClsStubBuilder(
|
|||||||
private val classId: ClassId,
|
private val classId: ClassId,
|
||||||
private val outerContext: ClsStubBuilderContext
|
private val outerContext: ClsStubBuilderContext
|
||||||
) {
|
) {
|
||||||
private val c = outerContext.child(classProto.typeParameterList, classId.shortClassName, TypeTable(classProto.typeTable))
|
|
||||||
private val typeStubBuilder = TypeClsStubBuilder(c)
|
|
||||||
private val classKind = Flags.CLASS_KIND[classProto.flags]
|
private val classKind = Flags.CLASS_KIND[classProto.flags]
|
||||||
|
private val c = outerContext.child(classProto.typeParameterList, classKind, classId.shortClassName, TypeTable(classProto.typeTable))
|
||||||
|
private val typeStubBuilder = TypeClsStubBuilder(c)
|
||||||
private val supertypeIds = run {
|
private val supertypeIds = run {
|
||||||
val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
|
val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
|
||||||
//empty supertype list if single supertype is Any
|
//empty supertype list if single supertype is Any
|
||||||
@@ -64,6 +64,10 @@ private class ClassClsStubBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val companionObjectName = if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.getCompanionObjectName()) else null
|
private val companionObjectName = if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.getCompanionObjectName()) else null
|
||||||
|
private val isCompanionOfClass: Boolean get() {
|
||||||
|
return classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT &&
|
||||||
|
(outerContext.classKind?.let { it == ProtoBuf.Class.Kind.CLASS || it == ProtoBuf.Class.Kind.ENUM_CLASS } ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
|
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
|
||||||
|
|
||||||
@@ -137,7 +141,8 @@ private class ClassClsStubBuilder(
|
|||||||
|
|
||||||
val primaryConstructorProto = classProto.constructorList.find { !Flags.IS_SECONDARY.get(it.flags) } ?: return
|
val primaryConstructorProto = classProto.constructorList.find { !Flags.IS_SECONDARY.get(it.flags) } ?: return
|
||||||
|
|
||||||
createConstructorStub(classOrObjectStub, primaryConstructorProto, c, ProtoContainer.Class(classProto, c.nameResolver, c.typeTable))
|
createConstructorStub(classOrObjectStub, primaryConstructorProto, c,
|
||||||
|
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDelegationSpecifierList() {
|
private fun createDelegationSpecifierList() {
|
||||||
@@ -175,7 +180,7 @@ private class ClassClsStubBuilder(
|
|||||||
private fun createEnumEntryStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
private fun createEnumEntryStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
||||||
if (classKind != ProtoBuf.Class.Kind.ENUM_CLASS) return
|
if (classKind != ProtoBuf.Class.Kind.ENUM_CLASS) return
|
||||||
|
|
||||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
|
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false)
|
||||||
val enumEntries: List<Pair<Int, List<ClassId>>> =
|
val enumEntries: List<Pair<Int, List<ClassId>>> =
|
||||||
if (classProto.enumEntryList.isNotEmpty())
|
if (classProto.enumEntryList.isNotEmpty())
|
||||||
classProto.enumEntryList.map { enumEntryProto ->
|
classProto.enumEntryList.map { enumEntryProto ->
|
||||||
@@ -206,7 +211,7 @@ private class ClassClsStubBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
|
||||||
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
|
val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass)
|
||||||
|
|
||||||
for (secondaryConstructorProto in classProto.constructorList) {
|
for (secondaryConstructorProto in classProto.constructorList) {
|
||||||
if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
|
if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
|
||||||
|
|||||||
+8
-4
@@ -39,7 +39,7 @@ class ClsStubBuilderComponents(
|
|||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
typeTable: TypeTable
|
typeTable: TypeTable
|
||||||
): ClsStubBuilderContext {
|
): ClsStubBuilderContext {
|
||||||
return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable)
|
return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, classKind = null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,11 +69,13 @@ class ClsStubBuilderContext(
|
|||||||
val nameResolver: NameResolver,
|
val nameResolver: NameResolver,
|
||||||
val containerFqName: FqName,
|
val containerFqName: FqName,
|
||||||
val typeParameters: TypeParameters,
|
val typeParameters: TypeParameters,
|
||||||
val typeTable: TypeTable
|
val typeTable: TypeTable,
|
||||||
|
val classKind: ProtoBuf.Class.Kind?
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun ClsStubBuilderContext.child(
|
internal fun ClsStubBuilderContext.child(
|
||||||
typeParameterList: List<ProtoBuf.TypeParameter>,
|
typeParameterList: List<ProtoBuf.TypeParameter>,
|
||||||
|
classKind: ProtoBuf.Class.Kind? = null,
|
||||||
name: Name? = null,
|
name: Name? = null,
|
||||||
typeTable: TypeTable = this.typeTable
|
typeTable: TypeTable = this.typeTable
|
||||||
): ClsStubBuilderContext {
|
): ClsStubBuilderContext {
|
||||||
@@ -82,7 +84,8 @@ internal fun ClsStubBuilderContext.child(
|
|||||||
this.nameResolver,
|
this.nameResolver,
|
||||||
if (name != null) this.containerFqName.child(name) else this.containerFqName,
|
if (name != null) this.containerFqName.child(name) else this.containerFqName,
|
||||||
this.typeParameters.child(nameResolver, typeParameterList),
|
this.typeParameters.child(nameResolver, typeParameterList),
|
||||||
typeTable
|
typeTable,
|
||||||
|
classKind
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +95,7 @@ internal fun ClsStubBuilderContext.child(nameResolver: NameResolver, typeTable:
|
|||||||
nameResolver,
|
nameResolver,
|
||||||
this.containerFqName,
|
this.containerFqName,
|
||||||
this.typeParameters,
|
this.typeParameters,
|
||||||
typeTable
|
typeTable,
|
||||||
|
classKind = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
private @b(E.E2) companion object {
|
private @b(E.E2) companion object {
|
||||||
|
@f val field = 42
|
||||||
}
|
}
|
||||||
|
|
||||||
class Nested @a private @b(E.E1) @b(E.E2) constructor()
|
class Nested @a private @b(E.E1) @b(E.E2) constructor()
|
||||||
@@ -43,4 +43,7 @@ annotation class b(val e: E)
|
|||||||
AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
||||||
annotation class c
|
annotation class c
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FIELD)
|
||||||
|
annotation class f
|
||||||
|
|
||||||
enum class E { E1, E2 }
|
enum class E { E1, E2 }
|
||||||
|
|||||||
@@ -44,6 +44,19 @@ PsiJetFileStubImpl[package=]
|
|||||||
OBJECT_DECLARATION:[fqName=Annotations.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
|
OBJECT_DECLARATION:[fqName=Annotations.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
|
||||||
MODIFIER_LIST:[private companion]
|
MODIFIER_LIST:[private companion]
|
||||||
CLASS_BODY:
|
CLASS_BODY:
|
||||||
|
PROPERTY:[fqName=Annotations.Companion.field, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=field]
|
||||||
|
MODIFIER_LIST:[public final]
|
||||||
|
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=f]
|
||||||
|
ANNOTATION_TARGET:[useSiteTarget=FIELD]
|
||||||
|
CONSTRUCTOR_CALLEE:
|
||||||
|
TYPE_REFERENCE:
|
||||||
|
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||||
|
REFERENCE_EXPRESSION:[referencedName=f]
|
||||||
|
TYPE_REFERENCE:
|
||||||
|
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||||
|
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||||
|
REFERENCE_EXPRESSION:[referencedName=kotlin]
|
||||||
|
REFERENCE_EXPRESSION:[referencedName=Int]
|
||||||
PROPERTY:[fqName=Annotations.c, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=c]
|
PROPERTY:[fqName=Annotations.c, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=c]
|
||||||
MODIFIER_LIST:[private final]
|
MODIFIER_LIST:[private final]
|
||||||
TYPE_REFERENCE:
|
TYPE_REFERENCE:
|
||||||
|
|||||||
Reference in New Issue
Block a user