[Psi2Ir, Fir2Ir] Generate toString, hashCode, equals methods for MF VC
This commit is contained in:
committed by
Space
parent
c7edc353d3
commit
e97ca2ada4
+2
-5
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irString
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
@@ -91,7 +88,7 @@ interface InlineClassesUtils {
|
||||
/**
|
||||
* Should this class be treated as inline class?
|
||||
*/
|
||||
fun isClassInlineLike(klass: IrClass): Boolean = klass.isInline
|
||||
fun isClassInlineLike(klass: IrClass): Boolean = klass.isSingleFieldValueClass
|
||||
|
||||
/**
|
||||
* Unlike [org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType], doesn't use [IrClass.inlineClassRepresentation] because
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ internal fun IrFactory.buildClass(builder: IrClassBuilder): IrClass = with(build
|
||||
startOffset, endOffset, origin,
|
||||
IrClassSymbolImpl(),
|
||||
name, kind, visibility, modality,
|
||||
isCompanion, isInner, isData, isExternal, isInline, isExpect, isFun
|
||||
isCompanion, isInner, isData, isExternal, isValue, isExpect, isFun
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -211,7 +211,7 @@ class ExportModelGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
if (klass.isInline)
|
||||
if (klass.isSingleFieldValueClass)
|
||||
return Exportability.Prohibited("Inline class ${klass.fqNameWhenAvailable}")
|
||||
|
||||
return Exportability.Allowed
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
isBuiltin() && this != PrimitiveType.FLOATING_POINT_NUMBER
|
||||
|
||||
private fun IrType.isDefaultEqualsMethod() =
|
||||
findEqualsMethod()?.origin === IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER
|
||||
findEqualsMethod()?.origin === IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER
|
||||
|
||||
private fun IrExpression.isBoxIntrinsic() =
|
||||
this is IrCall && symbol == icUtils.boxIntrinsic
|
||||
|
||||
+4
-2
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -125,7 +127,7 @@ private fun IrSimpleFunction.overridesReturningDifferentType(returnType: IrType)
|
||||
val owner = overridden.owner
|
||||
val overriddenReturnType = owner.returnType
|
||||
|
||||
if (!overriddenReturnType.erasedUpperBound.isInline) return true
|
||||
if (!overriddenReturnType.erasedUpperBound.isSingleFieldValueClass) return true
|
||||
|
||||
if (overriddenReturnType.isNullable() &&
|
||||
overriddenReturnType.makeNotNull().unboxInlineClass().isNullable()
|
||||
|
||||
+1
-1
@@ -1473,7 +1473,7 @@ class ExpressionCodegen(
|
||||
companion object {
|
||||
internal fun generateClassInstance(v: InstructionAdapter, classType: IrType, typeMapper: IrTypeMapper) {
|
||||
val asmType = typeMapper.mapType(classType)
|
||||
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
||||
if (classType.getClass()?.isSingleFieldValueClass == true || !isPrimitive(asmType)) {
|
||||
v.aconst(typeMapper.boxType(classType))
|
||||
} else {
|
||||
v.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
|
||||
+1
-1
@@ -318,7 +318,7 @@ class FunctionCodegen(private val irFunction: IrFunction, private val classCodeg
|
||||
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
|
||||
IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER,
|
||||
IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER,
|
||||
IrDeclarationOrigin.BRIDGE,
|
||||
IrDeclarationOrigin.BRIDGE_SPECIAL,
|
||||
JvmLoweredDeclarationOrigin.ABSTRACT_BRIDGE_STUB,
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.mapping.IrTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
@@ -42,7 +43,7 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
|
||||
if (!isFromTypeUnboxed && isToTypeUnboxed) {
|
||||
val boxed = typeMapper.mapType(erasedTargetType, TypeMappingMode.CLASS_DECLARATION)
|
||||
val irClass = codegen.irFunction.parentAsClass
|
||||
if (irClass.isInline && irClass.symbol == irType.classifierOrNull && !irType.isNullable()) {
|
||||
if (irClass.isSingleFieldValueClass && irClass.symbol == irType.classifierOrNull && !irType.isNullable()) {
|
||||
// Use getfield instead of unbox-impl inside inline classes
|
||||
codegen.mv.getfield(boxed.internalName, irClass.inlineClassFieldName.asString(), target.descriptor)
|
||||
} else {
|
||||
|
||||
+1
-6
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.ir.allOverridden
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
@@ -27,14 +26,11 @@ import org.jetbrains.kotlin.codegen.SourceInfo
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
@@ -45,7 +41,6 @@ import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -166,7 +161,7 @@ private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?):
|
||||
return Opcodes.ACC_PUBLIC
|
||||
}
|
||||
|
||||
if (this is IrConstructor && parentAsClass.isInline && kind === OwnerKind.IMPLEMENTATION) {
|
||||
if (this is IrConstructor && parentAsClass.isSingleFieldValueClass && kind === OwnerKind.IMPLEMENTATION) {
|
||||
return Opcodes.ACC_PRIVATE
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genAreEqualCall
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
@@ -70,7 +71,7 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
if (a.isNullConst() || b.isNullConst()) {
|
||||
val irValue = if (a.isNullConst()) b else a
|
||||
val value = irValue.accept(codegen, data)
|
||||
return if (!isPrimitive(value.type) && (irValue.type.classOrNull?.owner?.isInline != true || irValue.type.isNullable()))
|
||||
return if (!isPrimitive(value.type) && (irValue.type.classOrNull?.owner?.isSingleFieldValueClass != true || irValue.type.isNullable()))
|
||||
BooleanNullCheck(value)
|
||||
else {
|
||||
value.discard()
|
||||
|
||||
+2
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.materialize
|
||||
import org.jetbrains.kotlin.backend.jvm.mapping.mapTypeAsDeclaration
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetClass
|
||||
@@ -76,7 +77,7 @@ object GetJavaPrimitiveType : IntrinsicMethod() {
|
||||
}
|
||||
|
||||
private fun IrType.isInlineClassType(): Boolean {
|
||||
return (classOrNull ?: return false).owner.isInline
|
||||
return (classOrNull ?: return false).owner.isSingleFieldValueClass
|
||||
}
|
||||
|
||||
private fun Type.isVoidOrPrimitiveWrapper(): Boolean =
|
||||
|
||||
+2
-1
@@ -37,7 +37,8 @@ object HashCode : IntrinsicMethod() {
|
||||
val target = context.state.target
|
||||
when {
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> {
|
||||
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ||
|
||||
irFunction.origin == IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER -> {
|
||||
// TODO generate or lower IR for data class / inline class 'hashCode'?
|
||||
DescriptorAsmUtil.genHashCode(mv, mv, receiverType, target)
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.boxType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -33,7 +34,7 @@ object JavaClassProperty : IntrinsicMethod() {
|
||||
when {
|
||||
value.type == Type.VOID_TYPE ->
|
||||
invokeGetClass(value.materializedAt(AsmTypes.UNIT_TYPE, value.codegen.context.irBuiltIns.unitType))
|
||||
value.irType.classOrNull?.owner?.isInline == true ->
|
||||
value.irType.classOrNull?.owner?.isSingleFieldValueClass == true ->
|
||||
invokeGetClass(value.materializedAtBoxed(value.irType))
|
||||
isPrimitive(value.type) -> {
|
||||
value.discard()
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
|
||||
bridgeTargets.forEach { createBridges(declaration, it) }
|
||||
|
||||
if (declaration.isInline) {
|
||||
if (declaration.isSingleFieldValueClass) {
|
||||
// Inline class (implementing 'MutableCollection<T>', where T is Int or an inline class mapped to Int)
|
||||
// can contain a static replacement for a function 'remove', which forces value parameter boxing
|
||||
// in order to avoid signature clash with 'remove(int)' method in 'java.util.List'.
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||
import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.hasDefaultValue
|
||||
|
||||
@@ -37,7 +38,7 @@ internal val jvmDefaultConstructorPhase = makeIrFilePhase(
|
||||
private class JvmDefaultConstructorLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (irClass.kind != ClassKind.CLASS || irClass.visibility == DescriptorVisibilities.LOCAL || irClass.isInline || irClass.isInner ||
|
||||
if (irClass.kind != ClassKind.CLASS || irClass.visibility == DescriptorVisibilities.LOCAL || irClass.isSingleFieldValueClass || irClass.isInner ||
|
||||
irClass.modality == Modality.SEALED
|
||||
)
|
||||
return
|
||||
|
||||
+6
-6
@@ -85,7 +85,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.isInline) {
|
||||
if (declaration.isSingleFieldValueClass) {
|
||||
val irConstructor = declaration.primaryConstructor!!
|
||||
// The field getter is used by reflection and cannot be removed here unless it is internal.
|
||||
declaration.declarations.removeIf {
|
||||
@@ -111,7 +111,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
}
|
||||
|
||||
private fun transformFunctionFlat(function: IrFunction): List<IrDeclaration>? {
|
||||
if (function is IrConstructor && function.isPrimary && function.constructedClass.isInline)
|
||||
if (function is IrConstructor && function.isPrimary && function.constructedClass.isSingleFieldValueClass)
|
||||
return null
|
||||
|
||||
val replacement = context.inlineClassReplacements.getReplacementFunction(function)
|
||||
@@ -166,7 +166,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
bridgeFunction.overriddenSymbols = replacement.overriddenSymbols
|
||||
|
||||
// Replace the function body with a wrapper
|
||||
if (!bridgeFunction.isFakeOverride || !bridgeFunction.parentAsClass.isInline) {
|
||||
if (!bridgeFunction.isFakeOverride || !bridgeFunction.parentAsClass.isSingleFieldValueClass) {
|
||||
createBridgeBody(bridgeFunction, replacement)
|
||||
} else {
|
||||
// Fake overrides redirect from the replacement to the original function, which is in turn replaced during interfacePhase.
|
||||
@@ -417,7 +417,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
if (symbol != context.irBuiltIns.eqeqSymbol)
|
||||
return false
|
||||
|
||||
val leftClass = getValueArgument(0)?.type?.classOrNull?.owner?.takeIf { it.isInline }
|
||||
val leftClass = getValueArgument(0)?.type?.classOrNull?.owner?.takeIf { it.isSingleFieldValueClass }
|
||||
?: return false
|
||||
|
||||
// Before version 1.4, we cannot rely on the Result.equals-impl0 method
|
||||
@@ -430,7 +430,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
val parent = field.parent
|
||||
if (field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD &&
|
||||
parent is IrClass &&
|
||||
parent.isInline &&
|
||||
parent.isSingleFieldValueClass &&
|
||||
field.name == parent.inlineClassFieldName) {
|
||||
val receiver = expression.receiver!!.transform(this, null)
|
||||
return coerceInlineClasses(receiver, receiver.type, field.type)
|
||||
@@ -492,7 +492,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
|
||||
// Anonymous initializers in inline classes are processed when building the primary constructor.
|
||||
override fun visitAnonymousInitializerNew(declaration: IrAnonymousInitializer): IrStatement {
|
||||
if (declaration.parent.safeAs<IrClass>()?.isInline == true)
|
||||
if (declaration.parent.safeAs<IrClass>()?.isSingleFieldValueClass == true)
|
||||
return declaration
|
||||
return super.visitAnonymousInitializerNew(declaration)
|
||||
}
|
||||
|
||||
-1
@@ -256,7 +256,6 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext, val inner
|
||||
name = Name.identifier("RunnerKt")
|
||||
kind = ClassKind.CLASS
|
||||
modality = Modality.FINAL
|
||||
isInline = false
|
||||
}.apply {
|
||||
parent = scriptingJvmPackage
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
|
||||
+1
-1
@@ -369,7 +369,7 @@ private class SyntheticAccessorTransformer(
|
||||
|
||||
val constructedClass = constructedClass
|
||||
|
||||
if (!DescriptorVisibilities.isPrivate(visibility) && !constructedClass.isInline && hasMangledParameters &&
|
||||
if (!DescriptorVisibilities.isPrivate(visibility) && !constructedClass.isSingleFieldValueClass && hasMangledParameters &&
|
||||
!constructedClass.isAnonymousObject
|
||||
) return true
|
||||
|
||||
|
||||
+2
-2
@@ -577,7 +577,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
||||
// All Kotlin inline classes are final,
|
||||
// and their supertypes are trivially mapped to reference types.
|
||||
val erasedAdapteeClass = getErasedClassForSignatureAdaptation(adapteeType)
|
||||
if (erasedAdapteeClass.isInline) {
|
||||
if (erasedAdapteeClass.isSingleFieldValueClass) {
|
||||
// Inline classes mapped to non-null reference types are a special case because they can't be boxed trivially.
|
||||
// TODO consider adding a special type annotation to force boxing on an inline class type regardless of its underlying type.
|
||||
val underlyingAdapteeType = getInlineClassUnderlyingType(erasedAdapteeClass)
|
||||
@@ -586,7 +586,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
||||
}
|
||||
|
||||
val erasedExpectedClass = getErasedClassForSignatureAdaptation(expectedType)
|
||||
return if (erasedExpectedClass.isInline) {
|
||||
return if (erasedExpectedClass.isSingleFieldValueClass) {
|
||||
// LambdaMetafactory doesn't know about method mangling.
|
||||
TypeAdaptationConstraint.CONFLICT
|
||||
} else {
|
||||
|
||||
@@ -57,7 +57,7 @@ object InlineClassAbi {
|
||||
fun mangledNameFor(irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): Name {
|
||||
if (irFunction is IrConstructor) {
|
||||
// Note that we might drop this convention and use standard mangling for constructors too, see KT-37186.
|
||||
assert(irFunction.constructedClass.isInline) {
|
||||
assert(irFunction.constructedClass.isSingleFieldValueClass) {
|
||||
"Should not mangle names of non-inline class constructors: ${irFunction.render()}"
|
||||
}
|
||||
return Name.identifier("constructor-impl")
|
||||
@@ -69,7 +69,7 @@ object InlineClassAbi {
|
||||
irFunction.returnType.takeIf { mangleReturnTypes && irFunction.hasMangledReturnType },
|
||||
irFunction.isSuspend
|
||||
)
|
||||
if (suffix == null && ((irFunction.parent as? IrClass)?.isInline != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) {
|
||||
if (suffix == null && ((irFunction.parent as? IrClass)?.isSingleFieldValueClass != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) {
|
||||
return irFunction.name
|
||||
}
|
||||
|
||||
@@ -121,16 +121,16 @@ object InlineClassAbi {
|
||||
val IrType.requiresMangling: Boolean
|
||||
get() {
|
||||
val irClass = erasedUpperBound
|
||||
return irClass.isInline && irClass.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME
|
||||
return irClass.isSingleFieldValueClass && irClass.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME
|
||||
}
|
||||
|
||||
val IrFunction.fullValueParameterList: List<IrValueParameter>
|
||||
get() = listOfNotNull(extensionReceiverParameter) + valueParameters
|
||||
|
||||
val IrFunction.hasMangledParameters: Boolean
|
||||
get() = dispatchReceiverParameter != null && parentAsClass.isInline ||
|
||||
get() = dispatchReceiverParameter != null && parentAsClass.isSingleFieldValueClass ||
|
||||
fullValueParameterList.any { it.type.requiresMangling } ||
|
||||
(this is IrConstructor && constructedClass.isInline)
|
||||
(this is IrConstructor && constructedClass.isSingleFieldValueClass)
|
||||
|
||||
val IrFunction.hasMangledReturnType: Boolean
|
||||
get() = returnType.isInlineClassType() && parentClassOrNull?.isFileClass != true
|
||||
@@ -139,5 +139,5 @@ val IrClass.inlineClassFieldName: Name
|
||||
get() = (inlineClassRepresentation ?: error("Not an inline class: ${render()}")).underlyingPropertyName
|
||||
|
||||
val IrFunction.isInlineClassFieldGetter: Boolean
|
||||
get() = (parent as? IrClass)?.isInline == true && this is IrSimpleFunction && extensionReceiverParameter == null &&
|
||||
get() = (parent as? IrClass)?.isSingleFieldValueClass == true && this is IrSimpleFunction && extensionReceiverParameter == null &&
|
||||
correspondingPropertySymbol?.let { it.owner.getter == this && it.owner.name == parentAsClass.inlineClassFieldName } == true
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -131,14 +130,14 @@ class JvmReflectSymbols(val context: JvmBackendContext) {
|
||||
fqName: FqName,
|
||||
classKind: ClassKind = ClassKind.CLASS,
|
||||
classModality: Modality = Modality.FINAL,
|
||||
classIsInline: Boolean = false,
|
||||
classIsValue: Boolean = false,
|
||||
block: (IrClass) -> Unit = {}
|
||||
): IrClassSymbol =
|
||||
context.irFactory.buildClass {
|
||||
name = fqName.shortName()
|
||||
kind = classKind
|
||||
modality = classModality
|
||||
isInline = classIsInline
|
||||
isValue = classIsValue
|
||||
}.apply {
|
||||
parent = javaLangReflectPackage
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
|
||||
@@ -84,14 +84,14 @@ class JvmSymbols(
|
||||
fqName: FqName,
|
||||
classKind: ClassKind = ClassKind.CLASS,
|
||||
classModality: Modality = Modality.FINAL,
|
||||
classIsInline: Boolean = false,
|
||||
classIsValue: Boolean = false,
|
||||
block: (IrClass) -> Unit = {}
|
||||
): IrClassSymbol =
|
||||
irFactory.buildClass {
|
||||
name = fqName.shortName()
|
||||
kind = classKind
|
||||
modality = classModality
|
||||
isInline = classIsInline
|
||||
isValue = classIsValue
|
||||
}.apply {
|
||||
parent = when (fqName.parent().asString()) {
|
||||
"kotlin" -> kotlinPackage
|
||||
@@ -271,7 +271,7 @@ class JvmSymbols(
|
||||
}
|
||||
|
||||
private val resultClassStub: IrClassSymbol =
|
||||
createClass(StandardNames.RESULT_FQ_NAME, classIsInline = true) { klass ->
|
||||
createClass(StandardNames.RESULT_FQ_NAME, classIsValue = true) { klass ->
|
||||
klass.addTypeParameter("T", irBuiltIns.anyNType, Variance.OUT_VARIANCE)
|
||||
klass.inlineClassRepresentation = InlineClassRepresentation(Name.identifier("value"), irBuiltIns.anyNType as IrSimpleType)
|
||||
}
|
||||
|
||||
+7
-7
@@ -63,7 +63,7 @@ class MemoizedInlineClassReplacements(
|
||||
null
|
||||
|
||||
// Mangle all functions in the body of an inline class
|
||||
it.parent.safeAs<IrClass>()?.isInline == true ->
|
||||
it.parent.safeAs<IrClass>()?.isSingleFieldValueClass == true ->
|
||||
when {
|
||||
it.isRemoveAtSpecialBuiltinStub() ->
|
||||
null
|
||||
@@ -93,7 +93,7 @@ class MemoizedInlineClassReplacements(
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (!this.isFakeOverride) return false
|
||||
val parentClass = parentClassOrNull ?: return false
|
||||
if (!parentClass.isInline) return false
|
||||
if (!parentClass.isSingleFieldValueClass) return false
|
||||
|
||||
val overridden = resolveFakeOverride() ?: return false
|
||||
if (!overridden.parentAsClass.isJvmInterface) return false
|
||||
@@ -113,7 +113,7 @@ class MemoizedInlineClassReplacements(
|
||||
*/
|
||||
val getBoxFunction: (IrClass) -> IrSimpleFunction =
|
||||
storageManager.createMemoizedFunction { irClass ->
|
||||
require(irClass.isInline)
|
||||
require(irClass.isSingleFieldValueClass)
|
||||
irFactory.buildFun {
|
||||
name = Name.identifier(KotlinTypeMapper.BOX_JVM_METHOD_NAME)
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_INLINE_CLASS_MEMBER
|
||||
@@ -134,7 +134,7 @@ class MemoizedInlineClassReplacements(
|
||||
*/
|
||||
val getUnboxFunction: (IrClass) -> IrSimpleFunction =
|
||||
storageManager.createMemoizedFunction { irClass ->
|
||||
require(irClass.isInline)
|
||||
require(irClass.isSingleFieldValueClass)
|
||||
irFactory.buildFun {
|
||||
name = Name.identifier(KotlinTypeMapper.UNBOX_JVM_METHOD_NAME)
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_INLINE_CLASS_MEMBER
|
||||
@@ -147,7 +147,7 @@ class MemoizedInlineClassReplacements(
|
||||
|
||||
private val specializedEqualsCache = storageManager.createCacheWithNotNullValues<IrClass, IrSimpleFunction>()
|
||||
fun getSpecializedEqualsMethod(irClass: IrClass, irBuiltIns: IrBuiltIns): IrSimpleFunction {
|
||||
require(irClass.isInline)
|
||||
require(irClass.isSingleFieldValueClass)
|
||||
return specializedEqualsCache.computeIfAbsent(irClass) {
|
||||
irFactory.buildFun {
|
||||
name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
|
||||
@@ -257,9 +257,9 @@ class MemoizedInlineClassReplacements(
|
||||
modality = Modality.OPEN
|
||||
}
|
||||
origin = when {
|
||||
function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER ->
|
||||
function.origin == IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER ->
|
||||
JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD
|
||||
function is IrConstructor && function.constructedClass.isInline ->
|
||||
function is IrConstructor && function.constructedClass.isSingleFieldValueClass ->
|
||||
JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR
|
||||
else ->
|
||||
replacementOrigin
|
||||
|
||||
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.ir
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.unboxInlineClass
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrScript
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
@@ -106,7 +103,7 @@ fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendCon
|
||||
return classifier.owner.representativeUpperBound.defaultValue(startOffset, endOffset, context)
|
||||
}
|
||||
|
||||
if (this !is IrSimpleType || hasQuestionMark || classOrNull?.owner?.isInline != true)
|
||||
if (this !is IrSimpleType || hasQuestionMark || classOrNull?.owner?.isSingleFieldValueClass != true)
|
||||
return IrConstImpl.defaultValueForType(startOffset, endOffset, this)
|
||||
|
||||
val underlyingType = unboxInlineClass()
|
||||
@@ -119,7 +116,7 @@ fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendCon
|
||||
}
|
||||
|
||||
fun IrType.isInlineClassType(): Boolean =
|
||||
erasedUpperBound.isInline
|
||||
erasedUpperBound.isSingleFieldValueClass
|
||||
|
||||
val IrType.upperBound: IrType
|
||||
get() = erasedUpperBound.symbol.starProjectedType
|
||||
|
||||
+2
-5
@@ -17,10 +17,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
@@ -121,7 +118,7 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
|
||||
|
||||
fun boxType(irType: IrType): Type {
|
||||
val irClass = irType.classOrNull?.owner
|
||||
if (irClass != null && irClass.isInline) {
|
||||
if (irClass != null && irClass.isSingleFieldValueClass) {
|
||||
return mapTypeAsDeclaration(irType)
|
||||
}
|
||||
val type = AbstractTypeMapper.mapType(this, irType)
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
}
|
||||
|
||||
private fun isBoxMethodForInlineClass(function: IrFunction): Boolean =
|
||||
function.parent.let { it is IrClass && it.isInline } &&
|
||||
function.parent.let { it is IrClass && it.isSingleFieldValueClass } &&
|
||||
function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_INLINE_CLASS_MEMBER &&
|
||||
function.name.asString() == "box-impl"
|
||||
|
||||
|
||||
+1
-2
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.ir.expressions.IrSetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
@@ -151,7 +150,7 @@ class WasmSharedVariablesManager(val context: JsCommonBackendContext, val builtI
|
||||
isInner = false
|
||||
isData = false
|
||||
isExternal = false
|
||||
isInline = false
|
||||
isValue = false
|
||||
isExpect = false
|
||||
isFun = false
|
||||
}
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ internal class KClassProxy(
|
||||
override val isFun: Boolean
|
||||
get() = state.classReference.isFun
|
||||
override val isValue: Boolean
|
||||
get() = state.classReference.isInline
|
||||
get() = state.classReference.isValue
|
||||
|
||||
override fun isInstance(value: Any?): Boolean {
|
||||
verify(value is State) { "Cannot interpret `isInstance` method for $value" }
|
||||
|
||||
+12
-10
@@ -20,10 +20,6 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
||||
@@ -41,7 +37,6 @@ import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET
|
||||
import org.jetbrains.kotlin.ir.util.createIrClassFromDescriptor
|
||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
||||
import org.jetbrains.kotlin.ir.util.properties
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
||||
@@ -55,7 +50,6 @@ import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DelegationResolver
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
|
||||
@@ -112,19 +106,23 @@ class ClassGenerator(
|
||||
|
||||
generateFakeOverrideMemberDeclarations(irClass, ktClassOrObject)
|
||||
|
||||
if (irClass.isInline && ktClassOrObject is KtClassOrObject) {
|
||||
if (irClass.isSingleFieldValueClass && ktClassOrObject is KtClassOrObject) {
|
||||
val representation = classDescriptor.inlineClassRepresentation
|
||||
?: error("Unknown representation for inline class: $classDescriptor")
|
||||
irClass.inlineClassRepresentation = representation.mapUnderlyingType { type ->
|
||||
type.toIrType() as? IrSimpleType ?: error("Inline class underlying type is not a simple type: $classDescriptor")
|
||||
}
|
||||
generateAdditionalMembersForInlineClasses(irClass, ktClassOrObject)
|
||||
generateAdditionalMembersForSingleFieldValueClasses(irClass, ktClassOrObject)
|
||||
}
|
||||
|
||||
if (irClass.isData && ktClassOrObject is KtClassOrObject) {
|
||||
generateAdditionalMembersForDataClass(irClass, ktClassOrObject)
|
||||
}
|
||||
|
||||
if (irClass.isMultiFieldValueClass && ktClassOrObject is KtClassOrObject) {
|
||||
generateAdditionalMembersForMultiFieldValueClasses(irClass, ktClassOrObject)
|
||||
}
|
||||
|
||||
if (DescriptorUtils.isEnumClass(classDescriptor)) {
|
||||
generateAdditionalMembersForEnumClass(irClass)
|
||||
}
|
||||
@@ -422,8 +420,12 @@ class ClassGenerator(
|
||||
return typeArguments
|
||||
}
|
||||
|
||||
private fun generateAdditionalMembersForInlineClasses(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
DataClassMembersGenerator(declarationGenerator).generateInlineClassMembers(ktClassOrObject, irClass)
|
||||
private fun generateAdditionalMembersForSingleFieldValueClasses(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
DataClassMembersGenerator(declarationGenerator).generateSingleFieldValueClassMembers(ktClassOrObject, irClass)
|
||||
}
|
||||
|
||||
private fun generateAdditionalMembersForMultiFieldValueClasses(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
DataClassMembersGenerator(declarationGenerator).generateMultiFieldValueClassMembers(ktClassOrObject, irClass)
|
||||
}
|
||||
|
||||
private fun generateAdditionalMembersForDataClass(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
|
||||
+6
-2
@@ -45,8 +45,12 @@ class DataClassMembersGenerator(
|
||||
declarationGenerator: DeclarationGenerator
|
||||
) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
|
||||
fun generateInlineClassMembers(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
|
||||
MyDataClassMethodGenerator(ktClassOrObject, irClass, IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER).generate()
|
||||
fun generateSingleFieldValueClassMembers(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
|
||||
MyDataClassMethodGenerator(ktClassOrObject, irClass, IrDeclarationOrigin.GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER).generate()
|
||||
}
|
||||
|
||||
fun generateMultiFieldValueClassMembers(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
|
||||
MyDataClassMethodGenerator(ktClassOrObject, irClass, IrDeclarationOrigin.GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER).generate()
|
||||
}
|
||||
|
||||
fun generateDataClassMembers(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ open class IrClassImpl(
|
||||
override var isInner: Boolean = false,
|
||||
override val isData: Boolean = false,
|
||||
override val isExternal: Boolean = false,
|
||||
override val isInline: Boolean = false,
|
||||
override val isValue: Boolean = false,
|
||||
override val isExpect: Boolean = false,
|
||||
override val isFun: Boolean = false,
|
||||
override val source: SourceElement = SourceElement.NO_SOURCE,
|
||||
|
||||
+2
-2
@@ -47,14 +47,14 @@ abstract class AbstractIrFactoryImpl : IrFactory {
|
||||
isInner: Boolean,
|
||||
isData: Boolean,
|
||||
isExternal: Boolean,
|
||||
isInline: Boolean,
|
||||
isValue: Boolean,
|
||||
isExpect: Boolean,
|
||||
isFun: Boolean,
|
||||
source: SourceElement,
|
||||
): IrClass =
|
||||
IrClassImpl(
|
||||
startOffset, endOffset, origin, symbol, name, kind, visibility, modality,
|
||||
isCompanion, isInner, isData, isExternal, isInline, isExpect, isFun, source,
|
||||
isCompanion, isInner, isData, isExternal, isValue, isExpect, isFun, source,
|
||||
factory = this
|
||||
)
|
||||
|
||||
|
||||
+2
-2
@@ -58,7 +58,7 @@ class IrFactoryImplForJsIC(override val stageController: StageController) : Abst
|
||||
isInner: Boolean,
|
||||
isData: Boolean,
|
||||
isExternal: Boolean,
|
||||
isInline: Boolean,
|
||||
isValue: Boolean,
|
||||
isExpect: Boolean,
|
||||
isFun: Boolean,
|
||||
source: SourceElement
|
||||
@@ -76,7 +76,7 @@ class IrFactoryImplForJsIC(override val stageController: StageController) : Abst
|
||||
isInner,
|
||||
isData,
|
||||
isExternal,
|
||||
isInline,
|
||||
isValue,
|
||||
isExpect,
|
||||
isFun,
|
||||
source,
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ class IrClassBuilder : IrDeclarationBuilder() {
|
||||
var isInner: Boolean = false
|
||||
var isData: Boolean = false
|
||||
var isExternal: Boolean = false
|
||||
var isInline: Boolean = false
|
||||
var isValue: Boolean = false
|
||||
var isExpect: Boolean = false
|
||||
var isFun: Boolean = false
|
||||
|
||||
@@ -30,7 +30,7 @@ class IrClassBuilder : IrDeclarationBuilder() {
|
||||
isInner = from.isInner
|
||||
isData = from.isData
|
||||
isExternal = from.isExternal
|
||||
isInline = from.isInline
|
||||
isValue = from.isValue
|
||||
isExpect = from.isExpect
|
||||
isFun = from.isFun
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.transformInPlace
|
||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
||||
import org.jetbrains.kotlin.ir.util.transformIfNeeded
|
||||
import org.jetbrains.kotlin.ir.util.transformInPlace
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
@@ -39,7 +40,7 @@ abstract class IrClass :
|
||||
abstract val isCompanion: Boolean
|
||||
abstract val isInner: Boolean
|
||||
abstract val isData: Boolean
|
||||
abstract val isInline: Boolean
|
||||
abstract val isValue: Boolean
|
||||
abstract val isExpect: Boolean
|
||||
abstract val isFun: Boolean
|
||||
|
||||
@@ -69,6 +70,12 @@ abstract class IrClass :
|
||||
}
|
||||
}
|
||||
|
||||
val IrClass.isSingleFieldValueClass
|
||||
get() = this.isValue && (this.inlineClassRepresentation != null || this.primaryConstructor?.valueParameters?.size == 1)
|
||||
|
||||
val IrClass.isMultiFieldValueClass
|
||||
get() = this.isValue && !isSingleFieldValueClass
|
||||
|
||||
fun IrClass.addMember(member: IrDeclaration) {
|
||||
declarations.add(member)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ interface IrDeclarationOrigin {
|
||||
object SCRIPT_PROVIDED_PROPERTY : IrDeclarationOriginImpl("SCRIPT_PROVIDED_PROPERTY")
|
||||
object SCRIPT_RESULT_PROPERTY : IrDeclarationOriginImpl("SCRIPT_RESULT_PROPERTY")
|
||||
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
|
||||
object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER")
|
||||
object GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_SINGLE_FIELD_VALUE_CLASS_MEMBER")
|
||||
object GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_MULTI_FIELD_VALUE_CLASS_MEMBER")
|
||||
object LOCAL_FUNCTION : IrDeclarationOriginImpl("LOCAL_FUNCTION")
|
||||
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
|
||||
object CATCH_PARAMETER : IrDeclarationOriginImpl("CATCH_PARAMETER")
|
||||
|
||||
@@ -40,7 +40,7 @@ interface IrFactory {
|
||||
isInner: Boolean = false,
|
||||
isData: Boolean = false,
|
||||
isExternal: Boolean = false,
|
||||
isInline: Boolean = false,
|
||||
isValue: Boolean = false,
|
||||
isExpect: Boolean = false,
|
||||
isFun: Boolean = false,
|
||||
source: SourceElement = SourceElement.NO_SOURCE,
|
||||
|
||||
@@ -33,7 +33,7 @@ class IrLazyClass(
|
||||
override val isInner: Boolean,
|
||||
override val isData: Boolean,
|
||||
override val isExternal: Boolean,
|
||||
override val isInline: Boolean,
|
||||
override val isValue: Boolean,
|
||||
override val isExpect: Boolean,
|
||||
override val isFun: Boolean,
|
||||
override val stubGenerator: DeclarationStubGenerator,
|
||||
|
||||
@@ -33,7 +33,7 @@ class LazyIrFactory(
|
||||
isInner: Boolean,
|
||||
isData: Boolean,
|
||||
isExternal: Boolean,
|
||||
isInline: Boolean,
|
||||
isValue: Boolean,
|
||||
isExpect: Boolean,
|
||||
isFun: Boolean,
|
||||
source: SourceElement
|
||||
@@ -42,7 +42,7 @@ class LazyIrFactory(
|
||||
else
|
||||
delegate.createClass(
|
||||
startOffset, endOffset, origin, symbol, name, kind, visibility, modality,
|
||||
isCompanion, isInner, isData, isExternal, isInline, isExpect, isFun, source
|
||||
isCompanion, isInner, isData, isExternal, isValue, isExpect, isFun, source
|
||||
)
|
||||
|
||||
override fun createConstructor(
|
||||
|
||||
@@ -604,12 +604,11 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl
|
||||
|
||||
override fun isData() = owner.isData
|
||||
|
||||
override fun isInline() = owner.isInline
|
||||
override fun isInline() = owner.isSingleFieldValueClass
|
||||
|
||||
override fun isFun() = owner.isFun
|
||||
|
||||
// In IR, inline and value are synonyms
|
||||
override fun isValue() = owner.isInline
|
||||
override fun isValue() = owner.isValue
|
||||
|
||||
override fun getThisAsReceiverParameter() = owner.thisReceiver?.toIrBasedDescriptor() as ReceiverParameterDescriptor
|
||||
|
||||
|
||||
@@ -457,7 +457,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
this as? IrTypeParameterSymbol
|
||||
|
||||
override fun TypeConstructorMarker.isInlineClass(): Boolean =
|
||||
(this as? IrClassSymbol)?.owner?.isInline == true
|
||||
(this as? IrClassSymbol)?.owner?.isSingleFieldValueClass == true
|
||||
|
||||
override fun TypeConstructorMarker.isInnerClass(): Boolean =
|
||||
(this as? IrClassSymbol)?.owner?.isInner == true
|
||||
|
||||
@@ -128,7 +128,7 @@ abstract class DataClassMembersGenerator(
|
||||
fun generateEqualsMethodBody(properties: List<IrProperty>) {
|
||||
val irType = irClass.defaultType
|
||||
|
||||
if (!irClass.isInline) {
|
||||
if (!irClass.isSingleFieldValueClass) {
|
||||
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
|
||||
}
|
||||
+irIfThenReturnFalse(irNotIs(irOther(), irType))
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.isInlineOrValueClass
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -269,7 +269,7 @@ abstract class DeclarationStubGenerator(
|
||||
isInner = descriptor.isInner,
|
||||
isData = descriptor.isData,
|
||||
isExternal = descriptor.isEffectivelyExternal(),
|
||||
isInline = descriptor.isInlineClass(),
|
||||
isValue = descriptor.isInlineOrValueClass(),
|
||||
isExpect = descriptor.isExpect,
|
||||
isFun = descriptor.isFun,
|
||||
stubGenerator = this,
|
||||
|
||||
@@ -147,7 +147,7 @@ open class DeepCopyIrTreeWithSymbols(
|
||||
isInner = declaration.isInner,
|
||||
isData = declaration.isData,
|
||||
isExternal = declaration.isExternal,
|
||||
isInline = declaration.isInline,
|
||||
isValue = declaration.isValue,
|
||||
isExpect = declaration.isExpect,
|
||||
isFun = declaration.isFun
|
||||
).apply {
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.isInlineOrValueClass
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
val ParameterDescriptor.indexOrMinusOne: Int
|
||||
@@ -39,5 +39,5 @@ fun IrFactory.createIrClassFromDescriptor(
|
||||
): IrClass = createClass(
|
||||
startOffset, endOffset, origin, symbol, name, descriptor.kind, visibility, modality,
|
||||
descriptor.isCompanionObject, descriptor.isInner, descriptor.isData, descriptor.isEffectivelyExternal(),
|
||||
descriptor.isInlineClass(), descriptor.isExpect, descriptor.isFun, descriptor.source
|
||||
descriptor.isInlineOrValueClass(), descriptor.isExpect, descriptor.isFun, descriptor.source
|
||||
)
|
||||
|
||||
@@ -475,7 +475,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false, privat
|
||||
"inner".takeIf { isInner },
|
||||
"data".takeIf { isData },
|
||||
"external".takeIf { isExternal },
|
||||
"inline".takeIf { isInline },
|
||||
"value".takeIf { isValue },
|
||||
"expect".takeIf { isExpect },
|
||||
"fun".takeIf { isFun }
|
||||
)
|
||||
|
||||
@@ -194,7 +194,8 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isVararg = INAPPLICABLE,
|
||||
isSuspend = INAPPLICABLE,
|
||||
isInner,
|
||||
isInline,
|
||||
isInline = false,
|
||||
isValue,
|
||||
isData,
|
||||
isCompanion,
|
||||
isFun,
|
||||
@@ -254,6 +255,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
enum / annotation / fun // as a modifier in `fun interface`
|
||||
companion
|
||||
inline
|
||||
value
|
||||
infix
|
||||
operator
|
||||
data
|
||||
@@ -271,6 +273,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isSuspend: Boolean,
|
||||
isInner: Boolean,
|
||||
isInline: Boolean,
|
||||
isValue: Boolean,
|
||||
isData: Boolean,
|
||||
isCompanion: Boolean,
|
||||
isFunInterface: Boolean,
|
||||
@@ -305,6 +308,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
p(isSuspend, "suspend")
|
||||
p(isInner, "inner")
|
||||
p(isInline, "inline")
|
||||
p(isValue, "value")
|
||||
p(isData, "data")
|
||||
p(isCompanion, "companion")
|
||||
p(isFunInterface, "fun")
|
||||
@@ -542,6 +546,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isSuspend = INAPPLICABLE,
|
||||
isInner = INAPPLICABLE,
|
||||
isInline,
|
||||
isValue = INAPPLICABLE,
|
||||
isData = INAPPLICABLE,
|
||||
isCompanion = INAPPLICABLE,
|
||||
isFunInterface = INAPPLICABLE,
|
||||
@@ -597,6 +602,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isSuspend,
|
||||
isInner = INAPPLICABLE,
|
||||
isInline,
|
||||
isValue = INAPPLICABLE,
|
||||
isData = INAPPLICABLE,
|
||||
isCompanion = INAPPLICABLE,
|
||||
isFunInterface = INAPPLICABLE,
|
||||
@@ -707,8 +713,9 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isVararg = INAPPLICABLE,
|
||||
isSuspend = getter?.isSuspend == true,
|
||||
isInner = INAPPLICABLE,
|
||||
// could be used on property if all all accessors have same state, otherwise must be defined on each accessor
|
||||
// could be used on property if all accessors have same state, otherwise must be defined on each accessor
|
||||
isInline = false,
|
||||
isValue = INAPPLICABLE,
|
||||
isData = INAPPLICABLE,
|
||||
isCompanion = INAPPLICABLE,
|
||||
isFunInterface = INAPPLICABLE,
|
||||
@@ -797,6 +804,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
isSuspend = INAPPLICABLE,
|
||||
isInner = INAPPLICABLE,
|
||||
isInline = INAPPLICABLE,
|
||||
isValue = INAPPLICABLE,
|
||||
isData = INAPPLICABLE,
|
||||
isCompanion = INAPPLICABLE,
|
||||
isFunInterface = INAPPLICABLE,
|
||||
|
||||
+4
-2
@@ -311,7 +311,7 @@ class IrDeclarationDeserializer(
|
||||
flags.isInner,
|
||||
flags.isData,
|
||||
flags.isExternal || isEffectivelyExternal,
|
||||
flags.isInline,
|
||||
flags.isValue,
|
||||
flags.isExpect,
|
||||
flags.isFun,
|
||||
)
|
||||
@@ -331,11 +331,13 @@ class IrDeclarationDeserializer(
|
||||
thisReceiver = deserializeIrValueParameter(proto.thisReceiver, -1)
|
||||
|
||||
inlineClassRepresentation = when {
|
||||
!flags.isInline -> null
|
||||
!(flags.isValue && primaryConstructor?.valueParameters?.size == 1) -> null
|
||||
proto.hasInlineClassRepresentation() -> deserializeInlineClassRepresentation(proto.inlineClassRepresentation)
|
||||
else -> computeMissingInlineClassRepresentationForCompatibility(this)
|
||||
}
|
||||
|
||||
// todo something when value classes
|
||||
|
||||
sealedSubclasses = proto.sealedSubclassList.map { deserializeIrSymbol(it) as IrClassSymbol }
|
||||
|
||||
fakeOverrideBuilder.enqueueClass(this, signature, compatibilityMode)
|
||||
|
||||
+5
-4
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.backend.common.serialization.encodings
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrFlags
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
||||
@@ -27,7 +27,7 @@ value class ClassFlags(val flags: Long) {
|
||||
val isCompanion: Boolean get() = IrFlags.CLASS_KIND.get(flags.toInt()) == ProtoBuf.Class.Kind.COMPANION_OBJECT
|
||||
val isInner: Boolean get() = IrFlags.IS_INNER.get(flags.toInt())
|
||||
val isData: Boolean get() = IrFlags.IS_DATA.get(flags.toInt())
|
||||
val isInline: Boolean get() = IrFlags.IS_INLINE_CLASS.get(flags.toInt())
|
||||
val isValue: Boolean get() = IrFlags.IS_VALUE_CLASS.get(flags.toInt())
|
||||
val isExpect: Boolean get() = IrFlags.IS_EXPECT_CLASS.get(flags.toInt())
|
||||
val isExternal: Boolean get() = IrFlags.IS_EXTERNAL_CLASS.get(flags.toInt())
|
||||
val isFun: Boolean get() = IrFlags.IS_FUN_INTERFACE.get(flags.toInt())
|
||||
@@ -40,8 +40,9 @@ value class ClassFlags(val flags: Long) {
|
||||
val modality = ProtoEnumFlags.modality(modality)
|
||||
val kind = ProtoEnumFlags.classKind(kind, isCompanion)
|
||||
|
||||
val flags =
|
||||
IrFlags.getClassFlags(hasAnnotation, visibility, modality, kind, isInner, isData, isExternal, isExpect, isInline, isFun)
|
||||
val flags = IrFlags.getClassFlags(
|
||||
hasAnnotation, visibility, modality, kind, isInner, isData, isExternal, isExpect, isValue, isFun
|
||||
)
|
||||
|
||||
flags.toLong()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user