diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.kt new file mode 100644 index 00000000000..16f1b2a6df1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.kt @@ -0,0 +1,16 @@ +// !CHECK_TYPE +// FILE: A.java + +public class A { + public A(E x, java.util.List y) {} +} + +// FILE: main.kt + +fun test(x: List, y: List) { + A("", x) checkType { _>() } + A("", y) checkType { _>() } + + A("", x) + A("", y) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.txt new file mode 100644 index 00000000000..86218cc3a36 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.txt @@ -0,0 +1,10 @@ +package + +public fun test(/*0*/ x: kotlin.collections.List, /*1*/ y: kotlin.collections.List): kotlin.Unit + +public open class A { + public constructor A(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List!) + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.kt new file mode 100644 index 00000000000..838f57a2b03 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.kt @@ -0,0 +1,17 @@ +// !CHECK_TYPE +// FILE: Outer.java + +public class Outer { + public class Inner { + public Inner(E x, java.util.List y, G z) {} + } +} + +// FILE: main.kt +fun test(x: List, y: List) { + Outer().Inner("", y, 1) checkType { _.Inner>() } + Outer().Inner("", y, 1) checkType { _.Inner>() } + + Outer().Inner("", x, 1) checkType { _.Inner>() } + Outer().Inner("", x, 1) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.txt new file mode 100644 index 00000000000..cfebcf50b3e --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.txt @@ -0,0 +1,17 @@ +package + +public fun test(/*0*/ x: kotlin.collections.List, /*1*/ y: kotlin.collections.List): kotlin.Unit + +public open class Outer { + public constructor 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 + + public open inner class Inner /*captured type parameters: /*1*/ T : kotlin.Any!*/ { + public constructor Inner(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List!, /*2*/ z: G!) + 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 + } +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.kt new file mode 100644 index 00000000000..3d3359abc4b --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.kt @@ -0,0 +1,18 @@ +// FILE: A.java + +public class A { + public A(T x, java.util.List y) {} +} + +// FILE: main.kt + +fun test(x: List, y: List) { + A("", x) // inferred as Any! + A("", y) + + A("", x) + + A("", x) + A("", y) + A("", y) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.txt new file mode 100644 index 00000000000..5804a0ca91e --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.txt @@ -0,0 +1,10 @@ +package + +public fun test(/*0*/ x: kotlin.collections.List, /*1*/ y: kotlin.collections.List): kotlin.Unit + +public open class A { + public constructor A(/*0*/ x: T!, /*1*/ y: kotlin.collections.(Mutable)List!) + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.kt new file mode 100644 index 00000000000..700d2984b40 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.kt @@ -0,0 +1,20 @@ +// FILE: A.java + +public class A { + public A(T x, Inv y) {} +} + +// FILE: main.kt + +class Inv + +fun test(x: Inv, y: Inv) { + A("", x) + A("", y) + + A("", x) + + A("", x) + A("", y) + A("", y) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.txt new file mode 100644 index 00000000000..fc99b2683e9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.txt @@ -0,0 +1,17 @@ +package + +public fun test(/*0*/ x: Inv, /*1*/ y: Inv): kotlin.Unit + +public open class A { + public constructor A(/*0*/ x: T!, /*1*/ y: Inv!) + 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 +} + +public final class Inv { + public constructor Inv() + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.kt new file mode 100644 index 00000000000..1be2ee95470 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.kt @@ -0,0 +1,11 @@ +// FILE: C.java + +// See KT-10410 +public class C { + public C(T t) { + } +} + +// FILE: main.kt + +fun foo() = C() diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.txt new file mode 100644 index 00000000000..84946d18c31 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.txt @@ -0,0 +1,10 @@ +package + +public fun foo(): C + +public open class C { + public constructor C(/*0*/ t: T!) + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.kt new file mode 100644 index 00000000000..b63283686ce --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.kt @@ -0,0 +1,19 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: R.java +public class R> { + public > R(F x) { + } +} + +// FILE: RImpl.java +public class RImpl extends R { + public RImpl() { + super(null); + } +} + +// FILE: main.kt +fun test() { + val x: R = R(RImpl()) + R(RImpl()) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.txt new file mode 100644 index 00000000000..7fbe20c71d9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.txt @@ -0,0 +1,17 @@ +package + +public fun test(): kotlin.Unit + +public open class R!> { + public constructor R!, /*1*/ F : R!>(/*0*/ x: F!) + 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 +} + +public open class RImpl : R { + public constructor RImpl() + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.kt new file mode 100644 index 00000000000..47827075260 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// !CHECK_TYPE +// FILE: A.java + +public class A { + public A(E x, java.util.List y) {} +} + +// FILE: main.kt + +class B1(x: List) : A("", x) +class B2(x: List) : A("", x) + +class C : A { + constructor(x: List) : super("", !; kotlin.collections.List)!>x) + constructor(x: List, y: Int) : super("", x) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.txt new file mode 100644 index 00000000000..6099b11a46e --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.txt @@ -0,0 +1,30 @@ +package + +public open class A { + public constructor A(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List!) + 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 +} + +public final class B1 : A { + public constructor B1(/*0*/ x: kotlin.collections.List) + 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 +} + +public final class B2 : A { + public constructor B2(/*0*/ x: kotlin.collections.List) + 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 +} + +public final class C : A { + public constructor C(/*0*/ x: kotlin.collections.List, /*1*/ y: kotlin.Int) + public constructor C(/*0*/ x: kotlin.collections.List) + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.kt new file mode 100644 index 00000000000..90d40316f65 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.kt @@ -0,0 +1,19 @@ +// !DIAGNOSTICS: -UNUSED_VALUE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE +// FILE: A.java + +public class A { + public A(T x, java.util.List y) {} +} + +// FILE: main.kt + +fun test(x: List, y: List) { + var z: A = A("", x) // E inferred from expected type + z = A("", y) + + z = A("", x) + + z = A("", x) + z = A("", y) + z = A("", y) +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.txt new file mode 100644 index 00000000000..c4e8803c15d --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.txt @@ -0,0 +1,10 @@ +package + +public fun test(/*0*/ x: kotlin.collections.List, /*1*/ y: kotlin.collections.List): kotlin.Unit + +public open class A { + public constructor A(/*0*/ x: T!, /*1*/ y: kotlin.collections.(Mutable)List!) + 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 +} diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.kt b/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.kt index 46824a24cda..35919d7f608 100644 --- a/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.kt +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.kt @@ -10,9 +10,8 @@ public class J { import java.io.Serializable -// TODO: report TYPE_MISMATCH here as well -fun cloneable(c: Cloneable) = J(c) +fun cloneable(c: Cloneable) = J(c) -fun serializable(s: Serializable) = J(s) +fun serializable(s: Serializable) = J(s) fun both(t: T) where T : Cloneable, T : Serializable = J(t) diff --git a/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.txt b/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.txt index 4642ace35df..d41c4ba8704 100644 --- a/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.txt +++ b/compiler/testData/diagnostics/tests/j+k/genericConstructorWithMultipleBounds.txt @@ -5,7 +5,7 @@ public fun cloneable(/*0*/ c: kotlin.Cloneable): J public fun serializable(/*0*/ s: java.io.Serializable): J public open class J { - public constructor J(/*0*/ t: kotlin.Cloneable!) + public constructor J(/*0*/ t: T!) where T : java.io.Serializable! 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 diff --git a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericDeep.txt b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericDeep.txt index f5b0442f9dd..5f02e0acc89 100644 --- a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericDeep.txt +++ b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericDeep.txt @@ -1,5 +1,5 @@ package test public open class ConstructorGenericDeep { - public constructor ConstructorGenericDeep(/*0*/ p0: java.lang.Class!) + public constructor ConstructorGenericDeep(/*0*/ p0: java.lang.Class!) } diff --git a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericSimple.txt b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericSimple.txt index 11b091671b0..aebc28d1815 100644 --- a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericSimple.txt +++ b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericSimple.txt @@ -1,5 +1,5 @@ package test public open class ConstructorGenericSimple { - public constructor ConstructorGenericSimple(/*0*/ p0: kotlin.Any!) + public constructor ConstructorGenericSimple(/*0*/ p0: P!) } diff --git a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.txt b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.txt index 23ed8d349ce..640603fca7b 100644 --- a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.txt +++ b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.txt @@ -1,5 +1,5 @@ package test public open class ConstructorGenericUpperBound { - public constructor ConstructorGenericUpperBound(/*0*/ p0: java.util.RandomAccess!) + public constructor ConstructorGenericUpperBound(/*0*/ p0: P!) } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/ConstructorWithNewTypeParams.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/ConstructorWithNewTypeParams.txt index 5ba590e8c9b..0c366c52a58 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/ConstructorWithNewTypeParams.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/ConstructorWithNewTypeParams.txt @@ -1,5 +1,5 @@ package test public open class ConstructorWithNewTypeParams { - public constructor ConstructorWithNewTypeParams(/*0*/ p0: kotlin.Any!) + public constructor ConstructorWithNewTypeParams(/*0*/ p0: U!) } diff --git a/compiler/testData/resolveConstructorDelegationCalls/generics4.txt b/compiler/testData/resolveConstructorDelegationCalls/generics4.txt index a4cf7456098..b6e8e95cb24 100644 --- a/compiler/testData/resolveConstructorDelegationCalls/generics4.txt +++ b/compiler/testData/resolveConstructorDelegationCalls/generics4.txt @@ -13,7 +13,7 @@ class A : B { Resolved call: Candidate descriptor: constructor B(x: X, y: Y) defined in B -Resulting descriptor: constructor B(x: T1, y: T2) defined in B +Resulting descriptor: constructor B(x: T1, y: T2) defined in B Explicit receiver kind = NO_EXPLICIT_RECEIVER Dispatch receiver = NO_RECEIVER diff --git a/compiler/testData/resolveConstructorDelegationCalls/generics5.txt b/compiler/testData/resolveConstructorDelegationCalls/generics5.txt index 28d32d003a4..2fadc4db3cd 100644 --- a/compiler/testData/resolveConstructorDelegationCalls/generics5.txt +++ b/compiler/testData/resolveConstructorDelegationCalls/generics5.txt @@ -13,7 +13,7 @@ class A : B { Resolved call: Candidate descriptor: constructor B(x: X, s: String) defined in B -Resulting descriptor: constructor B(x: T1, s: String) defined in B +Resulting descriptor: constructor B(x: T1, s: String) defined in B Explicit receiver kind = NO_EXPLICIT_RECEIVER Dispatch receiver = NO_RECEIVER diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2d8be884fd8..a7e65d369b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10197,6 +10197,63 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class GenericConstructor extends AbstractDiagnosticsTest { + public void testAllFilesPresentInGenericConstructor() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/genericConstructor"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classTypeParameterInferredFromArgument.kt") + public void testClassTypeParameterInferredFromArgument() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.kt"); + doTest(fileName); + } + + @TestMetadata("innerClass.kt") + public void testInnerClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/innerClass.kt"); + doTest(fileName); + } + + @TestMetadata("noClassTypeParameters.kt") + public void testNoClassTypeParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParameters.kt"); + doTest(fileName); + } + + @TestMetadata("noClassTypeParametersInvParameter.kt") + public void testNoClassTypeParametersInvParameter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/noClassTypeParametersInvParameter.kt"); + doTest(fileName); + } + + @TestMetadata("recursive.kt") + public void testRecursive() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/recursive.kt"); + doTest(fileName); + } + + @TestMetadata("selfTypes.kt") + public void testSelfTypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/selfTypes.kt"); + doTest(fileName); + } + + @TestMetadata("superCall.kt") + public void testSuperCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/superCall.kt"); + doTest(fileName); + } + + @TestMetadata("withClassTypeParameters.kt") + public void testWithClassTypeParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor/withClassTypeParameters.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/properties") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt index a8fbb81c263..96e35b28742 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -75,5 +75,6 @@ fun LazyJavaResolverContext.child( fun LazyJavaResolverContext.child( containingDeclaration: DeclarationDescriptor, - typeParameterOwner: JavaTypeParameterListOwner -) = this.child(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameterOwner)) + typeParameterOwner: JavaTypeParameterListOwner, + typeParametersIndexOffset: Int = 0 +) = this.child(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameterOwner, typeParametersIndexOffset)) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index ea01b04b286..799e7c37859 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -506,9 +506,14 @@ class LazyJavaClassMemberScope( classDescriptor, c.resolveAnnotations(constructor), /* isPrimary = */ false, c.components.sourceElementFactory.source(constructor) ) - val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.valueParameters) - constructorDescriptor.initialize(valueParameters.descriptors, constructor.visibility) + val c = c.child(constructorDescriptor, constructor, typeParametersIndexOffset = classDescriptor.declaredTypeParameters.size) + val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.valueParameters) + val constructorTypeParameters = + classDescriptor.declaredTypeParameters + + constructor.typeParameters.map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! } + + constructorDescriptor.initialize(valueParameters.descriptors, constructor.visibility, constructorTypeParameters) constructorDescriptor.setHasStableParameterNames(false) constructorDescriptor.setHasSynthesizedParameterNames(valueParameters.hasSynthesizedNames) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt index 0f5960d41b7..a8bbffe9c75 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/resolvers.kt @@ -43,14 +43,15 @@ interface TypeParameterResolver { class LazyJavaTypeParameterResolver( private val c: LazyJavaResolverContext, private val containingDeclaration: DeclarationDescriptor, - typeParameterOwner: JavaTypeParameterListOwner + typeParameterOwner: JavaTypeParameterListOwner, + private val typeParametersIndexOffset: Int ) : TypeParameterResolver { private val typeParameters: Map = typeParameterOwner.typeParameters.mapToIndex() private val resolve = c.storageManager.createMemoizedFunctionWithNullableValues { typeParameter: JavaTypeParameter -> typeParameters[typeParameter]?.let { index -> - LazyJavaTypeParameterDescriptor(c.child(this), typeParameter, index, containingDeclaration) + LazyJavaTypeParameterDescriptor(c.child(this), typeParameter, typeParametersIndexOffset + index, containingDeclaration) } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index fca5f127cfb..d5210e93a64 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -116,13 +116,8 @@ class LazyJavaTypeResolver( ?: ErrorUtils.createErrorTypeConstructor("Unresolved java classifier: " + javaType.presentableText) } is JavaTypeParameter -> { - if (isConstructorTypeParameter()) { - getConstructorTypeParameterSubstitute().getConstructor() - } - else { - typeParameterResolver.resolveTypeParameter(classifier)?.typeConstructor - ?: ErrorUtils.createErrorTypeConstructor("Unresolved Java type parameter: " + javaType.presentableText) - } + typeParameterResolver.resolveTypeParameter(classifier)?.typeConstructor + ?: ErrorUtils.createErrorTypeConstructor("Unresolved Java type parameter: " + javaType.presentableText) } else -> throw IllegalStateException("Unknown classifier kind: $classifier") } @@ -158,24 +153,6 @@ class LazyJavaTypeResolver( return kotlinDescriptor } - private fun isConstructorTypeParameter(): Boolean { - val classifier = classifier() - return classifier is JavaTypeParameter && classifier.getOwner() is JavaConstructor - } - - // We do not memoize the results of this method, because it would consume much memory, and the real gain is little: - // the case this method accounts for is very rare, no point in optimizing it - private fun getConstructorTypeParameterSubstitute(): KotlinType { - // If a Java constructor declares its own type parameters, we have no way of directly expressing them in Kotlin, - // so we replace each type parameter with its representative upper bound (which in Java is also the first bound) - val upperBounds = (classifier() as JavaTypeParameter).upperBounds - if (upperBounds.isEmpty()) { - return c.module.builtIns.nullableAnyType - } - - return transformJavaType(upperBounds.first(), UPPER_BOUND.toAttributes()) - } - private fun isRaw(): Boolean { if (javaType.isRaw) return true @@ -212,9 +189,6 @@ class LazyJavaTypeResolver( RawSubstitution.computeProjection(parameter, attr, erasedUpperBound) } } - if (isConstructorTypeParameter()) { - return getConstructorTypeParameterSubstitute().getArguments() - } if (typeParameters.size != javaType.typeArguments.size) { // Most of the time this means there is an error in the Java code @@ -265,10 +239,7 @@ class LazyJavaTypeResolver( // nullability will be taken care of in individual member signatures when (classifier()) { is JavaTypeParameter -> { - if (isConstructorTypeParameter()) - getConstructorTypeParameterSubstitute().isMarkedNullable() - else - attr.howThisTypeIsUsed !in setOf(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT, SUPERTYPE) + attr.howThisTypeIsUsed !in setOf(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT, SUPERTYPE) } is JavaClass, null -> attr.howThisTypeIsUsed !in setOf(TYPE_ARGUMENT, SUPERTYPE_ARGUMENT, SUPERTYPE) diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaConstructor.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaConstructor.kt index badd2d4e76f..5dccf3005cd 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaConstructor.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaConstructor.kt @@ -45,8 +45,5 @@ class ReflectJavaConstructor(override val member: Constructor<*>) : ReflectJavaM return getValueParameters(realTypes, realAnnotations, member.isVarArgs) } - override fun getTypeParameters(): List { - // TODO - return listOf() - } + override fun getTypeParameters() = member.typeParameters.map { ReflectJavaTypeParameter(it) } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ConstructorDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ConstructorDescriptorImpl.java index 1267e541077..a89d52fee43 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ConstructorDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ConstructorDescriptorImpl.java @@ -57,16 +57,25 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements public ConstructorDescriptorImpl initialize( @NotNull List unsubstitutedValueParameters, - @NotNull Visibility visibility + @NotNull Visibility visibility, + @NotNull List typeParameterDescriptors ) { super.initialize( null, calculateDispatchReceiverParameter(), - getContainingDeclaration().getDeclaredTypeParameters(), + typeParameterDescriptors, unsubstitutedValueParameters, null, Modality.FINAL, visibility); return this; } + public ConstructorDescriptorImpl initialize( + @NotNull List unsubstitutedValueParameters, + @NotNull Visibility visibility + ) { + initialize(unsubstitutedValueParameters, visibility, getContainingDeclaration().getDeclaredTypeParameters()); + return this; + } + @Nullable private ReceiverParameterDescriptor calculateDispatchReceiverParameter() { ClassDescriptor classDescriptor = getContainingDeclaration(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index b033023db15..6a36e5375f0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -660,7 +660,7 @@ internal class DescriptorRendererImpl( val classDescriptor = constructor.containingDeclaration builder.append(" ") renderName(classDescriptor, builder) - renderTypeParameters(classDescriptor.declaredTypeParameters, builder, false) + renderTypeParameters(constructor.typeParameters, builder, false) } renderValueParameters(constructor.valueParameters, constructor.hasSynthesizedParameterNames(), builder)