Minor, make ProtoContainer sealed with two subclasses

This commit is contained in:
Alexander Udalov
2015-12-17 03:27:07 +03:00
parent 745de229cc
commit 19372a7210
7 changed files with 49 additions and 44 deletions
@@ -113,7 +113,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<A> { override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<A> {
val signature = MemberSignature.fromFieldNameAndDesc( val signature = MemberSignature.fromFieldNameAndDesc(
container.nameResolver.getString(proto.name), container.nameResolver.getString(proto.name),
ClassMapperLite.mapClass(container.nameResolver.getClassId(container.classProto!!.fqName)) ClassMapperLite.mapClass(container.nameResolver.getClassId((container as ProtoContainer.Class).classProto.fqName))
) )
return findClassAndLoadMemberAnnotations(container, proto, signature) return findClassAndLoadMemberAnnotations(container, proto, signature)
} }
@@ -132,7 +132,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
container, getImplClassName(proto, container.nameResolver), isStaticFieldInOuter container, getImplClassName(proto, container.nameResolver), isStaticFieldInOuter
) )
if (kotlinClass == null) { if (kotlinClass == null) {
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.getFqName()}", null) errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.debugFqName()}", null)
return listOf() return listOf()
} }
@@ -186,7 +186,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
container, getImplClassName(proto, nameResolver), isStaticFieldInOuter(proto) container, getImplClassName(proto, nameResolver), isStaticFieldInOuter(proto)
) )
if (kotlinClass == null) { if (kotlinClass == null) {
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName()}", null) errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.debugFqName()}", null)
return null return null
} }
@@ -195,33 +195,29 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
private fun findClassWithAnnotationsAndInitializers( private fun findClassWithAnnotationsAndInitializers(
container: ProtoContainer, implClassName: Name?, isStaticFieldInOuter: Boolean container: ProtoContainer, implClassName: Name?, isStaticFieldInOuter: Boolean
): KotlinJvmBinaryClass? { ): KotlinJvmBinaryClass? = when (container) {
val (classProto, packageFqName) = container is ProtoContainer.Package -> {
return when { implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) }
packageFqName != null -> { }
implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(packageFqName, it)) } is ProtoContainer.Class -> {
val classId = container.nameResolver.getClassId(container.classProto.fqName)
if (implClassName != null) {
// TODO: store accurate name for nested traits
val implClassId =
if (implClassName.asString().endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX))
ClassId(classId.packageFqName, FqName(implClassName.asString().replace(JvmAbi.DEFAULT_IMPLS_SUFFIX, "." + JvmAbi.DEFAULT_IMPLS_CLASS_NAME)), false)
else
ClassId(classId.packageFqName, implClassName)
kotlinClassFinder.findKotlinClass(implClassId)
} }
classProto != null -> { else if (isStaticFieldInOuter && classId.isNestedClass) {
val classId = container.nameResolver.getClassId(classProto.fqName) // Backing fields of properties of a companion object are generated in the outer class
kotlinClassFinder.findKotlinClass(classId.outerClassId)
if (implClassName != null) { }
// TODO: store accurate name for nested traits else {
val implClassId =
if (implClassName.asString().endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX))
ClassId(classId.packageFqName, FqName(implClassName.asString().replace(JvmAbi.DEFAULT_IMPLS_SUFFIX, "." + JvmAbi.DEFAULT_IMPLS_CLASS_NAME)), false)
else
ClassId(classId.packageFqName, implClassName)
return kotlinClassFinder.findKotlinClass(implClassId)
}
if (isStaticFieldInOuter && classId.isNestedClass) {
// Backing fields of properties of a companion object are generated in the outer class
return kotlinClassFinder.findKotlinClass(classId.outerClassId)
}
kotlinClassFinder.findKotlinClass(classId) kotlinClassFinder.findKotlinClass(classId)
} }
else -> null
} }
} }
@@ -239,8 +239,8 @@ public class MemberDeserializer(private val c: DeserializationContext) {
} }
private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when(this) { private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when(this) {
is PackageFragmentDescriptor -> ProtoContainer(null, fqName, c.nameResolver, c.typeTable) is PackageFragmentDescriptor -> ProtoContainer.Package(fqName, c.nameResolver, c.typeTable)
is DeserializedClassDescriptor -> ProtoContainer(classProto, null, c.nameResolver, c.typeTable) is DeserializedClassDescriptor -> ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
else -> null // TODO: support annotations on lambdas and their parameters else -> null // TODO: support annotations on lambdas and their parameters
} }
} }
@@ -19,16 +19,25 @@ package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
public data class ProtoContainer( sealed class ProtoContainer(
val classProto: ProtoBuf.Class?,
val packageFqName: FqName?,
val nameResolver: NameResolver, val nameResolver: NameResolver,
val typeTable: TypeTable val typeTable: TypeTable
) { ) {
init { class Class(
assert((classProto != null) xor (packageFqName != null)) val classProto: ProtoBuf.Class,
nameResolver: NameResolver,
typeTable: TypeTable
) : ProtoContainer(nameResolver, typeTable) {
override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName()
} }
fun getFqName(): FqName = class Package(
packageFqName ?: nameResolver.getClassId(classProto!!.getFqName()).asSingleFqName() val fqName: FqName,
nameResolver: NameResolver,
typeTable: TypeTable
) : ProtoContainer(nameResolver, typeTable) {
override fun debugFqName(): FqName = fqName
}
abstract fun debugFqName(): FqName
} }
@@ -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(classProto, null, c.nameResolver, c.typeTable), proto ProtoContainer.Class(classProto, c.nameResolver, c.typeTable), proto
) )
} }
} ?: if (name in oldEnumEntryNames) Annotations.EMPTY } ?: if (name in oldEnumEntryNames) Annotations.EMPTY
@@ -76,7 +76,7 @@ abstract class CallableClsStubBuilder(
) { ) {
protected val c = outerContext.child(typeParameters) protected val c = outerContext.child(typeParameters)
protected val typeStubBuilder = TypeClsStubBuilder(c) protected val typeStubBuilder = TypeClsStubBuilder(c)
protected val isTopLevel: Boolean get() = protoContainer.packageFqName != null protected val isTopLevel: Boolean get() = protoContainer is ProtoContainer.Package
protected val callableStub: StubElement<out PsiElement> by lazy(LazyThreadSafetyMode.NONE) { doCreateCallableStub(parent) } protected val callableStub: StubElement<out PsiElement> by lazy(LazyThreadSafetyMode.NONE) { doCreateCallableStub(parent) }
fun build() { fun build() {
@@ -137,7 +137,7 @@ 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(classProto, null, c.nameResolver, c.typeTable)) createConstructorStub(classOrObjectStub, primaryConstructorProto, c, ProtoContainer.Class(classProto, c.nameResolver, c.typeTable))
} }
private fun createDelegationSpecifierList() { private fun createDelegationSpecifierList() {
@@ -175,7 +175,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(classProto, null, c.nameResolver, c.typeTable) val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
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 +206,7 @@ private class ClassClsStubBuilder(
} }
private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) { private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
val container = ProtoContainer(classProto, null, c.nameResolver, c.typeTable) val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
for (secondaryConstructorProto in classProto.constructorList) { for (secondaryConstructorProto in classProto.constructorList) {
if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) { if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
@@ -52,7 +52,7 @@ fun createPackageFacadeStub(
): KotlinFileStubImpl { ): KotlinFileStubImpl {
val fileStub = KotlinFileStubForIde.forFile(packageFqName, packageFqName.isRoot) val fileStub = KotlinFileStubForIde.forFile(packageFqName, packageFqName.isRoot)
setupFileStub(fileStub, packageFqName) setupFileStub(fileStub, packageFqName)
createCallableStubs(fileStub, c, ProtoContainer(null, packageFqName, c.nameResolver, c.typeTable), createCallableStubs(fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable),
packageProto.functionList, packageProto.propertyList) packageProto.functionList, packageProto.propertyList)
return fileStub return fileStub
} }
@@ -65,7 +65,7 @@ fun createFileFacadeStub(
val packageFqName = facadeFqName.parent() val packageFqName = facadeFqName.parent()
val fileStub = KotlinFileStubForIde.forFileFacadeStub(facadeFqName, packageFqName.isRoot) val fileStub = KotlinFileStubForIde.forFileFacadeStub(facadeFqName, packageFqName.isRoot)
setupFileStub(fileStub, packageFqName) setupFileStub(fileStub, packageFqName)
createCallableStubs(fileStub, c, ProtoContainer(null, packageFqName, c.nameResolver, c.typeTable), createCallableStubs(fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable),
packageProto.functionList, packageProto.propertyList) packageProto.functionList, packageProto.propertyList)
return fileStub return fileStub
} }
@@ -84,7 +84,7 @@ fun createMultifileClassStub(
val partHeader = partFile.classHeader val partHeader = partFile.classHeader
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(partHeader.annotationData!!, partHeader.strings!!) val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(partHeader.annotationData!!, partHeader.strings!!)
val partContext = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable)) val partContext = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
createCallableStubs(fileStub, partContext, ProtoContainer(null, packageFqName, partContext.nameResolver, partContext.typeTable), createCallableStubs(fileStub, partContext, ProtoContainer.Package(packageFqName, partContext.nameResolver, partContext.typeTable),
packageProto.functionList, packageProto.propertyList) packageProto.functionList, packageProto.propertyList)
} }
return fileStub return fileStub