From eea898abb532ee7ec7facde95bc9af68da3208ee Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 10 Nov 2015 15:16:19 +0300 Subject: [PATCH] Introduce PossiblyInnerType class Use it when rendering inner types, similar logic will be used in different subsystems --- .../kotlin/descriptors/typeParameterUtils.kt | 30 ++++++++++++++ .../kotlin/renderer/DescriptorRendererImpl.kt | 41 ++++++++----------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt index 788d6316378..169419e8421 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt @@ -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 { 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, + val outerType: PossiblyInnerType?) { + fun segments(): List = 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)) +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index 40c239cc611..188dbda49c1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -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) {