Introduce PossiblyInnerType class

Use it when rendering inner types, similar logic will be used in different subsystems
This commit is contained in:
Denis Zharkov
2015-11-10 15:16:19 +03:00
parent 9c8ad9e442
commit eea898abb5
2 changed files with 48 additions and 23 deletions
@@ -16,6 +16,9 @@
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
fun ClassDescriptor.computeConstructorTypeParameters(): List<TypeParameterDescriptor> {
val declaredParameters = declaredTypeParameters
@@ -44,3 +47,30 @@ private class CapturedTypeParameterDescriptor(
override fun getIndex() = declaredTypeParametersCount + originalDescriptor.index
override fun toString() = originalDescriptor.toString() + "[inner-copy]"
}
class PossiblyInnerType(
val classDescriptor: ClassDescriptor,
val arguments: List<TypeProjection>,
val outerType: PossiblyInnerType?) {
fun segments(): List<PossiblyInnerType> = outerType?.segments().orEmpty() + this
}
fun KotlinType.buildPossiblyInnerType(): PossiblyInnerType?
= buildPossiblyInnerType(constructor.declarationDescriptor as? ClassDescriptor, 0)
private fun KotlinType.buildPossiblyInnerType(classDescriptor: ClassDescriptor?, index: Int): PossiblyInnerType? {
if (classDescriptor == null) return null
val toIndex = classDescriptor.declaredTypeParameters.size + index
val argumentsSubList = arguments.subList(index, toIndex)
if (!classDescriptor.isInner) {
assert(toIndex == arguments.size) { "${arguments.size - toIndex} trailing arguments were found in $this type" }
return PossiblyInnerType(classDescriptor, argumentsSubList, null)
}
return PossiblyInnerType(
classDescriptor, argumentsSubList,
buildPossiblyInnerType(classDescriptor.containingDeclaration as? ClassDescriptor, toIndex))
}
@@ -246,15 +246,6 @@ internal class DescriptorRendererImpl(
}.toString()
}
private fun renderTypeArgumentsForTypeConstructor(
type: KotlinType,
typeConstructor: TypeConstructor
): String {
return type.arguments.zip(type.constructor.parameters).filter {
(it.second.original.containingDeclaration as? ClassifierDescriptor)?.typeConstructor == typeConstructor
}.map { it.first }.let { renderTypeArguments(it) }
}
private fun renderDefaultType(type: KotlinType): String {
val sb = StringBuilder()
@@ -278,27 +269,31 @@ internal class DescriptorRendererImpl(
type: KotlinType,
typeConstructor: TypeConstructor = type.constructor
): String =
StringBuilder().apply {
val classDescriptor = typeConstructor.declarationDescriptor as? ClassDescriptor
buildString {
if (classDescriptor is MissingDependencyErrorClass) {
val possiblyInnerType = type.buildPossiblyInnerType()
if (possiblyInnerType == null) {
append(renderTypeConstructor(typeConstructor))
append(renderTypeArguments(type.arguments))
return@apply
return@buildString
}
if (classDescriptor != null && classDescriptor.isInner) {
append(renderTypeConstructorAndArguments(type, (classDescriptor.containingDeclaration as ClassDescriptor).typeConstructor))
append('.')
append(renderName(classDescriptor.name))
}
else {
append(renderTypeConstructor(typeConstructor))
}
append(renderTypeArgumentsForTypeConstructor(type, typeConstructor))
append(renderPossiblyInnerType(possiblyInnerType))
}.toString()
private fun renderPossiblyInnerType(possiblyInnerType: PossiblyInnerType): String =
buildString {
possiblyInnerType.outerType?.let {
append(renderPossiblyInnerType(it))
append('.')
append(renderName(possiblyInnerType.classDescriptor.name))
} ?: append(renderTypeConstructor(possiblyInnerType.classDescriptor.typeConstructor))
append(renderTypeArguments(possiblyInnerType.arguments))
}
override fun renderTypeConstructor(typeConstructor: TypeConstructor): String {
val cd = typeConstructor.getDeclarationDescriptor()
return when (cd) {