Preserve original for constructors of LazySubstitutingClassDescriptor
We would like DeclarationDescriptor.getOriginal() to always point to a (preferably unique) unsubstituted descriptors for the given possibly substituted descriptor. In case of LazySubstitutingClassDescriptor (which can be observed for nested generic Java classes), this invariant was broken, because 'getOriginal()' for constructors of substituted class returned a copy created for this particular substituted class.
This commit is contained in:
+1
-1
@@ -463,7 +463,7 @@ open class WrappedClassConstructorDescriptor(
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
): ClassConstructorDescriptor {
|
||||
TODO("not implemented")
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun getModality() = Modality.FINAL
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
// FILE: javaConstructorWithTypeParameters.kt
|
||||
// DUMP_EXTERNAL_CLASS J
|
||||
fun test() = J<String>()
|
||||
// DUMP_EXTERNAL_CLASS J1
|
||||
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public <T> J() {}
|
||||
fun test1() = J1<Int>()
|
||||
|
||||
fun test2() = J1<Int, Int>(1)
|
||||
|
||||
fun test3(j1: J1<Any>) = j1.J2<Int>()
|
||||
|
||||
fun test4(j1: J1<Any>) = j1.J2<Int, Int>(1)
|
||||
|
||||
// FILE: J1.java
|
||||
public class J1<T1> {
|
||||
public J1() {}
|
||||
public <X1> J1(X1 x1) {}
|
||||
|
||||
public class J2<T2> {
|
||||
public J2() {}
|
||||
public <X2> J2(X2 x2) {}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,29 @@
|
||||
FILE fqName:<root> fileName:/javaConstructorWithTypeParameters.kt
|
||||
FUN name:test visibility:public modality:FINAL <> () returnType:<root>.J
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:<root>.J1<kotlin.Int>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test (): <root>.J declared in <root>'
|
||||
CALL 'public constructor <init> <T> () declared in <root>.J' type=<root>.J origin=null
|
||||
<T>: kotlin.String
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (): <root>.J1<kotlin.Int> declared in <root>'
|
||||
CALL 'public constructor <init> () declared in <root>.J1' type=<root>.J1<kotlin.Int> origin=null
|
||||
<T1>: kotlin.Int
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:<root>.J1<kotlin.Int>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test2 (): <root>.J1<kotlin.Int> declared in <root>'
|
||||
CALL 'public constructor <init> <X1> (x1: X1 of <root>.J1.<init>?) declared in <root>.J1' type=<root>.J1<kotlin.Int> origin=null
|
||||
<T1>: kotlin.Int
|
||||
<X1>: kotlin.Int
|
||||
x1: CONST Int type=kotlin.Int value=1
|
||||
FUN name:test3 visibility:public modality:FINAL <> (j1:<root>.J1<kotlin.Any>) returnType:<root>.J1.J2<kotlin.Int, kotlin.Any>
|
||||
VALUE_PARAMETER name:j1 index:0 type:<root>.J1<kotlin.Any>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test3 (j1: <root>.J1<kotlin.Any>): <root>.J1.J2<kotlin.Int, kotlin.Any> declared in <root>'
|
||||
CALL 'public constructor <init> () declared in <root>.J1.J2' type=<root>.J1.J2<kotlin.Int, kotlin.Any> origin=null
|
||||
<T2>: kotlin.Int
|
||||
$this: GET_VAR 'j1: <root>.J1<kotlin.Any> declared in <root>.test3' type=<root>.J1<kotlin.Any> origin=null
|
||||
FUN name:test4 visibility:public modality:FINAL <> (j1:<root>.J1<kotlin.Any>) returnType:<root>.J1.J2<kotlin.Int, kotlin.Any>
|
||||
VALUE_PARAMETER name:j1 index:0 type:<root>.J1<kotlin.Any>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test4 (j1: <root>.J1<kotlin.Any>): <root>.J1.J2<kotlin.Int, kotlin.Any> declared in <root>'
|
||||
CALL 'public constructor <init> <X2> (x2: X2 of <root>.J1.J2.<init>?) declared in <root>.J1.J2' type=<root>.J1.J2<kotlin.Int, kotlin.Any> origin=null
|
||||
<T2>: kotlin.Int
|
||||
<T1>: kotlin.Int
|
||||
$this: GET_VAR 'j1: <root>.J1<kotlin.Any> declared in <root>.test4' type=<root>.J1<kotlin.Any> origin=null
|
||||
x2: CONST Int type=kotlin.Int value=1
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:J1 modality:OPEN visibility:public superTypes:[<unbound IrClassSymbolImpl>]
|
||||
$this: VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:<this> type:<root>.J1<T1 of <root>.J1>
|
||||
TYPE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:T1 index:0 variance: superTypes:[<unbound IrClassSymbolImpl>?]
|
||||
CONSTRUCTOR IR_EXTERNAL_DECLARATION_STUB visibility:public <> () returnType:<root>.J1<T1 of <root>.J1>
|
||||
CONSTRUCTOR IR_EXTERNAL_DECLARATION_STUB visibility:public <X1> (x1:X1 of <root>.J1.<init>?) returnType:<root>.J1<T1 of <root>.J1>
|
||||
TYPE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:X1 index:1 variance: superTypes:[<unbound IrClassSymbolImpl>?]
|
||||
VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:x1 index:0 type:X1 of <root>.J1.<init>?
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:J2 modality:OPEN visibility:public [inner] superTypes:[<unbound IrClassSymbolImpl>]
|
||||
$this: VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:<this> type:<root>.J1.J2<T2 of <root>.J1.J2, T1 of <root>.J1>
|
||||
TYPE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:T2 index:0 variance: superTypes:[<unbound IrClassSymbolImpl>?]
|
||||
CONSTRUCTOR IR_EXTERNAL_DECLARATION_STUB visibility:public <> ($this:<root>.J1<T1 of <root>.J1>) returnType:<root>.J1.J2<T2 of <root>.J1.J2, T1 of <root>.J1>
|
||||
$outer: VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:<this> type:<root>.J1<T1 of <root>.J1>
|
||||
CONSTRUCTOR IR_EXTERNAL_DECLARATION_STUB visibility:public <X2> ($this:<root>.J1<T1 of <root>.J1>, x2:X2 of <root>.J1.J2.<init>?) returnType:<root>.J1.J2<T2 of <root>.J1.J2, T1 of <root>.J1>
|
||||
TYPE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:X2 index:1 variance: superTypes:[<unbound IrClassSymbolImpl>?]
|
||||
$outer: VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:<this> type:<root>.J1<T1 of <root>.J1>
|
||||
VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:x2 index:0 type:X2 of <root>.J1.J2.<init>?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:<unbound IrClassSymbolImpl>) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun hashCode (): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun toString (): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun hashCode (): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:<unbound IrClassSymbolImpl>
|
||||
overridden:
|
||||
public open fun toString (): <unbound IrClassSymbolImpl> declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER FAKE_OVERRIDE name:<this> type:kotlin.Any
|
||||
@@ -27,10 +27,10 @@ interface ClassConstructorDescriptor : ConstructorDescriptor {
|
||||
override fun substitute(substitutor: TypeSubstitutor): ClassConstructorDescriptor?
|
||||
|
||||
override fun copy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
): ClassConstructorDescriptor
|
||||
}
|
||||
+7
-2
@@ -135,8 +135,13 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
||||
Collection<ClassConstructorDescriptor> originalConstructors = original.getConstructors();
|
||||
Collection<ClassConstructorDescriptor> result = new ArrayList<ClassConstructorDescriptor>(originalConstructors.size());
|
||||
for (ClassConstructorDescriptor constructor : originalConstructors) {
|
||||
ClassConstructorDescriptor copy =
|
||||
constructor.copy(this, constructor.getModality(), constructor.getVisibility(), constructor.getKind(), false);
|
||||
ClassConstructorDescriptor copy = (ClassConstructorDescriptor) constructor.newCopyBuilder()
|
||||
.setOriginal(constructor.getOriginal())
|
||||
.setModality(constructor.getModality())
|
||||
.setVisibility(constructor.getVisibility())
|
||||
.setKind(constructor.getKind())
|
||||
.setCopyOverrides(false)
|
||||
.build();
|
||||
result.add(copy.substitute(getSubstitutor()));
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user