diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ForceResolveUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ForceResolveUtil.java index f67d72694e8..75969b7f516 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ForceResolveUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ForceResolveUtil.java @@ -99,7 +99,9 @@ public class ForceResolveUtil { else { forceResolveAllContents(type.getConstructor()); for (TypeProjection projection : type.getArguments()) { - forceResolveAllContents(projection.getType()); + if (!projection.isStarProjection()) { + forceResolveAllContents(projection.getType()); + } } } return type; diff --git a/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.A.kt b/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.A.kt new file mode 100644 index 00000000000..3c7973fdbdc --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.A.kt @@ -0,0 +1,9 @@ +package a + +trait Rec> { + fun t(): T +} + +trait Super { + fun foo(p: Rec<*, *>) = p.t() +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.B.kt b/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.B.kt new file mode 100644 index 00000000000..d2500c4c800 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.B.kt @@ -0,0 +1,11 @@ +import a.* + +fun main(args: Array) { + val declaredMethod = javaClass().getDeclaredMethod("foo", javaClass>()) + val genericString = declaredMethod.toGenericString() + if (genericString != "public abstract a.Rec a.Super.foo(a.Rec)") throw AssertionError(genericString) +} + +fun test(s: Super, p: Rec<*, *>) { + s.foo(p).t().t().t() +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt b/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt new file mode 100644 index 00000000000..9dedca787dc --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt @@ -0,0 +1,10 @@ +//ALLOW_AST_ACCESS +package test + +trait Rec> { + fun t(): T +} + +trait Super { + fun foo(p: Rec<*, *>) = p.t() +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.txt b/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.txt new file mode 100644 index 00000000000..a5545ef0d66 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.txt @@ -0,0 +1,9 @@ +package test + +internal trait Rec> { + internal abstract fun t(): T +} + +internal trait Super { + internal open fun foo(/*0*/ p: test.Rec<*, *>): test.Rec<*, *> +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java index 936c2c37f66..139caa3d2c6 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java @@ -150,6 +150,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest(fileName); } + @TestMetadata("RecursiveGeneric.A.kt") + public void testRecursiveGeneric() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/RecursiveGeneric.A.kt"); + doTest(fileName); + } + @TestMetadata("Simple.A.kt") public void testSimple() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/Simple.A.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index d76544847a8..d2daa551cc5 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -2492,6 +2492,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledKotlin(fileName); } + @TestMetadata("RecursiveGeneric.kt") + public void testRecursiveGeneric() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt"); + doTestCompiledKotlin(fileName); + } + @TestMetadata("SingleAbstractMethod.kt") public void testSingleAbstractMethod() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/SingleAbstractMethod.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java index f0e54d812a7..219772b67d8 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java @@ -642,6 +642,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD doTest(fileName); } + @TestMetadata("RecursiveGeneric.kt") + public void testRecursiveGeneric() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt"); + doTest(fileName); + } + @TestMetadata("SingleAbstractMethod.kt") public void testSingleAbstractMethod() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/SingleAbstractMethod.kt"); @@ -4066,6 +4072,24 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD doTest(fileName); } + @TestMetadata("RawSuperTypeWithBound.java") + public void testRawSuperTypeWithBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.java"); + doTest(fileName); + } + + @TestMetadata("RawSuperTypeWithRecursiveBound.java") + public void testRawSuperTypeWithRecursiveBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.java"); + doTest(fileName); + } + + @TestMetadata("RawSuperTypeWithRecursiveBoundMultipleParameters.java") + public void testRawSuperTypeWithRecursiveBoundMultipleParameters() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.java"); + doTest(fileName); + } + @TestMetadata("ReturnInnerSubclassOfSupersInner.java") public void testReturnInnerSubclassOfSupersInner() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.java"); diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java index c439103e9b9..4b72d2a31d4 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java @@ -6226,17 +6226,17 @@ public final class DebugProtoBuf { */ org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.Argument.Projection getProjection(); - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ boolean hasType(); /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ org.jetbrains.kotlin.serialization.DebugProtoBuf.Type getType(); /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder getTypeOrBuilder(); } @@ -6471,23 +6471,23 @@ public final class DebugProtoBuf { return projection_; } - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; public static final int TYPE_FIELD_NUMBER = 2; private org.jetbrains.kotlin.serialization.DebugProtoBuf.Type type_; /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public boolean hasType() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Type getType() { return type_; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder getTypeOrBuilder() { return type_; @@ -6502,13 +6502,11 @@ public final class DebugProtoBuf { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasType()) { - memoizedIsInitialized = 0; - return false; - } - if (!getType().isInitialized()) { - memoizedIsInitialized = 0; - return false; + if (hasType()) { + if (!getType().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } } memoizedIsInitialized = 1; return true; @@ -6732,13 +6730,11 @@ public final class DebugProtoBuf { } public final boolean isInitialized() { - if (!hasType()) { - - return false; - } - if (!getType().isInitialized()) { - - return false; + if (hasType()) { + if (!getType().isInitialized()) { + + return false; + } } return true; } @@ -6798,18 +6794,18 @@ public final class DebugProtoBuf { return this; } - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; private org.jetbrains.kotlin.serialization.DebugProtoBuf.Type type_ = org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.getDefaultInstance(); private com.google.protobuf.SingleFieldBuilder< org.jetbrains.kotlin.serialization.DebugProtoBuf.Type, org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder> typeBuilder_; /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public boolean hasType() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Type getType() { if (typeBuilder_ == null) { @@ -6819,7 +6815,7 @@ public final class DebugProtoBuf { } } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder setType(org.jetbrains.kotlin.serialization.DebugProtoBuf.Type value) { if (typeBuilder_ == null) { @@ -6835,7 +6831,7 @@ public final class DebugProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder setType( org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.Builder builderForValue) { @@ -6849,7 +6845,7 @@ public final class DebugProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder mergeType(org.jetbrains.kotlin.serialization.DebugProtoBuf.Type value) { if (typeBuilder_ == null) { @@ -6868,7 +6864,7 @@ public final class DebugProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder clearType() { if (typeBuilder_ == null) { @@ -6881,7 +6877,7 @@ public final class DebugProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.Builder getTypeBuilder() { bitField0_ |= 0x00000002; @@ -6889,7 +6885,7 @@ public final class DebugProtoBuf { return getTypeFieldBuilder().getBuilder(); } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder getTypeOrBuilder() { if (typeBuilder_ != null) { @@ -6899,7 +6895,7 @@ public final class DebugProtoBuf { } } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ private com.google.protobuf.SingleFieldBuilder< org.jetbrains.kotlin.serialization.DebugProtoBuf.Type, org.jetbrains.kotlin.serialization.DebugProtoBuf.Type.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder> @@ -16960,7 +16956,7 @@ public final class DebugProtoBuf { "\n\016TYPE_PARAMETER\020\001\032\313\001\n\010Argument\022U\n\nproje" + "ction\030\001 \001(\0162<.org.jetbrains.kotlin.seria" + "lization.Type.Argument.Projection:\003INV\0226" + - "\n\004type\030\002 \002(\0132(.org.jetbrains.kotlin.seri" + + "\n\004type\030\002 \001(\0132(.org.jetbrains.kotlin.seri" + "alization.Type\"0\n\nProjection\022\006\n\002IN\020\000\022\007\n\003" + "OUT\020\001\022\007\n\003INV\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParamet" + "er\022\n\n\002id\030\001 \002(\005\022\014\n\004name\030\002 \002(\005\022\026\n\007reified\030" + diff --git a/core/serialization/src/descriptors.proto b/core/serialization/src/descriptors.proto index 61b62c4c2fb..425158e7db1 100644 --- a/core/serialization/src/descriptors.proto +++ b/core/serialization/src/descriptors.proto @@ -121,7 +121,7 @@ message Type { } optional Projection projection = 1 [default = INV]; - required Type type = 2; + optional Type type = 2; // when projection is STAR, no type is written, otherwise type must be specified } repeated Argument argument = 2; diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java b/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java index 7f80bcca941..4a52072f5a4 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java @@ -350,9 +350,9 @@ public class DescriptorSerializer { if (projection != ProtoBuf.Type.Argument.Projection.INV) { builder.setProjection(projection); } + builder.setType(type(typeProjection.getType())); } - builder.setType(type(typeProjection.getType())); return builder; } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java b/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java index e06edd1243a..479edd6a729 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java @@ -5004,13 +5004,13 @@ public final class ProtoBuf { */ org.jetbrains.kotlin.serialization.ProtoBuf.Type.Argument.Projection getProjection(); - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ boolean hasType(); /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ org.jetbrains.kotlin.serialization.ProtoBuf.Type getType(); } @@ -5196,17 +5196,17 @@ public final class ProtoBuf { return projection_; } - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; public static final int TYPE_FIELD_NUMBER = 2; private org.jetbrains.kotlin.serialization.ProtoBuf.Type type_; /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public boolean hasType() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.ProtoBuf.Type getType() { return type_; @@ -5221,13 +5221,11 @@ public final class ProtoBuf { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; - if (!hasType()) { - memoizedIsInitialized = 0; - return false; - } - if (!getType().isInitialized()) { - memoizedIsInitialized = 0; - return false; + if (hasType()) { + if (!getType().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } } memoizedIsInitialized = 1; return true; @@ -5400,13 +5398,11 @@ public final class ProtoBuf { } public final boolean isInitialized() { - if (!hasType()) { - - return false; - } - if (!getType().isInitialized()) { - - return false; + if (hasType()) { + if (!getType().isInitialized()) { + + return false; + } } return true; } @@ -5466,22 +5462,22 @@ public final class ProtoBuf { return this; } - // required .org.jetbrains.kotlin.serialization.Type type = 2; + // optional .org.jetbrains.kotlin.serialization.Type type = 2; private org.jetbrains.kotlin.serialization.ProtoBuf.Type type_ = org.jetbrains.kotlin.serialization.ProtoBuf.Type.getDefaultInstance(); /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public boolean hasType() { return ((bitField0_ & 0x00000002) == 0x00000002); } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public org.jetbrains.kotlin.serialization.ProtoBuf.Type getType() { return type_; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder setType(org.jetbrains.kotlin.serialization.ProtoBuf.Type value) { if (value == null) { @@ -5493,7 +5489,7 @@ public final class ProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder setType( org.jetbrains.kotlin.serialization.ProtoBuf.Type.Builder builderForValue) { @@ -5503,7 +5499,7 @@ public final class ProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder mergeType(org.jetbrains.kotlin.serialization.ProtoBuf.Type value) { if (((bitField0_ & 0x00000002) == 0x00000002) && @@ -5518,7 +5514,7 @@ public final class ProtoBuf { return this; } /** - * required .org.jetbrains.kotlin.serialization.Type type = 2; + * optional .org.jetbrains.kotlin.serialization.Type type = 2; */ public Builder clearType() { type_ = org.jetbrains.kotlin.serialization.ProtoBuf.Type.getDefaultInstance(); diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt index 4931abdbf9d..65e622e47d8 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.utils.toReadOnlyList class DeserializedType( c: DeserializationContext, @@ -33,7 +34,12 @@ class DeserializedType( typeDeserializer.typeConstructor(typeProto) } - private val arguments = typeDeserializer.typeArguments(typeProto.getArgumentList()) + private val arguments = c.storageManager.createLazyValue { + typeProto.getArgumentList().mapIndexed { + index, proto -> + typeDeserializer.typeArgument(getConstructor().getParameters().getOrNull(index), proto) + }.toReadOnlyList() + } private val memberScope = c.storageManager.createLazyValue { computeMemberScope() @@ -41,7 +47,7 @@ class DeserializedType( override fun getConstructor(): TypeConstructor = constructor() - override fun getArguments(): List = arguments + override fun getArguments(): List = arguments() override fun isMarkedNullable(): Boolean = typeProto.getNullable() @@ -70,4 +76,8 @@ class DeserializedType( } override fun getAnnotations(): Annotations = Annotations.EMPTY + + private fun List.getOrNull(index: Int): E? { + return if (index in indices) this[index] else null + } } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index dc03a47c116..3b4da174a39 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.serialization.ProtoBuf @@ -99,13 +100,14 @@ public class TypeDeserializer( return c.components.moduleDescriptor.findClassAcrossModuleDependencies(id) } - fun typeArguments(protos: List): List = - protos.map { proto -> - val type = type(proto.getType()) - if (proto.getProjection() == ProtoBuf.Type.Argument.Projection.STAR) - TypeBasedStarProjectionImpl(type) - else TypeProjectionImpl(variance(proto.getProjection()), type) - }.toReadOnlyList() + fun typeArgument(parameter: TypeParameterDescriptor?, typeArgumentProto: ProtoBuf.Type.Argument): TypeProjection { + return if (typeArgumentProto.getProjection() == ProtoBuf.Type.Argument.Projection.STAR) + if (parameter == null) + TypeBasedStarProjectionImpl(KotlinBuiltIns.getInstance().getNullableAnyType()) + else + StarProjectionImpl(parameter) + else TypeProjectionImpl(variance(typeArgumentProto.getProjection()), type(typeArgumentProto.getType())) + } override fun toString() = debugName + (if (parent == null) "" else ". Child of ${parent.debugName}") } diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java index 598665307e4..67e9fcd4733 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java @@ -636,6 +636,12 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest { doTest(fileName); } + @TestMetadata("RecursiveGeneric.kt") + public void testRecursiveGeneric() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/RecursiveGeneric.kt"); + doTest(fileName); + } + @TestMetadata("SingleAbstractMethod.kt") public void testSingleAbstractMethod() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/class/SingleAbstractMethod.kt");