From 303c7563027c4e571275dd7da7b6cd98e0c7a64f Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 27 Nov 2015 18:57:00 +0300 Subject: [PATCH] Refine generic signature for fields - For vals use the same semantics as for return types - For vars use the same semantics as for value parameters --- .../codegen/ImplementationBodyCodegen.java | 2 +- .../kotlin/codegen/PropertyCodegen.java | 2 +- .../kotlin/codegen/state/JetTypeMapper.java | 49 +++++++++++++------ .../fullJdk/genericBackingFieldSignature.kt | 8 +-- .../declarationSiteVariance/OutInField.kt | 2 +- .../wildcardOptimization/fields.kt | 25 ++++++++++ .../compiler/WriteSignatureTestGenerated.java | 6 +++ 7 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index e450da33b84..1c4d61a0ae8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -886,7 +886,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED); FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property), modifiers, context.getFieldName(property, false), - type.getDescriptor(), typeMapper.mapFieldSignature(property.getType()), + type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property), info.defaultValue); AnnotationCodegen.forField(fv, typeMapper).genAnnotations(property, type); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 83fcdc1bed6..dd92fc2cd31 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -360,7 +360,7 @@ public class PropertyCodegen { v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, Pair.create(type, name)); FieldVisitor fv = builder.newField(JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(), - typeMapper.mapFieldSignature(jetType), defaultValue); + typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue); Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations); AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 263f174d94e..856fdb737b3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -325,20 +325,24 @@ public class JetTypeMapper { //noinspection ConstantConditions return mapType(descriptor.getReturnType(), sw, TypeMappingMode.GENERIC_TYPE); } - else { - boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration()); - TypeMappingMode typeMappingModeFromAnnotation = - TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod); - if (typeMappingModeFromAnnotation != null) { - return mapType(returnType, sw, typeMappingModeFromAnnotation); - } - TypeMappingMode mappingMode = TypeMappingMode.getOptimalModeForReturnType( - returnType, - /* isAnnotationMethod = */ isAnnotationMethod); + return mapReturnType(descriptor, sw, returnType); + } - return mapType(returnType, sw, mappingMode); + @NotNull + private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw, @NotNull KotlinType returnType) { + boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration()); + TypeMappingMode typeMappingModeFromAnnotation = + TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod); + if (typeMappingModeFromAnnotation != null) { + return mapType(returnType, sw, typeMappingModeFromAnnotation); } + + TypeMappingMode mappingMode = TypeMappingMode.getOptimalModeForReturnType( + returnType, + /* isAnnotationMethod = */ isAnnotationMethod); + + return mapType(returnType, sw, mappingMode); } @NotNull @@ -1108,9 +1112,16 @@ public class JetTypeMapper { } @Nullable - public String mapFieldSignature(@NotNull KotlinType backingFieldType) { + public String mapFieldSignature(@NotNull KotlinType backingFieldType, @NotNull PropertyDescriptor propertyDescriptor) { BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE); - mapType(backingFieldType, sw, TypeMappingMode.DEFAULT); + + if (!propertyDescriptor.isVar()) { + mapReturnType(propertyDescriptor, sw, backingFieldType); + } + else { + writeParameterType(sw, backingFieldType, propertyDescriptor); + } + return sw.makeJavaGenericSignature(); } @@ -1211,6 +1222,16 @@ public class JetTypeMapper { ) { sw.writeParameterType(kind); + writeParameterType(sw, type, callableDescriptor); + + sw.writeParameterTypeEnd(); + } + + private void writeParameterType( + @NotNull BothSignatureWriter sw, + @NotNull KotlinType type, + @NotNull CallableDescriptor callableDescriptor + ) { TypeMappingMode typeMappingMode; TypeMappingMode typeMappingModeFromAnnotation = @@ -1227,8 +1248,6 @@ public class JetTypeMapper { } mapType(type, sw, typeMappingMode); - - sw.writeParameterTypeEnd(); } private static void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) { diff --git a/compiler/testData/codegen/boxWithStdlib/fullJdk/genericBackingFieldSignature.kt b/compiler/testData/codegen/boxWithStdlib/fullJdk/genericBackingFieldSignature.kt index b033b3ca478..a57a390b03d 100644 --- a/compiler/testData/codegen/boxWithStdlib/fullJdk/genericBackingFieldSignature.kt +++ b/compiler/testData/codegen/boxWithStdlib/fullJdk/genericBackingFieldSignature.kt @@ -58,23 +58,23 @@ fun box(): String { val classField3 = clz.getDeclaredField("classField3"); - if (classField3.getGenericType().toString() != "Zout") + if (classField3.getGenericType().toString() != "Zout") return "fail3:" + classField3.getGenericType(); val classField4 = clz.getDeclaredField("classField4"); - if (classField4.getGenericType().toString() != "Zin") + if (classField4.getGenericType().toString() != "Zin") return "fail4:" + classField4.getGenericType(); val classField5 = clz.getDeclaredField("delegateLazy\$delegate"); - if (classField5.getGenericType().toString() != "kotlin.Lazy>") + if (classField5.getGenericType().toString() != "kotlin.Lazy>") return "fail5:" + classField5.getGenericType(); val classField6 = clz.getDeclaredField("delegateNotNull\$delegate"); - if (classField6.getGenericType().toString() != "kotlin.properties.ReadWriteProperty>") + if (classField6.getGenericType().toString() != "kotlin.properties.ReadWriteProperty>") return "fail6:" + classField6.getGenericType(); diff --git a/compiler/testData/writeSignature/declarationSiteVariance/OutInField.kt b/compiler/testData/writeSignature/declarationSiteVariance/OutInField.kt index 86aac6cc5e7..224bd93f560 100644 --- a/compiler/testData/writeSignature/declarationSiteVariance/OutInField.kt +++ b/compiler/testData/writeSignature/declarationSiteVariance/OutInField.kt @@ -3,7 +3,7 @@ public val mutList: MutableList = throw Exception() // field: OutInFieldKt::list // jvm signature: Ljava/util/List; -// generic signature: Ljava/util/List<+Ljava/lang/String;>; +// generic signature: Ljava/util/List; // field: OutInFieldKt::mutList // jvm signature: Ljava/util/List; diff --git a/compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt b/compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt new file mode 100644 index 00000000000..3a1551d82ce --- /dev/null +++ b/compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt @@ -0,0 +1,25 @@ +class Out + +class Final +open class Open + +@JvmField +val NO_WILDCARDS: Out = Out() +// field: FieldsKt::NO_WILDCARDS +// generic signature: LOut; + +@JvmField +var HAS_WILDCARDS: Out = Out() +// field: FieldsKt::HAS_WILDCARDS +// generic signature: LOut<+LOpen;>; + +@JvmField +var NO_WILDCARDS_VAR: Out = Out() +// field: FieldsKt::NO_WILDCARDS_VAR +// generic signature: LOut; + +@JvmSuppressWildcards +@JvmField +var SUPPRESSED: Out = Out() +// field: FieldsKt::SUPPRESSED +// generic signature: LOut; diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java index 36d829d6296..2cbef267ad0 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java @@ -432,6 +432,12 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest { doTest(fileName); } + @TestMetadata("fields.kt") + public void testFields() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt"); + doTest(fileName); + } + @TestMetadata("finalReturnType.kt") public void testFinalReturnType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/finalReturnType.kt");