Copy only nullability/mutability annotations to types

Also don't render copied annotations
This commit is contained in:
Alexander Udalov
2015-04-10 18:50:12 +03:00
parent 3369da94e4
commit d7c810a4d0
7 changed files with 53 additions and 22 deletions
@@ -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 { internal final class A {
public constructor A() public constructor A()
@@ -1,10 +1,10 @@
package package
a() internal fun <no name provided>(): kotlin.Unit a() internal fun <no name provided>(): kotlin.Unit
internal fun <no name provided>(): kotlin.Unit internal fun <no name provided>(): kotlin.Unit
internal fun outerFun(): kotlin.Unit internal fun outerFun(): kotlin.Unit
internal fun A.<no name provided>(): kotlin.Unit internal fun A.<no name provided>(): kotlin.Unit
internal fun A.<no name provided>(): kotlin.Unit internal fun [a()] A.<no name provided>(): kotlin.Unit
internal trait A { internal trait A {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean 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 equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final fun A.<no name provided>(): kotlin.Unit
internal final fun B.<no name provided>(): kotlin.Unit internal final fun B.<no name provided>(): kotlin.Unit
internal final fun [a()] A.<no name provided>(): kotlin.Unit
} }
internal final annotation class a : kotlin.Annotation { internal final annotation class a : kotlin.Annotation {
@@ -58,12 +58,8 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
// TODO: add these annotations when they are retained at runtime // TODO: add these annotations when they are retained at runtime
"kotlin.deprecated", "kotlin.deprecated",
"kotlin.data", "kotlin.data",
"kotlin.inline", "kotlin.inline"
"org.jetbrains.annotations.NotNull", ).map { FqName(it) } + JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES)
"org.jetbrains.annotations.Nullable",
"org.jetbrains.annotations.Mutable",
"org.jetbrains.annotations.ReadOnly"
).map { FqName(it) })
.setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE) .setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE)
.setParameterNameRenderingPolicy(DescriptorRenderer.ParameterNameRenderingPolicy.NONE) .setParameterNameRenderingPolicy(DescriptorRenderer.ParameterNameRenderingPolicy.NONE)
.setIncludePropertyConstant(false) .setIncludePropertyConstant(false)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java; package org.jetbrains.kotlin.load.java;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
@@ -98,6 +99,15 @@ public final class JvmAnnotationNames {
@Deprecated @Deprecated
public static final FqName OLD_KOTLIN_TRAIT_IMPL = new FqName("jet.KotlinTraitImpl"); 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<FqName> ANNOTATIONS_COPIED_TO_TYPES = KotlinPackage.setOf(
JETBRAINS_READONLY_ANNOTATION,
JETBRAINS_MUTABLE_ANNOTATION,
JETBRAINS_NOT_NULL_ANNOTATION,
JETBRAINS_NULLABLE_ANNOTATION
);
private static final Set<JvmClassName> SPECIAL_ANNOTATIONS = new HashSet<JvmClassName>(); private static final Set<JvmClassName> SPECIAL_ANNOTATIONS = new HashSet<JvmClassName>();
private static final Set<JvmClassName> NULLABILITY_ANNOTATIONS = new HashSet<JvmClassName>(); private static final Set<JvmClassName> NULLABILITY_ANNOTATIONS = new HashSet<JvmClassName>();
static { static {
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations 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.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.components.TypeUsage
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 projectionKind = if (attr.howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT || isVararg) OUT_VARIANCE else INVARIANT
val result = c.module.builtIns.getArrayType(projectionKind, componentType) val result = c.module.builtIns.getArrayType(projectionKind, componentType)
return@run TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull) return@run TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull)
}.replaceAnnotations(attr.annotations) }.replaceAnnotations(attr.typeAnnotations)
} }
fun makeStarProjection( fun makeStarProjection(
@@ -291,7 +292,7 @@ class LazyJavaTypeResolver(
override fun isMarkedNullable(): Boolean = nullable() override fun isMarkedNullable(): Boolean = nullable()
override fun getAnnotations() = attr.annotations override fun getAnnotations() = attr.typeAnnotations
} }
public object FlexibleJavaClassifierTypeCapabilities : FlexibleTypeCapabilities { public object FlexibleJavaClassifierTypeCapabilities : FlexibleTypeCapabilities {
@@ -351,7 +352,7 @@ trait JavaTypeAttributes {
get() = INFLEXIBLE get() = INFLEXIBLE
val allowFlexible: Boolean val allowFlexible: Boolean
get() = true get() = true
val annotations: Annotations val typeAnnotations: Annotations
val isForAnnotationParameter: Boolean val isForAnnotationParameter: Boolean
get() = false get() = false
} }
@@ -366,10 +367,15 @@ class LazyJavaTypeAttributes(
c: LazyJavaResolverContext, c: LazyJavaResolverContext,
val annotationOwner: JavaAnnotationOwner, val annotationOwner: JavaAnnotationOwner,
override val howThisTypeIsUsed: TypeUsage, override val howThisTypeIsUsed: TypeUsage,
override val annotations: Annotations, annotations: Annotations,
override val allowFlexible: Boolean = true, override val allowFlexible: Boolean = true,
override val isForAnnotationParameter: Boolean = false override val isForAnnotationParameter: Boolean = false
): JavaTypeAttributes { ): 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 { override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue {
if (annotations.isMarkedReadOnly() && !annotations.isMarkedMutable()) if (annotations.isMarkedReadOnly() && !annotations.isMarkedMutable())
@@ -395,7 +401,7 @@ fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParamet
override val isMarkedNotNull: Boolean = false override val isMarkedNotNull: Boolean = false
override val allowFlexible: Boolean = allowFlexible override val allowFlexible: Boolean = allowFlexible
override val annotations: Annotations = Annotations.EMPTY override val typeAnnotations: Annotations = Annotations.EMPTY
override val isForAnnotationParameter: Boolean = isForAnnotationParameter override val isForAnnotationParameter: Boolean = isForAnnotationParameter
} }
@@ -61,6 +61,14 @@ public class DescriptorRendererBuilder {
private boolean renderCompanionObjectName = false; private boolean renderCompanionObjectName = false;
private boolean renderAccessors = false; private boolean renderAccessors = false;
// See JvmAnnotationNames#ANNOTATIONS_COPIED_TO_TYPES
private Collection<FqName> 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() { public DescriptorRendererBuilder() {
} }
@@ -153,6 +161,12 @@ public class DescriptorRendererBuilder {
return this; return this;
} }
@NotNull
public DescriptorRendererBuilder setExcludedTypeAnnotationClasses(@NotNull Collection<FqName> excludedTypeAnnotationClasses) {
this.excludedTypeAnnotationClasses = excludedTypeAnnotationClasses;
return this;
}
@NotNull @NotNull
public DescriptorRendererBuilder setPrettyFunctionTypes(boolean prettyFunctionTypes) { public DescriptorRendererBuilder setPrettyFunctionTypes(boolean prettyFunctionTypes) {
this.prettyFunctionTypes = prettyFunctionTypes; this.prettyFunctionTypes = prettyFunctionTypes;
@@ -236,10 +250,11 @@ public class DescriptorRendererBuilder {
return new DescriptorRendererImpl( return new DescriptorRendererImpl(
nameShortness, withDefinedIn, modifiers, startFromName, debugMode, classWithPrimaryConstructor, verbose, unitReturnType, nameShortness, withDefinedIn, modifiers, startFromName, debugMode, classWithPrimaryConstructor, verbose, unitReturnType,
normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName, normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName,
overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant, overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, excludedTypeAnnotationClasses,
parameterNameRenderingPolicy, withoutTypeParameters, receiverAfterName, renderCompanionObjectName, withoutSuperTypes, includePropertyConstant, parameterNameRenderingPolicy, withoutTypeParameters, receiverAfterName, renderCompanionObjectName,
typeNormalizer, renderDefaultValues, flexibleTypesForCode, secondaryConstructorsAsPrimary, withoutSuperTypes, typeNormalizer, renderDefaultValues, flexibleTypesForCode, secondaryConstructorsAsPrimary,
renderAccessors); renderAccessors
);
} }
} }
@@ -43,7 +43,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE; import static org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE;
public class DescriptorRendererImpl implements DescriptorRenderer { public class DescriptorRendererImpl implements DescriptorRenderer {
private final Function1<JetType, JetType> typeNormalizer; private final Function1<JetType, JetType> typeNormalizer;
private final NameShortness nameShortness; private final NameShortness nameShortness;
private final boolean withDefinedIn; private final boolean withDefinedIn;
@@ -70,6 +69,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
private final boolean includePropertyConstant; private final boolean includePropertyConstant;
private final boolean secondaryConstructorsAsPrimary; private final boolean secondaryConstructorsAsPrimary;
private final Set<FqName> excludedAnnotationClasses; private final Set<FqName> excludedAnnotationClasses;
private final Set<FqName> excludedTypeAnnotationClasses;
private final boolean renderAccessors; private final boolean renderAccessors;
/* package */ DescriptorRendererImpl( /* package */ DescriptorRendererImpl(
@@ -89,6 +89,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
@NotNull ValueParametersHandler handler, @NotNull ValueParametersHandler handler,
@NotNull TextFormat textFormat, @NotNull TextFormat textFormat,
@NotNull Collection<FqName> excludedAnnotationClasses, @NotNull Collection<FqName> excludedAnnotationClasses,
@NotNull Collection<FqName> excludedTypeAnnotationClasses,
boolean includePropertyConstant, boolean includePropertyConstant,
@NotNull ParameterNameRenderingPolicy parameterNameRenderingPolicy, @NotNull ParameterNameRenderingPolicy parameterNameRenderingPolicy,
boolean withoutTypeParameters, boolean withoutTypeParameters,
@@ -118,6 +119,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
this.secondaryConstructorsAsPrimary = secondaryConstructorsAsPrimary; this.secondaryConstructorsAsPrimary = secondaryConstructorsAsPrimary;
this.renderAccessors = renderAccessors; this.renderAccessors = renderAccessors;
this.excludedAnnotationClasses = new HashSet<FqName>(excludedAnnotationClasses); this.excludedAnnotationClasses = new HashSet<FqName>(excludedAnnotationClasses);
this.excludedTypeAnnotationClasses = new HashSet<FqName>(excludedTypeAnnotationClasses);
this.prettyFunctionTypes = prettyFunctionTypes; this.prettyFunctionTypes = prettyFunctionTypes;
this.uninferredTypeParameterAsName = uninferredTypeParameterAsName; this.uninferredTypeParameterAsName = uninferredTypeParameterAsName;
this.parameterNameRenderingPolicy = parameterNameRenderingPolicy; this.parameterNameRenderingPolicy = parameterNameRenderingPolicy;
@@ -538,12 +540,14 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
private void renderAnnotations(@NotNull Annotated annotated, @NotNull StringBuilder builder, boolean needBrackets) { private void renderAnnotations(@NotNull Annotated annotated, @NotNull StringBuilder builder, boolean needBrackets) {
if (!modifiers.contains(Modifier.ANNOTATIONS)) return; if (!modifiers.contains(Modifier.ANNOTATIONS)) return;
Set<FqName> excluded = annotated instanceof JetType ? excludedTypeAnnotationClasses : excludedAnnotationClasses;
StringBuilder annotationsBuilder = new StringBuilder(); StringBuilder annotationsBuilder = new StringBuilder();
for (AnnotationDescriptor annotation : annotated.getAnnotations()) { for (AnnotationDescriptor annotation : annotated.getAnnotations()) {
ClassDescriptor annotationClass = (ClassDescriptor) annotation.getType().getConstructor().getDeclarationDescriptor(); ClassDescriptor annotationClass = (ClassDescriptor) annotation.getType().getConstructor().getDeclarationDescriptor();
assert annotationClass != null; assert annotationClass != null;
if (!excludedAnnotationClasses.contains(DescriptorUtils.getFqNameSafe(annotationClass))) { if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) {
annotationsBuilder.append(renderAnnotation(annotation)).append(" "); annotationsBuilder.append(renderAnnotation(annotation)).append(" ");
} }
} }