Refactor ClassId.getOuterClassId, make it nullable

This commit is contained in:
Alexander Udalov
2017-02-22 14:36:58 +03:00
parent 21de67cac1
commit 86994f81c3
6 changed files with 17 additions and 14 deletions
@@ -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() {
@@ -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
@@ -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 ->
@@ -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<Int> {
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)
}
@@ -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
}
@@ -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