Support generic constructors defined in Java
#KT-10686 Fixed #KT-10410 Fixed
This commit is contained in:
compiler/testData/diagnostics/tests/j+k/genericConstructor/classTypeParameterInferredFromArgument.kt
Vendored
+16
@@ -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)
|
||||
}
|
||||
+10
@@ -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
|
||||
}
|
||||
}
|
||||
+18
@@ -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)
|
||||
}
|
||||
+10
@@ -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
|
||||
}
|
||||
Vendored
+20
@@ -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<!>)
|
||||
}
|
||||
Vendored
+17
@@ -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
|
||||
}
|
||||
+19
@@ -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)
|
||||
}
|
||||
+10
@@ -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
|
||||
}
|
||||
+2
-3
@@ -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)
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
+7
-2
@@ -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)
|
||||
|
||||
|
||||
@@ -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<JavaTypeParameter, Int> = 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-32
@@ -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)
|
||||
|
||||
+1
-4
@@ -45,8 +45,5 @@ class ReflectJavaConstructor(override val member: Constructor<*>) : ReflectJavaM
|
||||
return getValueParameters(realTypes, realAnnotations, member.isVarArgs)
|
||||
}
|
||||
|
||||
override fun getTypeParameters(): List<JavaTypeParameter> {
|
||||
// TODO
|
||||
return listOf()
|
||||
}
|
||||
override fun getTypeParameters() = member.typeParameters.map { ReflectJavaTypeParameter(it) }
|
||||
}
|
||||
|
||||
+11
-2
@@ -57,16 +57,25 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
||||
|
||||
public ConstructorDescriptorImpl initialize(
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@NotNull Visibility visibility
|
||||
@NotNull Visibility visibility,
|
||||
@NotNull List<TypeParameterDescriptor> typeParameterDescriptors
|
||||
) {
|
||||
super.initialize(
|
||||
null, calculateDispatchReceiverParameter(),
|
||||
getContainingDeclaration().getDeclaredTypeParameters(),
|
||||
typeParameterDescriptors,
|
||||
unsubstitutedValueParameters, null,
|
||||
Modality.FINAL, visibility);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstructorDescriptorImpl initialize(
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@NotNull Visibility visibility
|
||||
) {
|
||||
initialize(unsubstitutedValueParameters, visibility, getContainingDeclaration().getDeclaredTypeParameters());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ReceiverParameterDescriptor calculateDispatchReceiverParameter() {
|
||||
ClassDescriptor classDescriptor = getContainingDeclaration();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user