From d7c810a4d032d3cfbedc70a55ce6d2657be77a2d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 10 Apr 2015 18:50:12 +0300 Subject: [PATCH] Copy only nullability/mutability annotations to types Also don't render copied annotations --- .../tests/annotations/typeAnnotations.txt | 4 ++-- .../FunctionWithMissingNames.txt | 6 ++--- .../AbstractJvmRuntimeDescriptorLoaderTest.kt | 8 ++----- .../kotlin/load/java/JvmAnnotationNames.java | 10 ++++++++ .../java/lazy/types/LazyJavaTypeResolver.kt | 16 +++++++++---- .../renderer/DescriptorRendererBuilder.java | 23 +++++++++++++++---- .../renderer/DescriptorRendererImpl.java | 8 +++++-- 7 files changed, 53 insertions(+), 22 deletions(-) diff --git a/compiler/testData/diagnostics/tests/annotations/typeAnnotations.txt b/compiler/testData/diagnostics/tests/annotations/typeAnnotations.txt index 306979dda44..fd97850b6c7 100644 --- a/compiler/testData/diagnostics/tests/annotations/typeAnnotations.txt +++ b/compiler/testData/diagnostics/tests/annotations/typeAnnotations.txt @@ -1,6 +1,6 @@ -package +package -internal fun A.foo(/*0*/ a: kotlin.Int): kotlin.Unit +internal fun [[ERROR : x]()] A.foo(/*0*/ a: [[ERROR : x]()] kotlin.Int): kotlin.Unit internal final class A { public constructor A() diff --git a/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.txt b/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.txt index fbe124fd600..23271620703 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.txt +++ b/compiler/testData/diagnostics/tests/declarationChecks/FunctionWithMissingNames.txt @@ -1,10 +1,10 @@ -package +package a() internal fun (): kotlin.Unit internal fun (): kotlin.Unit internal fun outerFun(): kotlin.Unit internal fun A.(): kotlin.Unit -internal fun A.(): kotlin.Unit +internal fun [a()] A.(): kotlin.Unit internal trait A { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -25,8 +25,8 @@ internal final class Outer { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - internal final fun A.(): kotlin.Unit internal final fun B.(): kotlin.Unit + internal final fun [a()] A.(): kotlin.Unit } internal final annotation class a : kotlin.Annotation { diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt index 08e69e7d34c..cce5d63a04e 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt @@ -58,12 +58,8 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi // TODO: add these annotations when they are retained at runtime "kotlin.deprecated", "kotlin.data", - "kotlin.inline", - "org.jetbrains.annotations.NotNull", - "org.jetbrains.annotations.Nullable", - "org.jetbrains.annotations.Mutable", - "org.jetbrains.annotations.ReadOnly" - ).map { FqName(it) }) + "kotlin.inline" + ).map { FqName(it) } + JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES) .setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE) .setParameterNameRenderingPolicy(DescriptorRenderer.ParameterNameRenderingPolicy.NONE) .setIncludePropertyConstant(false) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 2822b29f437..1ec733c4758 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.load.java; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; @@ -98,6 +99,15 @@ public final class JvmAnnotationNames { @Deprecated public static final FqName OLD_KOTLIN_TRAIT_IMPL = new FqName("jet.KotlinTraitImpl"); + // When these annotations appear on a declaration, they are copied to the _type_ of the declaration, becoming type annotations + // See also DescriptorRendererBuilder#excludedTypeAnnotationClasses + public static final Set ANNOTATIONS_COPIED_TO_TYPES = KotlinPackage.setOf( + JETBRAINS_READONLY_ANNOTATION, + JETBRAINS_MUTABLE_ANNOTATION, + JETBRAINS_NOT_NULL_ANNOTATION, + JETBRAINS_NULLABLE_ANNOTATION + ); + private static final Set SPECIAL_ANNOTATIONS = new HashSet(); private static final Set NULLABILITY_ANNOTATIONS = new HashSet(); static { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 7e4973dd794..4291436540c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.components.TypeUsage.* @@ -93,7 +94,7 @@ class LazyJavaTypeResolver( val projectionKind = if (attr.howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT || isVararg) OUT_VARIANCE else INVARIANT val result = c.module.builtIns.getArrayType(projectionKind, componentType) return@run TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull) - }.replaceAnnotations(attr.annotations) + }.replaceAnnotations(attr.typeAnnotations) } fun makeStarProjection( @@ -291,7 +292,7 @@ class LazyJavaTypeResolver( override fun isMarkedNullable(): Boolean = nullable() - override fun getAnnotations() = attr.annotations + override fun getAnnotations() = attr.typeAnnotations } public object FlexibleJavaClassifierTypeCapabilities : FlexibleTypeCapabilities { @@ -351,7 +352,7 @@ trait JavaTypeAttributes { get() = INFLEXIBLE val allowFlexible: Boolean get() = true - val annotations: Annotations + val typeAnnotations: Annotations val isForAnnotationParameter: Boolean get() = false } @@ -366,10 +367,15 @@ class LazyJavaTypeAttributes( c: LazyJavaResolverContext, val annotationOwner: JavaAnnotationOwner, override val howThisTypeIsUsed: TypeUsage, - override val annotations: Annotations, + annotations: Annotations, override val allowFlexible: Boolean = true, override val isForAnnotationParameter: Boolean = false ): JavaTypeAttributes { + override val typeAnnotations: Annotations by c.storageManager.createLazyValue { + AnnotationsImpl(JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES.map { fqName -> + annotations.findAnnotation(fqName) + }.filterNotNull()) + } override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue { if (annotations.isMarkedReadOnly() && !annotations.isMarkedMutable()) @@ -395,7 +401,7 @@ fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParamet override val isMarkedNotNull: Boolean = false override val allowFlexible: Boolean = allowFlexible - override val annotations: Annotations = Annotations.EMPTY + override val typeAnnotations: Annotations = Annotations.EMPTY override val isForAnnotationParameter: Boolean = isForAnnotationParameter } diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererBuilder.java b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererBuilder.java index 6bebd4f444f..34e9d4c83de 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererBuilder.java +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererBuilder.java @@ -61,6 +61,14 @@ public class DescriptorRendererBuilder { private boolean renderCompanionObjectName = false; private boolean renderAccessors = false; + // See JvmAnnotationNames#ANNOTATIONS_COPIED_TO_TYPES + private Collection excludedTypeAnnotationClasses = KotlinPackage.setOf( + new FqName("org.jetbrains.annotations.ReadOnly"), + new FqName("org.jetbrains.annotations.Mutable"), + new FqName("org.jetbrains.annotations.NotNull"), + new FqName("org.jetbrains.annotations.Nullable") + ); + public DescriptorRendererBuilder() { } @@ -153,6 +161,12 @@ public class DescriptorRendererBuilder { return this; } + @NotNull + public DescriptorRendererBuilder setExcludedTypeAnnotationClasses(@NotNull Collection excludedTypeAnnotationClasses) { + this.excludedTypeAnnotationClasses = excludedTypeAnnotationClasses; + return this; + } + @NotNull public DescriptorRendererBuilder setPrettyFunctionTypes(boolean prettyFunctionTypes) { this.prettyFunctionTypes = prettyFunctionTypes; @@ -236,10 +250,11 @@ public class DescriptorRendererBuilder { return new DescriptorRendererImpl( nameShortness, withDefinedIn, modifiers, startFromName, debugMode, classWithPrimaryConstructor, verbose, unitReturnType, normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName, - overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant, - parameterNameRenderingPolicy, withoutTypeParameters, receiverAfterName, renderCompanionObjectName, withoutSuperTypes, - typeNormalizer, renderDefaultValues, flexibleTypesForCode, secondaryConstructorsAsPrimary, - renderAccessors); + overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, excludedTypeAnnotationClasses, + includePropertyConstant, parameterNameRenderingPolicy, withoutTypeParameters, receiverAfterName, renderCompanionObjectName, + withoutSuperTypes, typeNormalizer, renderDefaultValues, flexibleTypesForCode, secondaryConstructorsAsPrimary, + renderAccessors + ); } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java index 441aa3620d6..275bd81f010 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java @@ -43,7 +43,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject; import static org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE; public class DescriptorRendererImpl implements DescriptorRenderer { - private final Function1 typeNormalizer; private final NameShortness nameShortness; private final boolean withDefinedIn; @@ -70,6 +69,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private final boolean includePropertyConstant; private final boolean secondaryConstructorsAsPrimary; private final Set excludedAnnotationClasses; + private final Set excludedTypeAnnotationClasses; private final boolean renderAccessors; /* package */ DescriptorRendererImpl( @@ -89,6 +89,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull ValueParametersHandler handler, @NotNull TextFormat textFormat, @NotNull Collection excludedAnnotationClasses, + @NotNull Collection excludedTypeAnnotationClasses, boolean includePropertyConstant, @NotNull ParameterNameRenderingPolicy parameterNameRenderingPolicy, boolean withoutTypeParameters, @@ -118,6 +119,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { this.secondaryConstructorsAsPrimary = secondaryConstructorsAsPrimary; this.renderAccessors = renderAccessors; this.excludedAnnotationClasses = new HashSet(excludedAnnotationClasses); + this.excludedTypeAnnotationClasses = new HashSet(excludedTypeAnnotationClasses); this.prettyFunctionTypes = prettyFunctionTypes; this.uninferredTypeParameterAsName = uninferredTypeParameterAsName; this.parameterNameRenderingPolicy = parameterNameRenderingPolicy; @@ -538,12 +540,14 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private void renderAnnotations(@NotNull Annotated annotated, @NotNull StringBuilder builder, boolean needBrackets) { if (!modifiers.contains(Modifier.ANNOTATIONS)) return; + Set excluded = annotated instanceof JetType ? excludedTypeAnnotationClasses : excludedAnnotationClasses; + StringBuilder annotationsBuilder = new StringBuilder(); for (AnnotationDescriptor annotation : annotated.getAnnotations()) { ClassDescriptor annotationClass = (ClassDescriptor) annotation.getType().getConstructor().getDeclarationDescriptor(); assert annotationClass != null; - if (!excludedAnnotationClasses.contains(DescriptorUtils.getFqNameSafe(annotationClass))) { + if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) { annotationsBuilder.append(renderAnnotation(annotation)).append(" "); } }