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.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("<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(
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))
}
@@ -14,7 +14,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
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> EXPLICIT_SERIALIZABLE_IS_REQUIRED = DiagnosticFactory0.create(WARNING);
@@ -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)
@@ -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,
@@ -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
}
}