[FIR] Fix Kotlin-Java supertype recursion problem

This commit is contained in:
Mikhail Glukhikh
2020-02-10 11:59:33 +03:00
parent cc0e39ebca
commit 9a80850700
4 changed files with 90 additions and 47 deletions
@@ -122,7 +122,10 @@ class JavaSymbolProvider(
classId,
{
val foundClass = findClass(classId, content)
if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) {
if (foundClass == null || foundClass.annotations.any {
it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME
}
) {
null to null
} else {
FirRegularClassSymbol(classId) to foundClass
@@ -136,13 +139,13 @@ class JavaSymbolProvider(
if (!isTopLevel) {
val parentId = ClassId(classId.packageFqName, parentFqName, false)
val parentClassSymbol = getClassLikeSymbolByFqName(parentId)
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol] ?:
(parentClassSymbol?.fir as? FirJavaClass)?.javaTypeParameterStack
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
?: (parentClassSymbol?.fir as? FirJavaClass)?.javaTypeParameterStack
if (parentStack != null) {
javaTypeParameterStack.addStack(parentStack)
}
}
buildJavaClass {
val firJavaClass = buildJavaClass {
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirSourceElement()
session = this@JavaSymbolProvider.session
symbol = firSymbol
@@ -158,11 +161,6 @@ class JavaSymbolProvider(
scopeProvider = this@JavaSymbolProvider.scopeProvider
typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
for (supertype in javaClass.supertypes) {
superTypeRefs += supertype.toFirResolvedTypeRef(
this@JavaSymbolProvider.session, javaTypeParameterStack, typeParametersNullability = ConeNullability.UNKNOWN
)
}
// TODO: may be we can process fields & methods later.
// However, they should be built up to override resolve stage
for (javaField in javaClass.fields) {
@@ -218,7 +216,7 @@ class JavaSymbolProvider(
): FirJavaConstructorBuilder {
val constructorSymbol = FirConstructorSymbol(constructorId)
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
val firJavaConstructor = FirJavaConstructorBuilder().apply {
return FirJavaConstructorBuilder().apply {
source = psi?.toFirSourceElement()
session = this@JavaSymbolProvider.session
symbol = constructorSymbol
@@ -233,7 +231,6 @@ class JavaSymbolProvider(
}
typeParameters += classTypeParameters
}
return firJavaConstructor
}
if (javaClassDeclaredConstructors.isEmpty() && javaClass.classKind == ClassKind.CLASS) {
@@ -260,6 +257,13 @@ class JavaSymbolProvider(
isNotSam = isNotSam()
parentClassTypeParameterStackCache.remove(firSymbol)
}
firJavaClass.replaceSuperTypeRefs(
javaClass.supertypes.map { supertype ->
supertype.toFirResolvedTypeRef(
this@JavaSymbolProvider.session, javaTypeParameterStack, typeParametersNullability = ConeNullability.UNKNOWN
)
}
)
}
}
}
@@ -1,35 +1,33 @@
// Compiler crashes on this tests so it's commented
// FILE: K1.kt
class K2: J1() {
class Q : Nested()
fun bar() {
<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>baz<!>()
//// FILE: K1.kt
//class K2: J1() {
// class Q : Nested()
// fun bar() {
// foo()
// baz()
//
// superClass()
// superI()
// }
//}
//
//// FILE: J1.java
//public class J1 extends K2() {
// public class Nested {}
//
// void baz() {}
//}
//
//// FILE: K2.kt
//open class KFirst : SuperClass(), SuperI {
// fun foo() {
// }
//}
//
//// FILE: K3.kt
//abstract class SuperClass {
// fun superClass() {}
//}
//
//interface SuperI {
// fun superI() {}
//}
<!UNRESOLVED_REFERENCE!>superClass<!>()
<!UNRESOLVED_REFERENCE!>superI<!>()
}
}
// FILE: J1.java
public class J1 extends K2() {
public class Nested {}
void baz() {}
}
// FILE: K2.kt
open class KFirst : SuperClass(), SuperI {
fun foo() {
}
}
// FILE: K3.kt
abstract class SuperClass {
fun superClass() {}
}
interface SuperI {
fun superI() {}
}
@@ -1,3 +1,46 @@
FILE: K1.kt
public final class K2 : R|J1| {
public constructor(): R|K2| {
super<R|J1|>()
}
public final class Q : R|ERROR CLASS: Symbol not found, for `Nested`| {
public constructor(): R|K2.Q| {
super<R|ERROR CLASS: Symbol not found, for `Nested`|>()
}
}
public final fun bar(): R|kotlin/Unit| {
<Unresolved name: foo>#()
<Unresolved name: baz>#()
<Unresolved name: superClass>#()
<Unresolved name: superI>#()
}
}
FILE: K2.kt
public open class KFirst : R|SuperClass|, R|SuperI| {
public constructor(): R|KFirst| {
super<R|SuperClass|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
FILE: K3.kt
public abstract class SuperClass : R|kotlin/Any| {
public constructor(): R|SuperClass| {
super<R|kotlin/Any|>()
}
public final fun superClass(): R|kotlin/Unit| {
}
}
public abstract interface SuperI : R|kotlin/Any| {
public open fun superI(): R|kotlin/Unit| {
}
}
@@ -1,2 +0,0 @@
Failures detected in FirSupertypeResolverTransformer, file: /K.kt
Cause: kotlin.UninitializedPropertyAccessException: lateinit property fir has not been initialized