Add multiplatform test with substitution, fix deep supertypes
This commit fixes ambiguity problems introduced before in MPP tests with deep supertypes #KT-29636 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
0e3fecf614
commit
bd769f8fd7
@@ -38,6 +38,8 @@ sourceSets {
|
|||||||
|
|
||||||
projectTest {
|
projectTest {
|
||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
|
jvmArgs!!.removeIf { it.contains("-Xmx") }
|
||||||
|
maxHeapSize = "3g"
|
||||||
}
|
}
|
||||||
|
|
||||||
testsJar()
|
testsJar()
|
||||||
+13
-8
@@ -29,9 +29,13 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority: B
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun lookupSuperTypes(klass: FirRegularClass, lookupInterfaces: Boolean): List<ConeClassLikeType> {
|
protected fun lookupSuperTypes(
|
||||||
|
klass: FirRegularClass,
|
||||||
|
lookupInterfaces: Boolean,
|
||||||
|
deep: Boolean
|
||||||
|
): List<ConeClassLikeType> {
|
||||||
return mutableListOf<ConeClassLikeType>().also {
|
return mutableListOf<ConeClassLikeType>().also {
|
||||||
if (lookupInterfaces) klass.symbol.collectSuperTypes(it)
|
if (lookupInterfaces) klass.symbol.collectSuperTypes(it, deep)
|
||||||
else klass.symbol.collectSuperClasses(it)
|
else klass.symbol.collectSuperClasses(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,21 +67,22 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority: B
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeSymbol.collectSuperTypes(list: MutableList<ConeClassLikeType>) {
|
private fun ConeClassLikeSymbol.collectSuperTypes(list: MutableList<ConeClassLikeType>, deep: Boolean) {
|
||||||
when (this) {
|
when (this) {
|
||||||
is ConeClassSymbol -> {
|
is ConeClassSymbol -> {
|
||||||
val superClassTypes =
|
val superClassTypes =
|
||||||
this.superTypes.mapNotNull { it.computePartialExpansion() }
|
this.superTypes.mapNotNull { it.computePartialExpansion() }
|
||||||
list += superClassTypes
|
list += superClassTypes
|
||||||
superClassTypes.forEach {
|
if (deep)
|
||||||
if (it !is ConeClassErrorType) {
|
superClassTypes.forEach {
|
||||||
it.symbol.collectSuperTypes(list)
|
if (it !is ConeClassErrorType) {
|
||||||
|
it.symbol.collectSuperTypes(list, deep)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is ConeTypeAliasSymbol -> {
|
is ConeTypeAliasSymbol -> {
|
||||||
val expansion = expansionType?.computePartialExpansion() ?: return
|
val expansion = expansionType?.computePartialExpansion() ?: return
|
||||||
expansion.symbol.collectSuperTypes(list)
|
expansion.symbol.collectSuperTypes(list, deep)
|
||||||
}
|
}
|
||||||
else -> error("?!id:1")
|
else -> error("?!id:1")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(rev
|
|||||||
private fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession = session): FirClassUseSiteScope {
|
private fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession = session): FirClassUseSiteScope {
|
||||||
val superTypeScope = FirCompositeScope(mutableListOf())
|
val superTypeScope = FirCompositeScope(mutableListOf())
|
||||||
val declaredScope = FirClassDeclaredMemberScope(this, useSiteSession)
|
val declaredScope = FirClassDeclaredMemberScope(this, useSiteSession)
|
||||||
lookupSuperTypes(this, lookupInterfaces = true).asReversed()
|
lookupSuperTypes(this, lookupInterfaces = true, deep = false)
|
||||||
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
|
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
|
||||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
|
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
|
||||||
val symbol = useSiteSuperType.symbol
|
val symbol = useSiteSuperType.symbol
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ open class FirTypeResolveTransformer(
|
|||||||
return withScopeCleanup {
|
return withScopeCleanup {
|
||||||
val firProvider = FirProvider.getInstance(regularClass.session)
|
val firProvider = FirProvider.getInstance(regularClass.session)
|
||||||
val classId = regularClass.symbol.classId
|
val classId = regularClass.symbol.classId
|
||||||
lookupSuperTypes(regularClass, lookupInterfaces = false).asReversed().mapTo(towerScope.scopes) {
|
lookupSuperTypes(regularClass, lookupInterfaces = false, deep = true).asReversed().mapTo(towerScope.scopes) {
|
||||||
val symbol = it.symbol
|
val symbol = it.symbol
|
||||||
if (symbol is FirBasedSymbol<*>) {
|
if (symbol is FirBasedSymbol<*>) {
|
||||||
FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session))
|
FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session))
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
abstract class A {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Y {
|
||||||
|
fun baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B : A(), Y {
|
||||||
|
fun bar() {
|
||||||
|
foo()
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : B() {
|
||||||
|
fun test() {
|
||||||
|
foo()
|
||||||
|
bar()
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
FILE: three.kt
|
||||||
|
public abstract class A {
|
||||||
|
public constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
public final function foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface Y {
|
||||||
|
public open function baz(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open class B : R|A|, R|Y| {
|
||||||
|
public constructor(): super<R|A|>()
|
||||||
|
|
||||||
|
public final function bar(): R|kotlin/Unit| {
|
||||||
|
R|/A.foo|()
|
||||||
|
R|/Y.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class C : R|B| {
|
||||||
|
public constructor(): super<R|B|>()
|
||||||
|
|
||||||
|
public final function test(): R|kotlin/Unit| {
|
||||||
|
R|/A.foo|()
|
||||||
|
R|/B.bar|()
|
||||||
|
R|/Y.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -264,6 +264,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
|||||||
public void testSimpleFakeOverride() throws Exception {
|
public void testSimpleFakeOverride() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt");
|
runTest("compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("three.kt")
|
||||||
|
public void testThree() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/overrides/three.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
expect open class A<T>() {
|
||||||
|
open fun foo(arg: T)
|
||||||
|
}
|
||||||
|
open class B : A<String>() {
|
||||||
|
// Fake: override fun foo(arg: String) = super.foo(arg)
|
||||||
|
// Fake (JVM only) (?): override fun bar(arg: String): String = super.bar(arg)
|
||||||
|
}
|
||||||
|
open class C : B() {
|
||||||
|
open fun bar(arg: CharSequence): String = arg.toString()
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
FILE: common.kt
|
||||||
|
<T> public open expect class A {
|
||||||
|
public constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
public open function foo(arg: R|T|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
}
|
||||||
|
public open class B : R|A<kotlin/String>| {
|
||||||
|
public constructor(): super<R|A<kotlin/String>|>()
|
||||||
|
|
||||||
|
}
|
||||||
|
public open class C : R|B| {
|
||||||
|
public constructor(): super<R|B|>()
|
||||||
|
|
||||||
|
public open function bar(arg: R|kotlin/CharSequence|): R|kotlin/String| {
|
||||||
|
return@@@bar <Unresolved name: arg>#.<Unresolved name: toString>#()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
actual open class A<T> {
|
||||||
|
actual open fun foo(arg: T) {}
|
||||||
|
open fun bar(arg: T): T = arg
|
||||||
|
}
|
||||||
|
class D : C() {
|
||||||
|
// Fake: override fun bar(arg: CharSequence): String = super.bar(arg)
|
||||||
|
fun test() {
|
||||||
|
foo("")
|
||||||
|
bar("")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
FILE: jvm.kt
|
||||||
|
<T> public open actual class A {
|
||||||
|
public constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
public open actual function foo(arg: R|T|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public open function bar(arg: R|T|): R|T| {
|
||||||
|
return@@@bar <Unresolved name: arg>#
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class D : R|C| {
|
||||||
|
public constructor(): super<R|C|>()
|
||||||
|
|
||||||
|
public final function test(): R|kotlin/Unit| {
|
||||||
|
R|FakeOverride</A.foo>|(String())
|
||||||
|
R|FakeOverride</A.bar>|(String())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -13,8 +13,8 @@ FILE: jvm.kt
|
|||||||
public constructor(): super<R|B|>()
|
public constructor(): super<R|B|>()
|
||||||
|
|
||||||
public final function test(): R|kotlin/Unit| {
|
public final function test(): R|kotlin/Unit| {
|
||||||
<Ambiguity: foo, [/A.foo, /A.foo]>#()
|
R|/A.foo|()
|
||||||
<Ambiguity: bar, [/A.bar, /A.bar]>#()
|
R|/A.bar|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -22,7 +22,7 @@ FILE: jvm.kt
|
|||||||
public constructor(): super<R|B|>()
|
public constructor(): super<R|B|>()
|
||||||
|
|
||||||
public final function test(): R|kotlin/Unit| {
|
public final function test(): R|kotlin/Unit| {
|
||||||
<Ambiguity: foo, [/A.foo, /A.foo]>#()
|
R|/A.foo|()
|
||||||
<Unresolved name: bar>#()
|
<Unresolved name: bar>#()
|
||||||
<Unresolved name: baz>#()
|
<Unresolved name: baz>#()
|
||||||
}
|
}
|
||||||
@@ -33,8 +33,8 @@ FILE: jvm.kt
|
|||||||
|
|
||||||
public final function test(): R|kotlin/Unit| {
|
public final function test(): R|kotlin/Unit| {
|
||||||
R|/A.foo|()
|
R|/A.foo|()
|
||||||
<Ambiguity: bar, [/X.bar, /X.bar]>#()
|
R|/X.bar|()
|
||||||
<Ambiguity: baz, [/Y.baz, /Y.baz]>#()
|
R|/Y.baz|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -34,6 +34,11 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe
|
|||||||
runTest("idea/testData/fir/multiModule/basic/");
|
runTest("idea/testData/fir/multiModule/basic/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mppFakeOverrides")
|
||||||
|
public void testMppFakeOverrides() throws Exception {
|
||||||
|
runTest("idea/testData/fir/multiModule/mppFakeOverrides/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mppMemberType")
|
@TestMetadata("mppMemberType")
|
||||||
public void testMppMemberType() throws Exception {
|
public void testMppMemberType() throws Exception {
|
||||||
runTest("idea/testData/fir/multiModule/mppMemberType/");
|
runTest("idea/testData/fir/multiModule/mppMemberType/");
|
||||||
|
|||||||
Reference in New Issue
Block a user