DescriptorRender: cleanup code

This commit is contained in:
Dmitry Gridin
2019-07-26 15:16:30 +03:00
parent 80b09b9a08
commit a2f937e282
3 changed files with 197 additions and 157 deletions
@@ -44,8 +44,8 @@ abstract class DescriptorRenderer {
abstract fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean): String abstract fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean): String
fun renderFunctionParameters(functionDescriptor: FunctionDescriptor): String fun renderFunctionParameters(functionDescriptor: FunctionDescriptor): String =
= renderValueParameters(functionDescriptor.valueParameters, functionDescriptor.hasSynthesizedParameterNames()) renderValueParameters(functionDescriptor.valueParameters, functionDescriptor.hasSynthesizedParameterNames())
abstract fun renderName(name: Name, rootRenderedElement: Boolean): String abstract fun renderName(name: Name, rootRenderedElement: Boolean): String
@@ -55,7 +55,13 @@ abstract class DescriptorRenderer {
fun appendBeforeValueParameters(parameterCount: Int, builder: StringBuilder) fun appendBeforeValueParameters(parameterCount: Int, builder: StringBuilder)
fun appendAfterValueParameters(parameterCount: Int, builder: StringBuilder) fun appendAfterValueParameters(parameterCount: Int, builder: StringBuilder)
fun appendBeforeValueParameter(parameter: ValueParameterDescriptor, parameterIndex: Int, parameterCount: Int, builder: StringBuilder) fun appendBeforeValueParameter(
parameter: ValueParameterDescriptor,
parameterIndex: Int,
parameterCount: Int,
builder: StringBuilder
)
fun appendAfterValueParameter(parameter: ValueParameterDescriptor, parameterIndex: Int, parameterCount: Int, builder: StringBuilder) fun appendAfterValueParameter(parameter: ValueParameterDescriptor, parameterIndex: Int, parameterCount: Int, builder: StringBuilder)
object DEFAULT : ValueParametersHandler { object DEFAULT : ValueParametersHandler {
@@ -67,10 +73,20 @@ abstract class DescriptorRenderer {
builder.append(")") builder.append(")")
} }
override fun appendBeforeValueParameter(parameter: ValueParameterDescriptor, parameterIndex: Int, parameterCount: Int, builder: StringBuilder) { override fun appendBeforeValueParameter(
parameter: ValueParameterDescriptor,
parameterIndex: Int,
parameterCount: Int,
builder: StringBuilder
) {
} }
override fun appendAfterValueParameter(parameter: ValueParameterDescriptor, parameterIndex: Int, parameterCount: Int, builder: StringBuilder) { override fun appendAfterValueParameter(
parameter: ValueParameterDescriptor,
parameterIndex: Int,
parameterCount: Int,
builder: StringBuilder
) {
if (parameterIndex != parameterCount - 1) { if (parameterIndex != parameterCount - 1) {
builder.append(", ") builder.append(", ")
} }
@@ -86,28 +102,33 @@ abstract class DescriptorRenderer {
return DescriptorRendererImpl(options) return DescriptorRendererImpl(options)
} }
@JvmField val COMPACT_WITH_MODIFIERS: DescriptorRenderer = withOptions { @JvmField
val COMPACT_WITH_MODIFIERS: DescriptorRenderer = withOptions {
withDefinedIn = false withDefinedIn = false
} }
@JvmField val COMPACT: DescriptorRenderer = withOptions { @JvmField
val COMPACT: DescriptorRenderer = withOptions {
withDefinedIn = false withDefinedIn = false
modifiers = emptySet() modifiers = emptySet()
} }
@JvmField val COMPACT_WITHOUT_SUPERTYPES: DescriptorRenderer = withOptions { @JvmField
val COMPACT_WITHOUT_SUPERTYPES: DescriptorRenderer = withOptions {
withDefinedIn = false withDefinedIn = false
modifiers = emptySet() modifiers = emptySet()
withoutSuperTypes = true withoutSuperTypes = true
} }
@JvmField val COMPACT_WITH_SHORT_TYPES: DescriptorRenderer = withOptions { @JvmField
val COMPACT_WITH_SHORT_TYPES: DescriptorRenderer = withOptions {
modifiers = emptySet() modifiers = emptySet()
classifierNamePolicy = ClassifierNamePolicy.SHORT classifierNamePolicy = ClassifierNamePolicy.SHORT
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED parameterNameRenderingPolicy = ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED
} }
@JvmField val ONLY_NAMES_WITH_SHORT_TYPES: DescriptorRenderer = withOptions { @JvmField
val ONLY_NAMES_WITH_SHORT_TYPES: DescriptorRenderer = withOptions {
withDefinedIn = false withDefinedIn = false
modifiers = emptySet() modifiers = emptySet()
classifierNamePolicy = ClassifierNamePolicy.SHORT classifierNamePolicy = ClassifierNamePolicy.SHORT
@@ -119,55 +140,57 @@ abstract class DescriptorRenderer {
startFromName = true startFromName = true
} }
@JvmField val FQ_NAMES_IN_TYPES: DescriptorRenderer = withOptions { @JvmField
val FQ_NAMES_IN_TYPES: DescriptorRenderer = withOptions {
modifiers = DescriptorRendererModifier.ALL modifiers = DescriptorRendererModifier.ALL
} }
@JvmField val SHORT_NAMES_IN_TYPES: DescriptorRenderer = withOptions { @JvmField
val SHORT_NAMES_IN_TYPES: DescriptorRenderer = withOptions {
classifierNamePolicy = ClassifierNamePolicy.SHORT classifierNamePolicy = ClassifierNamePolicy.SHORT
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED parameterNameRenderingPolicy = ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED
} }
@JvmField val DEBUG_TEXT: DescriptorRenderer = withOptions { @JvmField
val DEBUG_TEXT: DescriptorRenderer = withOptions {
debugMode = true debugMode = true
classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED
modifiers = DescriptorRendererModifier.ALL modifiers = DescriptorRendererModifier.ALL
} }
@JvmField val HTML: DescriptorRenderer = withOptions { @JvmField
val HTML: DescriptorRenderer = withOptions {
textFormat = RenderingFormat.HTML textFormat = RenderingFormat.HTML
modifiers = DescriptorRendererModifier.ALL modifiers = DescriptorRendererModifier.ALL
} }
fun getClassifierKindPrefix(classifier: ClassifierDescriptorWithTypeParameters): String = fun getClassifierKindPrefix(classifier: ClassifierDescriptorWithTypeParameters): String = when (classifier) {
when (classifier) { is TypeAliasDescriptor ->
is TypeAliasDescriptor -> "typealias"
"typealias" is ClassDescriptor ->
is ClassDescriptor -> if (classifier.isCompanionObject) {
if (classifier.isCompanionObject) { "companion object"
"companion object" } else when (classifier.kind) {
} ClassKind.CLASS -> "class"
else when (classifier.kind) { ClassKind.INTERFACE -> "interface"
ClassKind.CLASS -> "class" ClassKind.ENUM_CLASS -> "enum class"
ClassKind.INTERFACE -> "interface" ClassKind.OBJECT -> "object"
ClassKind.ENUM_CLASS -> "enum class" ClassKind.ANNOTATION_CLASS -> "annotation class"
ClassKind.OBJECT -> "object" ClassKind.ENUM_ENTRY -> "enum entry"
ClassKind.ANNOTATION_CLASS -> "annotation class"
ClassKind.ENUM_ENTRY -> "enum entry"
}
else ->
throw AssertionError("Unexpected classifier: $classifier")
} }
else ->
throw AssertionError("Unexpected classifier: $classifier")
}
} }
} }
enum class AnnotationArgumentsRenderingPolicy( enum class AnnotationArgumentsRenderingPolicy(
val includeAnnotationArguments: Boolean = false, val includeAnnotationArguments: Boolean = false,
val includeEmptyAnnotationArguments: Boolean = false val includeEmptyAnnotationArguments: Boolean = false
) { ) {
NO_ARGUMENTS(), NO_ARGUMENTS,
UNLESS_EMPTY(true), UNLESS_EMPTY(true),
ALWAYS_PARENTHESIZED(true, true) ALWAYS_PARENTHESIZED(includeAnnotationArguments = true, includeEmptyAnnotationArguments = true)
} }
interface DescriptorRendererOptions { interface DescriptorRendererOptions {
@@ -227,8 +250,8 @@ interface DescriptorRendererOptions {
object ExcludedTypeAnnotations { object ExcludedTypeAnnotations {
val internalAnnotationsForResolve = setOf( val internalAnnotationsForResolve = setOf(
FqName("kotlin.internal.NoInfer"), FqName("kotlin.internal.NoInfer"),
FqName("kotlin.internal.Exact") FqName("kotlin.internal.Exact")
) )
} }
@@ -278,9 +301,9 @@ enum class DescriptorRendererModifier(val includeByDefault: Boolean) {
companion object { companion object {
@JvmField @JvmField
val DEFAULTS = DescriptorRendererModifier.values().filter { it.includeByDefault }.toSet() val DEFAULTS = values().filter { it.includeByDefault }.toSet()
@JvmField @JvmField
val ALL = DescriptorRendererModifier.values().toSet() val ALL = values().toSet()
} }
} }
@@ -28,35 +28,32 @@ import org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
import java.util.* import java.util.*
internal class DescriptorRendererImpl( internal class DescriptorRendererImpl(
val options: DescriptorRendererOptionsImpl val options: DescriptorRendererOptionsImpl
) : DescriptorRenderer(), DescriptorRendererOptions by options/* this gives access to options without qualifier */ { ) : DescriptorRenderer(), DescriptorRendererOptions by options/* this gives access to options without qualifier */ {
init { init {
assert(options.isLocked) assert(options.isLocked)
} }
private val functionTypeAnnotationsRenderer: DescriptorRendererImpl by lazy { private val functionTypeAnnotationsRenderer: DescriptorRendererImpl by lazy {
this.withOptions { withOptions {
excludedTypeAnnotationClasses += listOf(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) excludedTypeAnnotationClasses += listOf(KotlinBuiltIns.FQ_NAMES.extensionFunctionType)
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.ALWAYS_PARENTHESIZED annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.ALWAYS_PARENTHESIZED
} as DescriptorRendererImpl } as DescriptorRendererImpl
} }
private val functionTypeParameterTypesRenderer: DescriptorRenderer by lazy { private val functionTypeParameterTypesRenderer: DescriptorRenderer by lazy {
this.withOptions { excludedTypeAnnotationClasses += listOf(KotlinBuiltIns.FQ_NAMES.parameterName) } withOptions { excludedTypeAnnotationClasses += listOf(KotlinBuiltIns.FQ_NAMES.parameterName) }
} }
/* FORMATTING */ /* FORMATTING */
private fun renderKeyword(keyword: String): String { private fun renderKeyword(keyword: String): String = when (textFormat) {
when (textFormat) { RenderingFormat.PLAIN -> keyword
RenderingFormat.PLAIN -> return keyword RenderingFormat.HTML -> if (boldOnlyForNamesInHtml) keyword else "<b>$keyword</b>"
RenderingFormat.HTML -> return if (boldOnlyForNamesInHtml) keyword else "<b>$keyword</b>"
}
} }
private fun renderError(keyword: String): String { private fun renderError(keyword: String): String = when (textFormat) {
when (textFormat) { RenderingFormat.PLAIN -> keyword
RenderingFormat.PLAIN -> return keyword RenderingFormat.HTML -> "<font color=red><b>$keyword</b></font>"
RenderingFormat.HTML -> return "<font color=red><b>$keyword</b></font>"
}
} }
private fun escape(string: String) = textFormat.escape(string) private fun escape(string: String) = textFormat.escape(string)
@@ -64,27 +61,23 @@ internal class DescriptorRendererImpl(
private fun lt() = escape("<") private fun lt() = escape("<")
private fun gt() = escape(">") private fun gt() = escape(">")
private fun arrow(): String { private fun arrow(): String = when (textFormat) {
return when (textFormat) { RenderingFormat.PLAIN -> escape("->")
RenderingFormat.PLAIN -> escape("->") RenderingFormat.HTML -> "&rarr;"
RenderingFormat.HTML -> "&rarr;"
}
} }
override fun renderMessage(message: String): String { override fun renderMessage(message: String): String = when (textFormat) {
return when (textFormat) { RenderingFormat.PLAIN -> message
RenderingFormat.PLAIN -> message RenderingFormat.HTML -> "<i>$message</i>"
RenderingFormat.HTML -> "<i>$message</i>"
}
} }
/* NAMES RENDERING */ /* NAMES RENDERING */
override fun renderName(name: Name, rootRenderedElement: Boolean): String { override fun renderName(name: Name, rootRenderedElement: Boolean): String {
val escaped = escape(name.render()) val escaped = escape(name.render())
if (boldOnlyForNamesInHtml && textFormat == RenderingFormat.HTML && rootRenderedElement) { return if (boldOnlyForNamesInHtml && textFormat == RenderingFormat.HTML && rootRenderedElement) {
return "<b>$escaped</b>" "<b>$escaped</b>"
} } else
return escaped escaped
} }
private fun renderName(descriptor: DeclarationDescriptor, builder: StringBuilder, rootRenderedElement: Boolean) { private fun renderName(descriptor: DeclarationDescriptor, builder: StringBuilder, rootRenderedElement: Boolean) {
@@ -113,12 +106,10 @@ internal class DescriptorRendererImpl(
private fun renderFqName(pathSegments: List<Name>) = escape(org.jetbrains.kotlin.renderer.renderFqName(pathSegments)) private fun renderFqName(pathSegments: List<Name>) = escape(org.jetbrains.kotlin.renderer.renderFqName(pathSegments))
override fun renderClassifierName(klass: ClassifierDescriptor): String { override fun renderClassifierName(klass: ClassifierDescriptor): String = if (ErrorUtils.isError(klass)) {
if (ErrorUtils.isError(klass)) { klass.typeConstructor.toString()
return klass.typeConstructor.toString() } else
} classifierNamePolicy.renderClassifier(klass, this)
return classifierNamePolicy.renderClassifier(klass, this)
}
/* TYPES RENDERING */ /* TYPES RENDERING */
override fun renderType(type: KotlinType): String = buildString { override fun renderType(type: KotlinType): String = buildString {
@@ -160,8 +151,7 @@ internal class DescriptorRendererImpl(
append("<Not computed yet>") append("<Not computed yet>")
return return
} }
val unwrappedType = type.unwrap() when (val unwrappedType = type.unwrap()) {
when (unwrappedType) {
is FlexibleType -> append(unwrappedType.render(this@DescriptorRendererImpl, this@DescriptorRendererImpl)) is FlexibleType -> append(unwrappedType.render(this@DescriptorRendererImpl, this@DescriptorRendererImpl))
is SimpleType -> renderSimpleType(unwrappedType) is SimpleType -> renderSimpleType(unwrappedType)
} }
@@ -175,8 +165,7 @@ internal class DescriptorRendererImpl(
if (ErrorUtils.isUninferredParameter(type)) { if (ErrorUtils.isUninferredParameter(type)) {
if (uninferredTypeParameterAsName) { if (uninferredTypeParameterAsName) {
append(renderError((type.constructor as UninferredParameterTypeConstructor).typeParameterDescriptor.name.toString())) append(renderError((type.constructor as UninferredParameterTypeConstructor).typeParameterDescriptor.name.toString()))
} } else {
else {
append("???") append("???")
} }
return return
@@ -188,8 +177,7 @@ internal class DescriptorRendererImpl(
} }
if (shouldRenderAsPrettyFunctionType(type)) { if (shouldRenderAsPrettyFunctionType(type)) {
renderFunctionType(type) renderFunctionType(type)
} } else {
else {
renderDefaultType(type) renderDefaultType(type)
} }
} }
@@ -204,33 +192,49 @@ internal class DescriptorRendererImpl(
// the case of complex type, e.g. (() -> Unit)? // the case of complex type, e.g. (() -> Unit)?
return "($lowerRendered)!" return "($lowerRendered)!"
} }
return lowerRendered + "!" return "$lowerRendered!"
} }
val kotlinCollectionsPrefix = classifierNamePolicy.renderClassifier(builtIns.collection, this).substringBefore("Collection") val kotlinCollectionsPrefix = classifierNamePolicy.renderClassifier(builtIns.collection, this).substringBefore("Collection")
val mutablePrefix = "Mutable" val mutablePrefix = "Mutable"
// java.util.List<Foo> -> (Mutable)List<Foo!>! // java.util.List<Foo> -> (Mutable)List<Foo!>!
val simpleCollection = replacePrefixes(lowerRendered, kotlinCollectionsPrefix + mutablePrefix, upperRendered, kotlinCollectionsPrefix, "$kotlinCollectionsPrefix($mutablePrefix)") val simpleCollection = replacePrefixes(
lowerRendered,
kotlinCollectionsPrefix + mutablePrefix,
upperRendered,
kotlinCollectionsPrefix,
"$kotlinCollectionsPrefix($mutablePrefix)"
)
if (simpleCollection != null) return simpleCollection if (simpleCollection != null) return simpleCollection
// java.util.Map.Entry<Foo, Bar> -> (Mutable)Map.(Mutable)Entry<Foo!, Bar!>! // java.util.Map.Entry<Foo, Bar> -> (Mutable)Map.(Mutable)Entry<Foo!, Bar!>!
val mutableEntry = replacePrefixes(lowerRendered, kotlinCollectionsPrefix + "MutableMap.MutableEntry", upperRendered, kotlinCollectionsPrefix + "Map.Entry", kotlinCollectionsPrefix + "(Mutable)Map.(Mutable)Entry") val mutableEntry = replacePrefixes(
lowerRendered,
kotlinCollectionsPrefix + "MutableMap.MutableEntry",
upperRendered,
kotlinCollectionsPrefix + "Map.Entry",
"$kotlinCollectionsPrefix(Mutable)Map.(Mutable)Entry"
)
if (mutableEntry != null) return mutableEntry if (mutableEntry != null) return mutableEntry
val kotlinPrefix = classifierNamePolicy.renderClassifier(builtIns.array, this).substringBefore("Array") val kotlinPrefix = classifierNamePolicy.renderClassifier(builtIns.array, this).substringBefore("Array")
// Foo[] -> Array<(out) Foo!>! // Foo[] -> Array<(out) Foo!>!
val array = replacePrefixes(lowerRendered, kotlinPrefix + escape("Array<"), upperRendered, kotlinPrefix + escape("Array<out "), kotlinPrefix + escape("Array<(out) ")) val array = replacePrefixes(
lowerRendered,
kotlinPrefix + escape("Array<"),
upperRendered,
kotlinPrefix + escape("Array<out "),
kotlinPrefix + escape("Array<(out) ")
)
if (array != null) return array if (array != null) return array
return "($lowerRendered..$upperRendered)" return "($lowerRendered..$upperRendered)"
} }
override fun renderTypeArguments(typeArguments: List<TypeProjection>): String { override fun renderTypeArguments(typeArguments: List<TypeProjection>): String = if (typeArguments.isEmpty()) ""
if (typeArguments.isEmpty()) return "" else buildString {
return buildString { append(lt())
append(lt()) this.appendTypeProjections(typeArguments)
this.appendTypeProjections(typeArguments) append(gt())
append(gt())
}
} }
private fun StringBuilder.renderDefaultType(type: KotlinType) { private fun StringBuilder.renderDefaultType(type: KotlinType) {
@@ -243,8 +247,7 @@ internal class DescriptorRendererImpl(
append(type.constructor.toString()) // Debug name of an error type is more informative append(type.constructor.toString()) // Debug name of an error type is more informative
} }
append(renderTypeArguments(type.arguments)) append(renderTypeArguments(type.arguments))
} } else {
else {
renderTypeConstructorAndArguments(type) renderTypeConstructorAndArguments(type)
} }
@@ -258,8 +261,8 @@ internal class DescriptorRendererImpl(
} }
private fun StringBuilder.renderTypeConstructorAndArguments( private fun StringBuilder.renderTypeConstructorAndArguments(
type: KotlinType, type: KotlinType,
typeConstructor: TypeConstructor = type.constructor typeConstructor: TypeConstructor = type.constructor
) { ) {
val possiblyInnerType = type.buildPossiblyInnerType() val possiblyInnerType = type.buildPossiblyInnerType()
if (possiblyInnerType == null) { if (possiblyInnerType == null) {
@@ -281,13 +284,10 @@ internal class DescriptorRendererImpl(
append(renderTypeArguments(possiblyInnerType.arguments)) append(renderTypeArguments(possiblyInnerType.arguments))
} }
override fun renderTypeConstructor(typeConstructor: TypeConstructor): String { override fun renderTypeConstructor(typeConstructor: TypeConstructor): String = when (val cd = typeConstructor.declarationDescriptor) {
val cd = typeConstructor.declarationDescriptor is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd)
return when (cd) { null -> typeConstructor.toString()
is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd) else -> error("Unexpected classifier: " + cd::class.java)
null -> typeConstructor.toString()
else -> error("Unexpected classifier: " + cd::class.java)
}
} }
override fun renderTypeProjection(typeProjection: TypeProjection) = buildString { override fun renderTypeProjection(typeProjection: TypeProjection) = buildString {
@@ -298,8 +298,7 @@ internal class DescriptorRendererImpl(
typeProjections.joinTo(this, ", ") { typeProjections.joinTo(this, ", ") {
if (it.isStarProjection) { if (it.isStarProjection) {
"*" "*"
} } else {
else {
val type = renderType(it.type) val type = renderType(it.type)
if (it.projectionKind == Variance.INVARIANT) type else "${it.projectionKind} $type" if (it.projectionKind == Variance.INVARIANT) type else "${it.projectionKind} $type"
} }
@@ -322,8 +321,7 @@ internal class DescriptorRendererImpl(
if (needParenthesis) { if (needParenthesis) {
if (isSuspend) { if (isSuspend) {
insert(lengthBefore, '(') insert(lengthBefore, '(')
} } else {
else {
if (hasAnnotations) { if (hasAnnotations) {
assert(last() == ' ') assert(last() == ' ')
if (get(lastIndex - 1) != ')') { if (get(lastIndex - 1) != ')') {
@@ -340,7 +338,7 @@ internal class DescriptorRendererImpl(
if (receiverType != null) { if (receiverType != null) {
val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable || val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable ||
receiverType.hasModifiersOrAnnotations() receiverType.hasModifiersOrAnnotations()
if (surroundReceiver) { if (surroundReceiver) {
append("(") append("(")
} }
@@ -375,7 +373,7 @@ internal class DescriptorRendererImpl(
} }
private fun KotlinType.hasModifiersOrAnnotations() = private fun KotlinType.hasModifiersOrAnnotations() =
isSuspendFunctionType || !annotations.isEmpty() isSuspendFunctionType || !annotations.isEmpty()
/* METHODS FOR ALL KINDS OF DESCRIPTORS */ /* METHODS FOR ALL KINDS OF DESCRIPTORS */
private fun StringBuilder.appendDefinedIn(descriptor: DeclarationDescriptor) { private fun StringBuilder.appendDefinedIn(descriptor: DeclarationDescriptor) {
@@ -395,7 +393,8 @@ internal class DescriptorRendererImpl(
if (withSourceFileForTopLevel && if (withSourceFileForTopLevel &&
containingDeclaration is PackageFragmentDescriptor && containingDeclaration is PackageFragmentDescriptor &&
descriptor is DeclarationDescriptorWithSource) { descriptor is DeclarationDescriptorWithSource
) {
descriptor.source.containingFile.name?.let { sourceFileName -> descriptor.source.containingFile.name?.let { sourceFileName ->
append(" ").append(renderMessage("in file")).append(" ").append(sourceFileName) append(" ").append(renderMessage("in file")).append(" ").append(sourceFileName)
} }
@@ -447,14 +446,14 @@ internal class DescriptorRendererImpl(
val allValueArguments = descriptor.allValueArguments val allValueArguments = descriptor.allValueArguments
val classDescriptor = if (renderDefaultAnnotationArguments) descriptor.annotationClass else null val classDescriptor = if (renderDefaultAnnotationArguments) descriptor.annotationClass else null
val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters
?.filter { it.declaresDefaultValue() } ?.filter { it.declaresDefaultValue() }
?.map { it.name } ?.map { it.name }
.orEmpty() .orEmpty()
val defaultList = parameterDescriptorsWithDefaultValue.filter { it !in allValueArguments }.map { "${it.asString()} = ..." } val defaultList = parameterDescriptorsWithDefaultValue.filter { it !in allValueArguments }.map { "${it.asString()} = ..." }
val argumentList = allValueArguments.entries val argumentList = allValueArguments.entries
.map { (name, value) -> .map { (name, value) ->
"${name.asString()} = ${if (name !in parameterDescriptorsWithDefaultValue) renderConstant(value) else "..."}" "${name.asString()} = ${if (name !in parameterDescriptorsWithDefaultValue) renderConstant(value) else "..."}"
} }
return (defaultList + argumentList).sorted() return (defaultList + argumentList).sorted()
} }
@@ -500,16 +499,17 @@ internal class DescriptorRendererImpl(
if (this.overriddenDescriptors.isNotEmpty()) { if (this.overriddenDescriptors.isNotEmpty()) {
if (containingClassDescriptor.modality != Modality.FINAL) return Modality.OPEN if (containingClassDescriptor.modality != Modality.FINAL) return Modality.OPEN
} }
if (containingClassDescriptor.kind == ClassKind.INTERFACE && this.visibility != Visibilities.PRIVATE) { return if (containingClassDescriptor.kind == ClassKind.INTERFACE && this.visibility != Visibilities.PRIVATE) {
return if (this.modality == Modality.ABSTRACT) Modality.ABSTRACT else Modality.OPEN if (this.modality == Modality.ABSTRACT) Modality.ABSTRACT else Modality.OPEN
} } else
return Modality.FINAL Modality.FINAL
} }
private fun renderModalityForCallable(callable: CallableMemberDescriptor, builder: StringBuilder) { private fun renderModalityForCallable(callable: CallableMemberDescriptor, builder: StringBuilder) {
if (!DescriptorUtils.isTopLevelDeclaration(callable) || callable.modality != Modality.FINAL) { if (!DescriptorUtils.isTopLevelDeclaration(callable) || callable.modality != Modality.FINAL) {
if (overrideRenderingPolicy == OverrideRenderingPolicy.RENDER_OVERRIDE && callable.modality == Modality.OPEN && if (overrideRenderingPolicy == OverrideRenderingPolicy.RENDER_OVERRIDE && callable.modality == Modality.OPEN &&
overridesSomething(callable)) { overridesSomething(callable)
) {
return return
} }
renderModality(callable.modality, builder, callable.implicitModalityWithoutExtensions()) renderModality(callable.modality, builder, callable.implicitModalityWithoutExtensions())
@@ -550,9 +550,9 @@ internal class DescriptorRendererImpl(
private fun renderAdditionalModifiers(functionDescriptor: FunctionDescriptor, builder: StringBuilder) { private fun renderAdditionalModifiers(functionDescriptor: FunctionDescriptor, builder: StringBuilder) {
val isOperator = val isOperator =
functionDescriptor.isOperator && (functionDescriptor.overriddenDescriptors.none { it.isOperator } || alwaysRenderModifiers) functionDescriptor.isOperator && (functionDescriptor.overriddenDescriptors.none { it.isOperator } || alwaysRenderModifiers)
val isInfix = val isInfix =
functionDescriptor.isInfix && (functionDescriptor.overriddenDescriptors.none { it.isInfix } || alwaysRenderModifiers) functionDescriptor.isInfix && (functionDescriptor.overriddenDescriptors.none { it.isInfix } || alwaysRenderModifiers)
renderModifier(builder, functionDescriptor.isTailrec, "tailrec") renderModifier(builder, functionDescriptor.isTailrec, "tailrec")
renderSuspendModifier(functionDescriptor, builder) renderSuspendModifier(functionDescriptor, builder)
@@ -599,8 +599,7 @@ internal class DescriptorRendererImpl(
if (!KotlinBuiltIns.isDefaultBound(upperBound)) { if (!KotlinBuiltIns.isDefaultBound(upperBound)) {
builder.append(" : ").append(renderType(upperBound)) builder.append(" : ").append(renderType(upperBound))
} }
} } else if (topLevel) {
else if (topLevel) {
var first = true var first = true
for (upperBound in typeParameter.upperBounds) { for (upperBound in typeParameter.upperBounds) {
if (KotlinBuiltIns.isDefaultBound(upperBound)) { if (KotlinBuiltIns.isDefaultBound(upperBound)) {
@@ -608,15 +607,13 @@ internal class DescriptorRendererImpl(
} }
if (first) { if (first) {
builder.append(" : ") builder.append(" : ")
} } else {
else {
builder.append(" & ") builder.append(" & ")
} }
builder.append(renderType(upperBound)) builder.append(renderType(upperBound))
first = false first = false
} }
} } else {
else {
// rendered with "where" // rendered with "where"
} }
@@ -628,7 +625,7 @@ internal class DescriptorRendererImpl(
private fun renderTypeParameters(typeParameters: List<TypeParameterDescriptor>, builder: StringBuilder, withSpace: Boolean) { private fun renderTypeParameters(typeParameters: List<TypeParameterDescriptor>, builder: StringBuilder, withSpace: Boolean) {
if (withoutTypeParameters) return if (withoutTypeParameters) return
if (!typeParameters.isEmpty()) { if (typeParameters.isNotEmpty()) {
builder.append(lt()) builder.append(lt())
renderTypeParameterList(builder, typeParameters) renderTypeParameterList(builder, typeParameters)
builder.append(gt()) builder.append(gt())
@@ -769,21 +766,25 @@ internal class DescriptorRendererImpl(
for (typeParameter in typeParameters) { for (typeParameter in typeParameters) {
typeParameter.upperBounds typeParameter.upperBounds
.drop(1) // first parameter is rendered by renderTypeParameter .drop(1) // first parameter is rendered by renderTypeParameter
.mapTo(upperBoundStrings) { renderName(typeParameter.name, false) + " : " + renderType(it) } .mapTo(upperBoundStrings) { renderName(typeParameter.name, false) + " : " + renderType(it) }
} }
if (!upperBoundStrings.isEmpty()) { if (upperBoundStrings.isNotEmpty()) {
builder.append(" ").append(renderKeyword("where")).append(" ") builder.append(" ").append(renderKeyword("where")).append(" ")
upperBoundStrings.joinTo(builder, ", ") upperBoundStrings.joinTo(builder, ", ")
} }
} }
override fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean): String { override fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean) = buildString {
return buildString { renderValueParameters(parameters, synthesizedParameterNames, this) } renderValueParameters(parameters, synthesizedParameterNames, this)
} }
private fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean, builder: StringBuilder) { private fun renderValueParameters(
parameters: Collection<ValueParameterDescriptor>,
synthesizedParameterNames: Boolean,
builder: StringBuilder
) {
val includeNames = shouldRenderParameterNames(synthesizedParameterNames) val includeNames = shouldRenderParameterNames(synthesizedParameterNames)
val parameterCount = parameters.size val parameterCount = parameters.size
valueParametersHandler.appendBeforeValueParameters(parameterCount, builder) valueParametersHandler.appendBeforeValueParameters(parameterCount, builder)
@@ -795,16 +796,19 @@ internal class DescriptorRendererImpl(
valueParametersHandler.appendAfterValueParameters(parameterCount, builder) valueParametersHandler.appendAfterValueParameters(parameterCount, builder)
} }
private fun shouldRenderParameterNames(synthesizedParameterNames: Boolean): Boolean { private fun shouldRenderParameterNames(synthesizedParameterNames: Boolean): Boolean = when (parameterNameRenderingPolicy) {
when (parameterNameRenderingPolicy) { ParameterNameRenderingPolicy.ALL -> true
ParameterNameRenderingPolicy.ALL -> return true ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED -> !synthesizedParameterNames
ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED -> return !synthesizedParameterNames ParameterNameRenderingPolicy.NONE -> false
ParameterNameRenderingPolicy.NONE -> return false
}
} }
/* VARIABLES */ /* VARIABLES */
private fun renderValueParameter(valueParameter: ValueParameterDescriptor, includeName: Boolean, builder: StringBuilder, topLevel: Boolean) { private fun renderValueParameter(
valueParameter: ValueParameterDescriptor,
includeName: Boolean,
builder: StringBuilder,
topLevel: Boolean
) {
if (topLevel) { if (topLevel) {
builder.append(renderKeyword("value-parameter")).append(" ") builder.append(renderKeyword("value-parameter")).append(" ")
} }
@@ -828,7 +832,7 @@ internal class DescriptorRendererImpl(
val withDefaultValue = val withDefaultValue =
defaultParameterValueRenderer != null && defaultParameterValueRenderer != null &&
(if (debugMode) valueParameter.declaresDefaultValue() else valueParameter.declaresOrInheritsDefaultValue()) (if (debugMode) valueParameter.declaresDefaultValue() else valueParameter.declaresOrInheritsDefaultValue())
if (withDefaultValue) { if (withDefaultValue) {
builder.append(" = ${defaultParameterValueRenderer!!(valueParameter)}") builder.append(" = ${defaultParameterValueRenderer!!(valueParameter)}")
} }
@@ -957,7 +961,8 @@ internal class DescriptorRendererImpl(
renderVisibility(klass.visibility, builder) renderVisibility(klass.visibility, builder)
} }
if (!(klass.kind == ClassKind.INTERFACE && klass.modality == Modality.ABSTRACT || if (!(klass.kind == ClassKind.INTERFACE && klass.modality == Modality.ABSTRACT ||
klass.kind.isSingleton && klass.modality == Modality.FINAL)) { klass.kind.isSingleton && klass.modality == Modality.FINAL)
) {
renderModality(klass.modality, builder, klass.implicitModalityWithoutExtensions()) renderModality(klass.modality, builder, klass.implicitModalityWithoutExtensions())
} }
renderMemberModifiers(klass, builder) renderMemberModifiers(klass, builder)
@@ -970,8 +975,7 @@ internal class DescriptorRendererImpl(
if (!isCompanionObject(klass)) { if (!isCompanionObject(klass)) {
if (!startFromName) renderSpaceIfNeeded(builder) if (!startFromName) renderSpaceIfNeeded(builder)
renderName(klass, builder, true) renderName(klass, builder, true)
} } else {
else {
renderCompanionObjectName(klass, builder) renderCompanionObjectName(klass, builder)
} }
@@ -1010,7 +1014,7 @@ internal class DescriptorRendererImpl(
} }
private fun renderClassKindPrefix(klass: ClassDescriptor, builder: StringBuilder) { private fun renderClassKindPrefix(klass: ClassDescriptor, builder: StringBuilder) {
builder.append(renderKeyword(DescriptorRenderer.getClassifierKindPrefix(klass))) builder.append(renderKeyword(getClassifierKindPrefix(klass)))
} }
@@ -1129,7 +1133,13 @@ internal class DescriptorRendererImpl(
} }
} }
private fun replacePrefixes(lowerRendered: String, lowerPrefix: String, upperRendered: String, upperPrefix: String, foldedPrefix: String): String? { private fun replacePrefixes(
lowerRendered: String,
lowerPrefix: String,
upperRendered: String,
upperPrefix: String,
foldedPrefix: String
): String? {
if (lowerRendered.startsWith(lowerPrefix) && upperRendered.startsWith(upperPrefix)) { if (lowerRendered.startsWith(lowerPrefix) && upperRendered.startsWith(upperPrefix)) {
val lowerWithoutPrefix = lowerRendered.substring(lowerPrefix.length) val lowerWithoutPrefix = lowerRendered.substring(lowerPrefix.length)
val upperWithoutPrefix = upperRendered.substring(upperPrefix.length) val upperWithoutPrefix = upperRendered.substring(upperPrefix.length)
@@ -1138,14 +1148,14 @@ internal class DescriptorRendererImpl(
if (lowerWithoutPrefix == upperWithoutPrefix) return flexibleCollectionName if (lowerWithoutPrefix == upperWithoutPrefix) return flexibleCollectionName
if (differsOnlyInNullability(lowerWithoutPrefix, upperWithoutPrefix)) { if (differsOnlyInNullability(lowerWithoutPrefix, upperWithoutPrefix)) {
return flexibleCollectionName + "!" return "$flexibleCollectionName!"
} }
} }
return null return null
} }
private fun differsOnlyInNullability(lower: String, upper: String) private fun differsOnlyInNullability(lower: String, upper: String) =
= lower == upper.replace("?", "") || upper.endsWith("?") && ("$lower?") == upper || "($lower)?" == upper lower == upper.replace("?", "") || upper.endsWith("?") && ("$lower?") == upper || "($lower)?" == upper
private fun overridesSomething(callable: CallableMemberDescriptor) = !callable.overriddenDescriptors.isEmpty() private fun overridesSomething(callable: CallableMemberDescriptor) = !callable.overriddenDescriptors.isEmpty()
} }
@@ -23,9 +23,11 @@ import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
object IdeDescriptorRenderers { object IdeDescriptorRenderers {
@JvmField val APPROXIMATE_FLEXIBLE_TYPES: (KotlinType) -> KotlinType = { it.approximateFlexibleTypes(preferNotNull = false) } @JvmField
val APPROXIMATE_FLEXIBLE_TYPES: (KotlinType) -> KotlinType = { it.approximateFlexibleTypes(preferNotNull = false) }
@JvmField val APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL: (KotlinType) -> KotlinType = { it.approximateFlexibleTypes(preferNotNull = true) } @JvmField
val APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL: (KotlinType) -> KotlinType = { it.approximateFlexibleTypes(preferNotNull = true) }
private fun unwrapAnonymousType(type: KotlinType): KotlinType { private fun unwrapAnonymousType(type: KotlinType): KotlinType {
if (type.isDynamic()) return type if (type.isDynamic()) return type
@@ -54,31 +56,36 @@ object IdeDescriptorRenderers {
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
} }
@JvmField val SOURCE_CODE: DescriptorRenderer = BASE.withOptions { @JvmField
val SOURCE_CODE: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
} }
@JvmField val SOURCE_CODE_TYPES: DescriptorRenderer = BASE.withOptions { @JvmField
val SOURCE_CODE_TYPES: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
annotationFilter = { it !is BuiltInAnnotationDescriptor } annotationFilter = { it !is BuiltInAnnotationDescriptor }
parameterNamesInFunctionalTypes = false parameterNamesInFunctionalTypes = false
} }
@JvmField val SOURCE_CODE_TYPES_WITH_SHORT_NAMES: DescriptorRenderer = BASE.withOptions { @JvmField
val SOURCE_CODE_TYPES_WITH_SHORT_NAMES: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SHORT classifierNamePolicy = ClassifierNamePolicy.SHORT
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
modifiers -= DescriptorRendererModifier.ANNOTATIONS modifiers -= DescriptorRendererModifier.ANNOTATIONS
parameterNamesInFunctionalTypes = false parameterNamesInFunctionalTypes = false
} }
@JvmField val SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION: DescriptorRenderer = BASE.withOptions { @JvmField
val SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL(unwrapAnonymousType(it)) }
} }
@JvmField val SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS: DescriptorRenderer = BASE.withOptions { @JvmField
val SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SHORT classifierNamePolicy = ClassifierNamePolicy.SHORT
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
modifiers -= DescriptorRendererModifier.ANNOTATIONS modifiers -= DescriptorRendererModifier.ANNOTATIONS