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 {
public constructor A()
@@ -1,10 +1,10 @@
package
package
a() internal fun <no name provided>(): kotlin.Unit
internal fun <no name provided>(): 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()] A.<no name provided>(): 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.<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 {
@@ -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)
@@ -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<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> NULLABILITY_ANNOTATIONS = new HashSet<JvmClassName>();
static {
@@ -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
}
@@ -61,6 +61,14 @@ public class DescriptorRendererBuilder {
private boolean renderCompanionObjectName = 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() {
}
@@ -153,6 +161,12 @@ public class DescriptorRendererBuilder {
return this;
}
@NotNull
public DescriptorRendererBuilder setExcludedTypeAnnotationClasses(@NotNull Collection<FqName> 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
);
}
}
@@ -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<JetType, JetType> 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<FqName> excludedAnnotationClasses;
private final Set<FqName> excludedTypeAnnotationClasses;
private final boolean renderAccessors;
/* package */ DescriptorRendererImpl(
@@ -89,6 +89,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
@NotNull ValueParametersHandler handler,
@NotNull TextFormat textFormat,
@NotNull Collection<FqName> excludedAnnotationClasses,
@NotNull Collection<FqName> 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<FqName>(excludedAnnotationClasses);
this.excludedTypeAnnotationClasses = new HashSet<FqName>(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<FqName> 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(" ");
}
}