DescriptorRenderer to render annotations for all types + separate option to render annotation arguments + use it in IdeDescriptorRenderers

This commit is contained in:
Valentin Kipyatkov
2016-09-30 21:34:22 +03:00
parent 8baa9ba1de
commit ec51076355
373 changed files with 1433 additions and 1355 deletions
@@ -178,6 +178,7 @@ interface DescriptorRendererOptions {
var textFormat: RenderingFormat
var excludedAnnotationClasses: Set<FqName>
var excludedTypeAnnotationClasses: Set<FqName>
var includeAnnotationArguments: Boolean
var includePropertyConstant: Boolean
var parameterNameRenderingPolicy: ParameterNameRenderingPolicy
var withoutTypeParameters: Boolean
@@ -223,7 +224,9 @@ object ExcludedTypeAnnotations {
val internalAnnotationsForResolve = setOf(
FqName("kotlin.internal.NoInfer"),
FqName("kotlin.internal.Exact"),
KotlinBuiltIns.FQ_NAMES.parameterName)
KotlinBuiltIns.FQ_NAMES.extensionFunctionType,
KotlinBuiltIns.FQ_NAMES.parameterName
)
}
enum class RenderingFormat {
@@ -175,6 +175,7 @@ internal class DescriptorRendererImpl(
}
return
}
if (type.isError) {
renderDefaultType(type)
return
@@ -227,7 +228,7 @@ internal class DescriptorRendererImpl(
}
private fun StringBuilder.renderDefaultType(type: KotlinType) {
renderAnnotations(type, this)
this.renderAnnotations(type)
if (type.isError) {
append(type.constructor.toString()) // Debug name of an error type is more informative
@@ -292,10 +293,25 @@ internal class DescriptorRendererImpl(
}
private fun StringBuilder.renderFunctionType(type: KotlinType) {
val isNullable = type.isMarkedNullable
if (isNullable) append("(")
val lengthBefore = length
renderAnnotations(type)
val hasAnnotations = length != lengthBefore
val isNullable = type.isMarkedNullable
val receiverType = type.getReceiverTypeFromFunctionType()
val needParenthesis = isNullable || (hasAnnotations && receiverType != null)
if (needParenthesis && hasAnnotations) {
assert(last() == ' ')
if (get(lastIndex - 1) != ')') {
// last annotation rendered without parenthesis - need to add them otherwise parsing will be incorrect
insert(lastIndex, "()")
}
}
if (needParenthesis) append("(")
if (receiverType != null) {
val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable
if (surroundReceiver) {
@@ -325,7 +341,9 @@ internal class DescriptorRendererImpl(
append(") ").append(arrow()).append(" ")
renderNormalizedType(type.getReturnTypeFromFunctionType())
if (isNullable) append(")?")
if (needParenthesis) append(")")
if (isNullable) append("?")
}
@@ -346,27 +364,24 @@ internal class DescriptorRendererImpl(
append(if (fqName.isRoot) "root package" else renderFqName(fqName))
}
}
private fun renderAnnotations(annotated: Annotated, builder: StringBuilder) {
private fun StringBuilder.renderAnnotations(annotated: Annotated) {
if (DescriptorRendererModifier.ANNOTATIONS !in modifiers) return
val excluded = if (annotated is KotlinType) excludedTypeAnnotationClasses else excludedAnnotationClasses
val annotationsBuilder = StringBuilder().apply {
// Sort is needed just to fix some order when annotations resolved from modifiers
// See AnnotationResolver.resolveAndAppendAnnotationsFromModifiers for clarification
// This hack can be removed when modifiers will be resolved without annotations
// Sort is needed just to fix some order when annotations resolved from modifiers
// See AnnotationResolver.resolveAndAppendAnnotationsFromModifiers for clarification
// This hack can be removed when modifiers will be resolved without annotations
val sortedAnnotations = annotated.annotations.getAllAnnotations()
for ((annotation, target) in sortedAnnotations) {
val annotationClass = annotation.type.constructor.declarationDescriptor as ClassDescriptor
val sortedAnnotations = annotated.annotations.getAllAnnotations()
for ((annotation, target) in sortedAnnotations) {
val annotationClass = annotation.type.constructor.declarationDescriptor as ClassDescriptor
if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) {
append(renderAnnotation(annotation, target)).append(" ")
}
if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) {
append(renderAnnotation(annotation, target)).append(" ")
}
}
builder.append(annotationsBuilder)
}
override fun renderAnnotation(annotation: AnnotationDescriptor, target: AnnotationUseSiteTarget?): String {
@@ -377,12 +392,17 @@ internal class DescriptorRendererImpl(
}
val annotationType = annotation.type
append(renderType(annotationType))
if (verbose) {
renderAndSortAnnotationArguments(annotation).joinTo(this, ", ", "(", ")")
if (annotationType.isError || annotationType.constructor.declarationDescriptor is NotFoundClasses.MockClassDescriptor) {
append(" /* annotation class not found */")
if (includeAnnotationArguments) {
val arguments = renderAndSortAnnotationArguments(annotation)
if (arguments.isNotEmpty()) {
arguments.joinTo(this, ", ", "(", ")")
}
}
if (verbose && (annotationType.isError || annotationType.constructor.declarationDescriptor is NotFoundClasses.MockClassDescriptor)) {
append(" /* annotation class not found */")
}
}
}
@@ -526,7 +546,7 @@ internal class DescriptorRendererImpl(
builder.append(renderKeyword(variance)).append(" ")
}
renderAnnotations(typeParameter, builder)
builder.renderAnnotations(typeParameter)
renderName(typeParameter, builder)
val upperBoundsCount = typeParameter.upperBounds.size
@@ -588,7 +608,7 @@ internal class DescriptorRendererImpl(
/* FUNCTIONS */
private fun renderFunction(function: FunctionDescriptor, builder: StringBuilder) {
if (!startFromName) {
renderAnnotations(function, builder)
builder.renderAnnotations(function)
renderVisibility(function.visibility, builder)
renderModalityForCallable(function, builder)
@@ -650,7 +670,7 @@ internal class DescriptorRendererImpl(
}
private fun renderConstructor(constructor: ConstructorDescriptor, builder: StringBuilder) {
renderAnnotations(constructor, builder)
builder.renderAnnotations(constructor)
renderVisibility(constructor.visibility, builder)
renderMemberKind(constructor, builder)
@@ -724,7 +744,7 @@ internal class DescriptorRendererImpl(
builder.append("/*").append(valueParameter.index).append("*/ ")
}
renderAnnotations(valueParameter, builder)
builder.renderAnnotations(valueParameter)
if (valueParameter.isCrossinline) {
builder.append("crossinline ")
@@ -781,7 +801,7 @@ internal class DescriptorRendererImpl(
private fun renderProperty(property: PropertyDescriptor, builder: StringBuilder) {
if (!startFromName) {
renderAnnotations(property, builder)
builder.renderAnnotations(property)
renderVisibility(property.visibility, builder)
if (property.isConst) {
@@ -816,7 +836,7 @@ internal class DescriptorRendererImpl(
}
private fun renderTypeAlias(typeAlias: TypeAliasDescriptor, builder: StringBuilder) {
renderAnnotations(typeAlias, builder)
builder.renderAnnotations(typeAlias)
renderVisibility(typeAlias.visibility, builder)
builder.append(renderKeyword("typealias")).append(" ")
renderName(typeAlias, builder)
@@ -843,7 +863,7 @@ internal class DescriptorRendererImpl(
val isEnumEntry = klass.kind == ClassKind.ENUM_ENTRY
if (!startFromName) {
renderAnnotations(klass, builder)
builder.renderAnnotations(klass)
if (!isEnumEntry) {
renderVisibility(klass.visibility, builder)
}
@@ -874,7 +894,7 @@ internal class DescriptorRendererImpl(
val primaryConstructor = klass.unsubstitutedPrimaryConstructor
if (primaryConstructor != null) {
builder.append(" ")
renderAnnotations(primaryConstructor, builder)
builder.renderAnnotations(primaryConstructor)
renderVisibility(primaryConstructor.visibility, builder)
builder.append("constructor")
renderValueParameters(primaryConstructor.valueParameters, primaryConstructor.hasSynthesizedParameterNames(), builder)
@@ -97,6 +97,8 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions {
ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
+ ExcludedTypeAnnotations.internalAnnotationsForResolve)
override var includeAnnotationArguments: Boolean by property(false)
override var alwaysRenderModifiers by property(false)
override var renderConstructorKeyword by property(true)
@@ -39,6 +39,7 @@ public class MemberComparator implements Comparator<DeclarationDescriptor> {
public Unit invoke(DescriptorRendererOptions options) {
options.setWithDefinedIn(false);
options.setVerbose(true);
options.setIncludeAnnotationArguments(true);
options.setModifiers(DescriptorRendererModifier.ALL);
return Unit.INSTANCE;
}