From 7123202670b34283e4a17dde2169bef054975d80 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 7 Feb 2018 15:31:21 +0100 Subject: [PATCH] Add getExtensionOrNull utility for protobuf messages --- .../kotlin/incremental/IncrementalJsCache.kt | 12 +++++------ .../org/jetbrains/kotlin/inline/inlineUtil.kt | 5 +++-- .../kotlin/load/kotlin/moduleName.kt | 7 +++---- ...tBinaryClassAnnotationAndConstantLoader.kt | 8 +++---- .../serialization/jvm/JvmProtoBufUtil.kt | 9 +++----- .../AnnotationAndConstantLoaderImpl.kt | 3 +-- .../deserialization/ProtoBufUtil.kt | 12 +++++++++++ .../reflect/jvm/internal/RuntimeTypeMapper.kt | 21 ++++++++----------- .../src/kotlin/reflect/jvm/internal/util.kt | 9 ++------ .../LightMemberOriginForCompiledElement.kt | 5 +++-- .../AbstractJsProtoComparisonTest.kt | 15 ++++++------- 11 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBufUtil.kt diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt index a75bd4ac7a3..47b3a8d618b 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt @@ -19,12 +19,16 @@ package org.jetbrains.kotlin.incremental import com.intellij.util.io.DataExternalizer import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl import org.jetbrains.kotlin.incremental.js.TranslationResultValue -import org.jetbrains.kotlin.incremental.storage.* +import org.jetbrains.kotlin.incremental.storage.BasicStringMap +import org.jetbrains.kotlin.incremental.storage.DirtyClassesFqNameMap +import org.jetbrains.kotlin.incremental.storage.SourceToFqNameMap +import org.jetbrains.kotlin.incremental.storage.StringToLongMapExternalizer 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.NameResolverImpl +import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull import org.jetbrains.kotlin.serialization.js.JsProtoBuf import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol import java.io.DataInput @@ -177,11 +181,7 @@ fun getProtoData(sourceFile: File, metadata: ByteArray): Map } proto.`package`.apply { - val packageFqName = if (hasExtension(JsProtoBuf.packageFqName)) { - nameResolver.getPackageFqName(getExtension(JsProtoBuf.packageFqName)) - } - else FqName.ROOT - + val packageFqName = getExtensionOrNull(JsProtoBuf.packageFqName)?.let(nameResolver::getPackageFqName) ?: FqName.ROOT val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt")) classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/inline/inlineUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/inline/inlineUtil.kt index cbe1b489e62..ac26c0cfd2e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/inline/inlineUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/inline/inlineUtil.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.serialization.Flags import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.TypeTable +import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull import org.jetbrains.kotlin.serialization.jvm.BitEncoding import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmMethodSignature @@ -62,8 +63,8 @@ private fun inlineAccessorsJvmNames(properties: List, nameRes } val inlineAccessors = arrayListOf() propertiesWithInlineAccessors.forEach { proto -> - if (proto.hasExtension(JvmProtoBuf.propertySignature)) { - val signature = proto.getExtension(JvmProtoBuf.propertySignature) + val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) + if (signature != null) { if (proto.hasGetterFlags() && Flags.IS_INLINE_ACCESSOR.get(proto.getterFlags)) { inlineAccessors.add(signature.getter) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/moduleName.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/moduleName.kt index 16eb5b50030..aab624d7499 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/moduleName.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/moduleName.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor +import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf fun getJvmModuleNameForDeserializedDescriptor(descriptor: DeclarationDescriptor): String? { @@ -20,8 +21,7 @@ fun getJvmModuleNameForDeserializedDescriptor(descriptor: DeclarationDescriptor) parent is DeserializedClassDescriptor -> { val classProto = parent.classProto val nameResolver = parent.c.nameResolver - return classProto.getExtension(JvmProtoBuf.classModuleName) - ?.takeIf { classProto.hasExtension(JvmProtoBuf.classModuleName) } + return classProto.getExtensionOrNull(JvmProtoBuf.classModuleName) ?.let(nameResolver::getString) ?: JvmAbi.DEFAULT_MODULE_NAME } @@ -30,8 +30,7 @@ fun getJvmModuleNameForDeserializedDescriptor(descriptor: DeclarationDescriptor) if (source is JvmPackagePartSource) { val packageProto = source.packageProto val nameResolver = source.nameResolver - return packageProto.getExtension(JvmProtoBuf.packageModuleName) - ?.takeIf { packageProto.hasExtension(JvmProtoBuf.packageModuleName) } + return packageProto.getExtensionOrNull(JvmProtoBuf.packageModuleName) ?.let(nameResolver::getString) ?: JvmAbi.DEFAULT_MODULE_NAME } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index 6b49b19f8ae..b15cecc7bac 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -311,9 +311,7 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader { MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null) } - proto is ProtoBuf.Property && proto.hasExtension(propertySignature) -> { - val signature = proto.getExtension(propertySignature) + proto is ProtoBuf.Property -> { + val signature = proto.getExtensionOrNull(propertySignature) ?: return null when (kind) { AnnotatedCallableKind.PROPERTY_GETTER -> MemberSignature.fromMethod(nameResolver, signature.getter) AnnotatedCallableKind.PROPERTY_SETTER -> MemberSignature.fromMethod(nameResolver, signature.setter) diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt index 6811eba6bf4..cf88228cc04 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt @@ -63,8 +63,7 @@ object JvmProtoBufUtil { nameResolver: NameResolver, typeTable: TypeTable ): String? { - val signature = - if (proto.hasExtension(JvmProtoBuf.methodSignature)) proto.getExtension(JvmProtoBuf.methodSignature) else null + val signature = proto.getExtensionOrNull(JvmProtoBuf.methodSignature) val name = if (signature != null && signature.hasName()) signature.name else proto.name val desc = if (signature != null && signature.hasDesc()) { nameResolver.getString(signature.desc) @@ -85,8 +84,7 @@ object JvmProtoBufUtil { nameResolver: NameResolver, typeTable: TypeTable ): String? { - val signature = - if (proto.hasExtension(JvmProtoBuf.constructorSignature)) proto.getExtension(JvmProtoBuf.constructorSignature) else null + val signature = proto.getExtensionOrNull(JvmProtoBuf.constructorSignature) val desc = if (signature != null && signature.hasDesc()) { nameResolver.getString(signature.desc) } @@ -103,8 +101,7 @@ object JvmProtoBufUtil { nameResolver: NameResolver, typeTable: TypeTable ): PropertySignature? { - val signature = - if (proto.hasExtension(JvmProtoBuf.propertySignature)) proto.getExtension(JvmProtoBuf.propertySignature) else return null + val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null val field = if (signature.hasField()) signature.field else null diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt index 04d41759443..c1ae90048d2 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt @@ -90,8 +90,7 @@ class AnnotationAndConstantLoaderImpl( proto: ProtoBuf.Property, expectedType: KotlinType ): ConstantValue<*>? { - if (!proto.hasExtension(protocol.compileTimeValue)) return null - val value = proto.getExtension(protocol.compileTimeValue) + val value = proto.getExtensionOrNull(protocol.compileTimeValue) ?: return null return deserializer.resolveValue(expectedType, value, container.nameResolver) } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBufUtil.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBufUtil.kt new file mode 100644 index 00000000000..07ae21900ac --- /dev/null +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBufUtil.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.serialization.deserialization + +import org.jetbrains.kotlin.protobuf.GeneratedMessageLite + +fun , T> GeneratedMessageLite.ExtendableMessage.getExtensionOrNull( + extension: GeneratedMessageLite.GeneratedExtension +): T? = if (hasExtension(extension)) getExtension(extension) else null diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt index eb30cf58137..5174b0b1285 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor +import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import java.lang.reflect.Constructor @@ -120,10 +121,8 @@ internal sealed class JvmPropertySignature { val containingDeclaration = descriptor.containingDeclaration if (descriptor.visibility == Visibilities.INTERNAL && containingDeclaration is DeserializedClassDescriptor) { val classProto = containingDeclaration.classProto - val moduleName = - if (classProto.hasExtension(JvmProtoBuf.classModuleName)) - nameResolver.getString(classProto.getExtension(JvmProtoBuf.classModuleName)) - else JvmAbi.DEFAULT_MODULE_NAME + val moduleName = classProto.getExtensionOrNull(JvmProtoBuf.classModuleName)?.let(nameResolver::getString) + ?: JvmAbi.DEFAULT_MODULE_NAME return "$" + NameUtils.sanitizeAsJavaIdentifier(moduleName) } if (descriptor.visibility == Visibilities.PRIVATE && containingDeclaration is PackageFragmentDescriptor) { @@ -210,14 +209,12 @@ internal object RuntimeTypeMapper { return when (property) { is DeserializedPropertyDescriptor -> { val proto = property.proto - if (!proto.hasExtension(JvmProtoBuf.propertySignature)) { - // If this property has no JVM signature, it must be from built-ins - throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " + - "No metadata found for $property") - } - JvmPropertySignature.KotlinProperty( - property, proto, proto.getExtension(JvmProtoBuf.propertySignature), property.nameResolver, property.typeTable - ) + val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) + ?: // If this property has no JVM signature, it must be from built-ins + throw KotlinReflectionInternalError( + "Reflection on built-in Kotlin types is not yet fully supported. No metadata found for $property" + ) + JvmPropertySignature.KotlinProperty(property, proto, signature, property.nameResolver, property.typeTable) } is JavaPropertyDescriptor -> { val element = (property.source as? JavaSourceElement)?.javaElement diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt index b288a7c08fc..64e33617fa0 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt @@ -28,10 +28,7 @@ import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.serialization.ProtoBuf -import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext -import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer -import org.jetbrains.kotlin.serialization.deserialization.NameResolver -import org.jetbrains.kotlin.serialization.deserialization.TypeTable +import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.descriptors.VersionRequirementTable import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil @@ -139,9 +136,7 @@ internal val ReflectKotlinClass.packageModuleName: String? val (nameResolver, proto) = JvmProtoBufUtil.readPackageDataFrom(header.data!!, header.strings!!) // If no packageModuleName extension is written, the name is assumed to be JvmAbi.DEFAULT_MODULE_NAME // (see JvmSerializerExtension.serializePackage) - if (proto.hasExtension(JvmProtoBuf.packageModuleName)) - nameResolver.getString(proto.getExtension(JvmProtoBuf.packageModuleName)) - else JvmAbi.DEFAULT_MODULE_NAME + proto.getExtensionOrNull(JvmProtoBuf.packageModuleName)?.let(nameResolver::getString) ?: JvmAbi.DEFAULT_MODULE_NAME } KotlinClassHeader.Kind.MULTIFILE_CLASS -> { val partName = header.multifilePartNames.firstOrNull() ?: return null diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LightMemberOriginForCompiledElement.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LightMemberOriginForCompiledElement.kt index 4974a1ba59a..f0771715955 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LightMemberOriginForCompiledElement.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LightMemberOriginForCompiledElement.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor +import org.jetbrains.kotlin.serialization.deserialization.getExtensionOrNull import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil @@ -164,8 +165,8 @@ private object ByJvmSignatureIndexer : DecompiledTextIndexer } proto.`package`.apply { - val packageFqName = if (hasExtension(JsProtoBuf.packageFqName)) { - nameResolver.getPackageFqName(getExtension(JsProtoBuf.packageFqName)) - } - else FqName.ROOT - + val packageFqName = getExtensionOrNull(JsProtoBuf.packageFqName)?.let(nameResolver::getPackageFqName) ?: FqName.ROOT val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt")) classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName) } return classes -} \ No newline at end of file +}