Update error about unsupported inline classes

Remove unused declarations
This commit is contained in:
Leonid Startsev
2020-12-10 02:26:19 +03:00
parent 272273baed
commit a5ddb1fdf1
5 changed files with 46 additions and 46 deletions
@@ -7,49 +7,19 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor 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.*
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.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.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType 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.types.typeOrNull
import org.jetbrains.kotlin.ir.util.constructors 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.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
import org.jetbrains.kotlinx.serialization.compiler.resolve.* 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("<unsafe-coerce>")
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( class SerializerForInlineClassGenerator(
irClass: IrClass, irClass: IrClass,
compilerContext: SerializationPluginContext, 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) // 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 { private 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)) 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 { private fun IrBlockBodyBuilder.getFromBox(expression: IrExpression, serializableProperty: SerializableProperty): IrExpression =
return getProperty(expression, serializableProperty.irProp) getProperty(expression, serializableProperty.getIrPropertyFrom(serializableIrClass))
}
} }
@@ -14,7 +14,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
import static org.jetbrains.kotlin.diagnostics.Severity.WARNING; import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
public interface SerializationErrors { public interface SerializationErrors {
DiagnosticFactory0<PsiElement> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR); DiagnosticFactory2<PsiElement, String, String> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<PsiElement> PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0<PsiElement> PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> EXPLICIT_SERIALIZABLE_IS_REQUIRED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0<PsiElement> EXPLICIT_SERIALIZABLE_IS_REQUIRED = DiagnosticFactory0.create(WARNING);
@@ -123,10 +123,18 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
return false return false
} }
// if (descriptor.isInlineClass()) { if (descriptor.isInlineClass() && !canSupportInlineClasses(descriptor.module, trace)) {
// trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED) descriptor.onSerializableAnnotation {
// return false 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.hasSerializableAnnotationWithoutArgs) return false
if (descriptor.serializableAnnotationIsUseless) { if (descriptor.serializableAnnotationIsUseless) {
@@ -249,6 +257,11 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
private fun KotlinType.isUnsupportedInlineType() = isInlineClassType() && !KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType(this) 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( private fun AbstractSerialGenerator.checkType(
module: ModuleDescriptor, module: ModuleDescriptor,
type: KotlinType, type: KotlinType,
@@ -258,9 +271,13 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
) { ) {
if (type.genericIndex != null) return // type arguments always have serializer stored in class' field if (type.genericIndex != null) return // type arguments always have serializer stored in class' field
val element = ktType?.typeElement val element = ktType?.typeElement
// if (type.isUnsupportedInlineType()) { if (type.isUnsupportedInlineType() && !canSupportInlineClasses(module, trace)) {
// trace.report(SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED.on(element ?: fallbackElement)) trace.report(SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED.on(
// } element ?: fallbackElement,
VersionReader.minVersionForInlineClasses.toString(),
VersionReader.getVersionsForCurrentModuleFromTrace(module, trace)?.implementationVersion.toString()
))
}
val serializer = findTypeSerializerOrContextUnchecked(module, type) val serializer = findTypeSerializerOrContextUnchecked(module, type)
if (serializer != null) { if (serializer != null) {
checkCustomSerializerMatch(module, type, type, element, trace, fallbackElement) checkCustomSerializerMatch(module, type, type, element, trace, fallbackElement)
@@ -16,7 +16,9 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
init { init {
MAP.put( MAP.put(
SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED, 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( MAP.put(
SerializationErrors.PLUGIN_IS_NOT_ENABLED, SerializationErrors.PLUGIN_IS_NOT_ENABLED,
@@ -65,4 +65,13 @@ object VersionReader {
if (!file.exists()) return null if (!file.exists()) return null
return getVersionsFromManifest(file) 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
}
} }