Add inspections and quickfixes of redundant Json format instantiation

Resolves KT-45075
This commit is contained in:
Sergey Shanshin
2021-03-18 05:44:03 +03:00
committed by GitHub
parent 27174de891
commit cfca7183e5
43 changed files with 702 additions and 136 deletions
+1
View File
@@ -70,6 +70,7 @@ dependencies {
testCompile(projectTests(":kotlin-noarg-compiler-plugin")) testCompile(projectTests(":kotlin-noarg-compiler-plugin"))
testCompile(projectTests(":kotlin-sam-with-receiver-compiler-plugin")) testCompile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
testCompile(projectTests(":kotlinx-serialization-compiler-plugin")) testCompile(projectTests(":kotlinx-serialization-compiler-plugin"))
testCompile(projectTests(":kotlinx-serialization-ide-plugin"))
testCompile(projectTests(":plugins:fir:fir-plugin-prototype")) testCompile(projectTests(":plugins:fir:fir-plugin-prototype"))
testCompile(projectTests(":idea:jvm-debugger:jvm-debugger-test")) testCompile(projectTests(":idea:jvm-debugger:jvm-debugger-test"))
testCompile(projectTests(":generators:test-generator")) testCompile(projectTests(":generators:test-generator"))
@@ -196,6 +196,8 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.AbstractYamlNewWizardProj
import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationPluginIdeDiagnosticTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationQuickFixTest
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true") System.setProperty("java.awt.headless", "true")
@@ -1795,6 +1797,18 @@ fun main(args: Array<String>) {
} }
} }
testGroup(
"plugins/kotlin-serialization/kotlin-serialization-ide/test",
"plugins/kotlin-serialization/kotlin-serialization-ide/testData"
) {
testClass<AbstractSerializationPluginIdeDiagnosticTest> {
model("diagnostics")
}
testClass<AbstractSerializationQuickFixTest> {
model("quickfix", pattern = "^([\\w\\-_]+)\\.kt$", filenameStartsLowerCase = true)
}
}
testGroup("plugins/fir/fir-plugin-prototype/tests", "plugins/fir/fir-plugin-prototype/testData") { testGroup("plugins/fir/fir-plugin-prototype/tests", "plugins/fir/fir-plugin-prototype/testData") {
testClass<AbstractFirAllOpenDiagnosticTest> { testClass<AbstractFirAllOpenDiagnosticTest> {
model("") model("")
@@ -162,6 +162,8 @@ import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationPluginIdeDiagnosticTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationQuickFixTest
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true") System.setProperty("java.awt.headless", "true")
@@ -1220,6 +1222,18 @@ fun main(args: Array<String>) {
model("codegen") model("codegen")
} }
} }
testGroup(
"plugins/kotlin-serialization/kotlin-serialization-ide/test",
"plugins/kotlin-serialization/kotlin-serialization-ide/testData"
) {
testClass<AbstractSerializationPluginIdeDiagnosticTest> {
model("diagnostics")
}
testClass<AbstractSerializationQuickFixTest> {
model("quickfix", pattern = "^([\\w\\-_]+)\\.kt$", filenameStartsLowerCase = true)
}
}
/* /*
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") { testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
testClass<AbstractAndroidCompletionTest> { testClass<AbstractAndroidCompletionTest> {
@@ -159,6 +159,8 @@ import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginBytecodeListingTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest import org.jetbrains.kotlinx.serialization.AbstractSerializationPluginDiagnosticTest
import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest import org.jetbrains.kotlinx.serialization.AbstractSerializationIrBytecodeListingTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationPluginIdeDiagnosticTest
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationQuickFixTest
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true") System.setProperty("java.awt.headless", "true")
@@ -1148,6 +1150,18 @@ fun main(args: Array<String>) {
model("codegen") model("codegen")
} }
} }
testGroup(
"plugins/kotlin-serialization/kotlin-serialization-ide/test",
"plugins/kotlin-serialization/kotlin-serialization-ide/testData"
) {
testClass<AbstractSerializationPluginIdeDiagnosticTest> {
model("diagnostics")
}
testClass<AbstractSerializationQuickFixTest> {
model("quickfix", pattern = "^([\\w\\-_]+)\\.kt$", filenameStartsLowerCase = true)
}
}
/* /*
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") { testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
testClass<AbstractAndroidCompletionTest> { testClass<AbstractAndroidCompletionTest> {
@@ -21,7 +21,7 @@ dependencies {
testCompile(projectTests(":compiler:tests-common")) testCompile(projectTests(":compiler:tests-common"))
testCompile(commonDep("junit:junit")) testCompile(commonDep("junit:junit"))
testImplementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-jvm:1.0-M1-1.4.0-rc") { isTransitive = false } testImplementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.1.0")
testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") } testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") }
testRuntimeOnly(intellijDep()) { includeJars("platform-concurrency") } testRuntimeOnly(intellijDep()) { includeJars("platform-concurrency") }
@@ -29,6 +29,8 @@ public interface SerializationErrors {
DiagnosticFactory0<PsiElement> TRANSIENT_MISSING_INITIALIZER = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> TRANSIENT_MISSING_INITIALIZER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> TRANSIENT_IS_REDUNDANT = DiagnosticFactory0.create(WARNING); DiagnosticFactory0<PsiElement> TRANSIENT_IS_REDUNDANT = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> JSON_FORMAT_REDUNDANT_DEFAULT = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> JSON_FORMAT_REDUNDANT = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> INCORRECT_TRANSIENT = DiagnosticFactory0.create(WARNING); DiagnosticFactory0<PsiElement> INCORRECT_TRANSIENT = DiagnosticFactory0.create(WARNING);
@@ -42,4 +44,4 @@ public interface SerializationErrors {
.initializeFactoryNamesAndDefaultErrorMessages(SerializationErrors.class, SerializationPluginErrorsRendering.INSTANCE); .initializeFactoryNamesAndDefaultErrorMessages(SerializationErrors.class, SerializationPluginErrorsRendering.INSTANCE);
} }
}; };
} }
@@ -74,6 +74,14 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
SerializationErrors.TRANSIENT_IS_REDUNDANT, SerializationErrors.TRANSIENT_IS_REDUNDANT,
"Property does not have backing field which makes it non-serializable and therefore @Transient is redundant" "Property does not have backing field which makes it non-serializable and therefore @Transient is redundant"
) )
MAP.put(
SerializationErrors.JSON_FORMAT_REDUNDANT_DEFAULT,
"Redundant creation of Json default format. Creating instances for each usage can be slow."
)
MAP.put(
SerializationErrors.JSON_FORMAT_REDUNDANT,
"Redundant creation of Json format. Creating instances for each usage can be slow."
)
MAP.put( MAP.put(
SerializationErrors.INCORRECT_TRANSIENT, SerializationErrors.INCORRECT_TRANSIENT,
"@kotlin.jvm.Transient does not affect @Serializable classes. Please use @kotlinx.serialization.Transient instead." "@kotlin.jvm.Transient does not affect @Serializable classes. Please use @kotlinx.serialization.Transient instead."
@@ -96,4 +104,4 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
Renderers.STRING Renderers.STRING
) )
} }
} }
@@ -13,7 +13,7 @@ import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComp
import java.io.File import java.io.File
abstract class AbstractSerializationIrBytecodeListingTest : AbstractAsmLikeInstructionListingTest() { abstract class AbstractSerializationIrBytecodeListingTest : AbstractAsmLikeInstructionListingTest() {
private val runtimeLibraryPath = getSerializationLibraryRuntimeJar() private val coreLibraryPath = getSerializationCoreLibraryJar()
override fun getExpectedTextFileName(wholeFile: File): String { override fun getExpectedTextFileName(wholeFile: File): String {
return wholeFile.nameWithoutExtension + ".ir.txt" return wholeFile.nameWithoutExtension + ".ir.txt"
@@ -23,6 +23,6 @@ abstract class AbstractSerializationIrBytecodeListingTest : AbstractAsmLikeInstr
override fun setupEnvironment(environment: KotlinCoreEnvironment) { override fun setupEnvironment(environment: KotlinCoreEnvironment) {
SerializationComponentRegistrar.registerExtensions(environment.project) SerializationComponentRegistrar.registerExtensions(environment.project)
environment.updateClasspath(listOf(JvmClasspathRoot(runtimeLibraryPath!!))) environment.updateClasspath(listOf(JvmClasspathRoot(coreLibraryPath!!)))
} }
} }
@@ -5,17 +5,16 @@
package org.jetbrains.kotlinx.serialization package org.jetbrains.kotlinx.serialization
import junit.framework.TestCase
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.codegen.AbstractAsmLikeInstructionListingTest import org.jetbrains.kotlin.codegen.AbstractAsmLikeInstructionListingTest
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComponentRegistrar import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComponentRegistrar
abstract class AbstractSerializationPluginBytecodeListingTest : AbstractAsmLikeInstructionListingTest() { abstract class AbstractSerializationPluginBytecodeListingTest : AbstractAsmLikeInstructionListingTest() {
private val runtimeLibraryPath = getSerializationLibraryRuntimeJar() private val coreLibraryPath = getSerializationCoreLibraryJar()
override fun setupEnvironment(environment: KotlinCoreEnvironment) { override fun setupEnvironment(environment: KotlinCoreEnvironment) {
SerializationComponentRegistrar.registerExtensions(environment.project) SerializationComponentRegistrar.registerExtensions(environment.project)
environment.updateClasspath(listOf(JvmClasspathRoot(runtimeLibraryPath!!))) environment.updateClasspath(listOf(JvmClasspathRoot(coreLibraryPath!!)))
} }
} }
@@ -13,10 +13,10 @@ import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComp
@OptIn(ObsoleteTestInfrastructure::class) @OptIn(ObsoleteTestInfrastructure::class)
abstract class AbstractSerializationPluginDiagnosticTest : AbstractDiagnosticsTest() { abstract class AbstractSerializationPluginDiagnosticTest : AbstractDiagnosticsTest() {
private val runtimeLibraryPath = getSerializationLibraryRuntimeJar() private val coreLibraryPath = getSerializationCoreLibraryJar()
override fun setupEnvironment(environment: KotlinCoreEnvironment) { override fun setupEnvironment(environment: KotlinCoreEnvironment) {
SerializationComponentRegistrar.registerExtensions(environment.project) SerializationComponentRegistrar.registerExtensions(environment.project)
environment.updateClasspath(listOf(JvmClasspathRoot(runtimeLibraryPath!!))) environment.updateClasspath(listOf(JvmClasspathRoot(coreLibraryPath!!)))
} }
} }
@@ -13,25 +13,25 @@ import java.io.File
import kotlin.test.assertTrue import kotlin.test.assertTrue
class RuntimeLibraryInClasspathTest { class RuntimeLibraryInClasspathTest {
private val runtimeLibraryPath = getSerializationLibraryRuntimeJar() private val coreLibraryPath = getSerializationCoreLibraryJar()
@Test @Test
fun testRuntimeLibraryExists() { fun testRuntimeLibraryExists() {
TestCase.assertNotNull( TestCase.assertNotNull(
"kotlinx-serialization runtime library is not found. Make sure it is present in test classpath", "kotlinx-serialization runtime library is not found. Make sure it is present in test classpath",
runtimeLibraryPath coreLibraryPath
) )
} }
@Test @Test
fun testRuntimeHasSufficientVersion() { fun testRuntimeHasSufficientVersion() {
val version = VersionReader.getVersionsFromManifest(runtimeLibraryPath!!) val version = VersionReader.getVersionsFromManifest(coreLibraryPath!!)
assertTrue(version.currentCompilerMatchRequired(), "Runtime version too high") assertTrue(version.currentCompilerMatchRequired(), "Runtime version too high")
assertTrue(version.implementationVersionMatchSupported(), "Runtime version too low") assertTrue(version.implementationVersionMatchSupported(), "Runtime version too low")
} }
} }
internal fun getSerializationLibraryRuntimeJar(): File? = try { internal fun getSerializationCoreLibraryJar(): File? = try {
PathUtil.getResourcePathForClass(Class.forName("kotlinx.serialization.KSerializer")) PathUtil.getResourcePathForClass(Class.forName("kotlinx.serialization.KSerializer"))
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
null null
@@ -165,10 +165,6 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public ListOfUsers patch(kotlinx.serialization.encoding.Decoder decoder, ListOfUsers old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder decoder, java.lang.Object old)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, ListOfUsers value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, ListOfUsers value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -276,18 +272,19 @@ public final class ListOfUsers : java/lang/Object {
public void <init>(int seen1, java.util.List list, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, java.util.List list, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
LINENUMBER (12) LINENUMBER (12)
ALOAD (0) ICONST_1
INVOKESPECIAL (java/lang/Object, <init>, ()V) ICONST_1
ILOAD (1)
IAND
IF_ICMPEQ (L1)
ILOAD (1) ILOAD (1)
ICONST_1 ICONST_1
IAND GETSTATIC (INSTANCE, LListOfUsers$$serializer;)
IFNE (L1) INVOKEVIRTUAL (ListOfUsers$$serializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
NEW INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
DUP
LDC (list)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
ATHROW
LABEL (L1) LABEL (L1)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (list, Ljava/util/List;) PUTFIELD (list, Ljava/util/List;)
@@ -453,10 +450,6 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public OptionalUser patch(kotlinx.serialization.encoding.Decoder decoder, OptionalUser old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder decoder, java.lang.Object old)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, OptionalUser value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, OptionalUser value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -608,31 +601,41 @@ public final class OptionalUser : java/lang/Object {
public void <init>(int seen1, User user, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, User user, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
LINENUMBER (9) LINENUMBER (9)
ICONST_0
ILOAD (1)
IAND
IFEQ (L1)
ILOAD (1)
ICONST_0
GETSTATIC (INSTANCE, LOptionalUser$$serializer;)
INVOKEVIRTUAL (OptionalUser$$serializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
LABEL (L1)
ALOAD (0) ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V) INVOKESPECIAL (java/lang/Object, <init>, ()V)
ILOAD (1) ILOAD (1)
ICONST_1 ICONST_1
IAND IAND
IFNE (L1) IFNE (L2)
ALOAD (0) ALOAD (0)
LABEL (L2) LABEL (L3)
LINENUMBER (10) LINENUMBER (10)
NEW NEW
DUP DUP
LDC () LDC ()
LDC () LDC ()
INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V) INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V)
LABEL (L3) LABEL (L4)
LINENUMBER (9) LINENUMBER (9)
PUTFIELD (user, LUser;) PUTFIELD (user, LUser;)
GOTO (L4) GOTO (L5)
LABEL (L1) LABEL (L2)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (user, LUser;) PUTFIELD (user, LUser;)
LABEL (L4)
RETURN
LABEL (L5) LABEL (L5)
RETURN
LABEL (L6)
} }
public void <init>() { public void <init>() {
@@ -829,10 +832,6 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public User patch(kotlinx.serialization.encoding.Decoder decoder, User old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder decoder, java.lang.Object old)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, User value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, User value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -948,36 +947,27 @@ public final class User : java/lang/Object {
public void <init>(int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
LINENUMBER (6) LINENUMBER (6)
ICONST_3
ICONST_3
ILOAD (1)
IAND
IF_ICMPEQ (L1)
ILOAD (1)
ICONST_3
GETSTATIC (INSTANCE, LUser$$serializer;)
INVOKEVIRTUAL (User$$serializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
LABEL (L1)
ALOAD (0) ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V) INVOKESPECIAL (java/lang/Object, <init>, ()V)
ILOAD (1)
ICONST_1
IAND
IFNE (L1)
NEW
DUP
LDC (firstName)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
ATHROW
LABEL (L1)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (firstName, Ljava/lang/String;) PUTFIELD (firstName, Ljava/lang/String;)
ILOAD (1)
ICONST_2
IAND
IFNE (L2)
NEW
DUP
LDC (lastName)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
ATHROW
LABEL (L2)
ALOAD (0) ALOAD (0)
ALOAD (3) ALOAD (3)
PUTFIELD (lastName, Ljava/lang/String;) PUTFIELD (lastName, Ljava/lang/String;)
RETURN RETURN
LABEL (L3) LABEL (L2)
} }
public final java.lang.String getFirstName() public final java.lang.String getFirstName()
@@ -144,10 +144,6 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public ListOfUsers patch(kotlinx.serialization.encoding.Decoder decoder, ListOfUsers old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder p0, java.lang.Object p1)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, ListOfUsers value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, ListOfUsers value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -241,19 +237,20 @@ public final class ListOfUsers : java/lang/Object {
public void <init>(int seen1, java.util.List list, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, java.util.List list, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
ALOAD (0) ICONST_1
INVOKESPECIAL (java/lang/Object, <init>, ()V) DUP
ILOAD (1)
IAND
IF_ICMPEQ (L1)
ILOAD (1) ILOAD (1)
ICONST_1 ICONST_1
IAND GETSTATIC (INSTANCE, LListOfUsers$$serializer;)
IFNE (L1)
NEW
DUP
LDC (list)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
CHECKCAST CHECKCAST
ATHROW INVOKEINTERFACE (kotlinx/serialization/KSerializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
LABEL (L1) LABEL (L1)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (list, Ljava/util/List;) PUTFIELD (list, Ljava/util/List;)
@@ -427,10 +424,6 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public OptionalUser patch(kotlinx.serialization.encoding.Decoder decoder, OptionalUser old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder p0, java.lang.Object p1)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, OptionalUser value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, OptionalUser value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -553,19 +546,31 @@ public final class OptionalUser : java/lang/Object {
public void <init>(int seen1, User user, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, User user, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
ICONST_0
DUP
ILOAD (1)
IAND
IF_ICMPEQ (L1)
ILOAD (1)
ICONST_0
GETSTATIC (INSTANCE, LOptionalUser$$serializer;)
CHECKCAST
INVOKEINTERFACE (kotlinx/serialization/KSerializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
LABEL (L1)
ALOAD (0) ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V) INVOKESPECIAL (java/lang/Object, <init>, ()V)
ILOAD (1) ILOAD (1)
ICONST_1 ICONST_1
IAND IAND
IFEQ (L1) IFEQ (L2)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (user, LUser;) PUTFIELD (user, LUser;)
GOTO (L2) GOTO (L3)
LABEL (L1) LABEL (L2)
ALOAD (0) ALOAD (0)
LABEL (L3) LABEL (L4)
LINENUMBER (10) LINENUMBER (10)
NEW NEW
DUP DUP
@@ -573,9 +578,9 @@ public final class OptionalUser : java/lang/Object {
LDC () LDC ()
INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V) INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V)
PUTFIELD (user, LUser;) PUTFIELD (user, LUser;)
LABEL (L2) LABEL (L3)
RETURN RETURN
LABEL (L4) LABEL (L5)
} }
public final User getUser() public final User getUser()
@@ -781,10 +786,6 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor()
public User patch(kotlinx.serialization.encoding.Decoder decoder, User old)
public java.lang.Object patch(kotlinx.serialization.encoding.Decoder p0, java.lang.Object p1)
public void serialize(kotlinx.serialization.encoding.Encoder encoder, User value) { public void serialize(kotlinx.serialization.encoding.Encoder encoder, User value) {
LABEL (L0) LABEL (L0)
ALOAD (1) ALOAD (1)
@@ -886,38 +887,28 @@ public final class User : java/lang/Object {
public void <init>(int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) { public void <init>(int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0) LABEL (L0)
ICONST_3
DUP
ILOAD (1)
IAND
IF_ICMPEQ (L1)
ILOAD (1)
ICONST_3
GETSTATIC (INSTANCE, LUser$$serializer;)
CHECKCAST
INVOKEINTERFACE (kotlinx/serialization/KSerializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
INVOKESTATIC (kotlinx/serialization/internal/PluginExceptionsKt, throwMissingFieldException, (IILkotlinx/serialization/descriptors/SerialDescriptor;)V)
LABEL (L1)
ALOAD (0) ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V) INVOKESPECIAL (java/lang/Object, <init>, ()V)
ILOAD (1)
ICONST_1
IAND
IFNE (L1)
NEW
DUP
LDC (firstName)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
CHECKCAST
ATHROW
LABEL (L1)
ALOAD (0) ALOAD (0)
ALOAD (2) ALOAD (2)
PUTFIELD (firstName, Ljava/lang/String;) PUTFIELD (firstName, Ljava/lang/String;)
ILOAD (1)
ICONST_2
IAND
IFNE (L2)
NEW
DUP
LDC (lastName)
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
CHECKCAST
ATHROW
LABEL (L2)
ALOAD (0) ALOAD (0)
ALOAD (3) ALOAD (3)
PUTFIELD (lastName, Ljava/lang/String;) PUTFIELD (lastName, Ljava/lang/String;)
RETURN RETURN
LABEL (L3) LABEL (L2)
} }
public final java.lang.String getFirstName() public final java.lang.String getFirstName()
@@ -15,7 +15,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Derived public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Derived): Derived
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Derived): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Derived): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -45,7 +44,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Parent public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Parent
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Parent): Parent
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Parent): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Parent): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -1,4 +1,5 @@
// This test enshures that analysis ends up without compiler exceptions // This test enshures that analysis ends up without compiler exceptions
// !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE
import kotlinx.serialization.* import kotlinx.serialization.*
@@ -13,7 +13,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Digest public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Digest
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Digest): Digest
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Digest): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Digest): kotlin.Unit
public final /*synthesized*/ fun serializer(): kotlinx.serialization.KSerializer<Digest> public final /*synthesized*/ fun serializer(): kotlinx.serialization.KSerializer<Digest>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -16,7 +16,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Derived public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Derived): Derived
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Derived): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Derived): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -15,7 +15,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Basic public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Basic
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Basic): Basic
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Basic): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Basic): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -45,7 +44,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Inside public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Inside
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Inside): Inside
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Inside): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Inside): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -82,7 +80,6 @@ public final class NonSerializable {
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): WithImplicitType public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): WithImplicitType
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: WithImplicitType): WithImplicitType
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: WithImplicitType): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: WithImplicitType): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -15,7 +15,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Foo public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Foo
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Foo): Foo
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Foo): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Foo): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -51,7 +50,6 @@ public final class NopeNullableSerializer : kotlinx.serialization.KSerializer<No
public open override /*1*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Nope? public open override /*1*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Nope?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Nope?): Nope?
public open override /*1*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Nope?): kotlin.Nothing public open override /*1*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Nope?): kotlin.Nothing
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -15,7 +15,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Test public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): Test
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: Test): Test
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Test): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: Test): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -6,7 +6,6 @@ public object EnumSerializer : kotlinx.serialization.KSerializer<ExplicitlyMarke
public open override /*1*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): ExplicitlyMarkedEnumCustom public open override /*1*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): ExplicitlyMarkedEnumCustom
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: ExplicitlyMarkedEnumCustom): ExplicitlyMarkedEnumCustom
public open override /*1*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: ExplicitlyMarkedEnumCustom): kotlin.Nothing public open override /*1*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: ExplicitlyMarkedEnumCustom): kotlin.Nothing
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
@@ -32,7 +31,6 @@ public object EnumSerializer : kotlinx.serialization.KSerializer<ExplicitlyMarke
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): EnumUsage public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): EnumUsage
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: EnumUsage): EnumUsage
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: EnumUsage): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: EnumUsage): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -70,7 +68,6 @@ public object EnumSerializer : kotlinx.serialization.KSerializer<ExplicitlyMarke
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): ExplicitlyMarkedEnum public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): ExplicitlyMarkedEnum
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: ExplicitlyMarkedEnum): ExplicitlyMarkedEnum
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: ExplicitlyMarkedEnum): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: ExplicitlyMarkedEnum): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -1,3 +1,4 @@
// !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE
// WITH_RUNTIME // WITH_RUNTIME
// SKIP_TXT // SKIP_TXT
@@ -15,4 +16,4 @@ object BazSerializer: KSerializer<Baz>
class Foo1(@Polymorphic val i: Baz) class Foo1(@Polymorphic val i: Baz)
@Serializable @Serializable
class Foo2(val li: MutableList<@Serializable(with = BazSerializer::class) Baz>) class Foo2(val li: MutableList<@Serializable(with = BazSerializer::class) Baz>)
@@ -1,3 +1,4 @@
// !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE
// WITH_RUNTIME // WITH_RUNTIME
// SKIP_TXT // SKIP_TXT
@@ -32,4 +33,4 @@ class Foo5(@Serializable(with = BazSerializer::class) val i: <!SERIALIZER_TYPE_I
class Foo6(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_NULLABILITY_INCOMPATIBLE, SERIALIZER_TYPE_INCOMPATIBLE!>Bar<!>) class Foo6(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_NULLABILITY_INCOMPATIBLE, SERIALIZER_TYPE_INCOMPATIBLE!>Bar<!>)
@Serializable @Serializable
class Foo7(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar?<!>) class Foo7(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar?<!>)
@@ -19,7 +19,6 @@ package
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): WithTransients public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): WithTransients
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: WithTransients): WithTransients
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: WithTransients): kotlin.Unit public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: WithTransients): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>> public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
@@ -19,8 +19,24 @@ dependencies {
excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) } excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("gradle"))
testCompileOnly(intellijDep()) testCompile(toolsJar())
testRuntimeOnly(intellijDep()) testCompile(projectTests(":idea"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":idea:idea-test-framework"))
testCompile(project(":kotlin-test:kotlin-test-junit"))
testCompile(commonDep("junit:junit"))
testCompile(projectTests(":idea:idea-frontend-independent"))
testImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") }
testRuntime(project(":allopen-ide-plugin"))
testRuntime(project(":plugins:parcelize:parcelize-ide"))
testRuntime(project(":sam-with-receiver-ide-plugin"))
testRuntime(project(":noarg-ide-plugin"))
testCompile(intellijDep())
testCompile(intellijPluginDep("java"))
} }
sourceSets { sourceSets {
@@ -29,7 +45,8 @@ sourceSets {
} }
runtimeJar() runtimeJar()
testsJar()
projectTest(parallel = true) { projectTest(parallel = true) {
workingDir = rootDir
} }
@@ -0,0 +1,2 @@
extract.json.to.property=Extract Json format creation to property
replace.with.default.json.format=Replace with default Json format instance
@@ -0,0 +1,96 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.compiler.diagnostic
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.callUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.unpackFunctionLiteral
import org.jetbrains.kotlin.resolve.BindingContext
class JsonFormatRedundantDiagnostic : CallChecker {
private val jsonFqName = FqName("kotlinx.serialization.json.Json")
private val jsonDefaultFqName = FqName("kotlinx.serialization.json.Json.Default")
private val parameterNameFrom = Name.identifier("from")
private val parameterNameBuilderAction = Name.identifier("builderAction")
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val functionDescriptor = resolvedCall.resultingDescriptor as? SimpleFunctionDescriptor ?: return
val bindingContext = context.trace.bindingContext
if (isJsonFormatCreation(functionDescriptor)) {
if (isDefaultFormat(resolvedCall, bindingContext)) {
context.trace.report(SerializationErrors.JSON_FORMAT_REDUNDANT_DEFAULT.on(resolvedCall.call.callElement))
}
return
}
val receiverExpression = resolvedCall.getReceiverExpression() ?: return
val receiverResolvedCall = receiverExpression.getResolvedCall(bindingContext) ?: return
val receiverFunctionDescriptor = receiverResolvedCall.resultingDescriptor as? SimpleFunctionDescriptor ?: return
if (isJsonFormatCreation(receiverFunctionDescriptor) && !isDefaultFormat(receiverResolvedCall, bindingContext)) {
context.trace.report(SerializationErrors.JSON_FORMAT_REDUNDANT.on(receiverExpression.originalElement))
}
}
private fun isJsonFormatCreation(descriptor: SimpleFunctionDescriptor): Boolean {
return descriptor.importableFqName == jsonFqName
}
private fun isDefaultFormat(resolvedCall: ResolvedCall<*>, context: BindingContext): Boolean {
var defaultFrom = false
var emptyBuilder = false
resolvedCall.valueArguments.forEach { (paramDesc, arg) ->
when (paramDesc.name) {
parameterNameFrom -> defaultFrom = isDefaultFormatArgument(arg, context)
parameterNameBuilderAction -> emptyBuilder = isEmptyFunctionArgument(arg)
}
}
return defaultFrom && emptyBuilder
}
private fun isDefaultFormatArgument(arg: ResolvedValueArgument, context: BindingContext): Boolean {
if (arg is DefaultValueArgument) return true
if (arg !is ExpressionValueArgument) return false
val expression = arg.valueArgument?.getArgumentExpression() ?: return false
val fqName = context[BindingContext.EXPRESSION_TYPE_INFO, expression]?.type?.fqName ?: return false
return fqName == jsonDefaultFqName
}
private fun isEmptyFunctionArgument(arg: ResolvedValueArgument): Boolean {
if (arg !is ExpressionValueArgument) {
return false
}
val argumentExpression = arg.valueArgument?.getArgumentExpression() ?: return false
val blockExpression = if (argumentExpression is KtNamedFunction) {
// anonymous functions
argumentExpression.bodyBlockExpression ?: return true
} else {
// function literal
argumentExpression.unpackFunctionLiteral()?.bodyExpression
}
return blockExpression?.statements?.isEmpty() ?: false
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.JsonFormatRedundantDiagnostic
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginIDEDeclarationChecker import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginIDEDeclarationChecker
class SerializationIDEContainerContributor : StorageComponentContainerContributor { class SerializationIDEContainerContributor : StorageComponentContainerContributor {
@@ -19,5 +20,6 @@ class SerializationIDEContainerContributor : StorageComponentContainerContributo
moduleDescriptor: ModuleDescriptor moduleDescriptor: ModuleDescriptor
) { ) {
container.useInstance(SerializationPluginIDEDeclarationChecker()) container.useInstance(SerializationPluginIDEDeclarationChecker())
container.useInstance(JsonFormatRedundantDiagnostic())
} }
} }
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey
import org.jetbrains.kotlin.util.AbstractKotlinBundle
@NonNls
private const val BUNDLE = "messages.KotlinSerializationBundle"
object KotlinSerializationBundle : AbstractKotlinBundle(BUNDLE) {
@JvmStatic
fun message(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = getMessage(key, *params)
@JvmStatic
fun htmlMessage(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String =
getMessage(key, *params).withHtml()
}
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea.quickfixes
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationErrors
import org.jetbrains.kotlinx.serialization.idea.KotlinSerializationBundle
internal class JsonRedundantDefaultQuickFix(expression: KtCallExpression) : KotlinQuickFixAction<KtCallExpression>(expression) {
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val element = element ?: return
val call = element as? KtCallExpression ?: return
val callee = call.calleeExpression ?: return
call.replace(callee)
}
override fun getFamilyName(): String = text
override fun getText(): String = KotlinSerializationBundle.message("replace.with.default.json.format")
object Factory : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
if (diagnostic.factory != SerializationErrors.JSON_FORMAT_REDUNDANT_DEFAULT) return null
val castedDiagnostic = SerializationErrors.JSON_FORMAT_REDUNDANT_DEFAULT.cast(diagnostic)
val element: KtCallExpression = castedDiagnostic.psiElement as? KtCallExpression ?: return null
return JsonRedundantDefaultQuickFix(element)
}
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea.quickfixes
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
import org.jetbrains.kotlin.idea.refactoring.chooseContainerElementIfNecessary
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHintByKey
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getOutermostParentContainedIn
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationErrors
import org.jetbrains.kotlinx.serialization.idea.KotlinSerializationBundle
internal class JsonRedundantQuickFix(expression: KtCallExpression) : KotlinQuickFixAction<KtCallExpression>(expression) {
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
editor ?: return
val element = element ?: return
selectContainer(element, project, editor) {
editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE)
val outermostParent = element.getOutermostParentContainedIn(it)
if (outermostParent == null) {
showErrorHintByKey(project, editor, "cannot.refactor.no.container", text)
return@selectContainer
}
KotlinIntroducePropertyHandler().doInvoke(project, editor, file, listOf(element), outermostParent)
}
}
override fun getFamilyName(): String = text
override fun getText(): String = KotlinSerializationBundle.message("extract.json.to.property")
object Factory : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
if (diagnostic.factory != SerializationErrors.JSON_FORMAT_REDUNDANT) return null
val castedDiagnostic = SerializationErrors.JSON_FORMAT_REDUNDANT.cast(diagnostic)
val element: KtCallExpression = castedDiagnostic.psiElement as? KtCallExpression ?: return null
return JsonRedundantQuickFix(element)
}
}
private fun selectContainer(element: PsiElement, project: Project, editor: Editor, onSelect: (PsiElement) -> Unit) {
val parent = element.parent ?: throw AssertionError("Should have at least one parent")
val containers = parent.getExtractionContainers(strict = true, includeAll = true)
.filter { it is KtClassBody || (it is KtFile && !it.isScript()) }
if (containers.isEmpty()) {
showErrorHintByKey(project, editor, "cannot.refactor.no.container", text)
return
}
chooseContainerElementIfNecessary(
containers,
editor,
KotlinBundle.message("title.select.target.code.block"),
true,
{ it },
{ onSelect(it) }
)
}
}
@@ -12,5 +12,7 @@ import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationErro
class SerializationQuickFixContributor : QuickFixContributor { class SerializationQuickFixContributor : QuickFixContributor {
override fun registerQuickFixes(quickFixes: QuickFixes) { override fun registerQuickFixes(quickFixes: QuickFixes) {
quickFixes.register(SerializationErrors.INCORRECT_TRANSIENT, AddKotlinxSerializationTransientImportQuickFix.Factory) quickFixes.register(SerializationErrors.INCORRECT_TRANSIENT, AddKotlinxSerializationTransientImportQuickFix.Factory)
quickFixes.register(SerializationErrors.JSON_FORMAT_REDUNDANT_DEFAULT, JsonRedundantDefaultQuickFix.Factory)
quickFixes.register(SerializationErrors.JSON_FORMAT_REDUNDANT, JsonRedundantQuickFix.Factory)
} }
} }
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationIDEContainerContributor
@OptIn(ObsoleteTestInfrastructure::class)
abstract class AbstractSerializationPluginIdeDiagnosticTest : AbstractDiagnosticsTest() {
private val coreLibraryPath = getSerializationCoreLibraryJar()!!
private val jsonLibraryPath = getSerializationJsonLibraryJar()!!
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
if (!StorageComponentContainerContributor.getInstances(project).any { it is SerializationIDEContainerContributor }) {
StorageComponentContainerContributor.registerExtension(project, SerializationIDEContainerContributor())
}
environment.updateClasspath(listOf(JvmClasspathRoot(coreLibraryPath), JvmClasspathRoot(jsonLibraryPath)))
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea
import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixTest
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
abstract class AbstractSerializationQuickFixTest : AbstractQuickFixTest() {
override fun setUp() {
super.setUp()
val coreJar = getSerializationCoreLibraryJar()!!
val jsonJar = getSerializationJsonLibraryJar()!!
ConfigLibraryUtil.addLibrary(module, "Serialization core", coreJar.parentFile.absolutePath, arrayOf(coreJar.name))
ConfigLibraryUtil.addLibrary(module, "Serialization JSON", jsonJar.parentFile.absolutePath, arrayOf(jsonJar.name))
}
override fun tearDown() {
ConfigLibraryUtil.removeLibrary(module, "Serialization JSON")
ConfigLibraryUtil.removeLibrary(module, "Serialization core")
super.tearDown()
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea
import junit.framework.TestCase
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.VersionReader
import org.junit.Test
import java.io.File
import kotlin.test.assertTrue
class RuntimeLibraryInClasspathTest {
private val runtimeLibraryPath = getSerializationCoreLibraryJar()
@Test
fun testRuntimeLibraryExists() {
TestCase.assertNotNull(
"kotlinx-serialization runtime library is not found. Make sure it is present in test classpath",
runtimeLibraryPath
)
}
@Test
fun testRuntimeHasSufficientVersion() {
val version = VersionReader.getVersionsFromManifest(runtimeLibraryPath!!)
assertTrue(version.currentCompilerMatchRequired(), "Runtime version too high")
assertTrue(version.implementationVersionMatchSupported(), "Runtime version too low")
}
}
internal fun getSerializationCoreLibraryJar(): File? = try {
PathUtil.getResourcePathForClass(Class.forName("kotlinx.serialization.KSerializer"))
} catch (e: ClassNotFoundException) {
null
}
internal fun getSerializationJsonLibraryJar(): File? = try {
PathUtil.getResourcePathForClass(Class.forName("kotlinx.serialization.json.Json"))
} catch (e: ClassNotFoundException) {
null
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class SerializationPluginIdeDiagnosticTestGenerated extends AbstractSerializationPluginIdeDiagnosticTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInDiagnostics() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("JsonRedundantFormat.kt")
public void testJsonRedundantFormat() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics/JsonRedundantFormat.kt");
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.idea;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-ide/testData/quickfix")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class SerializationQuickFixTestGenerated extends AbstractSerializationQuickFixTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInQuickfix() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/kotlin-serialization/kotlin-serialization-ide/testData/quickfix"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true);
}
@TestMetadata("DefaultFormat.kt")
public void testDefaultFormat() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-ide/testData/quickfix/DefaultFormat.kt");
}
@TestMetadata("DefaultFormatWithAlias.kt")
public void testDefaultFormatWithAlias() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-ide/testData/quickfix/DefaultFormatWithAlias.kt");
}
}
@@ -0,0 +1,82 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
// SKIP_TXT
// FILE: test.kt
import kotlinx.serialization.*
import kotlinx.serialization.json.*
object Instance
val defaultWarn = <!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>
val receiverWarn = <!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.encodeToString(Instance)
val noWarnFormat = Json {encodeDefaults = true}
val receiverNoWarn = noWarnFormat.encodeToString(Instance)
val defaultNoWarn = Json.encodeToString(Instance)
class SomeContainerClass {
val memberDefaultWarn = <!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>
val memberReceiverWarn = <!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.encodeToString(Instance)
val memberNoWarnFormat = Json {encodeDefaults = true}
val memberReceiverNoWarn = noWarnFormat.encodeToString(Instance)
val memberDefaultNoWarn = Json.encodeToString(Instance)
fun testDefaultWarnings() {
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json() {}<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>.encodeToString(Any())
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>.encodeToString(Instance)
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json { /*some comment*/ }<!>.encodeToString(Instance)
val localDefaultFormat = <!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(Json.Default) {}<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(Json) {}<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(Json.Default, {})<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(builderAction = {})<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(builderAction = fun JsonBuilder.() {})<!>
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json(builderAction = fun JsonBuilder.() = Unit)<!>
"{}".let {
<!JSON_FORMAT_REDUNDANT_DEFAULT!>Json {}<!>.decodeFromString<Any>(it)
}
}
fun testReceiverWarnings() {
<!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.encodeToString(Instance)
val encoded = <!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.encodeToString(Instance)
<!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.decodeFromString<Any>("{}")
<!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.hashCode()
<!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.toString()
<!JSON_FORMAT_REDUNDANT!>Json(noWarnFormat) {encodeDefaults = true}<!>.encodeToString(Instance)
<!JSON_FORMAT_REDUNDANT!>Json(builderAction = {encodeDefaults = true})<!>.encodeToString(Instance)
<!JSON_FORMAT_REDUNDANT!>Json(noWarnFormat, {encodeDefaults = true})<!>.encodeToString(Instance)
<!JSON_FORMAT_REDUNDANT!>Json(builderAction = fun JsonBuilder.() {encodeDefaults = true})<!>.encodeToString(Instance)
"{}".let {
<!JSON_FORMAT_REDUNDANT!>Json {encodeDefaults = true}<!>.decodeFromString<Any>(it)
}
}
fun testReceiverNoWarnings() {
val localFormat = Json {encodeDefaults = true}
localFormat.encodeToString(Instance)
localFormat.decodeFromString<Any>("{}")
localFormat.hashCode()
localFormat.toString()
}
fun testDefaultNoWarnings() {
val localDefault = Json
Json.encodeToString(Instance)
Json.decodeFromString<Any>("{}")
Json.hashCode()
Json.toString()
Json(builderAction = this::builder)
Json(Json.Default, this::builder)
}
private fun builder(builder: JsonBuilder) {
//now its empty builder
}
}
@@ -0,0 +1,7 @@
// "Replace with default Json format instance" "true"
import kotlinx.serialization.*
import kotlinx.serialization.json.*
fun foo() {
<caret>Json {}.encodeToString(Any())
}
@@ -0,0 +1,7 @@
// "Replace with default Json format instance" "true"
import kotlinx.serialization.*
import kotlinx.serialization.json.*
fun foo() {
Json.encodeToString(Any())
}
@@ -0,0 +1,8 @@
// "Replace with default Json format instance" "true"
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.json.Json as Alias
fun foo() {
<caret>Alias {}
}
@@ -0,0 +1,8 @@
// "Replace with default Json format instance" "true"
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.json.Json as Alias
fun foo() {
Alias
}