From 86994f81c30a7c758f3d5ddd2f5871914b18d102 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 22 Feb 2017 14:36:58 +0300 Subject: [PATCH] Refactor ClassId.getOuterClassId, make it nullable --- .../src/org/jetbrains/kotlin/name/ClassId.java | 6 ++++-- .../serialization/deserialization/ClassDeserializer.kt | 5 +++-- .../deserialization/MetadataPackageFragmentProvider.kt | 2 +- .../serialization/deserialization/NotFoundClasses.kt | 8 ++++---- .../serialization/deserialization/findClassInModule.kt | 3 +-- .../idea/decompiler/stubBuilder/ClassClsStubBuilder.kt | 7 ++++--- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java b/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java index 54952802089..547cd70cf3b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java +++ b/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.name; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A class name which is used to uniquely identify a Kotlin class. @@ -73,9 +74,10 @@ public final class ClassId { return new ClassId(getPackageFqName(), relativeClassName.child(name), local); } - @NotNull + @Nullable public ClassId getOuterClassId() { - return new ClassId(getPackageFqName(), relativeClassName.parent(), local); + FqName parent = relativeClassName.parent(); + return parent.isRoot() ? null : new ClassId(getPackageFqName(), parent, local); } public boolean isNestedClass() { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt index 20160369c98..89fad66b26f 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt @@ -44,8 +44,9 @@ class ClassDeserializer(private val components: DeserializationComponents) { ?: return null val (nameResolver, classProto) = classData - val outerContext = if (classId.isNestedClass) { - val outerClass = deserializeClass(classId.outerClassId) as? DeserializedClassDescriptor ?: return null + val outerClassId = classId.outerClassId + val outerContext = if (outerClassId != null) { + val outerClass = deserializeClass(outerClassId) as? DeserializedClassDescriptor ?: return null // Find the outer class first and check if he knows anything about the nested class we're looking for if (!outerClass.hasNestedClass(classId.shortClassName)) return null diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt index 863d3816453..a9b71164923 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt @@ -73,7 +73,7 @@ class MetadataPackageFragment( private val finder: KotlinMetadataFinder ) : DeserializedPackageFragment(fqName, storageManager, module) { override val classDataFinder = ClassDataFinder { classId -> - val topLevelClassId = generateSequence(classId) { classId -> if (classId.isNestedClass) classId.outerClassId else null }.last() + val topLevelClassId = generateSequence(classId, ClassId::getOuterClassId).last() val stream = finder.findMetadata(topLevelClassId) ?: return@ClassDataFinder null val (message, nameResolver) = readProto(stream) message.class_List.firstOrNull { classProto -> diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt index a7fb176fe72..e9dd3d1afcf 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt @@ -70,9 +70,9 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo throw UnsupportedOperationException("Unresolved local class: $classId") } - val container = - if (classId.isNestedClass) getOrCreateClass(classId.outerClassId, typeParametersCount.drop(1)) - else packageFragments(classId.packageFqName) + val container = classId.outerClassId?.let { outerClassId -> + getOrCreateClass(outerClassId, typeParametersCount.drop(1)) + } ?: packageFragments(classId.packageFqName) // Treat a class with a nested ClassId as inner for simplicity, otherwise the outer type cannot have generic arguments val isInner = classId.isNestedClass @@ -182,7 +182,7 @@ private fun createTypeParameters( private fun computeTypeParametersCount(classId: ClassId, proto: ProtoBuf.Type, typeTable: TypeTable): List { val typeParametersCount = generateSequence(proto) { it.outerType(typeTable) }.map { it.argumentCount }.toMutableList() - val classNestingLevel = generateSequence(classId) { if (it.isNestedClass) it.outerClassId else null }.count() + val classNestingLevel = generateSequence(classId, ClassId::getOuterClassId).count() while (typeParametersCount.size < classNestingLevel) { typeParametersCount.add(0) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/findClassInModule.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/findClassInModule.kt index 2767a9f4a8a..de9e4efb647 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/findClassInModule.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/findClassInModule.kt @@ -40,7 +40,7 @@ fun ModuleDescriptor.findNonGenericClassAcrossDependencies(classId: ClassId, not if (existingClass != null) return existingClass // Take a list of N zeros, where N is the number of class names in the given ClassId - val typeParametersCount = generateSequence(classId) { if (it.isNestedClass) it.outerClassId else null }.map { 0 }.toList() + val typeParametersCount = generateSequence(classId, ClassId::getOuterClassId).map { 0 }.toList() return notFoundClasses.getClass(classId, typeParametersCount).declarationDescriptor as ClassDescriptor } @@ -62,4 +62,3 @@ fun ModuleDescriptor.findTypeAliasAcrossModuleDependencies(classId: ClassId): Ty val lastName = segments[lastNameIndex] return currentClass.unsubstitutedMemberScope.getContributedClassifier(lastName, NoLookupLocation.FROM_DESERIALIZATION) as? TypeAliasDescriptor } - diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt index 44b03841bb1..09bbfd92dd4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt @@ -253,9 +253,10 @@ private class ClassClsStubBuilder( "Root file: ${rootFile.canonicalPath}\n" + "Dir: ${rootFile.parent.canonicalPath}\n" + "Children:\n" + - "${rootFile.parent.children.sortedBy { it.name }.joinToString(separator = "\n") { - it.name + " (valid: ${it.isValid})" - } }") + rootFile.parent.children.sortedBy { it.name }.joinToString(separator = "\n") { + "${it.name} (valid: ${it.isValid})" + } + ) return } val (nameResolver, classProto) = classDataWithSource.classData