From 7f46d7555ed46501c8d8a1113034a0a356232549 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 8 Oct 2013 20:11:15 +0400 Subject: [PATCH] Do not write "? extends" and "? super" in immediate arguments of supertypes in Java generic signatures --- .../jetbrains/jet/codegen/ClosureCodegen.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 4 +-- .../jet/codegen/state/JetTypeMapper.java | 29 +++++++++++-------- .../jet/codegen/state/JetTypeMapperMode.java | 5 ++++ .../codegen/box/callableReference/toString.kt | 6 ++-- .../box/functions/functionNtoString.kt | 16 +++++----- .../functionLiteralGenericSignature.kt | 22 ++++++++------ .../MappedSupertypeWithVariance.kt | 6 ++++ .../SuperClassWithVariance.kt | 7 +++++ .../SuperTraitWithVariance.kt | 7 +++++ .../SuperTypeWithVarianceInArguments.kt | 8 +++++ .../compiler/WriteSignatureTestGenerated.java | 20 +++++++++++++ 12 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 compiler/testData/writeSignature/declarationSiteVariance/MappedSupertypeWithVariance.kt create mode 100644 compiler/testData/writeSignature/declarationSiteVariance/SuperClassWithVariance.kt create mode 100644 compiler/testData/writeSignature/declarationSiteVariance/SuperTraitWithVariance.kt create mode 100644 compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 7e835ccaa45..4774f256e2e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -301,7 +301,7 @@ public class ClosureCodegen extends GenerationStateAware { BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS, true); typeMapper.writeFormalTypeParameters(Collections.emptyList(), sw); sw.writeSuperclass(); - typeMapper.mapType(supertype, sw, JetTypeMapperMode.TYPE_PARAMETER); + typeMapper.mapType(supertype, sw, JetTypeMapperMode.SUPER_TYPE); sw.writeSuperclassEnd(); String signature = sw.makeJavaGenericSignature(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index cc25e708512..20a67465756 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -366,7 +366,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { signatureVisitor.writeClassEnd(); } else { - typeMapper.mapType(superClassType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER); + typeMapper.mapType(superClassType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE); } signatureVisitor.writeSuperclassEnd(); } @@ -381,7 +381,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (isInterface(superClassDescriptor)) { signatureVisitor.writeInterface(); - Type jvmName = typeMapper.mapType(superType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER); + Type jvmName = typeMapper.mapType(superType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE); signatureVisitor.writeInterfaceEnd(); superInterfacesLinkedHashSet.add(jvmName.getInternalName()); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index d3d5886d7b8..07d9859ad72 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -267,12 +267,13 @@ public class JetTypeMapper extends BindingTraceAware { } } + boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE; if (known != null) { if (kind == JetTypeMapperMode.VALUE) { return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed); } - else if (kind == JetTypeMapperMode.TYPE_PARAMETER) { - return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, arrayParameter); + else if (kind == JetTypeMapperMode.TYPE_PARAMETER || kind == JetTypeMapperMode.SUPER_TYPE) { + return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, arrayParameter, projectionsAllowed); } else if (kind == JetTypeMapperMode.TRAIT_IMPL) { throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType); @@ -345,7 +346,7 @@ public class JetTypeMapper extends BindingTraceAware { asmType = descriptorAsmType; } - writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed); + writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed); checkValidType(asmType); return asmType; @@ -386,7 +387,8 @@ public class JetTypeMapper extends BindingTraceAware { BothSignatureWriter signatureVisitor, Type asmType, JetType jetType, - Variance howThisTypeIsUsed + Variance howThisTypeIsUsed, + boolean projectionsAllowed ) { if (signatureVisitor != null) { signatureVisitor.writeClassBegin(asmType); @@ -395,11 +397,13 @@ public class JetTypeMapper extends BindingTraceAware { for (TypeParameterDescriptor parameter : jetType.getConstructor().getParameters()) { TypeProjection argument = arguments.get(parameter.getIndex()); - Variance projectionKind = getEffectiveVariance( - parameter.getVariance(), - argument.getProjectionKind(), - howThisTypeIsUsed - ); + Variance projectionKind = projectionsAllowed + ? getEffectiveVariance( + parameter.getVariance(), + argument.getProjectionKind(), + howThisTypeIsUsed + ) + : Variance.INVARIANT; signatureVisitor.writeTypeArgument(projectionKind); mapType(argument.getType(), signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER); @@ -434,7 +438,7 @@ public class JetTypeMapper extends BindingTraceAware { @Nullable BothSignatureWriter signatureVisitor, @NotNull Variance howThisTypeIsUsed ) { - return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, false); + return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, false, true); } private Type mapKnownAsmType( @@ -442,7 +446,8 @@ public class JetTypeMapper extends BindingTraceAware { Type asmType, @Nullable BothSignatureWriter signatureVisitor, @NotNull Variance howThisTypeIsUsed, - boolean arrayParameter + boolean arrayParameter, + boolean allowProjections ) { if (signatureVisitor != null) { if (jetType.getArguments().isEmpty()) { @@ -452,7 +457,7 @@ public class JetTypeMapper extends BindingTraceAware { signatureVisitor.writeAsmType(asmType); } else { - writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed); + writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, allowProjections); } } checkValidType(asmType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapperMode.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapperMode.java index 0851c5bf7ff..d67b4b7a3ff 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapperMode.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapperMode.java @@ -33,4 +33,9 @@ public enum JetTypeMapperMode { * jet.Int is mapped to Ljava/lang/Integer; */ TYPE_PARAMETER, + /** + * jet.Int is mapped to Ljava/lang/Integer; + * No projections allowed in immediate arguments + */ + SUPER_TYPE } diff --git a/compiler/testData/codegen/box/callableReference/toString.kt b/compiler/testData/codegen/box/callableReference/toString.kt index aef8169ea6d..ce5a8438ca5 100644 --- a/compiler/testData/codegen/box/callableReference/toString.kt +++ b/compiler/testData/codegen/box/callableReference/toString.kt @@ -9,15 +9,15 @@ fun A.baz() {} fun box(): String { val f = "${::foo}" - if (f != "jet.KFunctionImpl1") return "Fail foo: $f" + if (f != "jet.KFunctionImpl1") return "Fail foo: $f" val nameOfA = (A() as java.lang.Object).getClass().getName() val g = "${A::bar}" - if (g != "jet.KMemberFunctionImpl0") return "Fail bar: $g" + if (g != "jet.KMemberFunctionImpl0<$nameOfA, java.lang.String>") return "Fail bar: $g" val h = "${A::baz}" - if (h != "jet.KExtensionFunctionImpl0") return "Fail baz: $h" + if (h != "jet.KExtensionFunctionImpl0<$nameOfA, jet.Unit>") return "Fail baz: $h" return "OK" } diff --git a/compiler/testData/codegen/box/functions/functionNtoString.kt b/compiler/testData/codegen/box/functions/functionNtoString.kt index afc04d88154..bfef8690d4a 100644 --- a/compiler/testData/codegen/box/functions/functionNtoString.kt +++ b/compiler/testData/codegen/box/functions/functionNtoString.kt @@ -6,22 +6,22 @@ fun check(expected: String, obj: Any?) { fun box(): String { - check("jet.FunctionImpl0") + check("jet.FunctionImpl0") { () : Unit -> } - check("jet.FunctionImpl0") + check("jet.FunctionImpl0") { () : Int -> 42 } - check("jet.FunctionImpl1") + check("jet.FunctionImpl1") { (s: String) : Long -> 42.toLong() } - check("jet.FunctionImpl2") + check("jet.FunctionImpl2") { (x: Int, y: Int) : Unit -> } - check("jet.ExtensionFunctionImpl0") + check("jet.ExtensionFunctionImpl0") { Int.() : Unit -> } - check("jet.ExtensionFunctionImpl0") + check("jet.ExtensionFunctionImpl0") { Unit.() : Int -> 42 } - check("jet.ExtensionFunctionImpl1") + check("jet.ExtensionFunctionImpl1") { String.(s: String) : Long -> 42.toLong() } - check("jet.ExtensionFunctionImpl2") + check("jet.ExtensionFunctionImpl2") { Int.(x: Int, y: Int) : Unit -> } return "OK" diff --git a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt index e9604552c5d..f99bfe15067 100644 --- a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt +++ b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt @@ -14,18 +14,22 @@ val stringParamFun = { (x: String) : Unit -> } val listFun = { (l: List) : List -> l } val mutableListFun = { (l: MutableList) : MutableList -> null!! } +trait In +val funWithIn = { (x: In) : Unit -> } + val extensionFun = { Any.() : Unit -> } val extensionWithArgFun = { Long.(x: Any) : Date -> Date() } fun box(): String { - assertGenericSuper("jet.FunctionImpl0", unitFun) - assertGenericSuper("jet.FunctionImpl0", intFun) - assertGenericSuper("jet.FunctionImpl1", stringParamFun) - assertGenericSuper("jet.FunctionImpl1, ? extends java.util.List>", listFun) - assertGenericSuper("jet.FunctionImpl1, ? extends java.util.List>", mutableListFun) - - assertGenericSuper("jet.ExtensionFunctionImpl0", extensionFun) - assertGenericSuper("jet.ExtensionFunctionImpl1", extensionWithArgFun) - + assertGenericSuper("jet.FunctionImpl0", unitFun) + assertGenericSuper("jet.FunctionImpl0", intFun) + assertGenericSuper("jet.FunctionImpl1", stringParamFun) + assertGenericSuper("jet.FunctionImpl1, java.util.List>", listFun) + assertGenericSuper("jet.FunctionImpl1, java.util.List>", mutableListFun) + assertGenericSuper("jet.FunctionImpl1, jet.Unit>", funWithIn) + + assertGenericSuper("jet.ExtensionFunctionImpl0", extensionFun) + assertGenericSuper("jet.ExtensionFunctionImpl1", extensionWithArgFun) + return "OK" } diff --git a/compiler/testData/writeSignature/declarationSiteVariance/MappedSupertypeWithVariance.kt b/compiler/testData/writeSignature/declarationSiteVariance/MappedSupertypeWithVariance.kt new file mode 100644 index 00000000000..9441498ed92 --- /dev/null +++ b/compiler/testData/writeSignature/declarationSiteVariance/MappedSupertypeWithVariance.kt @@ -0,0 +1,6 @@ + +trait Derived: List + +// class: Derived +// jvm signature: Derived +// generic signature: Ljava/lang/Object;Ljava/util/List; diff --git a/compiler/testData/writeSignature/declarationSiteVariance/SuperClassWithVariance.kt b/compiler/testData/writeSignature/declarationSiteVariance/SuperClassWithVariance.kt new file mode 100644 index 00000000000..f50b52a9ec4 --- /dev/null +++ b/compiler/testData/writeSignature/declarationSiteVariance/SuperClassWithVariance.kt @@ -0,0 +1,7 @@ + +open class Base +class Derived: Base() + +// class: Derived +// jvm signature: Derived +// generic signature: LBase; diff --git a/compiler/testData/writeSignature/declarationSiteVariance/SuperTraitWithVariance.kt b/compiler/testData/writeSignature/declarationSiteVariance/SuperTraitWithVariance.kt new file mode 100644 index 00000000000..b2dc85c7503 --- /dev/null +++ b/compiler/testData/writeSignature/declarationSiteVariance/SuperTraitWithVariance.kt @@ -0,0 +1,7 @@ + +trait Base +class Derived: Base + +// class: Derived +// jvm signature: Derived +// generic signature: Ljava/lang/Object;LBase; diff --git a/compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt b/compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt new file mode 100644 index 00000000000..7e8ac77788c --- /dev/null +++ b/compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt @@ -0,0 +1,8 @@ + +trait Base +trait Intermediate +class Derived: Intermediate> + +// class: Derived +// jvm signature: Derived +// generic signature: Ljava/lang/Object;LIntermediate;>; diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/WriteSignatureTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/WriteSignatureTestGenerated.java index acc429b3d07..1bbb14867fe 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/WriteSignatureTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/WriteSignatureTestGenerated.java @@ -186,6 +186,11 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest { doTest("compiler/testData/writeSignature/declarationSiteVariance/InOfOutInOutPosition.kt"); } + @TestMetadata("MappedSupertypeWithVariance.kt") + public void testMappedSupertypeWithVariance() throws Exception { + doTest("compiler/testData/writeSignature/declarationSiteVariance/MappedSupertypeWithVariance.kt"); + } + @TestMetadata("OutInInPosition.kt") public void testOutInInPosition() throws Exception { doTest("compiler/testData/writeSignature/declarationSiteVariance/OutInInPosition.kt"); @@ -241,6 +246,21 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest { doTest("compiler/testData/writeSignature/declarationSiteVariance/PropertySetterOut.kt"); } + @TestMetadata("SuperClassWithVariance.kt") + public void testSuperClassWithVariance() throws Exception { + doTest("compiler/testData/writeSignature/declarationSiteVariance/SuperClassWithVariance.kt"); + } + + @TestMetadata("SuperTraitWithVariance.kt") + public void testSuperTraitWithVariance() throws Exception { + doTest("compiler/testData/writeSignature/declarationSiteVariance/SuperTraitWithVariance.kt"); + } + + @TestMetadata("SuperTypeWithVarianceInArguments.kt") + public void testSuperTypeWithVarianceInArguments() throws Exception { + doTest("compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt"); + } + } public static Test suite() {