From a5ddb1fdf13bfde6d973f6246cce1771623cad6e Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Thu, 10 Dec 2020 02:26:19 +0300 Subject: [PATCH] Update error about unsupported inline classes Remove unused declarations --- .../ir/SerializerForInlineClassGenerator.kt | 46 ++++--------------- .../diagnostic/SerializationErrors.java | 2 +- .../SerializationPluginDeclarationChecker.kt | 31 ++++++++++--- .../SerializationPluginErrorsRendering.kt | 4 +- .../compiler/diagnostic/VersionReader.kt | 9 ++++ 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt index 9e3785d6f5e..6ad6cce9d9c 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForInlineClassGenerator.kt @@ -7,49 +7,19 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.builders.declarations.addTypeParameter -import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter -import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.typeOrNull import org.jetbrains.kotlin.ir.util.constructors -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext import org.jetbrains.kotlinx.serialization.compiler.resolve.* -private fun SerializationPluginContext.coerceInlineClasses(argument: IrExpression, from: IrType, to: IrType): IrExpression { - if (this.platform?.isJvm() != true) return argument.apply { type = to } - val unsafeCoerce = irFactory.buildFun { - name = Name.special("") - origin = IrDeclarationOrigin.IR_BUILTINS_STUB - }.apply { - parent = IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment(moduleDescriptor, FqName("kotlin.jvm.internal")) - val src = addTypeParameter("T", irBuiltIns.anyNType) - val dst = addTypeParameter("R", irBuiltIns.anyNType) - addValueParameter("v", src.defaultType) - returnType = dst.defaultType - }.symbol - return IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, to, unsafeCoerce).apply { - putTypeArgument(0, from) - putTypeArgument(1, to) - putValueArgument(0, argument) - } -} - class SerializerForInlineClassGenerator( irClass: IrClass, compilerContext: SerializationPluginContext, @@ -129,14 +99,16 @@ class SerializerForInlineClassGenerator( ) } - // Compiler will elide these in corresponding inline class lowerings (when serialize/deserialize functions will be split in two) - fun IrBlockBodyBuilder.coerceToBox(expression: IrExpression, propertyType: IrType, inlineClassBoxType: IrType): IrExpression { - return irInvoke(null, serializableIrClass.constructors.single { it.isPrimary }.symbol, (inlineClassBoxType as IrSimpleType).arguments.map { it.typeOrNull }, listOf(expression)) - } + private fun IrBlockBodyBuilder.coerceToBox(expression: IrExpression, propertyType: IrType, inlineClassBoxType: IrType): IrExpression = + irInvoke( + null, + serializableIrClass.constructors.single { it.isPrimary }.symbol, + (inlineClassBoxType as IrSimpleType).arguments.map { it.typeOrNull }, + listOf(expression) + ) - fun IrBlockBodyBuilder.getFromBox(expression: IrExpression, serializableProperty: SerializableProperty): IrExpression { - return getProperty(expression, serializableProperty.irProp) - } + private fun IrBlockBodyBuilder.getFromBox(expression: IrExpression, serializableProperty: SerializableProperty): IrExpression = + getProperty(expression, serializableProperty.getIrPropertyFrom(serializableIrClass)) } \ No newline at end of file diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java index 54af6738761..abfe1313713 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java @@ -14,7 +14,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR; import static org.jetbrains.kotlin.diagnostics.Severity.WARNING; public interface SerializationErrors { - DiagnosticFactory0 INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR); + DiagnosticFactory2 INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 EXPLICIT_SERIALIZABLE_IS_REQUIRED = DiagnosticFactory0.create(WARNING); diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt index 6c45e5a74fd..9d9458fd1f0 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt @@ -123,10 +123,18 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker { return false } -// if (descriptor.isInlineClass()) { -// trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED) -// return false -// } + if (descriptor.isInlineClass() && !canSupportInlineClasses(descriptor.module, trace)) { + descriptor.onSerializableAnnotation { + trace.report( + SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED.on( + it, + VersionReader.minVersionForInlineClasses.toString(), + VersionReader.getVersionsForCurrentModuleFromTrace(descriptor.module, trace)?.implementationVersion.toString() + ) + ) + } + return false + } if (!descriptor.hasSerializableAnnotationWithoutArgs) return false if (descriptor.serializableAnnotationIsUseless) { @@ -249,6 +257,11 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker { private fun KotlinType.isUnsupportedInlineType() = isInlineClassType() && !KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType(this) + private fun canSupportInlineClasses(module: ModuleDescriptor, trace: BindingTrace): Boolean { + if (isIde) return true // do not get version from jar manifest in ide + return VersionReader.canSupportInlineClasses(module, trace) + } + private fun AbstractSerialGenerator.checkType( module: ModuleDescriptor, type: KotlinType, @@ -258,9 +271,13 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker { ) { if (type.genericIndex != null) return // type arguments always have serializer stored in class' field val element = ktType?.typeElement -// if (type.isUnsupportedInlineType()) { -// trace.report(SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED.on(element ?: fallbackElement)) -// } + if (type.isUnsupportedInlineType() && !canSupportInlineClasses(module, trace)) { + trace.report(SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED.on( + element ?: fallbackElement, + VersionReader.minVersionForInlineClasses.toString(), + VersionReader.getVersionsForCurrentModuleFromTrace(module, trace)?.implementationVersion.toString() + )) + } val serializer = findTypeSerializerOrContextUnchecked(module, type) if (serializer != null) { checkCustomSerializerMatch(module, type, type, element, trace, fallbackElement) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt index 185a9e8ff24..f561aba2015 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt @@ -16,7 +16,9 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension { init { MAP.put( SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED, - "Inline classes are not supported by kotlinx.serialization yet" + "Inline classes require runtime serialization library version at least {0}, while your classpath has {1}.", + Renderers.STRING, + Renderers.STRING, ) MAP.put( SerializationErrors.PLUGIN_IS_NOT_ENABLED, diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/VersionReader.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/VersionReader.kt index 22137b76b2f..529952317c3 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/VersionReader.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/VersionReader.kt @@ -65,4 +65,13 @@ object VersionReader { if (!file.exists()) return null return getVersionsFromManifest(file) } + + internal val minVersionForInlineClasses = ApiVersion.parse("1.1-M1-SNAPSHOT")!! + + fun canSupportInlineClasses(module: ModuleDescriptor, trace: BindingTrace): Boolean { + // Klibs do not have manifest file, unfortunately, so we hope for the better + val currentVersion = getVersionsForCurrentModuleFromTrace(module, trace) ?: return true + val implVersion = currentVersion.implementationVersion ?: return false + return implVersion >= minVersionForInlineClasses + } }