Support generic constructors defined in Java

#KT-10686 Fixed
 #KT-10410 Fixed
This commit is contained in:
Denis Zharkov
2016-01-22 16:02:46 +03:00
parent a02d1b75b8
commit 6542d091ee
32 changed files with 353 additions and 55 deletions
@@ -0,0 +1,16 @@
// !CHECK_TYPE
// FILE: A.java
public class A<E> {
public <T extends E> A(E x, java.util.List<T> y) {}
}
// FILE: main.kt
fun test(x: List<Int>, y: List<String>) {
A("", x) checkType { _<A<Any?>>() }
A("", y) checkType { _<A<String?>>() }
A<CharSequence, String>("", <!TYPE_MISMATCH!>x<!>)
A<CharSequence, String>("", y)
}
@@ -0,0 +1,10 @@
package
public fun test(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.collections.List<kotlin.String>): kotlin.Unit
public open class A</*0*/ E : kotlin.Any!> {
public constructor A</*0*/ E : kotlin.Any!, /*1*/ T : E!>(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List<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
}
@@ -0,0 +1,17 @@
// !CHECK_TYPE
// FILE: Outer.java
public class Outer<T> {
public class Inner<E> {
public <F extends E, G extends T> Inner(E x, java.util.List<F> y, G z) {}
}
}
// FILE: main.kt
fun test(x: List<Int>, y: List<String>) {
Outer<Int>().Inner("", y, 1) checkType { _<Outer<Int>.Inner<String>>() }
Outer<Int>().Inner<CharSequence, String, Int>("", y, 1) checkType { _<Outer<Int>.Inner<CharSequence>>() }
Outer<Int>().Inner("", x, 1) checkType { _<Outer<Int>.Inner<Any>>() }
Outer<Int>().Inner<CharSequence, String, Int>("", <!TYPE_MISMATCH!>x<!>, 1)
}
@@ -0,0 +1,17 @@
package
public fun test(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.collections.List<kotlin.String>): kotlin.Unit
public open class Outer</*0*/ T : kotlin.Any!> {
public constructor Outer</*0*/ T : kotlin.Any!>()
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</*0*/ E : kotlin.Any!> /*captured type parameters: /*1*/ T : kotlin.Any!*/ {
public constructor Inner</*0*/ E : kotlin.Any!, /*1*/ F : E!, /*2*/ G : T!>(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List<F!>!, /*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
}
}
@@ -0,0 +1,18 @@
// FILE: A.java
public class A {
public <T> A(T x, java.util.List<T> y) {}
}
// FILE: main.kt
fun test(x: List<Int>, y: List<String>) {
A("", x) // inferred as Any!
A("", y)
A<String>("", <!TYPE_MISMATCH!>x<!>)
A<Any>("", x)
A<String>("", y)
A<CharSequence>("", y)
}
@@ -0,0 +1,10 @@
package
public fun test(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.collections.List<kotlin.String>): kotlin.Unit
public open class A {
public constructor A</*0*/ T : kotlin.Any!>(/*0*/ x: T!, /*1*/ y: kotlin.collections.(Mutable)List<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
}
@@ -0,0 +1,20 @@
// FILE: A.java
public class A {
public <T> A(T x, Inv<T> y) {}
}
// FILE: main.kt
class Inv<T>
fun test(x: Inv<Int>, y: Inv<String>) {
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>A<!>("", x)
A("", y)
A<String>("", <!TYPE_MISMATCH!>x<!>)
A<Any>("", <!TYPE_MISMATCH!>x<!>)
A<String>("", y)
A<CharSequence>("", <!TYPE_MISMATCH!>y<!>)
}
@@ -0,0 +1,17 @@
package
public fun test(/*0*/ x: Inv<kotlin.Int>, /*1*/ y: Inv<kotlin.String>): kotlin.Unit
public open class A {
public constructor A</*0*/ T : kotlin.Any!>(/*0*/ x: T!, /*1*/ y: Inv<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
}
public final class Inv</*0*/ T> {
public constructor Inv</*0*/ 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
}
@@ -0,0 +1,11 @@
// FILE: C.java
// See KT-10410
public class C {
public <T extends T> C(T t) {
}
}
// FILE: main.kt
fun foo() = <!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>C<!>(<!NO_VALUE_FOR_PARAMETER!>)<!>
@@ -0,0 +1,10 @@
package
public fun foo(): C
public open class C {
public constructor C</*0*/ T : [ERROR : Cyclic upper bounds]>(/*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
}
@@ -0,0 +1,19 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// FILE: R.java
public class R<T extends R<T>> {
public <F extends R<F>> R(F x) {
}
}
// FILE: RImpl.java
public class RImpl extends R<RImpl> {
public RImpl() {
<RImpl>super(null);
}
}
// FILE: main.kt
fun test() {
val x: R<RImpl> = R(RImpl())
R<RImpl, RImpl>(RImpl())
}
@@ -0,0 +1,17 @@
package
public fun test(): kotlin.Unit
public open class R</*0*/ T : R<T!>!> {
public constructor R</*0*/ T : R<T!>!, /*1*/ F : R<F!>!>(/*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<RImpl!> {
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
}
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !CHECK_TYPE
// FILE: A.java
public class A<E> {
public <T extends E> A(E x, java.util.List<T> y) {}
}
// FILE: main.kt
class B1(x: List<String>) : A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><CharSequence><!>("", x)
class B2(x: List<Int>) : A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><CharSequence><!>("", x)
class C : A<CharSequence> {
constructor(x: List<String>) : super("", <!TYPE_MISMATCH(kotlin.collections.\(Mutable\)List<T!>!; kotlin.collections.List<kotlin.String>)!>x<!>)
constructor(x: List<Int>, y: Int) : super("", <!TYPE_MISMATCH!>x<!>)
}
@@ -0,0 +1,30 @@
package
public open class A</*0*/ E : kotlin.Any!> {
public constructor A</*0*/ E : kotlin.Any!, /*1*/ T : E!>(/*0*/ x: E!, /*1*/ y: kotlin.collections.(Mutable)List<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
}
public final class B1 : A<kotlin.CharSequence> {
public constructor B1(/*0*/ x: kotlin.collections.List<kotlin.String>)
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<kotlin.CharSequence> {
public constructor B2(/*0*/ x: kotlin.collections.List<kotlin.Int>)
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<kotlin.CharSequence> {
public constructor C(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.Int)
public constructor C(/*0*/ x: kotlin.collections.List<kotlin.String>)
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
}
@@ -0,0 +1,19 @@
// !DIAGNOSTICS: -UNUSED_VALUE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE
// FILE: A.java
public class A<E> {
public <T> A(T x, java.util.List<T> y) {}
}
// FILE: main.kt
fun test(x: List<Int>, y: List<String>) {
var z: A<Double> = A("", x) // E inferred from expected type
z = A("", y)
z = A<Double, String>("", <!TYPE_MISMATCH!>x<!>)
z = A<Double, Any>("", x)
z = A<Double, String>("", y)
z = A<Double, CharSequence>("", y)
}
@@ -0,0 +1,10 @@
package
public fun test(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.collections.List<kotlin.String>): kotlin.Unit
public open class A</*0*/ E : kotlin.Any!> {
public constructor A</*0*/ E : kotlin.Any!, /*1*/ T : kotlin.Any!>(/*0*/ x: T!, /*1*/ y: kotlin.collections.(Mutable)List<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
}
@@ -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) = <!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>J<!>(c)
fun serializable(s: Serializable) = J(<!TYPE_MISMATCH!>s<!>)
fun serializable(s: Serializable) = <!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>J<!>(s)
fun <T> both(t: T) where T : Cloneable, T : Serializable = J(t)
@@ -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 : kotlin.Cloneable!>(/*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
@@ -1,5 +1,5 @@
package test
public open class ConstructorGenericDeep {
public constructor ConstructorGenericDeep(/*0*/ p0: java.lang.Class<kotlin.Any!>!)
public constructor ConstructorGenericDeep</*0*/ P : kotlin.Any!>(/*0*/ p0: java.lang.Class<P!>!)
}
@@ -1,5 +1,5 @@
package test
public open class ConstructorGenericSimple {
public constructor ConstructorGenericSimple(/*0*/ p0: kotlin.Any!)
public constructor ConstructorGenericSimple</*0*/ P : kotlin.Any!>(/*0*/ p0: P!)
}
@@ -1,5 +1,5 @@
package test
public open class ConstructorGenericUpperBound {
public constructor ConstructorGenericUpperBound(/*0*/ p0: java.util.RandomAccess!)
public constructor ConstructorGenericUpperBound</*0*/ P : java.util.RandomAccess!>(/*0*/ p0: P!)
}
@@ -1,5 +1,5 @@
package test
public open class ConstructorWithNewTypeParams</*0*/ T : kotlin.Any!> {
public constructor ConstructorWithNewTypeParams</*0*/ T : kotlin.Any!>(/*0*/ p0: kotlin.Any!)
public constructor ConstructorWithNewTypeParams</*0*/ T : kotlin.Any!, /*1*/ U : kotlin.Any!>(/*0*/ p0: U!)
}
@@ -13,7 +13,7 @@ class A<T1, T2 : T1> : B<T1, T2> {
Resolved call:
Candidate descriptor: constructor B<X, Y : X>(x: X, y: Y) defined in B
Resulting descriptor: constructor B<X, Y : X>(x: T1, y: T2) defined in B
Resulting descriptor: constructor B<X, Y : T1>(x: T1, y: T2) defined in B
Explicit receiver kind = NO_EXPLICIT_RECEIVER
Dispatch receiver = NO_RECEIVER
@@ -13,7 +13,7 @@ class A<T1, T2 : T1> : B<T1, T2> {
Resolved call:
Candidate descriptor: constructor B<X, Y : X>(x: X, s: String) defined in B
Resulting descriptor: constructor B<X, Y : X>(x: T1, s: String) defined in B
Resulting descriptor: constructor B<X, Y : T1>(x: T1, s: String) defined in B
Explicit receiver kind = NO_EXPLICIT_RECEIVER
Dispatch receiver = NO_RECEIVER
@@ -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)