[FIR] Rework predicates system

Now predicates are split into LookupPredicate and DeclarationPredicate
  hierarchies. First one allows to perform global search for declarations
  and second one allows to check if some declaration matches the predicate.
Predicates with meta annotations are excluded from LookupPredicates,
  because it's impossible to create index of annotations with meta-annotations,
  because they can be located inside binary dependencies (so to achieve
  this we need to scan the whole classpath).
Also only one predicate with meta-annotations is left in DeclarationPredicate
  hierarchy (AnnotatedWithMeta)

^KT-53874 Fixed
^KT-53590 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-11-23 15:16:44 +02:00
committed by Space Team
parent 7a9a71a089
commit 246dc985a6
41 changed files with 934 additions and 605 deletions
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated
import org.jetbrains.kotlin.fir.extensions.predicate.or
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -57,7 +55,7 @@ class FirAllOpenPredicateMatcher(
}
}
override val predicate = run {
override val predicate = DeclarationPredicate.create {
val annotationFqNames = allOpenAnnotationFqNames.map { FqName(it) }
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
}
@@ -0,0 +1,36 @@
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class AllOpen {
// source: 'anonymousObject.kt'
}
@kotlin.Metadata
public final class Test$a$1 {
// source: 'anonymousObject.kt'
enclosing method Test.<init>()V
inner (anonymous) class Test$a$1
method <init>(): void
public final method run(): void
}
@kotlin.Metadata
public final class Test$b$1 {
// source: 'anonymousObject.kt'
enclosing method Test.b()V
inner (anonymous) class Test$b$1
method <init>(): void
public final method run(): void
}
@AllOpen
@kotlin.Metadata
public class Test {
// source: 'anonymousObject.kt'
private final @org.jetbrains.annotations.NotNull field a: java.lang.Runnable
inner (anonymous) class Test$a$1
inner (anonymous) class Test$b$1
public method <init>(): void
private final static method b$lambda$0(): void
public method b(): void
public @org.jetbrains.annotations.NotNull method getA(): java.lang.Runnable
}
@@ -1,6 +1,6 @@
// IGNORE_BACKEND_K2: JVM_IR
// FIR version does not go inside bodies
// Also it's quiestionable do we even need to transform local classes and anonymous objects
annotation class AllOpen
@AllOpen
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
// FIR version does not support double-transitive annotations by design
// MODULE: lib
annotation class AllOpen
@AllOpen
@@ -14,6 +13,8 @@ annotation class AnotherComponent
@java.lang.annotation.Documented
annotation class Documented
// MODULE: main(lib)
class TestWithoutAnnotations_ShouldBeFinal
@Documented
@@ -0,0 +1,103 @@
Module: lib
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class AllOpen {
// source: 'module_lib_metaAnnotation_differentModules.kt'
}
@OtherComponent
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class AnotherComponent {
// source: 'module_lib_metaAnnotation_differentModules.kt'
}
@java.lang.annotation.Documented
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class Documented {
// source: 'module_lib_metaAnnotation_differentModules.kt'
}
@AllOpen
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class MyComponent {
// source: 'module_lib_metaAnnotation_differentModules.kt'
}
@MyComponent
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class OtherComponent {
// source: 'module_lib_metaAnnotation_differentModules.kt'
}
Module: main
@Documented
@kotlin.Metadata
public final class ClassWithDocumented {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@MyComponent
@kotlin.Metadata
public abstract class MyComponentBase {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class MyComponentImpl2_ShouldBeFinal {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
public method method(): void
}
@kotlin.Metadata
public class MyComponentImpl3_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
public final method method_ShouldBeFinal(): void
}
@kotlin.Metadata
public class MyComponentImpl_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
public method method(): void
}
@AllOpen
@kotlin.Metadata
public class TestAllOpen_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@AnotherComponent
@kotlin.Metadata
public class TestAnotherComponent_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@MyComponent
@kotlin.Metadata
public class TestMyComponent_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@OtherComponent
@kotlin.Metadata
public class TestOtherComponent_ShouldBeOpen {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class TestWithoutAnnotations_ShouldBeFinal {
// source: 'module_main_metaAnnotation_differentModules.kt'
public method <init>(): void
}
@@ -0,0 +1,45 @@
annotation class AllOpen
@AllOpen
annotation class MyComponent
@MyComponent // Double-transitive annotations is supported
annotation class OtherComponent
@OtherComponent
annotation class AnotherComponent
@java.lang.annotation.Documented
annotation class Documented
class TestWithoutAnnotations_ShouldBeFinal
@Documented
class ClassWithDocumented
@AllOpen
class TestAllOpen_ShouldBeOpen
@MyComponent
class TestMyComponent_ShouldBeOpen
@OtherComponent
class TestOtherComponent_ShouldBeOpen
@AnotherComponent
class TestAnotherComponent_ShouldBeOpen
@MyComponent
abstract class MyComponentBase
class MyComponentImpl_ShouldBeOpen : MyComponentBase() {
fun method() {}
}
final class MyComponentImpl2_ShouldBeFinal : MyComponentBase() {
fun method() {}
}
class MyComponentImpl3_ShouldBeOpen : MyComponentBase() {
final fun method_ShouldBeFinal() {}
}
@@ -1,20 +1,20 @@
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class AllOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
}
@OtherComponent
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class AnotherComponent {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
}
@Documented
@kotlin.Metadata
public final class ClassWithDocumented {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@@ -22,40 +22,40 @@ public final class ClassWithDocumented {
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class Documented {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
}
@AllOpen
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class MyComponent {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
}
@MyComponent
@kotlin.Metadata
public abstract class MyComponentBase {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class MyComponentImpl2_ShouldBeFinal {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
public method method(): void
}
@kotlin.Metadata
public class MyComponentImpl3_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
public final method method_ShouldBeFinal(): void
}
@kotlin.Metadata
public class MyComponentImpl_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
public method method(): void
}
@@ -64,39 +64,39 @@ public class MyComponentImpl_ShouldBeOpen {
@java.lang.annotation.Retention(value=RUNTIME)
@kotlin.Metadata
public annotation class OtherComponent {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
}
@AllOpen
@kotlin.Metadata
public class TestAllOpen_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@AnotherComponent
@kotlin.Metadata
public class TestAnotherComponent_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@MyComponent
@kotlin.Metadata
public class TestMyComponent_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@OtherComponent
@kotlin.Metadata
public class TestOtherComponent_ShouldBeOpen {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class TestWithoutAnnotations_ShouldBeFinal {
// source: 'metaAnnotation.kt'
// source: 'metaAnnotation_sameModule.kt'
public method <init>(): void
}
@@ -56,9 +56,15 @@ public class BytecodeListingTestForAllOpenGenerated extends AbstractBytecodeList
}
@Test
@TestMetadata("metaAnnotation.kt")
public void testMetaAnnotation() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
@TestMetadata("metaAnnotation_differentModules.kt")
public void testMetaAnnotation_differentModules() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
}
@Test
@TestMetadata("metaAnnotation_sameModule.kt")
public void testMetaAnnotation_sameModule() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
}
@Test
@@ -56,9 +56,15 @@ public class FirBytecodeListingTestForAllOpenGenerated extends AbstractFirByteco
}
@Test
@TestMetadata("metaAnnotation.kt")
public void testMetaAnnotation() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
@TestMetadata("metaAnnotation_differentModules.kt")
public void testMetaAnnotation_differentModules() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
}
@Test
@TestMetadata("metaAnnotation_sameModule.kt")
public void testMetaAnnotation_sameModule() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
}
@Test
@@ -56,9 +56,15 @@ public class IrBytecodeListingTestForAllOpenGenerated extends AbstractIrBytecode
}
@Test
@TestMetadata("metaAnnotation.kt")
public void testMetaAnnotation() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
@TestMetadata("metaAnnotation_differentModules.kt")
public void testMetaAnnotation_differentModules() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
}
@Test
@TestMetadata("metaAnnotation_sameModule.kt")
public void testMetaAnnotation_sameModule() throws Exception {
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
}
@Test
@@ -12,9 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotatedOrUnder
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotatedOrUnder
import org.jetbrains.kotlin.fir.extensions.predicate.or
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.transform
import org.jetbrains.kotlin.name.FqName
@@ -22,7 +19,9 @@ import org.jetbrains.kotlin.name.FqName
class AllOpenStatusTransformer(session: FirSession) : FirStatusTransformerExtension(session) {
companion object {
private val ALL_OPEN = FqName("org.jetbrains.kotlin.fir.plugin.AllOpen")
private val PREDICATE: DeclarationPredicate = annotatedOrUnder(ALL_OPEN) or metaAnnotatedOrUnder(ALL_OPEN)
private val PREDICATE = DeclarationPredicate.create {
annotatedOrUnder(ALL_OPEN) or metaAnnotated(ALL_OPEN)
}
}
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotatedOrUnder
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.transform
import org.jetbrains.kotlin.fir.references.FirNamedReference
@@ -37,7 +36,7 @@ class AllPublicVisibilityTransformer(session: FirSession) : FirStatusTransformer
private val PrivateName = Name.identifier("Private")
private val ProtectedName = Name.identifier("Protected")
private val PREDICATE: DeclarationPredicate = annotatedOrUnder(AllPublicClassId.asSingleFqName())
private val PREDICATE = DeclarationPredicate.create { annotatedOrUnder(AllPublicClassId.asSingleFqName()) }
}
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -26,7 +25,7 @@ import org.jetbrains.kotlin.name.Name
class SomeAdditionalSupertypeGenerator(session: FirSession) : FirSupertypeGenerationExtension(session) {
companion object {
private val myInterfaceClassId = ClassId(FqName("foo"), Name.identifier("MyInterface"))
private val PREDICATE: DeclarationPredicate = annotated("MyInterfaceSupertype".fqn())
private val PREDICATE = DeclarationPredicate.create { annotated("MyInterfaceSupertype".fqn()) }
}
@@ -13,13 +13,11 @@ import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
import org.jetbrains.kotlin.fir.extensions.buildUserTypeFromQualifierParts
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.constructClassLikeType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -32,7 +30,7 @@ class SupertypeWithArgumentGenerator(session: FirSession) : FirSupertypeGenerati
companion object {
private val supertypeClassId = ClassId(FqName("foo"), Name.identifier("InterfaceWithArgument"))
private val annotationClassId = ClassId.topLevel("SupertypeWithTypeArgument".fqn())
private val PREDICATE: DeclarationPredicate = annotated(annotationClassId.asSingleFqName())
private val PREDICATE = DeclarationPredicate.create { annotated(annotationClassId.asSingleFqName()) }
}
@@ -5,12 +5,12 @@
package org.jetbrains.kotlin.fir.plugin.generators
import org.jetbrains.kotlin.GeneratedDeclarationKey
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.GeneratedDeclarationKey
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.fqn
@@ -40,7 +39,7 @@ class AdditionalMembersGenerator(session: FirSession) : FirDeclarationGeneration
private val MATERIALIZE_NAME = Name.identifier("materialize")
private val NESTED_NAME = Name.identifier("Nested")
private val PREDICATE: DeclarationPredicate = annotated("NestedClassAndMaterializeMember".fqn())
private val PREDICATE = LookupPredicate.create { annotated("NestedClassAndMaterializeMember".fqn()) }
}
private val predicateBasedProvider = session.predicateBasedProvider
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.fqn
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.name.SpecialNames
*/
class CompanionGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
companion object {
private val PREDICATE = annotated("CompanionWithFoo".fqn())
private val PREDICATE = LookupPredicate.create { annotated("CompanionWithFoo".fqn()) }
private val FOO_NAME = Name.identifier("foo")
}
@@ -17,8 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.fqn
@@ -43,7 +42,7 @@ class ExternalClassGenerator(session: FirSession) : FirDeclarationGenerationExte
private val GENERATED_CLASS_ID = ClassId(FOO_PACKAGE, Name.identifier("AllOpenGenerated"))
private val MATERIALIZE_NAME = Name.identifier("materialize")
private val PREDICATE: DeclarationPredicate = annotated("ExternalClassWithNested".fqn())
private val PREDICATE = LookupPredicate.create { annotated("ExternalClassWithNested".fqn()) }
}
object Key : GeneratedDeclarationKey() {
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildBlock
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.fqn
@@ -37,8 +37,8 @@ import org.jetbrains.kotlin.name.Name
*/
class MembersOfSerializerGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
companion object {
private val SERIALIZABLE_PREDICATE = annotated("MySerializable".fqn())
private val CORE_SERIALIZER_PREDICATE = annotated("CoreSerializer".fqn())
private val SERIALIZABLE_PREDICATE = LookupPredicate.create { annotated("MySerializable".fqn()) }
private val CORE_SERIALIZER_PREDICATE = LookupPredicate.create { annotated("CoreSerializer".fqn()) }
private val X_NAME = Name.identifier("x")
}
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.fqn
@@ -35,7 +34,7 @@ import org.jetbrains.kotlin.name.Name
*/
class TopLevelDeclarationsGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
companion object {
private val PREDICATE: DeclarationPredicate = annotated("DummyFunction".fqn())
private val PREDICATE = LookupPredicate.create { annotated("DummyFunction".fqn()) }
}
private val predicateBasedProvider = session.predicateBasedProvider
@@ -4,7 +4,7 @@ FILE: first.kt
super<R|kotlin/Any|>()
}
public open fun foo(): R|kotlin/Unit| {
public final fun foo(): R|kotlin/Unit| {
}
}
@@ -9,7 +9,7 @@ class A {
@Open
class B : A() {
override fun foo() {
<!OVERRIDING_FINAL_MEMBER!>override<!> fun foo() {
}
}
@@ -9,11 +9,13 @@ import org.jetbrains.kotlin.fir.extensions.predicate.*
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
object FirSerializationPredicates {
internal val serializerFor: DeclarationPredicate =
AnnotatedWith(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...)
internal val generatedSerializer: DeclarationPredicate =
ancestorAnnotated(SerializationAnnotations.serializableAnnotationFqName) // @Serializable X.$serializer
internal val hasMetaAnnotation = metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
internal val annotatedWithSerializableOrMeta =
AnnotatedWith(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
internal val serializerFor = DeclarationPredicate.create {
annotated(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...)
}
internal val hasMetaAnnotation = DeclarationPredicate.create {
metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
}
internal val annotatedWithSerializableOrMeta = DeclarationPredicate.create {
annotated(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
}
}
@@ -250,12 +250,6 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
return listOf(copy.symbol)
}
// FIXME: it seems that this list will always be used, why not provide it automatically?
private val matchedClasses by lazy {
session.predicateBasedProvider.getSymbolsByPredicate(FirSerializationPredicates.annotatedWithSerializableOrMeta)
.filterIsInstance<FirRegularClassSymbol>()
}
override fun generateConstructors(context: MemberGenerationContext): List<FirConstructorSymbol> {
val owner = context.owner
val defaultObjectConstructor = buildPrimaryConstructor(
@@ -291,10 +285,15 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
return listOf(defaultObjectConstructor.symbol)
}
fun addSerializerImplClass(
classId: ClassId
): FirClassLikeSymbol<*>? {
val owner = matchedClasses.firstOrNull { it.classId == classId.outerClassId } ?: return null
private fun getClassWithAnnotatedWithSerializableOrMeta(classId: ClassId?): FirRegularClassSymbol? {
if (classId == null) return null
return (session.symbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol)?.takeIf {
session.predicateBasedProvider.matches(FirSerializationPredicates.annotatedWithSerializableOrMeta, it)
}
}
fun addSerializerImplClass(classId: ClassId): FirClassLikeSymbol<*>? {
val owner = getClassWithAnnotatedWithSerializableOrMeta(classId.outerClassId) ?: return null
val hasTypeParams = owner.typeParameterSymbols.isNotEmpty()
val serializerKind = if (hasTypeParams) ClassKind.CLASS else ClassKind.OBJECT
val serializerFirClass = buildRegularClass {
@@ -332,7 +331,7 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
fun generateCompanionDeclaration(classId: ClassId): FirClassLikeSymbol<*>? {
if (classId.shortClassName != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) return null
val owner = matchedClasses.firstOrNull { it.classId == classId.outerClassId } ?: return null
val owner = getClassWithAnnotatedWithSerializableOrMeta(classId.outerClassId) ?: return null
if (owner.companionObjectSymbol != null) return null
val regularClass = buildRegularClass {
moduleData = session.moduleData
@@ -6,9 +6,7 @@
package org.jetbrains.kotlin.noarg.fir
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated
import org.jetbrains.kotlin.fir.extensions.predicate.or
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
import org.jetbrains.kotlin.name.FqName
@@ -22,7 +20,7 @@ class FirNoArgPredicateMatcher(
}
}
override val predicate = run {
override val predicate = DeclarationPredicate.create {
val annotationFqNames = noArgAnnotationFqNames.map { FqName(it) }
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
}
+2 -2
View File
@@ -7,8 +7,8 @@ class Outer {
fun local() {
@NoArg
class Local(val l: Any) {
class <!NOARG_ON_LOCAL_CLASS_ERROR!>Local<!>(val l: Any) {
@NoArg
inner class InnerLocal(val x: Any)
inner class <!NOARG_ON_INNER_CLASS_ERROR!>InnerLocal<!>(val x: Any)
}
}
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.defaultType
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
companion object {
private val PREDICATE = annotated(PARCELIZE_FQN, OLD_PARCELIZE_FQN)
private val PREDICATE = LookupPredicate.create { annotated(PARCELIZE_FQN, OLD_PARCELIZE_FQN) }
private val parcelizeMethodsNames = setOf(DESCRIBE_CONTENTS_NAME, WRITE_TO_PARCEL_NAME)
}