From 68e830a01273ae211aa1a4579375c5f4fb5b38af Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 27 Mar 2024 17:28:03 +0100 Subject: [PATCH] updated compiler plugin to make @Sparkify classes Serializable too, plus added test to see if the plugin is enabled in the project --- .../ir/DataClassSparkifyGenerator.kt | 14 +++--- .../box/dataClassInFunctionTest.fir.ir.txt | 12 ++--- .../box/dataClassIsProductTest.fir.ir.txt | 26 ++++++---- .../box/dataClassIsProductTest.fir.txt | 6 +++ .../testData/box/dataClassIsProductTest.kt | 4 ++ .../testData/box/dataClassTest.fir.ir.txt | 12 ++--- gradle/bootstraps/compiler-plugin.jar | Bin 46937 -> 47047 bytes .../jetbrains/kotlinx/spark/api/Encoding.kt | 6 ++- .../kotlinx/spark/api/CompilerPluginTest.kt | 47 ++++++++++++++++++ 9 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 kotlin-spark-api/src/test/kotlin/org/jetbrains/kotlinx/spark/api/CompilerPluginTest.kt diff --git a/compiler-plugin/src/main/kotlin/org/jetbrains/kotlinx/spark/api/compilerPlugin/ir/DataClassSparkifyGenerator.kt b/compiler-plugin/src/main/kotlin/org/jetbrains/kotlinx/spark/api/compilerPlugin/ir/DataClassSparkifyGenerator.kt index 7d3992dc..c27050d0 100644 --- a/compiler-plugin/src/main/kotlin/org/jetbrains/kotlinx/spark/api/compilerPlugin/ir/DataClassSparkifyGenerator.kt +++ b/compiler-plugin/src/main/kotlin/org/jetbrains/kotlinx/spark/api/compilerPlugin/ir/DataClassSparkifyGenerator.kt @@ -207,18 +207,20 @@ class DataClassSparkifyGenerator( if (!declaration.isData) return super.visitClass(declaration) - // add superclass + // add superclasses val scalaProductClass = productFqNames.firstNotNullOfOrNull { val classId = ClassId.topLevel(FqName(it)) -// ClassId( -// packageFqName = FqName("scala"), -// topLevelName = Name.identifier("Product"), -// ) pluginContext.referenceClass(classId) }!! declaration.superTypes += scalaProductClass.defaultType + val serializableClass = pluginContext.referenceClass( + ClassId.topLevel(FqName("java.io.Serializable")) + )!! + + declaration.superTypes += serializableClass.defaultType + // finding the constructor params val constructorParams = declaration.primaryConstructor?.valueParameters ?: return super.visitClass(declaration) @@ -349,7 +351,7 @@ class DataClassSparkifyGenerator( } val ioobClass = pluginContext.referenceClass( - FqName("java.lang.IndexOutOfBoundsException").toClassId() + ClassId(FqName("java.lang"), Name.identifier("IndexOutOfBoundsException")) )!! val ioobConstructor = ioobClass.constructors.first { it.owner.valueParameters.isEmpty() } val throwCall = irThrow( diff --git a/compiler-plugin/src/test/resources/testData/box/dataClassInFunctionTest.fir.ir.txt b/compiler-plugin/src/test/resources/testData/box/dataClassInFunctionTest.fir.ir.txt index c8c2aa17..edde60a0 100644 --- a/compiler-plugin/src/test/resources/testData/box/dataClassInFunctionTest.fir.ir.txt +++ b/compiler-plugin/src/test/resources/testData/box/dataClassInFunctionTest.fir.ir.txt @@ -94,7 +94,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt VALUE_PARAMETER name:n index:0 type:kotlin.Int FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String BLOCK_BODY - CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product] + CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable] annotations: Sparkify $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:foo.bar.box.User @@ -168,7 +168,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt CONST Double type=kotlin.Double value=2.0 BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product]' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' FUN GENERATED_DATA_CLASS_MEMBER name:component1 visibility:public modality:FINAL <> ($this:foo.bar.box.User) returnType:kotlin.String [operator] $this: VALUE_PARAMETER name: type:foo.bar.box.User BLOCK_BODY @@ -402,7 +402,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.box.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="name" p0: GET_VAR 'val user: foo.bar.box.User declared in foo.bar.box' type=foo.bar.box.User origin=null VAR name:age type:@[FlexibleNullability] kotlin.Any? [val] @@ -410,7 +410,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.box.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="age" p0: GET_VAR 'val user: foo.bar.box.User declared in foo.bar.box' type=foo.bar.box.User origin=null VAR name:a type:@[FlexibleNullability] kotlin.Any? [val] @@ -418,7 +418,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.box.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="a" p0: GET_VAR 'val user: foo.bar.box.User declared in foo.bar.box' type=foo.bar.box.User origin=null VAR name:b type:@[FlexibleNullability] kotlin.Any? [val] @@ -426,7 +426,7 @@ FILE fqName:foo.bar fileName:/dataClassInFunctionTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.box.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:local [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="b" p0: GET_VAR 'val user: foo.bar.box.User declared in foo.bar.box' type=foo.bar.box.User origin=null WHEN type=kotlin.Unit origin=IF diff --git a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.ir.txt b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.ir.txt index 7db10a08..d204965a 100644 --- a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.ir.txt +++ b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.ir.txt @@ -49,7 +49,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Annotation $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product] + CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable] annotations: Sparkify $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:foo.bar.User @@ -123,7 +123,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt CONST Double type=kotlin.Double value=2.0 BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' FUN GENERATED_DATA_CLASS_MEMBER name:component1 visibility:public modality:FINAL <> ($this:foo.bar.User) returnType:kotlin.String [operator] $this: VALUE_PARAMETER name: type:foo.bar.User BLOCK_BODY @@ -402,7 +402,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="name" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:age type:@[FlexibleNullability] kotlin.Any? [val] @@ -410,7 +410,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="age" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:a type:@[FlexibleNullability] kotlin.Any? [val] @@ -418,7 +418,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="a" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:b type:@[FlexibleNullability] kotlin.Any? [val] @@ -426,7 +426,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="b" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null WHEN type=kotlin.Unit origin=IF @@ -471,12 +471,18 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in foo.bar' CONST String type=kotlin.String value="User is not a Product" + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=NOT_INSTANCEOF typeOperand=java.io.Serializable + GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in foo.bar' + CONST String type=kotlin.String value="User is not Serializable" VAR name:canEqual type:@[FlexibleNullability] kotlin.Any? [val] CALL 'public open fun invoke (p0: @[FlexibleNullability] kotlin.Any?, vararg p1: @[FlexibleNullability] kotlin.Any?): @[FlexibleNullability] kotlin.Any? declared in java.lang.reflect.Method' type=@[FlexibleNullability] kotlin.Any? origin=null $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="canEqual" p1: VARARG type=@[FlexibleNullability] @[FlexibleArrayElementVariance] kotlin.Array?>? varargElementType=@[FlexibleNullability] java.lang.Class<*>? CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY @@ -499,7 +505,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="productArity" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null WHEN type=kotlin.Unit origin=IF @@ -518,7 +524,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="productElement" p1: VARARG type=@[FlexibleNullability] @[FlexibleArrayElementVariance] kotlin.Array?>? varargElementType=@[FlexibleNullability] java.lang.Class<*>? CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY @@ -545,7 +551,7 @@ FILE fqName:foo.bar fileName:/dataClassIsProductTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="productElement" p1: VARARG type=@[FlexibleNullability] @[FlexibleArrayElementVariance] kotlin.Array?>? varargElementType=@[FlexibleNullability] java.lang.Class<*>? CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY diff --git a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.txt b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.txt index d3df3864..d038809c 100644 --- a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.txt +++ b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.fir.txt @@ -44,6 +44,12 @@ FILE: dataClassIsProductTest.kt } } + @R|kotlin/Suppress|(names = vararg(String(USELESS_IS_CHECK))) when () { + (R|/user| !is R|java/io/Serializable|) -> { + ^box String(User is not Serializable) + } + } + lval canEqual: R|kotlin/Any!| = (Q|foo/bar/User|).R|kotlin/jvm/java|.R|SubstitutionOverride|(String(canEqual), vararg((Q|kotlin/Any|).R|kotlin/jvm/java|)).R|java/lang/reflect/Method.invoke|(R|/user|, vararg(R|/user|)) when () { !=(R|/canEqual|, Boolean(true)) -> { diff --git a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.kt b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.kt index f62410e3..629af08f 100644 --- a/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.kt +++ b/compiler-plugin/src/test/resources/testData/box/dataClassIsProductTest.kt @@ -28,6 +28,10 @@ fun box(): String { if (user !is foo.bar.Product) return "User is not a Product" + @Suppress("USELESS_IS_CHECK") + if (user !is java.io.Serializable) + return "User is not Serializable" + val canEqual = User::class.java.getMethod("canEqual", Any::class.java).invoke(user, user) if (canEqual != true) { return "Could invoke function canEqual() from Java but was false" diff --git a/compiler-plugin/src/test/resources/testData/box/dataClassTest.fir.ir.txt b/compiler-plugin/src/test/resources/testData/box/dataClassTest.fir.ir.txt index 842274d2..b669ac1b 100644 --- a/compiler-plugin/src/test/resources/testData/box/dataClassTest.fir.ir.txt +++ b/compiler-plugin/src/test/resources/testData/box/dataClassTest.fir.ir.txt @@ -189,7 +189,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:age type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null receiver: GET_VAR ': foo.bar.NormalUser declared in foo.bar.NormalUser.toString' type=foo.bar.NormalUser origin=null CONST String type=kotlin.String value=")" - CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product] + CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable] annotations: Sparkify $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:foo.bar.User @@ -263,7 +263,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt CONST Double type=kotlin.Double value=2.0 BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' FUN GENERATED_DATA_CLASS_MEMBER name:component1 visibility:public modality:FINAL <> ($this:foo.bar.User) returnType:kotlin.String [operator] $this: VALUE_PARAMETER name: type:foo.bar.User BLOCK_BODY @@ -542,7 +542,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="name" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:age type:@[FlexibleNullability] kotlin.Any? [val] @@ -550,7 +550,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="age" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:a type:@[FlexibleNullability] kotlin.Any? [val] @@ -558,7 +558,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="a" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null VAR name:b type:@[FlexibleNullability] kotlin.Any? [val] @@ -566,7 +566,7 @@ FILE fqName:foo.bar fileName:/dataClassTest.kt $this: CALL 'public open fun getMethod (p0: @[FlexibleNullability] kotlin.String?, vararg p1: @[FlexibleNullability] java.lang.Class<*>?): @[FlexibleNullability] java.lang.reflect.Method? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Method? origin=null $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm' type=java.lang.Class origin=GET_PROPERTY : foo.bar.User - $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product]' type=kotlin.reflect.KClass + $receiver: CLASS_REFERENCE 'CLASS CLASS name:User modality:FINAL visibility:public [data] superTypes:[kotlin.Any; foo.bar.Product; java.io.Serializable]' type=kotlin.reflect.KClass p0: CONST String type=kotlin.String value="b" p0: GET_VAR 'val user: foo.bar.User declared in foo.bar.box' type=foo.bar.User origin=null WHEN type=kotlin.Unit origin=IF diff --git a/gradle/bootstraps/compiler-plugin.jar b/gradle/bootstraps/compiler-plugin.jar index 84d321b1f654fb65e81f5aafbb091ecfc17f837a..2ea26a00e4761153ad5ca395caecf07e160af1d3 100644 GIT binary patch delta 22751 zcmV)qK$^eV?gGc}0u4}00|XQR00;;GK#O~k4RZtaihHqxYcT`$ihGmsF;5QlihEc~ z7fC>nR{#K;?5a%UMoO#TLVHr`Wwy4|~0{oxPo>o_c!9|Gk;nHaj!>O)$y-&amH<@ArQ1 zy|2FSo0-4<{Kp3XphDfwV16XJu6RSRZA~-~3df2!M%tP~;eXA=vDQFzV{xE0RNNS8 zX$>_8ql=r{*M-8xp=j~UKwDr&b08LLpqoN#x6BEKgV8`+B&q^qkhdYQDNx)T2(K$% zv}QxFu}uY$L8X-(LfaIIg)nQZxIQ|oIoJ{mw=L7pEQ^GiRFD}cQ$yiU+cXBTah7b0 z*900j2E$E6wSOfNE)H&P3x;E%NSH8n+A|{IHatCLzQ(P+E!12*KNQP;yx%egcmC2+ zr_N7WsG%(y3a^_o?H9X;7>_X#4ur#zwm_T4ZDFKsVS97)6b5};Q%QQD4}%egY8y7S z6o>G1G#qFyt`8G-EYuiNp)Z4hjq8Jr8x5GnfoPy5h<`US*mvA~v*V{^65MZ@5Bfo# z7jhw=fj?%Hpt=OZ*+(rz#Fz*AGZ@wwX>M-`(+P_k1~SNPjYgW<8`~1+1~U-Hkqj05 zUXWlYg9G=}dp_s`!*f7@y|8SX3y2T;!$`VV=!1cJYP1gq>#4B}1|;vF5ovBlqo52G z_Ftj&$VR$cHU2A;Nv?hIr%Zof~YpERH4EP#ZbwhB8{x>u);8U!#TYF7McX&5HPiO2G^v2?SZ;bDQsF=bKCK-zT0jQ-*fcswFVRkFbzKeW2OgNo zU?N8&YqYMhc_?=_gMvUK6^RiBiL9$3Vn*d>Yz2Q$c77i`0JPjk~$ ztU#O?Gn0pUZmehxu+$4n;1C8yoG4nkRAD)T>0L7a*qOn#f%fLM`j*ya#96^$qrEMi z9oYpJ_+SAX=7p883JYFJbA=s9U`=ySg?}Tkc?z}Zm5srmc=M!Hm3rem+U-aP^nul| zCXSMJT?H(`>iR%zA=Wn^tfh7}2-w<5VLV}O^o*X$2O-!%_iaoY!01h$3M~w3In_<} zR8-~h-XJoHFetRlPc3D!-hHWXloz7ZrtV`WO4l=b2>xjG7q#h&iY7%e2yj;o3xA?E zK20Gxg}SOuaI_cNVKWZRLNRJBeQ*ry=Y>PzSO#V8>w^l%qtz4DsxGFLat2M@x}<wAsT84M7N+#Vr@|zTTnsdC!%BWQ%FidBB#Qyh{$RDMoh`C z!Wmc{P=RHE=JsG>V1{NaNUKK1uz%$&INJ+n!Z{53C$H5-qk%1YmvkPMSVL@MV&D=> z8N_G>@O%b?lb0Jp#{?HejTVN%kkr9LypB()->=>W7s5qexBxE3N;$4xA5dKCggj5#a0OO+)Se0{j)m;nWvwV{1=$Bz!c|__3RmL@EYQ?s8tfSD0)G|vYv8vu zGP{Zui0+lwZP;e~db>`BtOTDOO&yC_&rcF7n~sXc4TovyN&H zG-sU!q*(P{xQ}K59azqi(0>af4egEVjm{=z*xJdUD#@@g?t#K^q|g}u6t)D~8rNfE zUD&ps2AaX9P-CDiILQNl^ul(iBu_h;F1Q)<#A2ECYDS>BS%n7}lsLA^bxlnn;udI5 zX`grE943^~JTDKmt=9~tH>M0$**7eXgg6`Ohv5+~JOq#04O=tB#DB|59S#a(u~~_0 zDm;#(E<23)=yyX*vjqVi6iXQ4Ne21xW+^@+!P2*cS9Lp1R%P<9@RS$+0#7@5D;+#l z#lPt-$kHvX=$Ua2mADP>pv-h93Vjxy^TIB89y?>qULT#_9>M`uI7Xv*dywRP2=OAk z)CUfLm$Bu_e!mK@>VKm2(Fw8e!RtigHFyJ?`?mGb$k8(*?cugXn}X4`&5@&h@DG{~ zUjT11nBbzosqi+|?zr=O@Gfld!aML!1|ytXR~6njtkHzt4y_FZqdxeMrj;MSM|wAv zyfSXmq)GdE;1ingr^FVLt}rpFCF$NVXAii0+_=o0^B6Mw&05?q^@cmEp)l_+~r zbVf9Yt;0O+c4M?LKDFtJ_u~d&RL3Zu7aucx4c~a-EBFug8kV=H@SQ%SIT&j@Y1u?1 zeeho>?E~M#4>;jV)zzl+!H)5N@DnNhGxd%`u~&$t^$OT~kIRf%`50pYw)ITJj;Sr8 z5vs=yZjMcrOMh!N9Bwgyrudl56fX!&MM9`|5Jzo|LBotoorJ^@?5jm=OUs%_b7Cmf zpdF&b9OlIu!ul}ihgMB#4pHQM`=-PiF5%Z$@Thj;9xHAzQYfk~%f(?B>&IZY?QPVu zv3#6Tt_?+FSe|qz7LRiPwwiUY{%nAk6|jK}$~ja>YJaUOqO!r9O*@SQGP@C)1**)C zrDR5=r8N-NW)KH)wafN^V-r}Y-!L{jhYe+WISgq{F4CHWxOyXTM8VSvYwj4O51Nee zr{0V^bg=ev9g1gq)6d4Rv0gTs?ag5BFJ&~9?Tdrzwb4k6PG-^3I58XBWDKfVDPOnA zgzc@nHkINl2)io1*`P3a#n?%Tx)y!*bay4y5BvC#xXC`ba4tCi7SdYva(-^7=r+Fdqk#jhtvIS>FwrUqo^i@RM%&C}vk;ukW-xU0eyL&bwg^SQwP0AGhs~vc z$<-$Kbfs+I=MnsT?4HKWaK3RN-MEM}ElUq;ZHZyEQ`r)n`bOH(V*_=VP^5Sm7T95T1kiRQ46t;C@UTfq*)S(YBD4@bg|VfwVFE=Bo; z5OOKVv^E2;G0htr+LV5WVKD5%Q0CgPBoarSV=4Nt9cUQ_SWRiMHPC6c1X}r7q9Ln! zXZPtL3eqBkW=BREDX&Htg)fcZ3`u9K9mQ|RZx{;3+CpIsE`Dy1b+y1zdK?W$mI*8^ z%i@!|JR*PTQW|L{vuD)DmeT)m4C207ij&k>Xu+R$qZAr^lPBisd;{Svd(IXog4xIF zaj&Dqgx4{xkvTZUMf&h`Pf4LA0x5xJ`&!@}xxj`f>Gk-)c|eNq^>dmMbAAyei24CK zQgg6NC5dW%ZJbLp)@7Ww@#BEe=G^p~vHdgMs@_CON$z6R*v>R2U8J>EIHgk78Np2M#?BPVMB3@~9i41duCP=kPh)Qq4j!$i`fkvB z<9Mhn*EmkhW^I-Z)8?57Xk^35nafEcEiM@%Q`Z72yEGogF4h1`S#}9f(RV+vG>vZ= zl)7VHiepgI)n!YSUBzH5&v;X1zhN*ctCLjrTP$y_#)|4#$H=|W@cGzv?0PRm*$p@Y z*K_JYBz7YX1Y+wWQEeT-$8M$&f0R);J#p5!^H%J}IN~AMmJzhY3-$*uyO!O~pr4aH zJ{y1A#_smQN_G#9Nwe22)70j^9JD}(U3k$tqslt9?I^ADgPVfQKK4hZc-eNg!-#IS zV_DTE_dfP#TKhPZJ%CqY=~s4Ar0Y=jkg?TfQYbR1As7t>nnTCXD9^(lVKBvgSx>Ir zvd45fM%@Vo(T^*;vM`xkWpxfeJ;9!&@Y8=^82D{(Q`u8}*weHCZX3=`t%>niJo_6K z$XLR93}$yRJYt@5v1i$HUbc%puZLi?9Px(xAbS~Uvs12m{~~*d0xmDpqEk$t9r)O* zT40&IhQs5O2=4koG-<9ku!+%DUSb~hk7Ur6w&WO-49z}oVb>gATuQ`TC~j(vJH>zQ z{7S1p#!4T1hrR1%Z?k`#KpV<|+^Snoga=K#GNq32GbV z>V526_FW&SW8X87jhVyP%ow;;to45f_9KM_{zprJSWx?D3#?lfYU?L#x3+#F0L}{I zUUaq0C*ZTNyn6E<3HTU0?sg%>TJwGb<} zwKc7>P4Njif;UI-2z?mLuwALsg9EX2Z=^I*M)ZIxgU}ae{eh;YxTlgaNV|U!zg^#w zIicT^$fKq9*>9bhNK+@dCZuIsiT~?DQy!02*1L*VW?B0e`U!bnAy>%9rm7hW@uIcK zlIUuedFDM8Tut^q*bc*^K z#(um#0}`Di6cf=BY(_DEeYh#O*(a32rF62~15+8)@oZqVt~l{wgiwE_FX1+931cfr zZF7@u%nHj$X;#0~2$Q`+wNQ(L6Y8J>G`-ovpv*;YqUS-ZslxtLCZ}QBrIo$(g2vzz zZvVwGZSQwgwz-Gn7FDf_@kXC;pioCG%5(<9u{6vK#agNNS`uswhOmuDu}UqsRZKFd z%*_;Lk;!NC@25>{NfLkNYCE+9Z64tu3Xdjt3kdVEP{0Sm0-RKZOj`wnML0Ibo++J6 za=i8vzmMasZ?;0Zhf8JIyOKTVNHW}hu&{*O-k@(w(>nq3G0)J^YM6(RhX~8a$IBUv zSlv%FB8hyoNvxp}C!4Ae(8rVwZGk8b2i9U8_6d#bJFl=t zXwpaXv%*dB3v2ZY>o|oqM;bRyk2Gyb^t~ay`86I?U{LK)UQ&P(QP0HlGQvionV7Wb za|2Bm+Fru}r`>;x2oa%`5RPK7#@^LVBzQ&D>$^{dm{-^!kkW4IT<1`@r-iVBr|ySg)`}I1XFzP_#bA z;Mrf8yzQFIo=%i4bfX-LT8%Q4*f}7aAe=}#o>LJ2 zS2ocKA?I_2^9bqJ*i>+4#(b)9fj(5G18oBqe_oCMMZ(3@v0cKTk8$rI;SgHnGIV+U z!iJ@F3uk}KV$gSf%0=XQg|Ib8xLmjr8)4%S#JVWXCq2T|v>$xD-jddb+w?HNZ}l+1 zwG8r8)}gVXT1V~f^{Bums#i4O8#JyyHFja#gc5%z+~^f<5N<+@wurG1kn9kTv)Xpe zRZCpXVJ+77klZc8?`hU@Yx0RqBOdJ${=k5RJ;Hw-w9KS+=QL$C>V{9)MseK>gu58z zg`#?VE*WMR-0SVhp62+)wl}2-_X+n1_fqw~j~>8@>dQ#CbZ^g*7%21dwcWMt6Ydu} ziT!r&-S{Rms=^MO#&*pG>8lpPpL2vi2@fzhU=P7mVW++^bw0PE%r7I}F z!fSsn6SC2aKP)`r6&?~E)x$Q6j0IkY$(nQVqxSA`;R!E1Av}rmV~Z&vx`Y=zee0I+ zSK%qbeOl`&r$+@Y2KfK-J~y~1bITv#vUhf*HYR)v2r z7?io#`lnr^-8oBB_W2l3L@Zj%x#33#i8ThA1B>;sM*>!DjIYAacE6EGM`=y0`s%x~ zhB++VGMJIrYG-KC1u5vcR*K~?n3mkLl=j%=>eZ{$j>jhDEsbbf-HeSxo={@L(Se2m zBGFla#`W&-;(M0T_AqIueEQBL9Ta~Dug1P4{W#^m{P^a?1T2FgiCv0GS;p=COt)iS zWxiRvZ?2ndh(I{;fmoapM@VfX_PC~(^VIYT({b4^P>{>X zVzRcm)OJUiO-R8#;qtC{v^={7TxqIr<3Y~R!$Cj6w^r=eh-gjZA z3T)es#u1@DvW}017P}K&UTUH;*>qgZyBXFYx`6XBEO7dx_&9c7V@!Wm_%^F&&h{9v z5WOz}$7c+dxi1G6h6_a^Yf`rHrW6OQ1*Fk`m%&kc4PM`E+Rr449tPGP4cEGss;
    4bv73R`CmR(-r)R{R=(td%KwSpAzrTQLys~r-c>qeox zv@4BgMb^f%9NYi=jG2EKolDuFYn+p*j^VGjHD#ae0IT6TgMpSKYTCM)amsJow<3D0 z<>_G#jW^D5T5T@azI)AbTc#>5;EXyt4DM8M5j||_uvU|JS6edfY`lbx!B|tiw6{d! z6w7!>uEid|i~G-=X!&5e*x-eg;!m2=*ii1gGseo( zCwI4oSvmN`HDVJfj4j(yJ343ntZVl{2``9*dBPoJo8^0#1 zE*uGOX^FIB*MWcILF#X)^epC9(kj2D&S!MD&YVnqVpwb?6CA~0|2@LS;nAL%iOh0z zub4$QLpzy)9u?OlQRkV`fYfvAmX^`d_a}9?lG!Nu#LeO{r0uazV|qtWdSzYLa*_pF zd)5NF#wU`-C&k|kn;eDBKKc3L-y^$jUpLnkLYtr+4bW2wtX%}W! z@{#W0p445}^uf)*7+&rkS=jf3K_2Z&Qv%5&MyBQ4Apyz)_8UxKUgY?mdwqR58J^2prST$i= zBUpO$tnSv6n~P7pSL`4|+|S^EJw#_PeNT-=#@W(K#?g(jgN*T~c-&+`q^Z3*I6E3x zr@xksKW>tqvv=YqSvmN`2gIGE@Ix-%Qe#4O^W>W;D;c5N!!;Q)N$JN(>Brs7bsXz+ zx6gldoN6#E5dT8z{FOl;OntY?srEhpf@)$yb+I zNZC*iDXS~@0x9=mys1gwrR1imF+By}D@{#S4nFZ^@l{gzH8%~03ARTXj0~AX{qIEm zAMt4!g;VO9LxGr^X;~su?@Y^_#QVgz#CLy4!*^Xw%aVX@re(=oJu)pz6-QcrKw5qn z4|**NL_@Sj=cXfw=jok}z(KlC{8;>y)cedu&?|xGCg_#O)FVN!6ltX5m!#sq84S?h z5Ey9O7+9AwLgQb=G-d6bMa=9ZeB#&Qe@N$VT`XdnVcjfZn)CL^B4(yg()$O}`$vBU z!}TD_X8m&n89r~|4;WZOSo;3#ZjU2ylktf^iM!Dj5;*Pe;)G`~V~_1c_Bp1v?4#L3 zlE@x1gB&B=LajLeiW}W;>Gf`3akG)^lT;~(RPs7)^t8faP~uK)QgdC8sHv-!OKSCF z(9fvF@r^l-gD3mv)Ouv_G45iF_>5kiB}1IkM;q) zCe|M3wleOfZdSuauumE)4JU>6Vj!*2bSZL!$Y5Se`{BX*_{6E{f0pQXY|Tm^gpfy{DmP zCJy}4ebOYUg!C(QnmE|uIZhnxGIh_y!Co4vSV<~Y#dkKPtlun&e}0L&^#lvzs391;&% znLa?^80mNZ4oJ^L`rUHyNz0`br144@?^!X!c2A@~n@pm9I8i@>!C-%5RVKWyIoOsq zNO0J?lP+LRFqvQ5HQqy8cigk^Nk>X+NbyFetvlIp9k=de%iKL%cd|<*)oJ&>v_9V8 z;$8ZirL}nmb%1o-D(jH1d$!6t3M5^RC0&n;Pw18e zj*fT3U765XW$%><9VZc=bb@pe8Q^6837sXhiwT`&{+^i7*$5^ZoJKY{oxza!*h>FE zOlp*Qp^HI?Ik#mIIIa5!CLBC`(wWlPr2RR(&yZUqvDZS!L*+Wgu%wq}Ena>&kctmEQXp z!C&XS7v^GMGxay5NZ<7MF=&SsV73HsnSTr8%V|9#V4}*>yl|} zhEeahC$grTy)u81&CbCm-6Y*Y8vmaEQ=Mj17gJz!)}ELGXUZg{ZzrYih!3pl!PKS2k;q;6> z;bF5x()tk{pvm;Ql1a0^Et#BiI3^xe=?`s(`89(w8B_y#O} zb%(pxw_Vcd?q1(^9p^oXw#!Q&^6$JdK2Oj64UxoJPj~OtN-XfaC(#~x=`#j{5>BG= zZ&%iLGV)rwk9(w?0cW@R-`y)lJbL-0FQk8yCBJ{-UopzWb+KZUnVC%Cs&-`u_~R{4USLb>Z^N%st_9E2*S+Aua;SmEQ`a1-E0H*oP2VwoJSVQcX}(nJ1H*0klCPmA`F?G0~u)`8EH^_gM#+{ zzLZkKy+I*8W3Oyb$V$N{50QtGy2JQ4D40N9Y)~-e?1>Eu86rvJk)&~9e1@*=OmZ

    j`F8w$@@RQ)vdn)zF6Qkz7}0h!XVjJNiP?UfA1ODUl$#I_ zy=hkh;rPBI?$BFWzFrBvWnDV>E>Qhge!en6s^Htv7Y zccZ!KrPDI@PA{E}f={lKXOOxxUG&oFpl*8U^qf7?OPfWK#&b#IdUJDK7mWtoEP|!w z>(%Dkj)6~}Codpf7rJk*b<8d_*LudDY_8)HN!=x+ZUci6ngnA&9ty9^*sag~M2{_o zrOVIhW}V%z@yUnC%gG*x@_!`O9^Ze(1|NHnp4i~yB%MsMicE5Nyhoq8B^+o8HKuMf ze?uhI_57`Z z9Y*i83NG0A5*2!K{}a)z7`-K6@N#Kaku_>Uuu(+QxShm zrVj?lo1ESw%7^aw=0ZM*?s;<|uWT{~eNR9>Hoh;N9$m;7NpSB=x5(Wq`_lP%_~hed z`nG_4692w*D`Xe@(yg-h#J+TExnuzP`ha{|e5b7T#^}`6fICEO%GoPBWwUee$!Ey) zF#`E){++UBR2MsC%~^Y5r);K7Qks9hOdy}1sO5AI6@pY(^Vjms+`UuFxp?^G3uXFN zfqaRJT5f^trj}b|?~z(=DVGdDpE8iQ#y`NJy<9y0l)l3^l1z)m$y`|+|I2?PscTGp z@>Mc@-ax*_=^IHr*e;ehtO0sral%eAnSnlcAm0$*tv4qaf9*f_vP(Qmuk3%;a}e&6 zZ>O=d3s{EUWzc%k3MZ6-yU~fgL~&S^rrJ1g!|+>W%{~-d^f-I z8oJ=ThMsg@L#p%clu*43cCxRvRvdI`Pk}+P2@0*_=p-;tg@9d@9du89ejbNYriu`{XDfBu6saey7 zcl*4C=wkc4c7IQ7pEm@NYHyKhZ^s|wUcNrm9Mm1g9nVeV>6OR0ouvEZcjfm;zxVkc z<4)qac#J!lsV5%ePL)O~eoQKUlK2LAB*lrdxg)O;XEz?--O*P^`9AqG`3utWU)V8r z0nzcB@b=kA@n8O9?@oX6NYSrJ(Qo2k|Ir`mcJVSrJwp$Dd5%-GPySZ^p49rU)0gKg z!5qIlXPKjWzC33miZuI)H2XOoHEd{$>Pyazfwo}S_&g+c)X*Y#uS5;`c=!}h1k_#; z`J;wb$S$IWR@r+ZYG^H&44{$$Jn^-GhW1!%Fig1?M?zV?F=v00ke;(w)&{b3@F`x! zM;iC#UmGx^x>y@9XYGl#flQgCbUrCvz+h;Ko15rKu+$(0cbM2Rf3Jjzd71c>0m>k< z!C?L{u{E}fFtIg2PlSo>B$FA2kr{@^clR${AB`OCLMQG1UfGv#C)uZrPzp(>QT)%} z>sT)K@#`6SVn=^|ToS28j~giaF!1QEqAzcAcQs3GKDpi9U5&L|pE6FN=L?hxI1deI znoMv3hyyP-dXt{P9?(gEXtaYE{icw9Q{(Sor4RGP_f$E4watH21X8luM*4pFueP}+;Zvq5 z2a>{dPG4=y0_*tIwk&zO=c{d5g_7R%Jpg5PJiMSi6XSYSJSA5z4|jN(_>{TIL8SRS z{^5=_wu_d`8lWdyGCRp+hDBtC#VJcP#sh6`mT2ssW$S?@8r#R%lqCwi%wIXg)e=qo z2{t!NG|7L5*Lq-yCh^=F>PN5cS5~I1io11QLvK3ILAXy@r5r)Zt#-94?%H_`J?XrL zROhWy8cDyVcqnjLAR36Sa}f&EGxSO*&{nihS*xrkwL<)%Km*K0DA35!6QRI_DAKHj zGz%wQtBCgnnha<+uT@OV*E_FO%)-E@v?@{36$gI-N=&=i#rqZ0z}>uGF)d?{ykF5I zk@Vh7dT)uZZZ2OR47*s}q}zLCb<;+$PdQdOo)kKPe_2z5aB;cYs5y9biLyfh$eqY85__X1h8%51`=>1gGO!vb>T>OOG~6Z zma^N2SD~;NA$hkjSj8=m;t;Maw^`gmf^K85oLf+QQzEa7Q^ZqA#vP6?_A+}Xl6ano zSIoKMc_ij828VKsp+}cyh1=32$4){n6E7zr_cB<`FNB_)NU1}-vaS`cBU$&mDb;@& zo1vWq+$!Ei0{-Y2vo;B^ep45(#Cyg2NaCN}GzkkLP3_Ie@7{AtdO&=TB<*xluw7~c z3&bZ$#v=?4;g-?R7!9>@Yw@)B3`uz0jlCK|Ev;xTmzDHo@fDKv7dN$sTAaG(P=L1? z72guyCLvF|aSBcpL$sX8E8}DF6Ow^$vsa3g4}v^NQQ$FVq@^sxE@xs!}ZQZdPRkHH#V8QDID?If;7noNJMYUlm-mOqL(^a*}bi^c#{PyQoGE zUz>80bdz*5N%FWT3fVq$brlDvDco{E%bdobqo=$hirA()naydzi$!#QYrif|le7!vi%8l6$FR7mFU$6N6(@grSIJkCyu~g?8dh)j za1wE&d=rUia3R9#9TZL??v%HYh-D0pbUOlYZ?f(3A4%8>cP4YQI3hnHKT0B2xv0JM z*`E@3lK71LHk@o{@8qrhvjoTG&N9>hNfmlO(Uwha?^4qGika zM39rb0m?v<*XCkqnekYP6aENgB;g;;;9zci?o}~moU$LGALC|VY<>p73BO#aApGMU zWBUBN)15?3Qw|_eC%JHZ*1geA^5!b_B=1yr?X#QVzOsKrX&@1&yX(?iiCCo^P9n~7 z(avOUb#xN2R#`^^&UF)$vD=L2B&St5isYQ{qGvI05p#k+RymH~FLGh0%)K#A0!~v- zCjpnbS--K|fa4_OeB}ZXas`92`sMbvP;>G8P^@ig%I$hPKV=%uTJq-`!WRVF0!@Lo z0G<@#AkaU+fNi7%!}FU%l)?$4&{WD;+0K&=^a?`+?QiEviJ!be{LA$U9vOcV zR|HSmjcIv?>^!MVC}Gnl7btncP@zOD@a0KEJq1#MP@oILMA zd3k*>r>{)O>x;j+a|hv>e#V(R{LRNRzPtiV^&fvPlnj_F;Prti*9XlVv?N!Te(1xe zNQg_!mJCQGl72z8yWp|B@bE44psCPQ=Jc4c^A09P?&#MTX=%m5Ms#9pbNjjw_PD;8 z!L@<*=C=Bl*5(+4y=I~twP9jIYaqHYw06s!U|4T%CvC)TY<%418#c8RW5=s4dKNcC z+M|Ds!I{A|?dxbEG;BQSA#c)l*UR5GET~)Tbwu{g(_p>h8w%s8+1?3-rG?J9tW2@F zI7YV?2U1 zzh%g?rhH5VT`NT(6s)Dos*>r7nq+^vx+IxK9g$FFQ4QW+lSo#UB$Cx--ip$yF;zvS zCAAghRVfFRH7N%*CEn_?G1Z!=szkD?MoXd?yj-p&%9C|ftN6W8VX4rRl#MB+a#B?8 zEk!4k>IKC}m1$?IwRB}7RYhmZ^gAXOq3z4cDNUuMtU^nbX=kgnbVX4`;(UKi;$HMl zc_pT>fY7}a61xsmO9iIOb$QjqsJxQcW2vBfDs{w~A}Zoq-pZ09DkP=a{bh8%x`fi@ zR0!}UEkk7u9hB>mYf7{$`fYy|nrQv5DowP0)8xeMR6J&R84O#}9&QV@1na}pJK-Fv zE*y@u>3dihK!=9QSh7>e+!^LjKmSuoird)uQXj7=x}YY-8CFZF;Kw+qPh)_mVk&?0M40E z;Om5fqJjbV@5F*Z_^)3o7=l0J?}uUIC)@`k#uwcOqsC9X55|o5OZUOvF#cW`wG;N; z4igw$39586NaB?+Sge1N3ntdeJD_-lU+#eN`=RPVymgGttu>}w;Vz^js`T$jP5vD0wB%k;2BV=I_Js;4f=WE9!K2AA2mcm8EiA&{ zBVZ~-@ozKi569r|S#SWH4W;Tmh%*4bTAX$~Yc zb2UdzN0Rl>59Vo<2kChd^zvXPA~8*{$`WE0z(QS2-WiyEIDkBDLcwAbGob^P)k=Qp zAvkm^^zlnO;ZT2c3|sL8c$bf#&V;yJH1Q$WcPsRt8295=&5s98+zyQl zYGuE?9oEy?iIi%_Q;J{N3E^5*tnw7?gw`DpUEx>nhgc_U*}D4$5k*N`Ax9Tf)B(p` z89$h?6He%aQ##@F6_10r1I|rhv=HU5u9dLl_@!E92mF6}g6dil3T` z`en+HD^~UM=W1nTfIl~-u%N@A@aO74dHy_u=skawBA|SK{!WP27Kl~-{XTy|Cp@+l z&Layw(FxBG@Bp!Dpnre?JRlu-l~^^%KS0MG>>q4k&!iM#5AhG#3A<|jV%1Q;AInru z2fT1I$jcdeam03bg+T}WU9-yLzZ%2_4!U~x1D){J&AU4X4w9}jnk(44dx4So`A2^r zswjV?xawCQhpVXA5Kpqu<8Ut7e08l4$S6LYRW7Nnv6@0DV%5*zk67i2Rr&rrXIB1x zy1ZRv@5iw?_et3K9jdx$=XdB1DptP7@r17f-lG##Bp!k=-GgN*tex`sJy?|Ums3&b zfR9%ceA)?L)aFnLEcmh$zTFN#GFZ_GyRm;XqC!%<*d^*rZC@(w_cNekuJPz=cI(76 zw?3%5wZMAKc|CLqvbl-l!Pk#`g1$kG?ah0 zgB^%^)b(dGI@lb#b54I&kN*~Ru!B0-g1ku`Y_Vo0wxEL@d^cN;Bv&OmDCICH{h1n6 zm0f+H3Wpwqf4i|0(mSjrc%;H=>@EHWstUpK-I&jGi7}6FsS46;?ACT;x8+T_Tt|1{ zp9=fpPY|GV@In>t*bOD%OTX<7X1;&5lI|LAx=V-DZw+EkAVK>7FgHNSZpd-Yi5XRF z0W$OAMQJyTwa%RmU?q7scE%i8Rd|r;W;JK`xXG@W$po;-C4hDmO|mgy`g9$}pk)A! z+cO~Ta2GRNv#U;J*X+gt$}dEY{Q|~fY&VTax`LDHxdXcZli_^WgThC8aFu^Pt8#y! zR&9!Gvp=Y3uhYbvxN{Vh%{NCU9$$mMH{;PC@civ~d?y^uI$$$<0Dm8a zEo>J%jr|9<2#lR3sP?V(zS4jbQfGI-2<25DC2TzJEk9ot@oEKhhIr>3ot z#}3Eos0aPqpB=$gV3;Sc~1# z4=|jq!yI0C6ZU88HM}>l^$cMSMN4g98xi?YIE*!Gli!En2-bpEB`g&=ER5%J+4+b` z4EnNPL7|4{L#%%~4bO`*XKHvJEk$@aY#|nO!c*BiSfk-7SbBUcqVf9*`sw`Gr!Yd( z$jf$N-d5tro`yN>D9oW^dD)9a@!U}1JCu6_i-BMG5^A&@LxfH&$!&ObpztCrW9^t4 zB;1E3cN69vfaUKpb~K*rFIq8 z5!SI<=qoINPuX!;mwduJtV@)m50>x2ShH#&M<`-Lv0kCRSl;$xC*iq#@jQcHo_IPG zYdQLf8(_Ycqp!FQ7HK(rSOW9e$s|{N6b5KHa=a@uMbQpNpxgp!BiiLuVk#|y z1JLT2Lz;gN)3FXVL0>IJcFvWiqUNWQO{K}Of}Md^`@nwkKz1fO3k299oyyLpPz9SV z{*Rr*&PA`@DW0!|FJxh?IFy}75f^bD`_B!tdfFomVB^^Zn97kRu>R~q zw4WEt`!(z$b}{t9Qhy%1gk6eqABN-DW$bcf^$LHiV^^@PkW1l)c!UB|i`bRs2t@&t znSv)N5V8adA_X-@>|ocfn9#v~x1vA038yER{5>Xb!{q(!4!Tnhizr$&=GK&O$cRKZ zWCXhtiP9i@8@o%7fcRG;A#CKm!}JJ<5#CrJPAk%*8%3t*Mv*?T!HGj+Vk7Aj8=0oN zVQqi@KOr97P^_XG>|Tl<7|{(pK$&}^Ofzt;0ZgE>Sf$*}?$ys#Uc)k*dv! zNciKspYY3CxCW<03nrj}9z^a%JGCj1HoJM4au_iE*`qp6VotR%o@HWcmI;|b7o=P( zP1wmE?__^P!IBns(1H#$XH3iky?>r^pM67CfLW;*{ zk8W(;eFhQECBpp$QD^*lt!DxXNy&er+%5Q+i2uWX^40HIr%*r<2Hp8yzo%0e)FJr& zUMwzGcL;m=y;^zLA&gvczffp|EDZnOE$q`FjQ8hF=oGL7Ueh6zV)e`wI)n;;ZhxV& zQ%b)t$nO+5&$;ZGW+9fZylu-yzHae*xC><>+6bzP~W9Q&@k9Hywig^lNJaVV7rnaxYZ-)>hD|ZO%tNMvmc{_v+E9fXp z|3nAo4(xZo&|aI5C8xljU)#TSAQ9=0dG&vMJB6b=h2wX^E<>eG;bbh%{q?JZ@O-Cm z+D_q&4&fZ|4+MXHhj2dZ6fS@45H5wgg{zhqQEAZQbb4v%OJNnQG#pH+X1zv{TZo;% zpQ$tmTAhI5sTcmUUAQLRmXVXU`ExU!?45vlQ!I9!g_E&l8dclxHJt2=JK3i>HtuBI zyGFpraB@MKlk+qu=Ovw-OHR%s)ifs$@DCu{4nn^V)SNs(bFwe#K3{*P`*H~-Nac&% zM=8^jfKqFQ=pms2|I*L|ZI)$54^*3;DL+??fG1Gg4vEW&GFJ4QZ z(ObGiUGArQFArNiw0FK%fXv>z-Kfj?mUTHlOI^OsRG0HI-Rwg*-=11AEZmGm&Zwn+ zpW)`*xSREg8+UVoVMc$g={DRvAkEDMnwtxfZq6e&7my7!H)BgrJ{W?YAFR1~5W2Y* z1!|S~PRq)Col%*wup~=EZf0r7r`i=HGgE1x7DFoy`BWP6sWcP}>`$d(AW%6QSUZ@y zjv<}G-L=E~!)k|%ReNdCZ@qgMAy$p_k1(8h-@uVog#$-QN9up)v<`bo?I`S`u$XB7 zX zzxc=MH~SL;I)rDm!l$1f?H{8R)8}f(`iJ|+ZWo@{0<3e00S%|Lae(k5jsyA&FDK25 z?BAzT z_%P|Q;hM2N(Tw%EVHX{ASbFsx3e>QqRo@9ag@2{2xoLmlT{!>~e}a8!nw}EDm9%+% zGJN|#=!=(rgaZ#$#f7`!FeAi!C?3&&IC*D@0B<$)OTSpB;shrx4q(Jpc0)M~=DJr8 zL@)};;thK4Qi_7CP;pqa8$=f}N0Bb(dy|pqL=fvII7nsJuo-wz$Nmc{#f&YaWaOkw znmHD0wiftHK(_QtZ4n5j`YPSXzIC9khQ~GUgXWPL^|kDl)-7-2|`MYKUHq zXbvxxF(1z3U0iom6Wh0z&;;%U6#rqa*w*e`O}f+aE{Lv|D9&=QquJ<(vw}oY8G-$*rbKA_D|ziXT#(v z`2p(fJ+EK21)SU!@7X5v>3e*du*2?eORe%4YY<)ARAJ?~Py*eg0oL~ZUHv{>Kh~Y? z(EdxaEv@5T*IsXz2xIli+YP0*cla#Q1BoS_%bAi-y;sv4I~yG=#X%SB zLne(fp4;E=-=HZ30|FeC>bp}Oj|Dumw&P#sPMs-Aif`1)k#l`}W9^V$XU5bC*S;Tz zgFGgC`Nv)6JeLF4f=!UgUBD|nz-u$fT*0mt@7#Avm@4MyivYT@!tC0cC$%kFQ&uu$JmO2nCft@JP4*sLkRt^=UG}^}?+nN(=)X7AGvT^^UGI$h zDY~DX;#i&K`lSGJjC!=ae!+#4I&~d%@1{rXxhwFXSM#3Z&(~4Q8e3AoUdC`oU+&Dj zpfq!DX>x5-_-!bluzf#9LQ)OczncP>zp0s9B`y1Isd8eoSDqli9d?{<(21_m?W z_AMd&B#UXvJW!9$P-A=aK?Q)A^7J4?HD3jdJ^{cftwWIjj#LQ^J1d=K=kq;W=bn*adeR|n-&D0@{Jv(i~ zj(hKHgFKnwP7dy|s>O^)(EJPnq?uX~Dq$i~#!WVo=U1npmuxh< z)?5$Z9=~jU!s)9+uXuD;ef$N}faFCv6T+LUsA~7bh`<{|dYiTMB87?KqVhG?(WZ|Z zdWg3hC!Oe#e|`$8Kcz>g$1h?6OwBOj14p~_LasHKhc3*m8gX2D^oM+3-O1n$P4)H< zO?CesV&?um6qm5H!T84@z;if^th=cF`N;-9(4@Y2hSQdq5L)DsR)|rRkya~|;zv|FlLhY`f7v6bUckGORm@W>`>f8Q`>8Yu!8W8O)d9O*8 zj0^rESIYm|Yd{M&fAVX$rmFfGHz7@DmQIm%t@P5Vn7%Ww+s7!^RcjusT*A!yw}U>L zfLrt(p0-2xYLPVCZppW2@I=Q0;l~jo!fpzJGn9P+sD=G|#duYOwD6%$FaKhE2cPRK zLQm&G$AgF&&*|djtM+P~?CzfBbK?~Wp&R4gH^p#I8R|~F68n)>5jj=(`w4rN5joN@ zrvw7SS+999g|}8Y?2<_{n_1V@hFv8`>-C z{#4Q5{l~mpQbm&T*W?rSr=rGNXrlSlgb$@vZ1+||=xLYDz7-E3c;C-V&H-`$L)OFtpOfQX z9A_Q5d5GUr**p)n(R(826ef=^)BsroKagEZoU^DWu*ANs9?$qLDpAMX>pnn*U*Mt7 z-Bw-YwkY+THgA>n_RU)~LLY5fM*--^RTdliA))!3TBo zPo6fz*X=8oER$BITRfDCCgDE&olj=f8M|LKJ8W#PyC9t#dhic1c(0M-+ZJJ6w7ZDj zV1on#LoTj5q&wnCEF{yX5<>j@l+>jrKZ^7bODu;k*nj@jzy0e?q@Yo+Zv+sQqd06rp z!$rcJ$&0wRoombR;b(N|SsNxG7_2>Ap0cexlN4Gj710|x*f8hZJCqh1f~=DniKHJ| zvR*r`H)goyD5Wsm6RICptC+m8=8SQ?lw8x`=6A5^?$JrJ^85UfZB9P!+$NGYM%P4B z&i7sUp;2!#sQ`woDX*H)Ath;cW(|K7+Hqr3sYVn+)u@Wf)C{;NmvX~a~ z_leTa<3!Q}!h0n?a>6$uOQXw4&xACNCQX|Kpkh^Z!c_inAl4l8cCZu)wpKVH5B{9? zGzL{U)R9563o6%CO0RCkO3tT!^!9rC9BK{yT=5RRf0{YZBFYj9+1_hBa8O~x8mXVo zR+=MbQOy_2ao4b5c@p5`Xo*ZDu#e_aN5n=NN^o3Arci@565T$K!Y<`d)!vriawA$! zGvQlAOlBe5Yi`tz3JjU=RGNTeDPs;+d(udzWP^2=UHh99_UaaKCI_`+x2A0jhBK_Y zv=B_EzFT(G)!A~Kk317%Rj3fd*R5xY3fUcVvQ-s(xd4Iv%LEij5^=NwatQ2G6GY^3 zeLsU80UY?qUeEZHzAtJ=X*YFsaG6RFC)8!Et8~Q`&8MxmXU4hC>AVlk?TmGZ>3hQd z&fz<+gJ5R&>5wbB-XJS#-wYRKUD0eMFbzIAXfT0}jko{}K3=+HzI#S!n=?Ao!OCSH( zIT|X;)a6hY%PhxaNLk*FBz2ccosv>wEgr*r*gNUm0D17TZ(6BD7I2$%GIiufLV{I% zrbJdS>Eh+L)NJEKM=RumuDZ7}i5HbfZy&f(XA`jXw_d)GsJuppu&kz9cs zL_YZ^7qz3Y6l@Fvv!%P}CE_wwHod6nS?B%iR{36&9fu`dV^D3~8c;$oeM+;dD!N{q z@06N=5Y5Eis#(Cs!4iNYm}8~QRTY!HRS+;UQ9BowVvRxVIAxOf!u&FI21wVhdlo3# zT<_#Wioqo^lW}Fb>68#8F?M)7&YsIv&H&s zc8h4*M_dx$vK=p+vaMlFWXnFUf^<652vHS+>M{k_S6_Wv!`e&WG>Fl+2fh_7R zEZ_`1{WO9(Pq&7g^m`CzB+rC6GpfYN<(Ku(ielYmN(+1pro6ec#F%drBH0BQr^E84 z(RNg|A+w#!TOn{zTe6m1fyqMcC~x^ezC~0+Qhp)Zc0J6FdQ02Q!Lmy`o&9j#^!I$w zbX{i=OiB9Wf3F32hVz$aBIvjNXAnwa2>SNF3&jP=Ga=T^ziZjOhy^F<{Qs_V_o6)0 z@T=kfjNQP3j|PCcXS;tPnF?A&;vNO_8F*{9E%lN_Ev;pjGOn3a(z=E*Z22r8Mbk`X{gw0s~}XY zK9b2hK^(CahjvD2OS)?U8fWl9evKxOE7V5JVv|EE#KQ8cEbOS+K314gsX)}ubsQMC zOhqgClPmbQi2Rzw8r#nfRx=dySWhhIpXm(;58^;cEn>5>p@UV>{4Mt{nWhuJB`3fV zd9OL)1C;({Nm4$jovSz!A)}C8H~0qHX8VGe=}^WjD}bg@F#|o)LZARDS6Z~U+&ioA zTTk}ZAa52`ZJ`{8!h(zNY)8v3C{j+#gOOqCE)#z3QsG6HI@GLYh|Z(MoQ1&I%3H#M zKTX{>P4!Ht(9W-6$G-xj$%)Ei<6M~Uuyecn!VX0|3@Mam{27RU*q<*-3CLeZAZYo{ zTm&xW{X1b+AethPhgY-y zQODgmBF37fmQ?aPu!*d!u6Wp{A4|CG!a`f)(u|?sy3h_$o>aDb@N@FuZUljIn8+z%)+&dR zYzPcIpzj4HJsQhi}uz?C}CYsMQkT^6;1k3EB*f5amf7hVy&g5PfOo5JSdWvw@s z@j}k~`kOx~#1U+_C%HuK@N%9Au)@L~OEV6jDM7jT8S5P^rN=ol<&h~s!Bq6D;0+;z zz2@P>pZ_QvkpZVoEm7)AQk%GCzVnTbuNUwP+io^-PmhV+21FSL!V07r5ok(uF5ZwN zx{Oz71x*Zd@d}mc%XnjFjWb$YXi_PbLa)Y`=i$Fo1rao5G^N3mvO)Dj(B4$zCGzni zmi{aF@>ZCuFAQ+4`Vqt*gNM`PMQ>lf@Lo8g6;7)aI9E1Y%UwhljA#&GMT9{PaYj?h zbMPY;-&gR9Eii4X662EZOK$gG@unscS5wso`E~GCE2VA?*EzG)(ri|p{F_zp|%0mbh4^2_D z@KJdLt+5)9{EG`Ht8U;HZh`GK3$UER;-zmlz$N!`gvt0X9{f_l+yMa2%j_-4o^a$-krF!lA0 ziPSS5GZeJ{;E;g==tuefy5gTg@Jp7!qyEW>#ye!}%_o7jtNf3chvU(~%rsD1n_B^ceWbNID&Lx-rKu~1>C!L#ovIy{q~ zuW}dPCPzHa3Jnc@5U48r;$Dj6Db=dt1-CoF5NXij<+;PEO+f#ZV6Oy{&(*yA_=mTO zub;aHyK}u4RiJ9t;^{j1pLz}lOWJSWa`RL_y>ZV}wXgWLlln2?za&Op`+vD5mOzrc zYuL!&^YE1os*cq%*K2EPGb=A*b@>cr9F2-By*p6dTxg~)t2^CWd&aBLGA zw41NR*Bz-Zk_-R>|Gc)6rv5$emqn=Pv~@w6@fFfF?N3anmllj43)kmgFQt{KUejJ> zZB2jFC^evujy9G~*H^CBYj_#Z8|kBGr#}u3f*M|p^s}YYA1mvR?ZlWmtjBnPTgpKW zkpg8)-8X_Jz8bZ9X?j;xld0zBugRll|Hj1ei`_Bk$#sqgn$f;Wr%p|~SX#|hDLwx# zcA7q&H^`buk?T)+qAX|On8KgF=2qYQqO7t&Gvl*G{oN;CUcGf!jk6Sv*ku&|)cD(? zY%lA?NZz`J*qy4waTc{%XGlh6aK9%@;FBB2!meJ`1r~>9vhm zW){^h16?X*^BE|SqGm*phF;tFKdU_Srt+9-vIiriB}>u#^XPwwnNh{vR>ew6lGaA_ zl8S$vQp^-bg;LU#KMmXYFAZL;Oc~Bv3O6}(c``fGI?o8@kdXCz$ag8_SxWC#UT?>@ z!gV7Pcdp`SxbllTktY-M*RnFdg+FeuU)NN<&~h^b(0fSlx$eG}RQ_%Fm}=>XBR+LT z8QK1kNkI+?xTchkqa~tQf+pGD*DI4PBTv`$TV2|;0h7)e*z`8GXP!2&xo*_BJ@hRm zOrUg#cz|Z=cyI97dBw5QV;MKmKPQ#{`oMOvg$RCSZ;~g85pUNk3&(}t)0oQ3m#X#u z=#66PFmHfoSp@cE6w{H}8pVua@)eZ!QD=xcGJID&Y5|iDCB9e>bv?cvPw?GO**_k< zq8*{BkBi1HeaX$$$dQfb)v!P8iGH0UO@6Y+&&{%Hpbvw61}~> z$JH>9{PQF?R3JFLi;VqU8MxtG6`uD$C4$@PUH*TGVEKl}Fzu9dF4)QR$7LevOAQvV zoX7u)66wI>W9g|clwlJ2|EKG4I)9@k?EKUJ?Yh%w2&0t!E2^anHz{+ar0X^zVeO=J jDY9OAQxgIfNQRmg;ugldeEXo|7<8r!?%O9*^;`Nc-QWO! delta 22630 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 return // not annotated but still happy as spark will like it - !isAnnotated && mismatchedNames.isEmpty() && isProduct -> return + !isAnnotated && mismatchedNames.isEmpty() && isProduct && isSerializable -> return } val warningMessage = buildString { @@ -264,6 +265,9 @@ object KotlinTypeInference : Serializable { if (!isProduct) { appendLine(" - It is not a scala.Product, which is fine for most cases, but can break compatibility with UDFs. You can let your data class implement scala.Product to fix this or let @Sparkify handle it for you.") } + if (!isSerializable) { + appendLine(" - It is not Serializable, which is fine for most cases, but can break compatibility. You can let your data class implement java.io.Serializable to fix this or let @Sparkify handle it for you.") + } } println(warningMessage) diff --git a/kotlin-spark-api/src/test/kotlin/org/jetbrains/kotlinx/spark/api/CompilerPluginTest.kt b/kotlin-spark-api/src/test/kotlin/org/jetbrains/kotlinx/spark/api/CompilerPluginTest.kt new file mode 100644 index 00000000..c9f684a7 --- /dev/null +++ b/kotlin-spark-api/src/test/kotlin/org/jetbrains/kotlinx/spark/api/CompilerPluginTest.kt @@ -0,0 +1,47 @@ +package org.jetbrains.kotlinx.spark.api + +import io.kotest.assertions.throwables.shouldNotThrowAny +import io.kotest.assertions.throwables.shouldThrowAny +import io.kotest.core.spec.style.ShouldSpec +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.beInstanceOf +import org.jetbrains.kotlinx.spark.api.plugin.annotations.ColumnName +import org.jetbrains.kotlinx.spark.api.plugin.annotations.Sparkify + +class CompilerPluginTest : ShouldSpec({ + + @Sparkify + data class User( + val name: String = "John Doe", + val age: Int = 25, + @ColumnName("test") + val isEmpty: Boolean = false, + ) + + context("Compiler Plugin") { + should("be enabled") { + val user = User() + shouldNotThrowAny { + User::class.java.getMethod("name").invoke(user) shouldBe user.name + User::class.java.getMethod("age").invoke(user) shouldBe user.age + User::class.java.getMethod("test").invoke(user) shouldBe user.isEmpty + } + + user should beInstanceOf() + user should beInstanceOf() + user should beInstanceOf() + + shouldNotThrowAny { + User::class.java.getMethod("canEqual", Any::class.java).invoke(user, user) shouldBe true + User::class.java.getMethod("productArity").invoke(user) shouldBe 3 + User::class.java.getMethod("productElement", Int::class.java).invoke(user, 0) shouldBe user.name + User::class.java.getMethod("productElement", Int::class.java).invoke(user, 1) shouldBe user.age + User::class.java.getMethod("productElement", Int::class.java).invoke(user, 2) shouldBe user.isEmpty + } + shouldThrowAny { + User::class.java.getMethod("productElement", Int::class.java).invoke(user, 10) + } + } + } +}) \ No newline at end of file