[FIR] Make FirProviderWithGeneratedFiles know about providers from mpp dependencies
During refactoring of FIR2IR commit 8ebb4127 introduced
`FirProviderWithGeneratedFiles` for lookups for containing FIR for
generated declaration
But it broke the logic of `Fir2IrIrGeneratedDeclarationsRegistrar`,
which provides annotations for metadata from generated IR annotations
(see `containingFile` function in it), as it started to use fir
provider from the platfrom session instead of provider of the
corresponding session
So to fix this issue `FirProviderWithGeneratedFiles` was changed in the
way so it sees declarations from dependant sessions too (only with
`dependsOn` relation), which allows to use provider for the leaf
platform session for declarations from any module within the same
HMPP hierarchy
^KT-64444 Fixed
This commit is contained in:
committed by
Space Team
parent
8feb4def4d
commit
7accda6cda
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -53,4 +54,14 @@ class Fir2IrCommonMemberStorage(
|
||||
val fakeOverridesInClass: MutableMap<IrClass, MutableMap<Fir2IrDeclarationStorage.FirOverrideKey, FirCallableDeclaration>> = mutableMapOf()
|
||||
|
||||
val irForFirSessionDependantDeclarationMap: MutableMap<Fir2IrDeclarationStorage.FakeOverrideIdentifier, IrSymbol> = mutableMapOf()
|
||||
|
||||
fun registerFirProvider(moduleData: FirModuleData, firProvider: FirProviderWithGeneratedFiles) {
|
||||
require(moduleData !in _previousFirProviders) { "FirProvider for $moduleData already registered"}
|
||||
_previousFirProviders[moduleData] = firProvider
|
||||
}
|
||||
|
||||
val previousFirProviders: Map<FirModuleData, FirProviderWithGeneratedFiles>
|
||||
get() = _previousFirProviders
|
||||
|
||||
private val _previousFirProviders: MutableMap<FirModuleData, FirProviderWithGeneratedFiles> = mutableMapOf()
|
||||
}
|
||||
|
||||
@@ -32,7 +32,11 @@ class Fir2IrComponentsStorage(
|
||||
specialSymbolProvider: Fir2IrSpecialSymbolProvider,
|
||||
initializedIrBuiltIns: IrBuiltInsOverFir?
|
||||
) : Fir2IrComponents {
|
||||
override val firProvider: FirProviderWithGeneratedFiles = FirProviderWithGeneratedFiles(session)
|
||||
override val firProvider: FirProviderWithGeneratedFiles = FirProviderWithGeneratedFiles(
|
||||
session,
|
||||
commonMemberStorage.previousFirProviders
|
||||
)
|
||||
|
||||
override val signatureComposer: FirBasedSignatureComposer = commonMemberStorage.firSignatureComposer
|
||||
override val symbolTable: SymbolTable = commonMemberStorage.symbolTable
|
||||
|
||||
|
||||
@@ -743,6 +743,8 @@ class Fir2IrConverter(
|
||||
components.fir2IrVisitor
|
||||
)
|
||||
|
||||
commonMemberStorage.registerFirProvider(session.moduleData, components.firProvider)
|
||||
|
||||
return Fir2IrResult(irModuleFragment, components, moduleDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -5,9 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
@@ -20,10 +22,14 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
|
||||
class FirProviderWithGeneratedFiles(val session: FirSession) : FirProvider() {
|
||||
class FirProviderWithGeneratedFiles(val session: FirSession, previousProviders: Map<FirModuleData, FirProviderWithGeneratedFiles>) : FirProvider() {
|
||||
private val generatedFilesProvider = FirProviderImpl(session, session.kotlinScopeProvider)
|
||||
|
||||
private val providers: List<FirProvider> = listOf(session.firProvider, generatedFilesProvider)
|
||||
private val providers: List<FirProvider> = buildList {
|
||||
add(session.firProvider)
|
||||
add(generatedFilesProvider)
|
||||
session.moduleData.dependsOnDependencies.mapNotNullTo(this) { previousProviders[it] }
|
||||
}
|
||||
|
||||
override val symbolProvider: FirSymbolProvider
|
||||
get() = providers.first().symbolProvider
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ annotation class AllPropertiesConstructor
|
||||
|
||||
annotation class AddAnnotations
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class AnnotationToAdd(
|
||||
val booleanValue: Boolean,
|
||||
val byteValue: Byte,
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
Module: common
|
||||
FILE: module_common_annotationsGeneratedInBackend_mpp.kt
|
||||
package test
|
||||
|
||||
@R|org/jetbrains/kotlin/fir/plugin/AddAnnotations|() public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|test/Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
FILE: module_platform_annotationsGeneratedInBackend_mpp.kt
|
||||
package test
|
||||
|
||||
@R|org/jetbrains/kotlin/fir/plugin/AddAnnotations|() public final class Other : R|kotlin/Any| {
|
||||
public constructor(): R|test/Other| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun checkClass(klass: R|kotlin/reflect/KClass<*>|): R|kotlin/Boolean| {
|
||||
lval foo: R|kotlin/reflect/KFunction<*>| = R|<local>/klass|.R|kotlin/reflect/full/declaredFunctions|.R|kotlin/collections/first|<R|kotlin/reflect/KFunction<*>|>(<L> = first@fun <anonymous>(it: R|kotlin/reflect/KFunction<*>|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
|
||||
^ ==(R|<local>/it|.R|SubstitutionOverride<kotlin/reflect/KFunction.name: R|kotlin/String|>|, String(foo))
|
||||
}
|
||||
)
|
||||
^checkClass R|<local>/foo|.R|kotlin/reflect/KAnnotatedElement.annotations|.R|kotlin/collections/any|<R|kotlin/Annotation|>(<L> = any@fun <anonymous>(it: R|kotlin/Annotation|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
|
||||
^ ==(R|<local>/it|.R|kotlin/jvm/annotationClass|<R|kotlin/Annotation|>.R|SubstitutionOverride<kotlin/reflect/KClass.simpleName: R|kotlin/String?|>|, String(AnnotationToAdd))
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun box(): R|kotlin/String| {
|
||||
when () {
|
||||
R|test/checkClass|(<getClass>(Q|test/Some|)).R|kotlin/Boolean.not|() -> {
|
||||
^box String(Fail: Some)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
R|test/checkClass|(<getClass>(Q|test/Other|)).R|kotlin/Boolean.not|() -> {
|
||||
^box String(Fail: Other)
|
||||
}
|
||||
}
|
||||
|
||||
^box String(OK)
|
||||
}
|
||||
Module: platform
|
||||
FILE: module_common_annotationsGeneratedInBackend_mpp.kt
|
||||
package test
|
||||
|
||||
@R|org/jetbrains/kotlin/fir/plugin/AddAnnotations|() public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|test/Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
FILE: module_platform_annotationsGeneratedInBackend_mpp.kt
|
||||
package test
|
||||
|
||||
@R|org/jetbrains/kotlin/fir/plugin/AddAnnotations|() public final class Other : R|kotlin/Any| {
|
||||
public constructor(): R|test/Other| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun checkClass(klass: R|kotlin/reflect/KClass<*>|): R|kotlin/Boolean| {
|
||||
lval foo: R|kotlin/reflect/KFunction<*>| = R|<local>/klass|.R|kotlin/reflect/full/declaredFunctions|.R|kotlin/collections/first|<R|kotlin/reflect/KFunction<*>|>(<L> = first@fun <anonymous>(it: R|kotlin/reflect/KFunction<*>|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
|
||||
^ ==(R|<local>/it|.R|SubstitutionOverride<kotlin/reflect/KFunction.name: R|kotlin/String|>|, String(foo))
|
||||
}
|
||||
)
|
||||
^checkClass R|<local>/foo|.R|kotlin/reflect/KAnnotatedElement.annotations|.R|kotlin/collections/any|<R|kotlin/Annotation|>(<L> = any@fun <anonymous>(it: R|kotlin/Annotation|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
|
||||
^ ==(R|<local>/it|.R|kotlin/jvm/annotationClass|<R|kotlin/Annotation|>.R|SubstitutionOverride<kotlin/reflect/KClass.simpleName: R|kotlin/String?|>|, String(AnnotationToAdd))
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun box(): R|kotlin/String| {
|
||||
when () {
|
||||
R|test/checkClass|(<getClass>(Q|test/Some|)).R|kotlin/Boolean.not|() -> {
|
||||
^box String(Fail: Some)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
R|test/checkClass|(<getClass>(Q|test/Other|)).R|kotlin/Boolean.not|() -> {
|
||||
^box String(Fail: Other)
|
||||
}
|
||||
}
|
||||
|
||||
^box String(OK)
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// LANGUAGE: +MultiPlatformProjects
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// WITH_STDLIB
|
||||
|
||||
// MODULE: common
|
||||
package test
|
||||
|
||||
import org.jetbrains.kotlin.fir.plugin.AddAnnotations
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@AddAnnotations
|
||||
class Some {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
// MODULE: platform()()(common)
|
||||
package test
|
||||
|
||||
import org.jetbrains.kotlin.fir.plugin.AddAnnotations
|
||||
import kotlin.reflect.KAnnotatedElement
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.declaredFunctions
|
||||
|
||||
@AddAnnotations
|
||||
class Other {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun checkClass(klass: KClass<*>): Boolean {
|
||||
val foo = klass.declaredFunctions.first { it.name == "foo" }
|
||||
return foo.annotations.any { it.annotationClass.simpleName == "AnnotationToAdd" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (!checkClass(Some::class)) return "Fail: Some"
|
||||
if (!checkClass(Other::class)) return "Fail: Other"
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -25,6 +25,12 @@ public class FirLightTreePluginBlackBoxCodegenTestGenerated extends AbstractFirL
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/fir-plugin-prototype/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsGeneratedInBackend_mpp.kt")
|
||||
public void testAnnotationsGeneratedInBackend_mpp() throws Exception {
|
||||
runTest("plugins/fir-plugin-prototype/testData/box/annotationsGeneratedInBackend_mpp.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("builtins.kt")
|
||||
public void testBuiltins() throws Exception {
|
||||
|
||||
+5
-3
@@ -37,9 +37,11 @@ class PluginAnnotationsProvider(testServices: TestServices) : EnvironmentConfigu
|
||||
|
||||
class PluginRuntimeAnnotationsProvider(testServices: TestServices) : RuntimeClasspathProvider(testServices) {
|
||||
override fun runtimeClassPaths(module: TestModule): List<File> {
|
||||
if (!module.targetPlatform.isJs()) return emptyList()
|
||||
val jar = findJsLib()
|
||||
return listOf(jar)
|
||||
return when {
|
||||
module.targetPlatform.isJvm() -> listOf(findJvmLib())
|
||||
module.targetPlatform.isJs() -> listOf(findJsLib())
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user