[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:
Dmitriy Novozhilov
2024-01-04 18:14:20 +02:00
committed by Space Team
parent 8feb4def4d
commit 7accda6cda
9 changed files with 177 additions and 6 deletions
@@ -42,6 +42,7 @@ annotation class AllPropertiesConstructor
annotation class AddAnnotations
@Retention(AnnotationRetention.RUNTIME)
annotation class AnnotationToAdd(
val booleanValue: Boolean,
val byteValue: Byte,
@@ -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)
}
@@ -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"
}
@@ -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 {
@@ -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()
}
}
}