diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescConstructorSymbol.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescConstructorSymbol.kt index cff48d4a99a..fcefccb6d91 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescConstructorSymbol.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescConstructorSymbol.kt @@ -56,7 +56,7 @@ internal class KtFe10DescConstructorSymbol( val callableId = descriptor.callableIdIfNotLocal if (callableId != null) { - val signature = descriptor.getSymbolPointerSignature(analysisContext) + val signature = descriptor.getSymbolPointerSignature() return KtFe10DescFunctionLikeSymbolPointer(callableId, signature) } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescFunctionSymbol.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescFunctionSymbol.kt index 2f4814baf0e..8fb3a227f35 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescFunctionSymbol.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/KtFe10DescFunctionSymbol.kt @@ -95,7 +95,7 @@ internal class KtFe10DescFunctionSymbol private constructor( val callableId = descriptor.callableIdIfNotLocal if (callableId != null) { - val signature = descriptor.getSymbolPointerSignature(analysisContext) + val signature = descriptor.getSymbolPointerSignature() return KtFe10DescFunctionLikeSymbolPointer(callableId, signature) } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt index 7ede1991d91..b7ecf464509 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.analysis.api.* import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.base.KtConstantValue import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext import org.jetbrains.kotlin.analysis.api.descriptors.symbols.KtFe10FileSymbol import org.jetbrains.kotlin.analysis.api.descriptors.symbols.KtFe10PackageSymbol @@ -21,14 +20,12 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.KtFe10PsiD import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.KtFe10PsiDefaultSetterParameterSymbol import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol import org.jetbrains.kotlin.analysis.api.descriptors.types.* -import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10Renderer import org.jetbrains.kotlin.analysis.api.impl.base.KtContextReceiverImpl import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError -import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor @@ -43,6 +40,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.inference.CapturedType import org.jetbrains.kotlin.resolve.constants.* @@ -537,13 +535,9 @@ internal fun ClassDescriptor.getSupertypesWithAny(): Collection { return if (hasClassSupertype) supertypes else listOf(builtIns.anyType) + supertypes } -internal fun DeclarationDescriptor.render(analysisContext: Fe10AnalysisContext, options: KtDeclarationRendererOptions): String { - val renderer = KtFe10Renderer(analysisContext, options) - return prettyPrint { renderer.render(this@render, this) }.trim() -} -internal fun CallableMemberDescriptor.getSymbolPointerSignature(analysisContext: Fe10AnalysisContext): String { - return render(analysisContext, KtDeclarationRendererOptions.DEFAULT) +internal fun CallableMemberDescriptor.getSymbolPointerSignature(): String { + return DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this) } internal fun createKtInitializerValue( diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/pointers/KtFe10DescFunctionLikeSymbolPointer.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/pointers/KtFe10DescFunctionLikeSymbolPointer.kt index 2369e958c31..070b3e92d6c 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/pointers/KtFe10DescFunctionLikeSymbolPointer.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/pointers/KtFe10DescFunctionLikeSymbolPointer.kt @@ -41,7 +41,7 @@ class KtFe10DescFunctionLikeSymbolPointer( return memberScope .getContributedDescriptors(DescriptorKindFilter.CALLABLES) { it == callableId.callableName } .filterIsInstance() - .firstOrNull { it.getSymbolPointerSignature(analysisContext) == signature } + .firstOrNull { it.getSymbolPointerSignature() == signature } ?.toKtCallableSymbol(analysisContext) as? T } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/base/KtFe10Type.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/base/KtFe10Type.kt index ed73a0f6c72..f37ad095813 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/base/KtFe10Type.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/base/KtFe10Type.kt @@ -5,13 +5,12 @@ package org.jetbrains.kotlin.analysis.api.descriptors.types.base -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext import org.jetbrains.kotlin.analysis.api.descriptors.annotations.KtFe10AnnotationsList -import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10TypeRenderer +import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10DebugTypeRenderer +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint @@ -33,6 +32,6 @@ interface KtFe10Type : KtLifetimeOwner, KtAnnotated { } internal fun KotlinType.asStringForDebugging(): String { - val renderer = KtFe10TypeRenderer(KtTypeRendererOptions.DEFAULT, isDebugText = true) + val renderer = KtFe10DebugTypeRenderer() return prettyPrint { renderer.render(this@asStringForDebugging, this) } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10DebugTypeRenderer.kt similarity index 71% rename from analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt rename to analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10DebugTypeRenderer.kt index 8a0caf49f8c..13a97866574 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10TypeRenderer.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10DebugTypeRenderer.kt @@ -6,14 +6,12 @@ package org.jetbrains.kotlin.analysis.api.descriptors.utils import org.jetbrains.kotlin.analysis.api.annotations.* -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.classId import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getKtNamedAnnotationArguments import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.builtins.* -import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.descriptors.PossiblyInnerType import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor @@ -32,7 +30,7 @@ import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor import org.jetbrains.kotlin.types.error.ErrorType import org.jetbrains.kotlin.types.typeUtil.builtIns -internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, private val isDebugText: Boolean = false) { +internal class KtFe10DebugTypeRenderer { private companion object { const val ERROR_TYPE_TEXT = "ERROR_TYPE" } @@ -41,18 +39,8 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr consumer.renderType(type) } - private fun KtFe10RendererConsumer.renderType(type: KotlinType) { - if (isDebugText) { - renderTypeAnnotationsDebug(type) - } else { - renderFe10Annotations( - type.annotations, - isSingleLineAnnotations = true, - renderAnnotationWithShortNames = options.shortQualifiedNames - ) { classId -> - classId != StandardClassIds.Annotations.ExtensionFunctionType - } - } + private fun PrettyPrinter.renderType(type: KotlinType) { + renderTypeAnnotationsDebug(type) when (val unwrappedType = type.unwrap()) { is DynamicType -> append("dynamic") is FlexibleType -> renderFlexibleType(unwrappedType) @@ -67,9 +55,7 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr is IntersectionTypeConstructor -> renderIntersectionType(typeConstructor) else -> { val descriptor = unwrappedType.constructor.declarationDescriptor - if (!isDebugText && options.renderFunctionType && descriptor is FunctionClassDescriptor) { - renderFunctionType(unwrappedType) - } else if (descriptor is TypeParameterDescriptor) { + if (descriptor is TypeParameterDescriptor) { renderTypeParameterType(descriptor) } else if (descriptor is ClassifierDescriptorWithTypeParameters) { renderOrdinaryType(unwrappedType) @@ -86,19 +72,19 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr } } - private fun KtFe10RendererConsumer.renderTypeAnnotationsDebug(type: KotlinType) { + private fun PrettyPrinter.renderTypeAnnotationsDebug(type: KotlinType) { val annotations = type.annotations .filter { it.annotationClass?.classId != StandardClassIds.Annotations.ExtensionFunctionType } printCollectionIfNotEmpty(annotations, separator = " ", postfix = " ") { renderTypeAnnotationDebug(it) } } - private fun KtFe10RendererConsumer.renderTypeAnnotationDebug(annotation: AnnotationDescriptor) { + private fun PrettyPrinter.renderTypeAnnotationDebug(annotation: AnnotationDescriptor) { val namedValues = annotation.getKtNamedAnnotationArguments() renderAnnotationDebug(annotation.annotationClass?.classId, namedValues) } - private fun KtFe10RendererConsumer.renderAnnotationDebug(classId: ClassId?, namedValues: List) { + private fun PrettyPrinter.renderAnnotationDebug(classId: ClassId?, namedValues: List) { append("@") if (classId != null) { @@ -116,7 +102,7 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr } } - private fun KtFe10RendererConsumer.renderConstantValueDebug(value: KtAnnotationValue) { + private fun PrettyPrinter.renderConstantValueDebug(value: KtAnnotationValue) { when (value) { is KtAnnotationApplicationValue -> renderAnnotationDebug(value.annotationValue.classId, value.annotationValue.arguments) is KtArrayAnnotationValue -> @@ -128,46 +114,44 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr } } - private fun KtFe10RendererConsumer.renderFlexibleType(type: FlexibleType) { + private fun PrettyPrinter.renderFlexibleType(type: FlexibleType) { val lowerBoundText = prettyPrint { renderType(type.lowerBound) } val upperBoundText = prettyPrint { renderType(type.upperBound) } append(DescriptorRenderer.COMPACT.renderFlexibleType(lowerBoundText, upperBoundText, type.builtIns)) } - private fun KtFe10RendererConsumer.renderDefinitelyNotNullType(type: DefinitelyNotNullType) { + private fun PrettyPrinter.renderDefinitelyNotNullType(type: DefinitelyNotNullType) { renderType(type.original) append(" & Any") } - private fun KtFe10RendererConsumer.renderErrorType() { + private fun PrettyPrinter.renderErrorType() { append(ERROR_TYPE_TEXT) } - private fun KtFe10RendererConsumer.renderCapturedType(type: CapturedType) { + private fun PrettyPrinter.renderCapturedType(type: CapturedType) { append("CapturedType(") renderTypeProjection(type.typeProjection) append(")") } - private fun KtFe10RendererConsumer.renderCapturedType(type: NewCapturedType) { + private fun PrettyPrinter.renderCapturedType(type: NewCapturedType) { append("CapturedType(") renderTypeProjection(type.constructor.projection) append(")") } - private fun KtFe10RendererConsumer.renderTypeVariableType(typeConstructor: NewTypeVariableConstructor) { + private fun PrettyPrinter.renderTypeVariableType(typeConstructor: NewTypeVariableConstructor) { val name = typeConstructor.originalTypeParameter?.name ?: SpecialNames.NO_NAME_PROVIDED append("TypeVariable(").append(name.asString()).append(")") } - private fun KtFe10RendererConsumer.renderIntersectionType(typeConstructor: IntersectionTypeConstructor) { - if (isDebugText) { - append("it") - } + private fun PrettyPrinter.renderIntersectionType(typeConstructor: IntersectionTypeConstructor) { + append("it") printCollection(typeConstructor.supertypes, separator = " & ", prefix = "(", postfix = ")") { renderType(it) } } - private fun KtFe10RendererConsumer.renderFunctionType(type: SimpleType) { + private fun PrettyPrinter.renderFunctionType(type: SimpleType) { if (type.isSuspendFunctionType || type.isKSuspendFunctionType) { append("suspend ") } @@ -193,41 +177,30 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr renderType(returnType) } - private fun KtFe10RendererConsumer.renderTypeParameterType(descriptor: TypeParameterDescriptor) { + private fun PrettyPrinter.renderTypeParameterType(descriptor: TypeParameterDescriptor) { append(descriptor.name.render()) } - private fun KtFe10RendererConsumer.renderOrdinaryType(type: SimpleType) { + private fun PrettyPrinter.renderOrdinaryType(type: SimpleType) { val nestedType = KtFe10JvmTypeMapperContext.getNestedType(type) - renderTypeSegment(nestedType.root, isRoot = true) + renderTypeSegment(nestedType.root) printCollectionIfNotEmpty(nestedType.nested, separator = ".", prefix = ".", postfix = "") { renderTypeSegment(it) } } - private fun KtFe10RendererConsumer.renderTypeSegment(typeSegment: PossiblyInnerType, isRoot: Boolean = false) { + private fun PrettyPrinter.renderTypeSegment(typeSegment: PossiblyInnerType) { val classifier = typeSegment.classifierDescriptor - if (isDebugText) { - append(classifier.maybeLocalClassId.asString()) - } else if (isRoot) { - val classId = classifier.maybeLocalClassId - if (!options.shortQualifiedNames && !classId.packageFqName.isRoot) { - renderFqName(classId.packageFqName) - append('.') - } - renderFqName(classId.relativeClassName) - } else { - append(classifier.name.render()) - } + append(classifier.maybeLocalClassId.asString()) val arguments = typeSegment.arguments printCollectionIfNotEmpty(arguments, separator = ", ", prefix = "<", postfix = ">") { renderTypeProjection(it) } } - private fun KtFe10RendererConsumer.renderFqName(fqName: FqName) { + private fun PrettyPrinter.renderFqName(fqName: FqName) { printCollection(fqName.pathSegments(), separator = ".") { append(it.render()) } } - private fun KtFe10RendererConsumer.renderTypeProjection(projection: TypeProjection) { + private fun PrettyPrinter.renderTypeProjection(projection: TypeProjection) { if (projection.isStarProjection) { append("*") } else { diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt deleted file mode 100644 index 73402910dec..00000000000 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10Renderer.kt +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.api.descriptors.utils - -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.RendererModifier -import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.classId -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.isExplicitOverride -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktModality -import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktVisibility -import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter -import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor -import org.jetbrains.kotlin.builtins.isFunctionType -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotated -import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor -import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.renderer.render -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue -import org.jetbrains.kotlin.resolve.calls.components.isVararg -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeApproximator -import org.jetbrains.kotlin.types.typeUtil.isNullableAny -import org.jetbrains.kotlin.types.typeUtil.isUnit -import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly - -internal typealias KtFe10RendererConsumer = PrettyPrinter - -internal class KtFe10Renderer( - private val analysisContext: Fe10AnalysisContext, - private val options: KtDeclarationRendererOptions, - isDebugText: Boolean = false -) { - private companion object { - val IGNORED_VISIBILITIES: Set = setOf( - Visibilities.Local, - Visibilities.PrivateToThis, - Visibilities.InvisibleFake, - Visibilities.Inherited, - Visibilities.Unknown, - Visibilities.DEFAULT_VISIBILITY - ) - - val IGNORED_SUPERTYPES: Set = setOf( - StandardClassIds.Enum, - StandardClassIds.Annotation - ) - } - - private val typeRenderer = KtFe10TypeRenderer(options.typeRendererOptions, isDebugText) - - private val typeApproximator = TypeApproximator( - analysisContext.builtIns, - analysisContext.resolveSession.languageVersionSettings - ) - - fun render(descriptor: DeclarationDescriptor, consumer: KtFe10RendererConsumer) { - consumer.renderDeclaration(descriptor) - } - - private fun KtFe10RendererConsumer.renderType(type: KotlinType, shouldApproximate: Boolean = false) { - if (shouldApproximate) { - val approximatedType = typeApproximator.approximateToSuperType(type.unwrap(), PublicApproximatorConfiguration(localTypes = true)) - ?: type.takeIf { it.constructor.declarationDescriptor?.name != SpecialNames.NO_NAME_PROVIDED } - ?: analysisContext.builtIns.anyType - - renderType(approximatedType, shouldApproximate = false) - return - } - - typeRenderer.render(type, this) - } - - private fun needsParenthesis(type: KotlinType): Boolean { - if (!type.annotations.isEmpty()) { - return true - } - - if (options.typeRendererOptions.renderFunctionType && type.isFunctionType) { - return true - } - - val descriptor = type.constructor.declarationDescriptor - if (descriptor is FunctionClassDescriptor && descriptor.functionKind.isSuspendType) { - return true - } - - return false - } - - private fun KtFe10RendererConsumer.renderDeclaration(descriptor: DeclarationDescriptor) { - when (descriptor) { - is ClassifierDescriptor -> renderClassifier(descriptor) - is CallableDescriptor -> renderCallable(descriptor) - else -> error("Unexpected descriptor kind: $descriptor") - } - } - - private fun KtFe10RendererConsumer.renderClassifier(descriptor: ClassifierDescriptor) { - when (descriptor) { - is TypeAliasDescriptor -> renderTypeAlias(descriptor) - is TypeParameterDescriptor -> renderTypeParameter(descriptor) - is ClassDescriptor -> { - if (descriptor.kind == ClassKind.ENUM_ENTRY) { - renderEnumEntry(descriptor) - } else { - renderClass(descriptor) - } - } - else -> error("Unexpected descriptor kind: $descriptor") - } - } - - private fun KtFe10RendererConsumer.renderTypeAlias(descriptor: TypeAliasDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - renderModifiers(descriptor) - append("typealias ") - } - renderName(descriptor) - renderTypeParameters(descriptor.declaredTypeParameters) - append(" = ") - renderType(descriptor.expandedType) - } - - private fun KtFe10RendererConsumer.renderTypeParameters(typeParameters: List) { - if (typeParameters.isNotEmpty()) append('<') - printCollection(typeParameters, separator = ", ") { renderTypeParameter(it) } - if (typeParameters.isNotEmpty()) append('>') - } - - private fun KtFe10RendererConsumer.renderTypeParameter(descriptor: TypeParameterDescriptor) { - renderModifier("reified", descriptor.isReified) - - val variance = descriptor.variance.label - renderModifier(variance, variance.isNotEmpty()) - - renderAnnotations(descriptor) - renderName(descriptor) - - val upperBounds = descriptor.upperBounds.filterNot { it.isNullableAny() } - if (upperBounds.isNotEmpty()) { - append(" : ") - renderType(upperBounds.first()) - } - } - - private fun KtFe10RendererConsumer.renderClass(descriptor: ClassDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - renderModifiers(descriptor) - - - if (DescriptorUtils.isAnonymousObject(descriptor)) { - append("object") - } else { - val classKeyword = when (descriptor.kind) { - ClassKind.CLASS -> "class" - ClassKind.INTERFACE -> "interface" - ClassKind.ENUM_CLASS -> "enum class" - ClassKind.ENUM_ENTRY -> error("enum entries should not be rendered via renderClass") - ClassKind.ANNOTATION_CLASS -> "annotation class" - ClassKind.OBJECT -> "object" - } - append(classKeyword) - } - } - - val shouldRenderName = !descriptor.name.isSpecial - && (!descriptor.isCompanionObject || descriptor.name != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) - - if (shouldRenderName) { - append(' ') - renderName(descriptor) - } - - renderTypeParameters(descriptor.declaredTypeParameters) - renderSupertypes(descriptor) - - renderWhereSuffix(descriptor.declaredTypeParameters) - - if (options.renderClassMembers) { - val (enumEntries, otherDeclarations) = descriptor.unsubstitutedMemberScope.getContributedDescriptors() - .filter { shouldRenderNestedDeclaration(descriptor, it) } - .partition { it is ClassDescriptor && it.kind == ClassKind.ENUM_ENTRY } - - val constructors = descriptor.constructors - .filter { shouldRenderNestedDeclaration(descriptor, it) } - - if (enumEntries.isNotEmpty() || otherDeclarations.isNotEmpty() || constructors.isNotEmpty()) { - append(' ') - withIndentInBraces { - printCollection(sortDeclarations(enumEntries), separator = ",\n") { - renderEnumEntry(it as ClassDescriptor) - } - - if (enumEntries.isNotEmpty() && (constructors.isNotEmpty() || otherDeclarations.isNotEmpty())) { - appendLine(";\n") - } - - printCollection(sortDeclarations(constructors + otherDeclarations), separator = "\n\n") { - renderDeclaration(it) - } - } - } - } - } - - private fun shouldRenderNestedDeclaration(owner: ClassDescriptor, declaration: DeclarationDescriptor): Boolean { - if (declaration is CallableMemberDescriptor && declaration.kind != CallableMemberDescriptor.Kind.DECLARATION) { - return false - } - - if ( - declaration is ConstructorDescriptor && !DescriptorUtils.isAnonymousObject(declaration.constructedClass) - && declaration.isPrimary && declaration.valueParameters.isEmpty() && declaration.annotations.isEmpty() - ) { - if (declaration.visibility == DescriptorVisibilities.DEFAULT_VISIBILITY) { - return false - } else if (owner.kind == ClassKind.OBJECT || owner.kind == ClassKind.ENUM_CLASS) { - return false - } - } - - if (declaration is FunctionDescriptor && owner.kind == ClassKind.ENUM_CLASS) { - if (declaration.name.asString() == "valueOf" && KotlinBuiltIns.isString(declaration.valueParameters.singleOrNull()?.type)) { - return false - } else if (declaration.name.asString() == "values" && declaration.valueParameters.isEmpty()) { - return false - } - } - - return true - } - - private fun sortDeclarations(declarations: List): List { - if (!options.sortNestedDeclarations) { - return declarations - } - - fun getDeclarationKind(declaration: DeclarationDescriptor): Int = when (declaration) { - is ConstructorDescriptor -> if (declaration.isPrimary) 1 else 2 - is PropertyDescriptor -> 3 - is FunctionDescriptor -> 4 - else -> 5 - } - - return declarations.sortedWith(Comparator { left, right -> - val kindResult = getDeclarationKind(left) - getDeclarationKind(right) - if (kindResult != 0) { - return@Comparator kindResult - } - - val nameResult = left.name.asString().compareTo(right.name.asString()) - if (nameResult != 0) { - return@Comparator nameResult - } - - val leftString = prettyPrint { renderDeclaration(left) } - val rightString = prettyPrint { renderDeclaration(right) } - return@Comparator leftString.compareTo(rightString) - }) - } - - private fun KtFe10RendererConsumer.renderSupertypes(descriptor: ClassDescriptor) { - val allowedSuperClasses = (listOfNotNull(descriptor.getSuperClassNotAny()) + descriptor.getSuperInterfaces()) - .filterTo(HashSet()) { it.classId !in IGNORED_SUPERTYPES } - - val supertypes = descriptor.typeConstructor.supertypes.filter { it.constructor.declarationDescriptor in allowedSuperClasses } - printCollectionIfNotEmpty(supertypes, separator = ", ", prefix = " : ") { renderType(it) } - } - - private fun KtFe10RendererConsumer.renderCallable(descriptor: CallableDescriptor) { - when (descriptor) { - is SyntheticFieldDescriptor -> renderSyntheticFieldDescriptor() - is PropertyGetterDescriptor -> renderPropertyAccessor(descriptor) - is PropertySetterDescriptor -> renderPropertyAccessor(descriptor) - is PropertyDescriptor -> renderProperty(descriptor) - is ConstructorDescriptor -> renderConstructor(descriptor) - is FunctionDescriptor -> renderFunction(descriptor) - is ValueParameterDescriptor -> renderValueParameter(descriptor) - is LocalVariableDescriptor -> renderLocalVariable(descriptor) - else -> error("Unexpected descriptor kind: $descriptor") - } - } - - private fun KtFe10RendererConsumer.renderSyntheticFieldDescriptor() { - append("field") - } - - private fun KtFe10RendererConsumer.renderPropertyAccessor(descriptor: PropertyAccessorDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - renderModifiers(descriptor) - } - - when (descriptor) { - is PropertyGetterDescriptor -> { - append("get()") - } - is PropertySetterDescriptor -> { - append("set(") - val valueParameter = descriptor.valueParameters.singleOrNull() - if (valueParameter != null) { - val name = valueParameter.name.takeIf { !it.isSpecial } ?: Name.identifier("value") - renderValueParameter(valueParameter, name) - } - append(")") - } - } - } - - private fun KtFe10RendererConsumer.renderEnumEntry(descriptor: ClassDescriptor) { - assert(descriptor.kind == ClassKind.ENUM_ENTRY) - renderName(descriptor) - } - - private fun KtFe10RendererConsumer.renderLocalVariable(descriptor: LocalVariableDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - append(if (descriptor.isVar) "var" else "val").append(' ') - } - - renderName(descriptor) - append(": ") - renderType(descriptor.type, shouldApproximate = options.approximateTypes) - } - - private fun KtFe10RendererConsumer.renderProperty(descriptor: PropertyDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - renderModifiers(descriptor) - append(if (descriptor.isVar) "var" else "val").append(' ') - renderTypeParameters(descriptor.typeParameters) - if (descriptor.typeParameters.isNotEmpty()) { - append(' ') - } - } - - renderReceiver(descriptor) - renderName(descriptor) - append(": ") - renderType(descriptor.type, shouldApproximate = options.approximateTypes) - renderWhereSuffix(descriptor.typeParameters) - - if (options.renderClassMembers) { - fun shouldRenderAccessor(accessor: PropertyAccessorDescriptor): Boolean { - return !accessor.annotations.isEmpty() - || accessor.visibility != descriptor.visibility - } - - val getter = descriptor.getter - val setter = descriptor.setter - - val shouldRenderAccessors = (getter != null && shouldRenderAccessor(getter)) || (setter != null && shouldRenderAccessor(setter)) - if (shouldRenderAccessors) { - withIndent { - if (getter != null) { - appendLine() - renderPropertyAccessor(getter) - } - if (setter != null) { - appendLine() - renderPropertyAccessor(setter) - } - } - } - } - } - - private fun KtFe10RendererConsumer.renderReceiver(descriptor: CallableDescriptor) { - val extensionReceiver = descriptor.extensionReceiverParameter ?: return - val needsParentheses = !extensionReceiver.annotations.isEmpty() || needsParenthesis(extensionReceiver.type) - if (needsParentheses) { - append('(') - } - renderType(extensionReceiver.type) - if (needsParentheses) { - append(')') - } - append('.') - } - - private fun KtFe10RendererConsumer.renderConstructor(descriptor: ConstructorDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - } - append("constructor") - renderValueParameters(descriptor.valueParameters) - } - - private fun KtFe10RendererConsumer.renderFunction(descriptor: FunctionDescriptor) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - renderModifiers(descriptor) - append("fun ") - renderTypeParameters(descriptor.typeParameters) - if (descriptor.typeParameters.isNotEmpty()) { - append(" ") - } - } - - renderReceiver(descriptor) - renderName(descriptor) - renderValueParameters(descriptor.valueParameters) - - val returnType = descriptor.returnType - if (returnType != null && !returnType.isUnit()) { - append(": ") - renderType(returnType, shouldApproximate = options.approximateTypes) - } - - renderWhereSuffix(descriptor.typeParameters) - } - - private fun KtFe10RendererConsumer.renderWhereSuffix(descriptors: List) { - val upperBoundStrings = ArrayList(0) - - for (typeParameter in descriptors) { - typeParameter.upperBounds - .drop(1) // first parameter is rendered by renderTypeParameter - .mapTo(upperBoundStrings) { typeParameter.name.render() + " : " + prettyPrint { renderType(it) } } - } - - if (upperBoundStrings.isNotEmpty()) { - append(" where ") - upperBoundStrings.joinTo(this, ", ") - append(' ') - } - } - - private fun KtFe10RendererConsumer.renderValueParameters(valueParameters: List) { - printCollection(valueParameters, separator = ", ", prefix = "(", postfix = ")") { renderValueParameter(it) } - } - - private fun KtFe10RendererConsumer.renderValueParameter(descriptor: ValueParameterDescriptor, name: Name = descriptor.name) { - if (options.renderDeclarationHeader) { - renderAnnotations(descriptor) - } - - renderModifiers(descriptor) - append(name.render()) - append(": ") - renderType(descriptor.varargElementType ?: descriptor.type) - - if (options.renderDefaultParameterValue && descriptor.hasDefaultValue()) { - append(" = ...") - } - } - - private fun KtFe10RendererConsumer.renderName(descriptor: DeclarationDescriptor) { - append(descriptor.name.render()) - } - - private fun KtFe10RendererConsumer.renderAnnotations(declaration: Annotated, predicate: (ClassId) -> Boolean = { true }) { - if (RendererModifier.ANNOTATIONS !in options.modifiers) { - return - } - val isSingleLineAnnotations = declaration is ValueParameterDescriptor || declaration is TypeParameterDescriptor - renderFe10Annotations( - declaration.annotations, - isSingleLineAnnotations, - renderAnnotationWithShortNames = options.typeRendererOptions.shortQualifiedNames, - predicate - ) - } - - private fun KtFe10RendererConsumer.renderModifiers(descriptor: DeclarationDescriptor) { - if (descriptor is MemberDescriptor) { - renderVisibility(descriptor) - } - - if (descriptor is PropertyDescriptor) { - renderModifier("const", descriptor.isConst, RendererModifier.CONST) - renderModifier("lateinit", descriptor.isLateInit, RendererModifier.LATEINIT) - } - - if (descriptor is ValueParameterDescriptor) { - renderModifier("crossinline", descriptor.isCrossinline) - renderModifier("noinline", descriptor.isNoinline) - } - - if (descriptor is MemberDescriptor) { - renderModifier("external", descriptor.isExternal) - renderModifier("expect", descriptor.isExpect, RendererModifier.EXPECT) - renderModifier("actual", descriptor.isActual, RendererModifier.ACTUAL) - renderModality(descriptor) - } - - if (descriptor is CallableMemberDescriptor) { - renderModifier("override", descriptor !is DeserializedDescriptor && descriptor.isExplicitOverride, RendererModifier.OVERRIDE) - } - - if (descriptor is ValueParameterDescriptor) { - renderModifier("vararg", descriptor.isVararg) - } - - if (descriptor is FunctionDescriptor) { - renderModifier("tailrec", descriptor.isTailrec) - renderModifier("suspend", descriptor.isSuspend) - renderModifier("inline", descriptor.isInline, RendererModifier.INLINE) - renderModifier("infix", descriptor.isInfix) - renderModifier("operator", descriptor.isOperator, RendererModifier.OPERATOR) - } - - if (descriptor is ClassDescriptor) { - renderModifier("inner", descriptor.isInner, RendererModifier.INNER) - renderModifier("data", descriptor.isData, RendererModifier.DATA) - renderModifier("inline", descriptor.isInline, RendererModifier.INNER) - renderModifier("fun", descriptor.isFun, RendererModifier.FUN) - renderModifier("companion", descriptor.isCompanionObject) - } - } - - private fun KtFe10RendererConsumer.renderVisibility(descriptor: DeclarationDescriptorWithVisibility) { - val visibility = descriptor.ktVisibility - renderModifier(visibility.internalDisplayName, visibility !in IGNORED_VISIBILITIES, RendererModifier.VISIBILITY) - } - - private fun KtFe10RendererConsumer.renderModality(descriptor: MemberDescriptor) { - if (descriptor is PropertyAccessorDescriptor || (descriptor is CallableMemberDescriptor && descriptor.isExplicitOverride)) { - return - } - - val modality = descriptor.ktModality - - renderModifier( - modality.name.toLowerCaseAsciiOnly(), - modality != getDefaultModality(descriptor), - RendererModifier.MODALITY - ) - } - - private fun getDefaultModality(descriptor: MemberDescriptor): Modality { - when (descriptor) { - is ClassDescriptor -> return if (descriptor.kind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL - is CallableMemberDescriptor -> { - val containingDeclaration = descriptor.containingDeclaration - if (containingDeclaration !is ClassDescriptor) { - return Modality.FINAL - } - if (descriptor.isExplicitOverride && containingDeclaration.ktModality != Modality.FINAL) { - return Modality.OPEN - } else if (containingDeclaration.kind == ClassKind.INTERFACE && descriptor.visibility != DescriptorVisibilities.PRIVATE) { - return if (descriptor.ktModality == Modality.ABSTRACT || descriptor.kind == CallableMemberDescriptor.Kind.DELEGATION) - Modality.ABSTRACT - else - Modality.OPEN - } - - return Modality.FINAL - } - else -> return Modality.FINAL - } - } - - private fun KtFe10RendererConsumer.renderModifier(text: String, state: Boolean, modifier: RendererModifier? = null) { - if (state && (modifier == null || modifier in options.modifiers)) { - append(text).append(' ') - } - } -} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt deleted file mode 100644 index fa75b3abcca..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.api.fir.renderer - -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.containingClassLookupTag -import org.jetbrains.kotlin.fir.containingClassForLocal -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.isInner -import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType -import org.jetbrains.kotlin.fir.renderWithType -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError -import org.jetbrains.kotlin.fir.resolve.toFirRegularClass -import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.renderer.render -import org.jetbrains.kotlin.utils.addToStdlib.applyIf - -internal class ConeTypeIdeRenderer( - private val session: FirSession, - private val options: KtTypeRendererOptions, -) { - companion object { - const val ERROR_TYPE_TEXT = "ERROR_TYPE" - } - - private fun StringBuilder.appendError(message: String? = null) { - append(ERROR_TYPE_TEXT) - if (message != null) append(" <$message>") - } - - private fun StringBuilder.renderAnnotationList(type: ConeKotlinType) { - if (options.renderTypeAnnotations) { - renderAnnotations(this@ConeTypeIdeRenderer, type.customAnnotations, session, isSingleLineAnnotations = true) - } - } - - fun renderType(type: ConeTypeProjection): String = buildString { - when (type) { - is ConeErrorType -> { - renderErrorType(type) - } - is ConeClassLikeType -> { - if (options.renderFunctionType && shouldRenderAsPrettyFunctionType(type)) { - renderAnnotationList(type) - renderFunctionType(type) - } else { - renderAnnotationList(type) - renderTypeConstructorAndArguments(type) - } - } - is ConeTypeParameterType -> { - renderAnnotationList(type) - append(type.lookupTag.name.asString()) - renderNullability(type.type) - } - is ConeIntersectionType -> { - renderAnnotationList(type) - type.intersectedTypes.joinTo(this, "&", prefix = "(", postfix = ")") { - renderType(it) - } - renderNullability(type.type) - } - is ConeDynamicType -> { - append("dynamic") - } - is ConeFlexibleType -> { - renderFlexibleType(type) - } - is ConeCapturedType -> { - renderAnnotationList(type) - append(type.renderReadableWithFqNames()) - renderNullability(type.type) - } - is ConeDefinitelyNotNullType -> { - renderAnnotationList(type) - append(renderType(type.original)) - append("!!") - } - else -> appendError("Unexpected cone type ${type::class.qualifiedName}") - } - } - - private fun StringBuilder.renderFlexibleType(type: ConeFlexibleType) { - renderAnnotationList(type) - append(renderFlexibleType(renderType(type.lowerBound), renderType(type.upperBound))) - } - - private fun StringBuilder.renderErrorType(type: ConeErrorType) { - val diagnostic = type.diagnostic - if (options.renderUnresolvedTypeAsResolved) { - when (diagnostic) { - is ConeUnresolvedError -> { - val qualifierRendered = diagnostic.qualifier.let { FqName(it).render() } - append(qualifierRendered) - } - - is ConeCannotInferParameterType -> { - append(diagnostic.typeParameter.name.render()) - } - - else -> { - appendError(diagnostic.reason) - } - } - } else { - appendError(diagnostic.reason) - } - } - - private fun StringBuilder.renderNullability(type: ConeKotlinType) { - if (type.nullability == ConeNullability.NULLABLE) { - append("?") - } - } - - - fun shouldRenderAsPrettyFunctionType(type: ConeKotlinType): Boolean { - return type.type.isBuiltinFunctionalType(session) && type.typeArguments.none { it.kind == ProjectionKind.STAR } - } - - private fun differsOnlyInNullability(lower: String, upper: String) = - lower == upper.replace("?", "") || upper.endsWith("?") && ("$lower?") == upper || "($lower)?" == upper - - - private fun renderFlexibleType(lowerRendered: String, upperRendered: String): String { - if (differsOnlyInNullability(lowerRendered, upperRendered)) { - if (upperRendered.startsWith("(")) { - // the case of complex type, e.g. (() -> Unit)? - return "($lowerRendered)!" - } - return "$lowerRendered!" - } - - val kotlinCollectionsPrefix = "kotlin.collections." - val mutablePrefix = "Mutable" - // java.util.List -> (Mutable)List! - val simpleCollection = replacePrefixes( - lowerRendered, - kotlinCollectionsPrefix + mutablePrefix, - upperRendered, - kotlinCollectionsPrefix, - "$kotlinCollectionsPrefix($mutablePrefix)" - ) - if (simpleCollection != null) return simpleCollection - // java.util.Map.Entry -> (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 - - val kotlinPrefix = "kotlin." - // Foo[] -> Array<(out) Foo!>! - val array = replacePrefixes( - lowerRendered, - kotlinPrefix + "Array<", - upperRendered, - kotlinPrefix + "Array { - require(isLocal) - var containingClassLookUp = containingClassForLocal() - val designation = mutableListOf(this) - @OptIn(LookupTagInternals::class) - while (containingClassLookUp != null && containingClassLookUp.classId.isLocal) { - val currentClass = containingClassLookUp.toFirRegularClass(moduleData.session) ?: break - designation.add(currentClass) - containingClassLookUp = currentClass.containingClassForLocal() - } - return designation - } - - private fun collectDesignationPathForLocal(declaration: FirDeclaration): List? { - @OptIn(LookupTagInternals::class) - val containingClass = when (declaration) { - is FirCallableDeclaration -> declaration.containingClassLookupTag()?.toFirRegularClass(declaration.moduleData.session) - is FirAnonymousObject -> return listOf(declaration) - is FirClassLikeDeclaration -> declaration.let { - if (!declaration.isLocal) return null - (it as? FirRegularClass)?.containingClassForLocal()?.toFirRegularClass(declaration.moduleData.session) - } - else -> error("Invalid declaration ${declaration.renderWithType()}") - } ?: return listOf(declaration) - - return if (containingClass.isLocal) { - containingClass.collectForLocal().reversed() - } else null - } - - private fun StringBuilder.renderTypeConstructorAndArguments(type: ConeClassLikeType) { - fun renderTypeArguments(typeArguments: Array, range: IntRange) { - if (range.any()) { - typeArguments.slice(range).joinTo(this, ", ", prefix = "<", postfix = ">") { - renderTypeProjection(it) - } - } - } - - val classSymbolToRender = type.lookupTag.toSymbol(session) - // To be able to render unresolved types like java.io.Serializable - val classId = classSymbolToRender?.classId ?: type.lookupTag.classId - - if (!options.shortQualifiedNames && !classId.isLocal) { - val packageName = classId.packageFqName.asString() - if (packageName.isNotEmpty()) { - append(packageName).append(".") - } - } - - if (classSymbolToRender !is FirRegularClassSymbol) { - append(classId.shortClassName) - if (type.typeArguments.any()) { - type.typeArguments.joinTo(this, ", ", prefix = "<", postfix = ">") { - renderTypeProjection(it) - } - } - return - } - - val designation = classSymbolToRender.fir.let { - val nonLocalDesignation = it.tryCollectDesignation() - nonLocalDesignation?.toSequence(includeTarget = true)?.toList() - ?: collectDesignationPathForLocal(it) - ?: emptyList() - } - - var typeParametersLeft = type.typeArguments.count() - fun needToRenderTypeParameters(index: Int): Boolean { - if (typeParametersLeft <= 0) return false - return index == designation.lastIndex || - (designation[index] as? FirRegularClass)?.isInner == true || - (designation[index + 1] as? FirRegularClass)?.isInner == true - } - - val classParentFqName = classId.relativeClassName.parent() - if (!classParentFqName.isRoot && designation.size == 1) { - // This code is added for a case we can't build designation (e.g. nested Java class), - // but still wish to render full class name - append(classParentFqName) - append(".") - } - - designation.filterIsInstance().forEachIndexed { index, currentClass -> - if (index != 0) append(".") - append(currentClass.name) - - if (needToRenderTypeParameters(index)) { - val typeParametersCount = currentClass.typeParameters.count { it is FirTypeParameter } - val begin = typeParametersLeft - typeParametersCount - val end = typeParametersLeft - check(begin >= 0) - typeParametersLeft -= typeParametersCount - renderTypeArguments(type.typeArguments, begin until end) - } - } - - renderNullability(type) - } - - private fun renderTypeProjection(typeProjection: ConeTypeProjection): String { - val type = typeProjection.type?.let(::renderType) ?: "???" - return when (typeProjection.kind) { - ProjectionKind.STAR -> "*" - ProjectionKind.IN -> "in $type" - ProjectionKind.OUT -> "out $type" - ProjectionKind.INVARIANT -> type - } - } - - private fun StringBuilder.renderFunctionType(type: ConeClassLikeType) { - val lengthBefore = length - val hasAnnotations = length != lengthBefore - - val isSuspend = type.isSuspendFunctionType(session) - val isNullable = type.isMarkedNullable - - val receiverType = type.receiverType(session) - - val needParenthesis = isNullable || (hasAnnotations && receiverType != null) - if (needParenthesis) { - if (isSuspend) { - insert(lengthBefore, '(') - } else { - if (hasAnnotations) { - check(last() == ' ') - if (get(lastIndex - 1) != ')') { - // last annotation rendered without parenthesis - need to add them otherwise parsing will be incorrect - insert(lastIndex, "()") - } - } - - append("(") - } - } - - if (isSuspend) { - append("suspend") - append(" ") - } - - if (receiverType != null) { - val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && - !receiverType.isMarkedNullable || - receiverType.isSuspendFunctionType(session) - if (surroundReceiver) { - append("(") - } - append(renderType(receiverType)) - if (surroundReceiver) { - append(")") - } - append(".") - } - - append("(") - - val notNullParametersType = type - .valueParameterTypesIncludingReceiver(session) - .applyIf(receiverType != null) { drop(1) } - - notNullParametersType.forEachIndexed { index, typeProjection -> - if (index != 0) append(", ") - append(renderTypeProjection(typeProjection)) - } - - append(") -> ") - - val returnType = type.returnType(session) - append(renderType(returnType)) - - if (needParenthesis) append(")") - - renderNullability(type) - } -} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirAnnotationsIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirAnnotationsIdeRenderer.kt deleted file mode 100644 index 32c12ebbffa..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirAnnotationsIdeRenderer.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.api.fir.renderer - -import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters -import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator -import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter -import org.jetbrains.kotlin.analysis.api.annotations.KtUnsupportedAnnotationValue -import org.jetbrains.kotlin.analysis.api.annotations.renderAsSourceCode -import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode -import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId -import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import kotlin.text.Appendable - -internal fun Appendable.renderAnnotations( - coneTypeIdeRenderer: ConeTypeIdeRenderer, - annotations: List, - session: FirSession, - isSingleLineAnnotations: Boolean, -) { - val separator = if (isSingleLineAnnotations) " " else "\n" - for (annotation in annotations) { - if (!annotation.isParameterName()) { - append(renderAnnotation(annotation, coneTypeIdeRenderer, session)) - append(separator) - } - } -} - - -private fun FirAnnotation.isParameterName(): Boolean { - return toAnnotationClassId()?.asSingleFqName() == StandardNames.FqNames.parameterName -} - -private fun renderAnnotation(annotation: FirAnnotation, coneTypeIdeRenderer: ConeTypeIdeRenderer, session: FirSession): String { - return buildString { - append('@') - val resolvedTypeRef = annotation.typeRef as? FirResolvedTypeRef - check(resolvedTypeRef != null) - append(coneTypeIdeRenderer.renderType(resolvedTypeRef.type)) - - val arguments = renderAndSortAnnotationArguments(annotation, session) - if (arguments.isNotEmpty()) { - arguments.joinTo(this, ", ", "(", ")") - } - } -} - -private fun renderAndSortAnnotationArguments(descriptor: FirAnnotation, session: FirSession): List { - val argumentList = mapAnnotationParameters(descriptor, session).entries.map { (name, value) -> - "$name = ${renderConstant(value, session)}" - } - return argumentList.sorted() -} - -private fun renderConstant(value: FirExpression, useSiteSession: FirSession): String { - val evaluated = FirCompileTimeConstantEvaluator.evaluate(value, KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION) - val constantValue = FirAnnotationValueConverter.toConstantValue(evaluated ?: value, useSiteSession) - ?: KtUnsupportedAnnotationValue - - return constantValue.renderAsSourceCode() -} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRenderer.kt deleted file mode 100644 index f5e5cd9af25..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRenderer.kt +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.api.fir.renderer - -import org.jetbrains.kotlin.KtFakeSourceElementKind -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter -import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint -import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.checkers.PsiSourceNavigator.getRawName -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.hasBody -import org.jetbrains.kotlin.fir.declarations.utils.isCompanion -import org.jetbrains.kotlin.fir.declarations.utils.visibility -import org.jetbrains.kotlin.fir.extensions.generatedMembers -import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.renderer.render - -internal class FirIdeRenderer private constructor( - options: KtDeclarationRendererOptions, - session: FirSession, -) : FirIdeRendererBase(options, session) { - fun PrettyPrinter.renderMemberDeclaration(declaration: FirDeclaration) { - when (declaration) { - is FirAnonymousObject -> renderAnonymousObject(declaration) - is FirRegularClass -> renderRegularClass(declaration) - is FirTypeAlias -> renderTypeAlias(declaration) - is FirConstructor -> renderConstructor(declaration) - is FirPropertyAccessor -> renderPropertyAccessor(declaration) - is FirSimpleFunction -> renderSimpleFunction(declaration) - is FirBackingField -> renderBackingField() - is FirEnumEntry -> renderEnumEntry(declaration) - is FirProperty -> renderPropertyOrField(declaration) - is FirValueParameter -> renderValueParameter(declaration) - is FirField -> renderPropertyOrField(declaration) - is FirErrorFunction -> error("FirErrorFunction should not be rendered") - is FirErrorProperty -> error("FirErrorProperty should not be rendered") - is FirAnonymousInitializer -> error("FirAnonymousInitializer should not be rendered") - is FirFile -> error("FirFile should not be rendered") - is FirTypeParameter -> renderTypeParameter(declaration) - is FirAnonymousFunction -> TODO() - } - } - - private fun PrettyPrinter.renderBackingField() { - append("field") - } - - private fun PrettyPrinter.renderPropertyOrField(variable: FirVariable) { - check(variable is FirProperty || variable is FirField) { - "Required either FirProperty or FirField but was ${variable::class.simpleName}" - } - renderAnnotationsAndModifiers(variable) - renderValVarPrefix(variable) - renderTypeParameters(variable) - renderReceiver(variable) - renderName(variable) - append(": ") - renderType(variable.returnTypeRef, approximate = options.approximateTypes) - - renderWhereSuffix(variable) - - fun FirPropertyAccessor?.needToRender() = this != null && (annotations.isNotEmpty() || visibility != variable.visibility) - val needToRenderAccessors = options.renderClassMembers && - (variable.getter.needToRender() || (variable.isVar && variable.setter.needToRender())) - - if (needToRenderAccessors) { - withIndent { - variable.getter?.let { getter -> - if (getter.needToRender()) { - appendLine() - renderPropertyAccessor(getter) - } - } - variable.setter?.let { setter -> - if (setter.needToRender()) { - appendLine() - renderPropertyAccessor(setter) - } - } - } - } - } - - private fun PrettyPrinter.renderPropertyAccessor(propertyAccessor: FirPropertyAccessor) { - renderAnnotationsAndModifiers(propertyAccessor) - append(if (propertyAccessor.isGetter) "get" else "set") - if (propertyAccessor.isSetter) { - append("(") - val valueParameter = propertyAccessor.valueParameters.first() - renderAnnotations(valueParameter) - append("value: ") - renderType(valueParameter.returnTypeRef) - append(")") - } else { - append("()") - } - renderFunctionBody(propertyAccessor) - } - - @Suppress("unused", "UNUSED_PARAMETER") - private fun PrettyPrinter.renderFunctionBody(function: FirFunction) { - // TODO implement with some settings - } - - private fun PrettyPrinter.renderSimpleFunction(simpleFunction: FirSimpleFunction) { - renderAnnotationsAndModifiers(simpleFunction) - append("fun ") - renderTypeParameters(simpleFunction) - renderReceiver(simpleFunction) - renderName(simpleFunction) - renderValueParameters(simpleFunction) - - val returnType = simpleFunction.returnTypeRef - if (options.renderUnitReturnType || !returnType.isUnit) { - append(": ") - renderType(returnType, approximate = options.approximateTypes) - append(' ') - } - - renderWhereSuffix(simpleFunction) - renderFunctionBody(simpleFunction) - } - - private fun PrettyPrinter.renderAnonymousObject(anonymousObject: FirAnonymousObject) { - renderAnnotationsAndModifiers(anonymousObject) - append("object ") - renderSuperTypes(anonymousObject) - renderClassBody(anonymousObject) - } - - private fun PrettyPrinter.renderClassBody(firClass: FirClass) { - if (!options.renderClassMembers) return - if (firClass.declarations.isEmpty()) return - - val allDeclarations = buildList { - firClass.declarations.filterNotTo(this) { member -> - member.isDefaultPrimaryConstructor() - || member.isDefaultEnumEntryMember(firClass) - || member is FirConstructor && firClass.classKind == ClassKind.OBJECT - } - addAll(firClass.generatedNestedClassifiers(useSiteSession)) - addAll(firClass.generatedMembers(useSiteSession)) - }.filterIsInstance() - if (allDeclarations.isEmpty()) return - - val (enumEntries, nonEnumEntries) = allDeclarations.partition { it is FirEnumEntry } - withIndentInBraces { - printCollection(sortDeclarations(enumEntries), separator = ",\n") { declaration -> - renderMemberDeclaration(declaration) - } - - if (enumEntries.isNotEmpty() && nonEnumEntries.isNotEmpty()) { - appendLine(";\n") - } - - printCollection(sortDeclarations(nonEnumEntries), separator = "\n\n") { declaration -> - renderMemberDeclaration(declaration) - } - } - } - - private fun PrettyPrinter.renderConstructor(constructor: FirConstructor) { - renderAnnotationsAndModifiers(constructor) - append("constructor") - renderValueParameters(constructor) - renderFunctionBody(constructor) - } - - private fun PrettyPrinter.renderRegularClass(regularClass: FirRegularClass) { - renderAnnotationsAndModifiers(regularClass) - renderClassifierKind(regularClass) - renderClassName(regularClass) - renderTypeParameters(regularClass) - printCharIfNotThere(' ') - renderSuperTypes(regularClass) - renderWhereSuffix(regularClass) - renderClassBody(regularClass) - } - - private fun PrettyPrinter.renderClassName(regularClass: FirRegularClass) { - if (!regularClass.isCompanion) { - renderName(regularClass) - } else { - if (regularClass.name != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) { - append(regularClass.name.render()) - } - } - } - - private fun PrettyPrinter.renderTypeAlias(typeAlias: FirTypeAlias) { - renderAnnotationsAndModifiers(typeAlias) - append("typealias ") - renderName(typeAlias) - renderTypeParameters(typeAlias) - printCharIfNotThere(' ') - append("= ") - renderType(typeAlias.expandedTypeRef) - } - - private fun PrettyPrinter.renderEnumEntry(enumEntry: FirEnumEntry) { - renderName(enumEntry) - } - - private fun PrettyPrinter.renderTypeParameter(typeParameter: FirTypeParameter) { - renderIf(typeParameter.isReified, "reified") - val variance = typeParameter.variance.label - renderIf(variance.isNotEmpty(), variance) - renderAnnotations(typeParameter) - renderName(typeParameter) - - val upperBoundsCount = typeParameter.bounds.size - if (upperBoundsCount >= 1) { - val upperBound = typeParameter.bounds.first() - if (!upperBound.isNullableAny) { - append(" : ") - renderType(upperBound) - } - } - } - - private fun PrettyPrinter.renderTypeParameters(declaration: FirMemberDeclaration) { - val typeParameters = declaration.typeParameters.filterIsInstance() - if (typeParameters.isNotEmpty()) { - append("<") - printCollection(typeParameters) { - renderTypeParameter(it) - } - append("> ") - } - } - - private fun PrettyPrinter.renderReceiver(firCallableDeclaration: FirCallableDeclaration) { - val receiverType = firCallableDeclaration.receiverTypeRef - if (receiverType != null) { - if (options.renderDeclarationHeader) { - renderAnnotations(firCallableDeclaration) - } - - val needBrackets = - typeIdeRenderer.shouldRenderAsPrettyFunctionType(receiverType.coneType) && receiverType.isMarkedNullable == true - - if (needBrackets) append('(') - renderType(receiverType) - if (needBrackets) append(')') - append(".") - } - } - - private fun PrettyPrinter.renderWhereSuffix(declaration: FirTypeParameterRefsOwner) { - val upperBoundStrings = ArrayList(0) - - for (typeParameter in declaration.typeParameters) { - if (typeParameter !is FirTypeParameter) continue - typeParameter.symbol.resolvedBounds - .drop(1) // first parameter is rendered by renderTypeParameter - .mapTo(upperBoundStrings) { typeParameter.name.render() + " : " + renderTypeToString(it.coneType) } - } - - if (upperBoundStrings.isNotEmpty()) { - append("where ") - upperBoundStrings.joinTo(this, ", ") - append(' ') - } - } - - private fun PrettyPrinter.renderValueParameters(function: FirFunction) { - printCollection(function.valueParameters, prefix = "(", postfix = ")") { - renderValueParameter(it) - } - } - - private fun PrettyPrinter.renderValueParameter(valueParameter: FirValueParameter) { - if (options.renderDeclarationHeader) { - renderAnnotations(valueParameter) - } - renderIf(valueParameter.isCrossinline, "crossinline") - renderIf(valueParameter.isNoinline, "noinline") - renderVariable(valueParameter) - - if (options.renderDefaultParameterValue) { - val withDefaultValue = valueParameter.defaultValue != null //TODO check if default value is inherited - if (withDefaultValue) { - append(" = ...") - } - } - } - - private fun PrettyPrinter.renderValVarPrefix(variable: FirVariable, isInPrimaryConstructor: Boolean = false) { - if (!isInPrimaryConstructor || variable !is FirValueParameter) { - append(if (variable.isVar) "var" else "val") - append(' ') - } - } - - private fun PrettyPrinter.renderVariable(variable: FirVariable) { - val typeToRender = variable.returnTypeRef.coneType - val isVarArg = (variable as? FirValueParameter)?.isVararg ?: false - renderIf(isVarArg, "vararg") - renderName(variable) - append(": ") - if (isVarArg) { - renderType(typeToRender.arrayElementType() ?: typeToRender) - } else { - renderType(typeToRender) - } - } - - fun sortDeclarations(declarations: List): List { - if (!options.sortNestedDeclarations) return declarations - - fun getDeclarationKind(declaration: FirDeclaration): Int = when (declaration) { - is FirEnumEntry -> 0 - is FirConstructor -> if (declaration.isPrimary) 1 else 2 - is FirProperty -> 3 - is FirFunction -> 4 - else -> 5 - } - - return declarations.sortedWith(Comparator { left, right -> - val kindResult = getDeclarationKind(left) - getDeclarationKind(right) - if (kindResult != 0) { - return@Comparator kindResult - } - - val nameResult = (left.getRawName() ?: "").compareTo(right.getRawName() ?: "") - if (nameResult != 0) { - return@Comparator nameResult - } - - val leftString = prettyPrint { renderMemberDeclaration(left) } - val rightString = prettyPrint { renderMemberDeclaration(right) } - return@Comparator leftString.compareTo(rightString) - }) - } - - - companion object { - fun render( - firDeclaration: FirDeclaration, - options: KtDeclarationRendererOptions, - session: FirSession - ): String { - val renderer = FirIdeRenderer(options, session) - return prettyPrint { - with(renderer) { renderMemberDeclaration(firDeclaration) } - }.trim { it.isWhitespace() } - } - } -} - -private fun FirDeclaration.isDefaultEnumEntryMember(firClass: FirClass): Boolean { - if (firClass.classKind != ClassKind.ENUM_CLASS) return false - if (this is FirConstructor) return isPrimary && valueParameters.isEmpty() - return source?.kind == KtFakeSourceElementKind.EnumGeneratedDeclaration -} - -private fun FirDeclaration.isDefaultPrimaryConstructor() = - this is FirConstructor && - isPrimary && - valueParameters.isEmpty() && - !hasBody && - visibility == Visibilities.DEFAULT_VISIBILITY diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRendererBase.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRendererBase.kt deleted file mode 100644 index 2ceb3feefd4..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/FirIdeRendererBase.kt +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.api.fir.renderer - -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.RendererModifier -import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator -import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.checkers.classKind -import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol -import org.jetbrains.kotlin.fir.containingClassLookupTag -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.* -import org.jetbrains.kotlin.fir.resolve.defaultType -import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.renderer.render -import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly -import org.jetbrains.kotlin.utils.addToStdlib.applyIf -import org.jetbrains.kotlin.utils.addToStdlib.ifTrue - -internal abstract class FirIdeRendererBase( - protected val options: KtDeclarationRendererOptions, - protected val useSiteSession: FirSession, -) { - protected val typeIdeRenderer: ConeTypeIdeRenderer = ConeTypeIdeRenderer(useSiteSession, options.typeRendererOptions) - - protected fun PrettyPrinter.renderAnnotations(declaration: FirDeclaration) { - if (RendererModifier.ANNOTATIONS in options.modifiers) { - val isSingleLineAnnotations = declaration is FirValueParameter || declaration is FirTypeParameter - renderAnnotations(typeIdeRenderer, declaration.annotations, useSiteSession, isSingleLineAnnotations) - } - } - - protected fun renderTypeToString(type: ConeTypeProjection): String { - return typeIdeRenderer.renderType(type) - } - - protected fun PrettyPrinter.renderType(type: ConeTypeProjection) { - append(renderTypeToString(type)) - } - - protected fun PrettyPrinter.renderType(firRef: FirTypeRef, approximate: Boolean = false) { - val coneType = firRef.coneType - val approximatedIfNeeded = approximate.ifTrue { - PublicTypeApproximator.approximateTypeToPublicDenotable(coneType, useSiteSession, approximateLocalTypes = true) - } ?: coneType - renderType(approximatedIfNeeded) - } - - protected fun PrettyPrinter.renderName(declaration: FirDeclaration) { - if (declaration is FirAnonymousObject) { - append("") - return - } - val name = when (declaration) { - is FirRegularClass -> declaration.name - is FirSimpleFunction -> declaration.name - is FirProperty -> declaration.name - is FirValueParameter -> declaration.name - is FirTypeParameter -> declaration.name - is FirTypeAlias -> declaration.name - is FirEnumEntry -> declaration.name - is FirField -> declaration.name - else -> TODO("Unexpected declaration ${declaration::class.qualifiedName}") - } - append(name.render()) - } - - private fun PrettyPrinter.renderVisibility(declaration: FirMemberDeclaration) { - if (declaration is FirConstructor && declaration.containingClassLookupTag()?.toFirRegularClassSymbol(useSiteSession)?.isEnumClass == true) { - return - } - val visibility = declaration.visibility - if (RendererModifier.VISIBILITY !in options.modifiers) return - - val currentVisibility = when (visibility) { - Visibilities.Local -> Visibilities.Public - Visibilities.PrivateToThis -> Visibilities.Public - Visibilities.InvisibleFake -> Visibilities.Public - Visibilities.Inherited -> Visibilities.Public - Visibilities.Unknown -> Visibilities.Public - else -> visibility - }.applyIf(options.normalizedVisibilities) { - normalize() - } - - if (currentVisibility == Visibilities.DEFAULT_VISIBILITY) return - append(currentVisibility.internalDisplayName) - append(' ') - } - - private fun PrettyPrinter.renderModality(memberDeclaration: FirMemberDeclaration) { - val modality = memberDeclaration.modality ?: return - if ((memberDeclaration as? FirRegularClass)?.isInterface == true) return - if (modality == Modality.FINAL) return - if (memberDeclaration.getContainingClassSymbol(useSiteSession)?.classKind == ClassKind.INTERFACE) return - if (memberDeclaration.isOverride) return - renderIf(RendererModifier.MODALITY in options.modifiers, modality.name.toLowerCaseAsciiOnly()) - } - - - private fun PrettyPrinter.renderOverride(callableMember: FirMemberDeclaration) { - if (RendererModifier.OVERRIDE !in options.modifiers) return - renderIf(callableMember.isOverride || options.forceRenderingOverrideModifier, "override") - } - - protected fun PrettyPrinter.renderIf(value: Boolean, text: String) { - if (value) { - append(text) - append(" ") - } - } - - protected fun PrettyPrinter.renderAnnotationsAndModifiers(declaration: FirMemberDeclaration) { - if (!options.renderDeclarationHeader) return - renderAnnotations(declaration) - renderVisibility(declaration) - renderOverride(declaration) - renderModality(declaration) - renderIf(declaration.isExternal, "external") - renderIf(RendererModifier.EXPECT in options.modifiers && declaration.isExpect, "expect") - renderIf(RendererModifier.ACTUAL in options.modifiers && declaration.isActual, "actual") - renderIf(declaration.isTailRec, "tailrec") - renderIf(declaration.isConst, "const") - renderIf(declaration.isInner, "inner") - renderIf(declaration.isLateInit, "lateinit") - renderIf(declaration.isSuspend, "suspend") - renderIf(declaration.isInline, "inline") - renderIf(declaration.isInfix, "infix") - renderIf(RendererModifier.OPERATOR in options.modifiers && declaration.isOperator, "operator") - } - - protected fun PrettyPrinter.renderClassifierKind(classifier: FirDeclaration) { - when (classifier) { - is FirTypeAlias -> append("typealias") - is FirRegularClass -> - append(if (classifier.isCompanion) "companion object" else classifier.classKind.codeRepresentation) - is FirAnonymousObject -> append("object") - is FirEnumEntry -> append("enum entry") - else -> - throw AssertionError("Unexpected classifier: $classifier") - } - append(' ') - } - - - protected fun PrettyPrinter.renderSuperTypes(klass: FirClass) { - if (klass.defaultType().isNothing) return - - val supertypes = klass.superTypeRefs.asSequence() - .applyIf(klass.classKind == ClassKind.ENUM_CLASS) { - filterNot { - it.coneType.classId == StandardClassIds.Enum - } - }.applyIf(klass.classKind == ClassKind.ANNOTATION_CLASS) { - filterNot { - it.coneType.classId == StandardClassIds.Annotation - } - }.toList() - - if (supertypes.isEmpty() || klass.superTypeRefs.singleOrNull()?.isAny == true) return - - append(": ") - printCollection(supertypes) { - renderType(it) - } - append(' ') - } -} - diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/containingDeclarationProvider/AbstractContainingDeclarationProviderByMemberScopeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/containingDeclarationProvider/AbstractContainingDeclarationProviderByMemberScopeTest.kt index b077ba963cb..0b391d020b8 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/containingDeclarationProvider/AbstractContainingDeclarationProviderByMemberScopeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/containingDeclarationProvider/AbstractContainingDeclarationProviderByMemberScopeTest.kt @@ -5,8 +5,6 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider -import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.renderScopeWithParentDeclarations import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt index dfd82818548..9dc2c57dc0b 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolDeclarationRendererProvider.kt @@ -11,124 +11,9 @@ import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclaratio import org.jetbrains.kotlin.analysis.api.renderer.types.KtTypeRenderer import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.types.Variance -/** - * KtType to string renderer options - * @see KtType - * @see KtSymbolDeclarationRendererProvider.renderType - */ -public data class KtTypeRendererOptions( - /** - * Render type name without package name for not local types - */ - public val shortQualifiedNames: Boolean = false, - /** - * Render public function types public functionN using Kotlin public function type syntax - * @see public function - * @sample public function0 returns () -> Int - */ - public val renderFunctionType: Boolean = true, - - /** - * When met type with unresolved qualifier, render it as it is resolved - * When `true` will render as `UnresolvedQualifier` - * When `false` will render as "ERROR_TYPE " - */ - public val renderUnresolvedTypeAsResolved: Boolean = true, - - /** - * Should annotations on types be rendered. - */ - public val renderTypeAnnotations: Boolean = true -) { - public companion object { - public val DEFAULT: KtTypeRendererOptions = KtTypeRendererOptions() - public val SHORT_NAMES: KtTypeRendererOptions = DEFAULT.copy(shortQualifiedNames = true) - } -} - -/** - * KtSymbol to string renderer options - * @see KtSymbol - * @see KtSymbolDeclarationRendererProvider.renderType - */ -public data class KtDeclarationRendererOptions( - /** - * Set of modifiers that needed to be rendered - * @see RendererModifier - */ - val modifiers: Set = RendererModifier.ALL, - /** - * Type render options @see KtTypeRendererOptions - * @see KtTypeRendererOptions - */ - val typeRendererOptions: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT, - /** - * Render Unit return type for public functions - */ - val renderUnitReturnType: Boolean = false, - /** - * Normalize java-specific visibilities for java declaration - */ - val normalizedVisibilities: Boolean = false, - /** - * Render members of a classes and objects if any - */ - val renderClassMembers: Boolean = false, - /** - * Approximate Kotlin not-denotable types into denotable for declarations return type - */ - val approximateTypes: Boolean = false, - - /** - * Declaration header is something like `public abstract class`, `public fun`, or `private public interface ` in a declaration. - */ - val renderDeclarationHeader: Boolean = true, - - /** - * Whether to forcefully add `override` modifier when rendering public functions or properties. Note that the [modifiers] option still - * controls whether `override` is rendered. That is, if [modifiers] don't contain `override`, then this flag does not have any effect. - */ - val forceRenderingOverrideModifier: Boolean = false, - - val renderDefaultParameterValue: Boolean = true, - - /** - * Sort nested declarations by kind (enum values, then constructors, then properties, then functions) and name. - */ - val sortNestedDeclarations: Boolean = false, -) { - public companion object { - public val DEFAULT: KtDeclarationRendererOptions = KtDeclarationRendererOptions() - } -} - -public enum class RendererModifier(public val includeByDefault: Boolean) { - VISIBILITY(true), - MODALITY(true), - OVERRIDE(true), - ANNOTATIONS(false), - INNER(true), - DATA(true), - INLINE(true), - EXPECT(true), - ACTUAL(true), - CONST(true), - LATEINIT(true), - FUN(true), - VALUE(true), - OPERATOR(true) - ; - - public companion object { - public val ALL: Set = values().toSet() - public val DEFAULT: Set = values().filterTo(mutableSetOf()) { it.includeByDefault } - public val NONE: Set = emptySet() - } -} public abstract class KtSymbolDeclarationRendererProvider : KtAnalysisSessionComponent() { public abstract fun renderDeclaration(symbol: KtDeclarationSymbol, renderer: KtDeclarationRenderer): String