Introduce writeDeclarationSiteProjections option into TypeMappingMode

This commit is contained in:
Denis Zharkov
2015-11-19 16:25:36 +03:00
parent d8297cd6f1
commit d22aaf9d52
2 changed files with 30 additions and 28 deletions
@@ -388,15 +388,14 @@ public class JetTypeMapper {
private Type mapType( private Type mapType(
@NotNull KotlinType jetType, @NotNull KotlinType jetType,
@Nullable BothSignatureWriter signatureVisitor, @Nullable BothSignatureWriter signatureVisitor,
@NotNull TypeMappingMode kind, @NotNull TypeMappingMode mode,
@NotNull Variance howThisTypeIsUsed @NotNull Variance howThisTypeIsUsed
) { ) {
Type builtinType = mapBuiltinType(jetType); Type builtinType = mapBuiltinType(jetType);
boolean projectionsAllowed = kind != TypeMappingMode.SUPER_TYPE;
if (builtinType != null) { if (builtinType != null) {
Type asmType = kind.getNeedPrimitiveBoxing() ? boxType(builtinType) : builtinType; Type asmType = mode.getNeedPrimitiveBoxing() ? boxType(builtinType) : builtinType;
writeGenericType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, projectionsAllowed); writeGenericType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, mode);
return asmType; return asmType;
} }
@@ -438,10 +437,10 @@ public class JetTypeMapper {
} }
} }
else { else {
arrayElementType = boxType(mapType(memberType, kind)); arrayElementType = boxType(mapType(memberType, mode));
if (signatureVisitor != null) { if (signatureVisitor != null) {
signatureVisitor.writeArrayType(); signatureVisitor.writeArrayType();
TypeMappingMode newMode = kind.isForAnnotationParameter() ? TypeMappingMode newMode = mode.isForAnnotationParameter() ?
TypeMappingMode.TYPE_PARAMETER_FOR_ANNOTATION : TypeMappingMode.TYPE_PARAMETER_FOR_ANNOTATION :
TypeMappingMode.TYPE_PARAMETER; TypeMappingMode.TYPE_PARAMETER;
mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind()); mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind());
@@ -453,15 +452,15 @@ public class JetTypeMapper {
} }
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
Type asmType = kind.isForAnnotationParameter() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ? Type asmType = mode.isForAnnotationParameter() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
AsmTypes.JAVA_CLASS_TYPE : AsmTypes.JAVA_CLASS_TYPE :
computeAsmType((ClassDescriptor) descriptor.getOriginal()); computeAsmType((ClassDescriptor) descriptor.getOriginal());
writeGenericType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, projectionsAllowed); writeGenericType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, mode);
return asmType; return asmType;
} }
if (descriptor instanceof TypeParameterDescriptor) { if (descriptor instanceof TypeParameterDescriptor) {
Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), kind); Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), mode);
if (signatureVisitor != null) { if (signatureVisitor != null) {
signatureVisitor.writeTypeVariable(descriptor.getName(), type); signatureVisitor.writeTypeVariable(descriptor.getName(), type);
} }
@@ -578,7 +577,7 @@ public class JetTypeMapper {
@NotNull Type asmType, @NotNull Type asmType,
@Nullable BothSignatureWriter signatureVisitor, @Nullable BothSignatureWriter signatureVisitor,
@NotNull Variance howThisTypeIsUsed, @NotNull Variance howThisTypeIsUsed,
boolean projectionsAllowed @NotNull TypeMappingMode mode
) { ) {
if (signatureVisitor != null) { if (signatureVisitor != null) {
if (hasNothingInArguments(type) || type.getArguments().isEmpty()) { if (hasNothingInArguments(type) || type.getArguments().isEmpty()) {
@@ -605,7 +604,7 @@ public class JetTypeMapper {
writeGenericArguments( writeGenericArguments(
signatureVisitor, signatureVisitor,
outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(), outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed); howThisTypeIsUsed, mode);
for (PossiblyInnerType innerPart : innerTypesAsList.subList(1, innerTypesAsList.size())) { for (PossiblyInnerType innerPart : innerTypesAsList.subList(1, innerTypesAsList.size())) {
ClassDescriptor classDescriptor = innerPart.getClassDescriptor(); ClassDescriptor classDescriptor = innerPart.getClassDescriptor();
@@ -613,7 +612,7 @@ public class JetTypeMapper {
writeGenericArguments( writeGenericArguments(
signatureVisitor, innerPart.getArguments(), signatureVisitor, innerPart.getArguments(),
classDescriptor.getDeclaredTypeParameters(), classDescriptor.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed howThisTypeIsUsed, mode
); );
} }
@@ -632,27 +631,22 @@ public class JetTypeMapper {
} }
private void writeGenericArguments( private void writeGenericArguments(
BothSignatureWriter signatureVisitor, @NotNull BothSignatureWriter signatureVisitor,
List<? extends TypeProjection> arguments, @NotNull List<? extends TypeProjection> arguments,
List<? extends TypeParameterDescriptor> parameters, @NotNull List<? extends TypeParameterDescriptor> parameters,
Variance howThisTypeIsUsed, @NotNull Variance howThisTypeIsUsed,
boolean projectionsAllowed @NotNull TypeMappingMode mode
) { ) {
for (Pair<? extends TypeParameterDescriptor, ? extends TypeProjection> item : CollectionsKt.zip(parameters, arguments)) { for (Pair<? extends TypeParameterDescriptor, ? extends TypeProjection> item : CollectionsKt.zip(parameters, arguments)) {
TypeParameterDescriptor parameter = item.getFirst(); TypeParameterDescriptor parameter = item.getFirst();
TypeProjection argument = item.getSecond(); TypeProjection argument = item.getSecond();
if (projectionsAllowed && argument.isStarProjection()) { if (argument.isStarProjection()) {
signatureVisitor.writeUnboundedWildcard(); signatureVisitor.writeUnboundedWildcard();
} }
else { else {
Variance projectionKind = projectionsAllowed Variance projectionKind =
? getEffectiveVariance( getEffectiveVariance(parameter.getVariance(), argument.getProjectionKind(), howThisTypeIsUsed, mode);
parameter.getVariance(),
argument.getProjectionKind(),
howThisTypeIsUsed
)
: Variance.INVARIANT;
signatureVisitor.writeTypeArgument(projectionKind); signatureVisitor.writeTypeArgument(projectionKind);
mapType(argument.getType(), signatureVisitor, TypeMappingMode.TYPE_PARAMETER); mapType(argument.getType(), signatureVisitor, TypeMappingMode.TYPE_PARAMETER);
@@ -679,7 +673,14 @@ public class JetTypeMapper {
}); });
} }
private static Variance getEffectiveVariance(Variance parameterVariance, Variance projectionKind, Variance howThisTypeIsUsed) { private static Variance getEffectiveVariance(
Variance parameterVariance,
Variance projectionKind,
Variance howThisTypeIsUsed,
TypeMappingMode mode
) {
if (!mode.getWriteDeclarationSiteProjections() && projectionKind == Variance.INVARIANT) return Variance.INVARIANT;
// Return type must not contain wildcards // Return type must not contain wildcards
if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind; if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind;
@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.codegen.state
internal enum class TypeMappingMode( internal enum class TypeMappingMode(
val needPrimitiveBoxing: Boolean = false, val needPrimitiveBoxing: Boolean = false,
val isForAnnotationParameter: Boolean = false val isForAnnotationParameter: Boolean = false,
val writeDeclarationSiteProjections: Boolean = true
) { ) {
/** /**
* kotlin.Int is mapped to I * kotlin.Int is mapped to I
@@ -32,7 +33,7 @@ internal enum class TypeMappingMode(
* kotlin.Int is mapped to Ljava/lang/Integer; * kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments * No projections allowed in immediate arguments
*/ */
SUPER_TYPE(needPrimitiveBoxing = true), SUPER_TYPE(needPrimitiveBoxing = true, writeDeclarationSiteProjections = false),
/** /**
* kotlin.reflect.KClass mapped to java.lang.Class * kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as DEFAULT * Other types mapped as DEFAULT