Make computation of arguments for raw types lazy

See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F

Stack overflow happens with the following classes:
class A<X extends B> // NB: raw type B in upper bound
class B<Y extends A> // NB: raw type A in upper bound

when calculating raw type for A, we start calculate ErasedUpperBound(Y),
thus starting calculating raw type for B => ErasedUpperBound(X) => RawType(A),
so we have SOE here.
The problem is that we calculating the arguments for these raw types eagerly,
while from the definition of ErasedUpperBound(Y) we only need a type constructor
of raw type B (and the number of parameters), we don't use its arguments.

The solution is to make arguments calculating for raw types lazy

 #KT-16528 Fixed
This commit is contained in:
Denis Zharkov
2017-03-09 17:14:52 +03:00
parent f2fea9a04a
commit 7173e56393
7 changed files with 90 additions and 2 deletions
@@ -0,0 +1,4 @@
// FILE: JavaScriptParser.java
public class JavaScriptParser<F extends JSPsiTypeParser> {}
// FILE: JSPsiTypeParser.java
public class JSPsiTypeParser<T extends JavaScriptParser> {}
@@ -0,0 +1,15 @@
package
public open class JSPsiTypeParser</*0*/ T : JavaScriptParser<(raw) JSPsiTypeParser<*>!>!> {
public constructor JSPsiTypeParser</*0*/ T : JavaScriptParser<(raw) JSPsiTypeParser<*>!>!>()
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 JavaScriptParser</*0*/ F : JSPsiTypeParser<(raw) JavaScriptParser<*>!>!> {
public constructor JavaScriptParser</*0*/ F : JSPsiTypeParser<(raw) JavaScriptParser<*>!>!>()
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
}