Don't use ForceResolveUtil.forceResolveAllContents in TypeResolver in order to avoid problems with cyclic hierarchy.
This commit is contained in:
@@ -116,13 +116,42 @@ public class TypeResolver(
|
||||
|
||||
if (!type.isBare) {
|
||||
for (argument in type.actualType.arguments) {
|
||||
ForceResolveUtil.forceResolveAllContents(argument.type)
|
||||
forceResolveTypeContents(argument.type)
|
||||
}
|
||||
}
|
||||
|
||||
return type
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is light version of ForceResolveUtil.forceResolveAllContents
|
||||
* We can't use ForceResolveUtil.forceResolveAllContents here because it runs ForceResolveUtil.forceResolveAllContents(getConstructor()),
|
||||
* which is unsafe for some cyclic cases. For Example:
|
||||
* class A: List<A.B> {
|
||||
* class B
|
||||
* }
|
||||
* Here when we resolve class B, we should resolve supertype for A and we shouldn't start resolve for class B,
|
||||
* otherwise it would be a cycle.
|
||||
* Now there is no cycle here because member scope for A is very clever and can get lazy descriptor for class B without resolving it.
|
||||
*
|
||||
* todo: find another way after release
|
||||
*/
|
||||
private fun forceResolveTypeContents(type: JetType) {
|
||||
type.annotations // force read type annotations
|
||||
if (type.isFlexible()) {
|
||||
forceResolveTypeContents(type.flexibility().lowerBound)
|
||||
forceResolveTypeContents(type.flexibility().upperBound)
|
||||
}
|
||||
else {
|
||||
type.constructor // force read type constructor
|
||||
for (projection in type.arguments) {
|
||||
if (!projection.isStarProjection) {
|
||||
forceResolveTypeContents(projection.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveTypeElement(c: TypeResolutionContext, annotations: Annotations, typeElement: JetTypeElement?): PossiblyBareType {
|
||||
var result: PossiblyBareType? = null
|
||||
typeElement?.accept(object : JetVisitorVoid() {
|
||||
@@ -343,7 +372,7 @@ public class TypeResolver(
|
||||
if (userType.qualifier != null) { // we must resolve all type references in arguments of qualifier type
|
||||
for (typeArgument in userType.qualifier!!.typeArguments) {
|
||||
typeArgument.typeReference?.let {
|
||||
ForceResolveUtil.forceResolveAllContents(resolveType(scope, it, trace, true))
|
||||
forceResolveTypeContents(resolveType(scope, it, trace, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
open class X<T>
|
||||
|
||||
class A: X<A.B>() {
|
||||
class B
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package
|
||||
|
||||
public final class A : X<A.B> {
|
||||
public constructor A()
|
||||
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 B {
|
||||
public constructor B()
|
||||
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 X</*0*/ T> {
|
||||
public constructor X</*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
|
||||
}
|
||||
@@ -3381,6 +3381,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassInSuperClassParameter.kt")
|
||||
public void testNestedClassInSuperClassParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/cyclicHierarchy/nestedClassInSuperClassParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("twoClassesWithNestedCycle.kt")
|
||||
public void testTwoClassesWithNestedCycle() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/cyclicHierarchy/twoClassesWithNestedCycle.kt");
|
||||
|
||||
Reference in New Issue
Block a user