[FIR IDE] Use proper FirSessions in FirSupertypesResolution

Symbols might be from other modules, so we need to use corresponding
`FirSession`s; otherwise it would be impossible to query symbols
from `firProvider`

^KTIJ-21714 Fixed
This commit is contained in:
Roman Golyshev
2022-05-12 21:00:21 +04:00
parent 11eb5ce39c
commit 254151d82c
11 changed files with 290 additions and 6 deletions
@@ -284,6 +284,24 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule.kt")
public void testInherentlyImportedTypeFromOtherModule() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule2.kt")
public void testInherentlyImportedTypeFromOtherModule2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule2.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule3.kt")
public void testInherentlyImportedTypeFromOtherModule3() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule3.kt");
}
@Test
@TestMetadata("intersectionScope.kt")
public void testIntersectionScope() throws Exception {
@@ -244,6 +244,21 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.kt");
}
@TestMetadata("inherentlyImportedTypeFromOtherModule.kt")
public void testInherentlyImportedTypeFromOtherModule() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule.kt");
}
@TestMetadata("inherentlyImportedTypeFromOtherModule2.kt")
public void testInherentlyImportedTypeFromOtherModule2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule2.kt");
}
@TestMetadata("inherentlyImportedTypeFromOtherModule3.kt")
public void testInherentlyImportedTypeFromOtherModule3() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule3.kt");
}
@TestMetadata("intersectionScope.kt")
public void testIntersectionScope() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/intersectionScope.kt");
@@ -0,0 +1,34 @@
Module: lib
FILE: module_lib_inherentlyImportedTypeFromOtherModule.kt
package dependency
public abstract class Test : R|kotlin/Any| {
public constructor(): R|dependency/Test| {
super<R|kotlin/Any|>()
}
public abstract interface Result : R|kotlin/Any| {
}
public final class Success : R|dependency/Test.Result| {
public constructor(): R|dependency/Test.Success| {
super<R|kotlin/Any|>()
}
}
}
Module: main
FILE: module_main_inherentlyImportedTypeFromOtherModule.kt
package main
public final class Main : R|dependency/Test| {
public constructor(): R|main/Main| {
super<R|dependency/Test|>()
}
public final fun usage(): R|dependency/Test.Result| {
^usage R|dependency/Test.Success.Success|()
}
}
@@ -0,0 +1,24 @@
// SKIP_JAVAC
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
// because it fails to parse module structure of multimodule test
// MODULE: lib
package dependency
abstract class Test {
interface Result
class Success : Result
}
// MODULE: main(lib)
package main
import dependency.Test
class Main : Test() {
fun usage(): Result {
return Success()
}
}
@@ -0,0 +1,46 @@
Module: lib
FILE: module_lib_inherentlyImportedTypeFromOtherModule2.kt
package lib
public abstract class FirstBase : R|kotlin/Any| {
public constructor(): R|lib/FirstBase| {
super<R|kotlin/Any|>()
}
public abstract interface Result : R|kotlin/Any| {
}
}
public abstract class SecondBase : R|lib/FirstBase| {
public constructor(): R|lib/SecondBase| {
super<R|lib/FirstBase|>()
}
}
public abstract class Test : R|lib/SecondBase| {
public constructor(): R|lib/Test| {
super<R|lib/SecondBase|>()
}
public final class Success : R|lib/FirstBase.Result| {
public constructor(): R|lib/Test.Success| {
super<R|kotlin/Any|>()
}
}
}
Module: main
FILE: module_main_inherentlyImportedTypeFromOtherModule2.kt
package main
public final class Main : R|lib/Test| {
public constructor(): R|main/Main| {
super<R|lib/Test|>()
}
public final fun usage(): R|lib/FirstBase.Result| {
^usage R|lib/Test.Success.Success|()
}
}
@@ -0,0 +1,27 @@
// SKIP_JAVAC
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
// because it fails to parse module structure of multimodule test
// MODULE: lib
package lib
abstract class FirstBase {
interface Result
}
abstract class SecondBase : FirstBase()
abstract class Test : SecondBase() {
class Success : Result
}
// MODULE: main(lib)
package main
import lib.Test
class Main : Test() {
fun usage(): Result {
return Success()
}
}
@@ -0,0 +1,50 @@
Module: lib1
FILE: module_lib1_inherentlyImportedTypeFromOtherModule3.kt
package lib1
public abstract class FirstBase : R|kotlin/Any| {
public constructor(): R|lib1/FirstBase| {
super<R|kotlin/Any|>()
}
public abstract interface Result : R|kotlin/Any| {
}
}
public abstract class SecondBase : R|lib1/FirstBase| {
public constructor(): R|lib1/SecondBase| {
super<R|lib1/FirstBase|>()
}
}
Module: lib2
FILE: module_lib2_inherentlyImportedTypeFromOtherModule3.kt
package lib2
public abstract class Test : R|lib1/SecondBase| {
public constructor(): R|lib2/Test| {
super<R|lib1/SecondBase|>()
}
public final class Success : R|lib1/FirstBase.Result| {
public constructor(): R|lib2/Test.Success| {
super<R|kotlin/Any|>()
}
}
}
Module: main
FILE: module_main_inherentlyImportedTypeFromOtherModule3.kt
package main
public final class Main : R|lib2/Test| {
public constructor(): R|main/Main| {
super<R|lib2/Test|>()
}
public final fun usage(): R|lib1/FirstBase.Result| {
^usage R|lib2/Test.Success.Success|()
}
}
@@ -0,0 +1,32 @@
// SKIP_JAVAC
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
// because it fails to parse module structure of multimodule test
// MODULE: lib1
package lib1
abstract class FirstBase {
interface Result
}
abstract class SecondBase : FirstBase()
// MODULE: lib2(lib1)
package lib2
import lib1.SecondBase
abstract class Test : SecondBase() {
class Success : Result
}
// MODULE: main(lib1, lib2)
package main
import lib2.Test
class Main : Test() {
fun usage(): Result {
return Success()
}
}
@@ -284,6 +284,24 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule.kt")
public void testInherentlyImportedTypeFromOtherModule() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule2.kt")
public void testInherentlyImportedTypeFromOtherModule2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule2.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule3.kt")
public void testInherentlyImportedTypeFromOtherModule3() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule3.kt");
}
@Test
@TestMetadata("intersectionScope.kt")
public void testIntersectionScope() throws Exception {
@@ -284,6 +284,24 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule.kt")
public void testInherentlyImportedTypeFromOtherModule() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule2.kt")
public void testInherentlyImportedTypeFromOtherModule2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule2.kt");
}
@Test
@TestMetadata("inherentlyImportedTypeFromOtherModule3.kt")
public void testInherentlyImportedTypeFromOtherModule3() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inherentlyImportedTypeFromOtherModule3.kt");
}
@Test
@TestMetadata("intersectionScope.kt")
public void testIntersectionScope() throws Exception {
@@ -243,9 +243,9 @@ open class FirSupertypeResolverVisitor(
if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierContainerFileIfAny(symbol)
else symbol.moduleData.session.firProvider.getFirClassifierContainerFileIfAny(symbol.classId)
private fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? =
private fun getFirClassifierByFqName(moduleSession: FirSession, classId: ClassId): FirClassLikeDeclaration? =
if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierByFqName(classId)
else session.firProvider.getFirClassifierByFqName(classId)
else moduleSession.firProvider.getFirClassifierByFqName(classId)
override fun visitElement(element: FirElement, data: Any?) {}
@@ -283,12 +283,13 @@ open class FirSupertypeResolverVisitor(
visited: MutableSet<FirClassLikeDeclaration> = mutableSetOf()
) {
if (!visited.add(classLikeDeclaration)) return
val supertypes =
val supertypes: List<ConeKotlinType> =
resolveSpecificClassLikeSupertypes(classLikeDeclaration, supertypeRefs).map { it.coneType }
for (supertype in supertypes) {
if (supertype !is ConeClassLikeType) continue
val fir = getFirClassifierByFqName(supertype.lookupTag.classId) ?: continue
val supertypeModuleSession = supertype.toSymbol(session)?.moduleData?.session ?: continue
val fir = getFirClassifierByFqName(supertypeModuleSession, supertype.lookupTag.classId) ?: continue
resolveAllSupertypes(fir, fir.supertypeRefs(), visited)
}
}
@@ -301,6 +302,7 @@ open class FirSupertypeResolverVisitor(
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration): PersistentList<FirScope> {
val classId = classLikeDeclaration.symbol.classId
val classModuleSession = classLikeDeclaration.moduleData.session
val result = when {
classId.isLocal -> {
@@ -316,11 +318,11 @@ open class FirSupertypeResolverVisitor(
}
}
classLikeDeclaration.safeAs<FirRegularClass>()?.isCompanion == true -> {
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
val outerClassFir = classId.outerClassId?.let { getFirClassifierByFqName(classModuleSession, it) } as? FirRegularClass
prepareScopeForCompanion(outerClassFir ?: return persistentListOf())
}
classId.isNestedClass -> {
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
val outerClassFir = classId.outerClassId?.let { getFirClassifierByFqName(classModuleSession, it) } as? FirRegularClass
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
}
else -> getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.let(::prepareFileScopes) ?: persistentListOf()