From b4addd05675cbb691cb264938950551a4c439b32 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 25 Dec 2015 02:13:09 +0300 Subject: [PATCH] Move builtins-related logic from DeserializedPackageFragment to BuiltinsPackageFragment --- .../BuiltInsSerializedResourcePaths.kt | 6 +- .../builtins/BuiltinsPackageFragment.kt | 35 ++++++++++++ .../serialization/SerializedResourcePaths.kt | 2 - .../DeserializedPackageFragment.kt | 55 +++++-------------- .../js/KotlinJavascriptPackageFragment.kt | 7 ++- ...KotlinJavascriptSerializedResourcePaths.kt | 13 ++--- 6 files changed, 63 insertions(+), 55 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsSerializedResourcePaths.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsSerializedResourcePaths.kt index bea7da9bf99..7c036d6f4f4 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsSerializedResourcePaths.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsSerializedResourcePaths.kt @@ -36,7 +36,7 @@ object BuiltInsSerializedResourcePaths : SerializedResourcePaths { val BUILTINS_FILE_EXTENSION = "kotlin_builtins" override fun getClassMetadataPath(classId: ClassId): String { - return packageFqNameToPath(classId.getPackageFqName()) + "/" + classId.getRelativeClassName().asString() + + return packageFqNameToPath(classId.packageFqName) + "/" + classId.relativeClassName.asString() + "." + CLASS_METADATA_FILE_EXTENSION } @@ -46,7 +46,7 @@ object BuiltInsSerializedResourcePaths : SerializedResourcePaths { override fun getStringTableFilePath(fqName: FqName): String = packageFqNameToPath(fqName) + "/" + shortName(fqName) + "." + STRING_TABLE_FILE_EXTENSION - override fun getBuiltInsFilePath(fqName: FqName): String = + fun getBuiltInsFilePath(fqName: FqName): String = packageFqNameToPath(fqName) + "/" + shortName(fqName) + "." + BUILTINS_FILE_EXTENSION @@ -54,5 +54,5 @@ object BuiltInsSerializedResourcePaths : SerializedResourcePaths { fqName.asString().replace('.', '/') private fun shortName(fqName: FqName): String = - if (fqName.isRoot()) "default-package" else fqName.shortName().asString() + if (fqName.isRoot) "default-package" else fqName.shortName().asString() } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt index 1713d9dbc74..cf68177e8ab 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt @@ -23,7 +23,10 @@ import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment +import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.storage.StorageManager +import java.io.DataInputStream import java.io.InputStream public class BuiltinsPackageFragment( @@ -32,6 +35,38 @@ public class BuiltinsPackageFragment( module: ModuleDescriptor, loadResource: (path: String) -> InputStream? ) : DeserializedPackageFragment(fqName, storageManager, module, BuiltInsSerializedResourcePaths, loadResource) { + val builtinsMessage = loadResource(BuiltInsSerializedResourcePaths.getBuiltInsFilePath(fqName))?.let { stream -> + val dataInput = DataInputStream(stream) + val version = BinaryVersion.create((1..dataInput.readInt()).map { dataInput.readInt() }.toIntArray()) + + if (!version.isCompatibleTo(BuiltinsPackageFragment.VERSION)) { + // TODO: report a proper diagnostic + throw UnsupportedOperationException( + "Kotlin built-in definition format version is not supported: " + + "expected ${BuiltinsPackageFragment.VERSION}, actual $version. " + + "Please update Kotlin" + ) + } + + BuiltInsProtoBuf.BuiltIns.parseFrom(stream, BuiltInsSerializedResourcePaths.extensionRegistry) + } + + override val nameResolver = + builtinsMessage?.let { NameResolverImpl(it.strings, it.qualifiedNames) } + ?: NameResolverImpl.read(loadResourceSure(serializedResourcePaths.getStringTableFilePath(fqName))) + + override val classIdToProto = builtinsMessage?.let { builtins -> + builtins.classList.toMapBy { klass -> + nameResolver.getClassId(klass.fqName) + } + } + + override fun computeMemberScope() = builtinsMessage?.let { builtins -> + DeserializedPackageMemberScope( + this, builtins.`package`, nameResolver, packagePartSource = null, components = components, + classNames = { classIdToProto!!.keys.filter { classId -> !classId.isNestedClass }.map { it.shortClassName } } + ) + } ?: super.computeMemberScope() protected override fun loadClassNames(packageProto: ProtoBuf.Package): Collection { return packageProto.getExtension(BuiltInsProtoBuf.className)?.map { id -> nameResolver.getName(id) } ?: listOf() diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/SerializedResourcePaths.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/SerializedResourcePaths.kt index c378c8888f7..49b263cc858 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/SerializedResourcePaths.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/SerializedResourcePaths.kt @@ -28,6 +28,4 @@ interface SerializedResourcePaths { fun getPackageFilePath(fqName: FqName): String fun getStringTableFilePath(fqName: FqName): String - - fun getBuiltInsFilePath(fqName: FqName): String? } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt index 87e1165f546..9e7f04d409d 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt @@ -16,18 +16,16 @@ package org.jetbrains.kotlin.serialization.deserialization -import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.SerializedResourcePaths -import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue -import java.io.DataInputStream import java.io.InputStream import javax.inject.Inject @@ -39,50 +37,25 @@ public abstract class DeserializedPackageFragment( private val loadResource: (path: String) -> InputStream? ) : PackageFragmentDescriptorImpl(module, fqName) { - val builtinsMessage = serializedResourcePaths.getBuiltInsFilePath(fqName)?.let(loadResource)?.let { stream -> - val dataInput = DataInputStream(stream) - val version = BinaryVersion.create((1..dataInput.readInt()).map { dataInput.readInt() }.toIntArray()) + abstract val nameResolver: NameResolver - if (!version.isCompatibleTo(BuiltinsPackageFragment.VERSION)) { - // TODO: report a proper diagnostic - throw UnsupportedOperationException( - "Kotlin built-in definition format version is not supported: " + - "expected ${BuiltinsPackageFragment.VERSION}, actual $version. " + - "Please update Kotlin" - ) - } - - BuiltInsProtoBuf.BuiltIns.parseFrom(stream, serializedResourcePaths.extensionRegistry) - } - - val nameResolver = - builtinsMessage?.let { NameResolverImpl(it.strings, it.qualifiedNames) } ?: - NameResolverImpl.read(loadResourceSure(serializedResourcePaths.getStringTableFilePath(fqName))) - - val classIdToProto = builtinsMessage?.let { builtins -> - builtins.classList.toMapBy { klass -> - nameResolver.getClassId(klass.fqName) - } - } + abstract val classIdToProto: Map? // component dependency cycle @set:Inject lateinit var components: DeserializationComponents - internal val deserializedMemberScope by storageManager.createLazyValue { - builtinsMessage?.let { builtins -> - DeserializedPackageMemberScope( - this, builtins.`package`, nameResolver, packagePartSource = null, components = components, - classNames = { classIdToProto!!.keys.filter { classId -> !classId.isNestedClass }.map { it.shortClassName } } - ) - } ?: run { - val packageStream = loadResourceSure(serializedResourcePaths.getPackageFilePath(fqName)) - val packageProto = ProtoBuf.Package.parseFrom(packageStream, serializedResourcePaths.extensionRegistry) - DeserializedPackageMemberScope( - this, packageProto, nameResolver, packagePartSource = null, components = components, - classNames = { loadClassNames(packageProto) } - ) - } + private val deserializedMemberScope by storageManager.createLazyValue { + computeMemberScope() + } + + protected open fun computeMemberScope(): DeserializedPackageMemberScope { + val packageStream = loadResourceSure(serializedResourcePaths.getPackageFilePath(fqName)) + val packageProto = ProtoBuf.Package.parseFrom(packageStream, serializedResourcePaths.extensionRegistry) + return DeserializedPackageMemberScope( + this, packageProto, nameResolver, packagePartSource = null, components = components, + classNames = { loadClassNames(packageProto) } + ) } override fun getMemberScope() = deserializedMemberScope diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt index 2d81434b26d..705b8de9456 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt @@ -17,10 +17,12 @@ package org.jetbrains.kotlin.serialization.js import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment +import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -30,10 +32,13 @@ public class KotlinJavascriptPackageFragment( module: ModuleDescriptor, loadResource: (path: String) -> InputStream? ) : DeserializedPackageFragment(fqName, storageManager, module, KotlinJavascriptSerializedResourcePaths, loadResource) { + override val nameResolver = NameResolverImpl.read(loadResourceSure(serializedResourcePaths.getStringTableFilePath(fqName))) + + override val classIdToProto: Map? get() = null protected override fun loadClassNames(packageProto: ProtoBuf.Package): Collection { val classesStream = loadResourceSure(KotlinJavascriptSerializedResourcePaths.getClassesInPackageFilePath(fqName)) val classesProto = JsProtoBuf.Classes.parseFrom(classesStream, serializedResourcePaths.extensionRegistry) - return classesProto.getClassNameList()?.map { id -> nameResolver.getName(id) } ?: listOf() + return classesProto.classNameList?.map { id -> nameResolver.getName(id) } ?: listOf() } } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt index b8a9a9d8f9d..bcb3e5a1054 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt @@ -37,7 +37,7 @@ object KotlinJavascriptSerializedResourcePaths : SerializedResourcePaths { override fun getClassMetadataPath(classId: ClassId): String { - return classId.getPackageFqName().toPath().withSepIfNotEmpty() + classId.getRelativeClassName().asString() + + return classId.packageFqName.toPath().withSepIfNotEmpty() + classId.relativeClassName.asString() + "." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION } @@ -47,14 +47,12 @@ object KotlinJavascriptSerializedResourcePaths : SerializedResourcePaths { override fun getStringTableFilePath(fqName: FqName): String = fqName.toPath().withSepIfNotEmpty() + shortName(fqName) + "." + STRING_TABLE_FILE_EXTENSION - override fun getBuiltInsFilePath(fqName: FqName): String? = null - private fun FqName.toPath() = this.asString().replace('.', '/') private fun String.withSepIfNotEmpty() = if (this.isEmpty()) this else this + "/" private fun shortName(fqName: FqName): String = - if (fqName.isRoot()) "default-package" else fqName.shortName().asString() + if (fqName.isRoot) "default-package" else fqName.shortName().asString() } @@ -62,7 +60,7 @@ private val PACKAGE_CLASS_NAME_SUFFIX: String = "Package" private val DEFAULT_PACKAGE_CLASS_NAME: String = "_Default" + PACKAGE_CLASS_NAME_SUFFIX private val DEFAULT_PACKAGE_METAFILE_NAME: String = DEFAULT_PACKAGE_CLASS_NAME + "." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION -public fun FqName.isPackageClassFqName(): Boolean = !this.isRoot() && getPackageClassFqName(this.parent()) == this +public fun FqName.isPackageClassFqName(): Boolean = !this.isRoot && getPackageClassFqName(this.parent()) == this public fun isDefaultPackageMetafile(fileName: String): Boolean = fileName == DEFAULT_PACKAGE_METAFILE_NAME @@ -85,10 +83,9 @@ private fun getPackageClassFqName(packageFQN: FqName): FqName { } private fun getPackageClassName(packageFQN: FqName): String { - return if (packageFQN.isRoot()) DEFAULT_PACKAGE_CLASS_NAME else capitalizeNonEmptyString(packageFQN.shortName().asString()) + PACKAGE_CLASS_NAME_SUFFIX + return if (packageFQN.isRoot) DEFAULT_PACKAGE_CLASS_NAME else capitalizeNonEmptyString(packageFQN.shortName().asString()) + PACKAGE_CLASS_NAME_SUFFIX } private fun capitalizeNonEmptyString(s: String): String { - return if (Character.isUpperCase(s.charAt(0))) s else Character.toUpperCase(s.charAt(0)) + s.substring(1) + return if (s[0].isUpperCase()) s else s[0].toUpperCase() + s.substring(1) } -