[FIR] Filter out incorrect library provides for dependencyProviders

Get rid of providers duplication
This commit is contained in:
Ivan Kochurkin
2022-10-21 22:17:52 +02:00
committed by Space Team
parent 8883de3f00
commit 194d1cfccf
12 changed files with 202 additions and 6 deletions
@@ -495,6 +495,24 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/NamedFunctionTypeParameterInSupertype.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplicationWithMpp.kt")
public void testNoLibraryProvidersDuplicationWithMpp() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplicationWithMpp.kt");
}
@Test
@TestMetadata("noSymbolProvidersDuplicationInDiamond.kt")
public void testNoSymbolProvidersDuplicationInDiamond() throws Exception {
runTest("compiler/testData/diagnostics/tests/noSymbolProvidersDuplicationInDiamond.kt");
}
@Test
@TestMetadata("Nullability.kt")
public void testNullability() throws Exception {
@@ -495,6 +495,24 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/NamedFunctionTypeParameterInSupertype.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplicationWithMpp.kt")
public void testNoLibraryProvidersDuplicationWithMpp() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplicationWithMpp.kt");
}
@Test
@TestMetadata("noSymbolProvidersDuplicationInDiamond.kt")
public void testNoSymbolProvidersDuplicationInDiamond() throws Exception {
runTest("compiler/testData/diagnostics/tests/noSymbolProvidersDuplicationInDiamond.kt");
}
@Test
@TestMetadata("Nullability.kt")
public void testNullability() throws Exception {
@@ -495,6 +495,24 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/NamedFunctionTypeParameterInSupertype.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplicationWithMpp.kt")
public void testNoLibraryProvidersDuplicationWithMpp() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplicationWithMpp.kt");
}
@Test
@TestMetadata("noSymbolProvidersDuplicationInDiamond.kt")
public void testNoSymbolProvidersDuplicationInDiamond() throws Exception {
runTest("compiler/testData/diagnostics/tests/noSymbolProvidersDuplicationInDiamond.kt");
}
@Test
@TestMetadata("Nullability.kt")
public void testNullability() throws Exception {
@@ -33,16 +33,46 @@ open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirDependenc
protected open val dependencyProviders by lazy {
val moduleData =
session.nullableModuleData ?: error("FirDependenciesSymbolProvider should not be created if there are no dependencies")
val result = (moduleData.dependencies + moduleData.friendDependencies + moduleData.dependsOnDependencies)
val visited = mutableSetOf<FirSymbolProvider>()
(moduleData.dependencies + moduleData.friendDependencies + moduleData.dependsOnDependencies)
.mapNotNull { session.sessionProvider?.getSession(it) }
.sortedBy { it.kind }
.map { it.symbolProvider }
result.flatMap {
when (it) {
is FirCompositeSymbolProvider -> it.providers
else -> listOf(it)
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
.sortedBy { it.session.kind }
}
/* It eliminates dependency and composite providers since the current dependency provider is composite in fact.
* To prevent duplications and resolving errors, library or source providers from other modules should be filtered out during flattening.
* It depends on the session's kind of the top-level provider */
private fun FirSymbolProvider.flatten(
visited: MutableSet<FirSymbolProvider>,
collectSourceProviders: Boolean
): List<FirSymbolProvider> {
val result = mutableListOf<FirSymbolProvider>()
fun FirSymbolProvider.collectProviders() {
if (!visited.add(this)) return
when {
this is FirDependenciesSymbolProviderImpl -> {
for (provider in dependencyProviders) {
provider.collectProviders()
}
}
this is FirCompositeSymbolProvider -> {
for (provider in providers) {
provider.collectProviders()
}
}
collectSourceProviders && session.kind == FirSession.Kind.Source ||
!collectSourceProviders && session.kind == FirSession.Kind.Library -> {
result.add(this)
}
}
}
collectProviders()
return result
}
@OptIn(FirSymbolProviderInternals::class)
@@ -3,6 +3,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND_K2: JVM_IR
// K2 status: caused by: java.lang.IllegalStateException: Should not be here!
// It will be fixed after merging of MPP branch
// MODULE: lib-common
// FILE: common.kt
@@ -0,0 +1,15 @@
// FIR_IDENTICAL
// TARGET_BACKEND: JVM
// WITH_STDLIB
// MODULE: lib
// MODULE: main()()(lib)
fun nullIfEmpty(list: List<String>): List<String>? {
return if (list.isNotEmpty()) {
list
} else {
null
}
}
@@ -0,0 +1,8 @@
// -- Module: <lib> --
package
// -- Module: <main> --
package
public fun nullIfEmpty(/*0*/ list: kotlin.collections.List<kotlin.String>): kotlin.collections.List<kotlin.String>?
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// !LANGUAGE: +MultiPlatformProjects
// TARGET_BACKEND: JVM
// WITH_STDLIB
// MODULE: lib
// MODULE: lib2
// MODULE: main(lib2)()(lib)
fun nullIfEmpty(list: List<String>): List<String>? {
return if (list.isNotEmpty()) {
list
} else {
null
}
}
@@ -0,0 +1,12 @@
// -- Module: <lib> --
package
// -- Module: <lib2> --
package
// -- Module: <main> --
package
public fun nullIfEmpty(/*0*/ list: kotlin.collections.List<kotlin.String>): kotlin.collections.List<kotlin.String>?
@@ -0,0 +1,19 @@
// FIR_IDENTICAL
// FIR_IDE_IGNORE
// !LANGUAGE: +MultiPlatformProjects
// TARGET_BACKEND: JVM
// MODULE: common
// TARGET_PLATFORM: Common
expect fun g0(): String
// MODULE: intermediate1()()(common)
// TARGET_PLATFORM: Common
// MODULE: intermediate2()()(common)
// TARGET_PLATFORM: Common
// MODULE: main()()(intermediate1, intermediate2)
// TARGET_PLATFORM: JVM
actual fun g0(): String = "OK"
@@ -0,0 +1,19 @@
// -- Module: <common> --
package
public expect fun g0(): kotlin.String
// -- Module: <intermediate1> --
package
public expect fun g0(): kotlin.String
// -- Module: <intermediate2> --
package
public expect fun g0(): kotlin.String
// -- Module: <main> --
package
public actual fun g0(): kotlin.String
@@ -495,6 +495,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/NamedFunctionTypeParameterInSupertype.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
}
@Test
@TestMetadata("noLibraryProvidersDuplicationWithMpp.kt")
public void testNoLibraryProvidersDuplicationWithMpp() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplicationWithMpp.kt");
}
@Test
@TestMetadata("noSymbolProvidersDuplicationInDiamond.kt")
public void testNoSymbolProvidersDuplicationInDiamond() throws Exception {
runTest("compiler/testData/diagnostics/tests/noSymbolProvidersDuplicationInDiamond.kt");
}
@Test
@TestMetadata("Nullability.kt")
public void testNullability() throws Exception {