[IR] Split implementation of DataClassMembersGenerator to IR based and descriptor based
This commit is contained in:
committed by
Space Team
parent
27f4b53570
commit
6bb7fc05df
+12
-15
@@ -6,12 +6,16 @@
|
|||||||
package org.jetbrains.kotlin.fir.backend.generators
|
package org.jetbrains.kotlin.fir.backend.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME
|
import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
||||||
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
@@ -67,32 +71,25 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
|
|||||||
val lookupTag: ConeClassLikeLookupTag,
|
val lookupTag: ConeClassLikeLookupTag,
|
||||||
val origin: IrDeclarationOrigin
|
val origin: IrDeclarationOrigin
|
||||||
) {
|
) {
|
||||||
private val irDataClassMembersGenerator = object : DataClassMembersGenerator(
|
private val irDataClassMembersGenerator = object : IrBasedDataClassMembersGenerator(
|
||||||
IrGeneratorContextBase(components.irBuiltIns),
|
IrGeneratorContextBase(components.irBuiltIns),
|
||||||
components.symbolTable,
|
components.symbolTable,
|
||||||
irClass,
|
irClass,
|
||||||
irClass.kotlinFqName,
|
irClass.kotlinFqName,
|
||||||
origin
|
origin,
|
||||||
|
forbidDirectFieldAccess = false
|
||||||
) {
|
) {
|
||||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction {
|
|
||||||
throw IllegalStateException("Not expect to see function declaration.")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? =
|
override fun getProperty(irValueParameter: IrValueParameter?): IrProperty =
|
||||||
irValueParameter?.let {
|
irValueParameter?.let {
|
||||||
irClass.properties.single { irProperty ->
|
irClass.properties.single { irProperty ->
|
||||||
irProperty.name == irValueParameter.name && irProperty.backingField?.type == irValueParameter.type
|
irProperty.name == irValueParameter.name && irProperty.backingField?.type == irValueParameter.type
|
||||||
}
|
}
|
||||||
}
|
} ?: error("Property for parameter $irValueParameter")
|
||||||
|
|
||||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType {
|
|
||||||
// TODO
|
|
||||||
return components.irBuiltIns.anyType
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class Fir2IrHashCodeFunctionInfo(override val symbol: IrSimpleFunctionSymbol) : HashCodeFunctionInfo {
|
inner class Fir2IrHashCodeFunctionInfo(override val symbol: IrSimpleFunctionSymbol) : HashCodeFunctionInfo {
|
||||||
override fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>) {
|
override fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>) {
|
||||||
@@ -219,7 +216,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
|
|||||||
irFunction.origin = origin
|
irFunction.origin = origin
|
||||||
val index = DataClassResolver.getComponentIndex(irFunction.name.asString())
|
val index = DataClassResolver.getComponentIndex(irFunction.name.asString())
|
||||||
val valueParameter = irClass.primaryConstructor!!.valueParameters[index - 1]
|
val valueParameter = irClass.primaryConstructor!!.valueParameters[index - 1]
|
||||||
val irProperty = irDataClassMembersGenerator.getProperty(null, valueParameter)!!
|
val irProperty = irDataClassMembersGenerator.getProperty(valueParameter)
|
||||||
irDataClassMembersGenerator.generateComponentFunction(irFunction, irProperty)
|
irDataClassMembersGenerator.generateComponentFunction(irFunction, irProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-15
@@ -6,9 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||||
@@ -54,29 +51,21 @@ open class LoweringDataClassMemberGenerator(
|
|||||||
origin: IrDeclarationOrigin,
|
origin: IrDeclarationOrigin,
|
||||||
forbidDirectFieldAccess: Boolean = false
|
forbidDirectFieldAccess: Boolean = false
|
||||||
) :
|
) :
|
||||||
DataClassMembersGenerator(
|
IrBasedDataClassMembersGenerator(
|
||||||
IrGeneratorContextBase(backendContext.irBuiltIns),
|
IrGeneratorContextBase(backendContext.irBuiltIns),
|
||||||
backendContext.ir.symbols.externalSymbolTable,
|
backendContext.ir.symbols.externalSymbolTable,
|
||||||
irClass,
|
irClass,
|
||||||
irClass.kotlinFqName,
|
irClass.kotlinFqName,
|
||||||
origin,
|
origin,
|
||||||
forbidDirectFieldAccess
|
forbidDirectFieldAccess,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction {
|
|
||||||
error("Descriptor API shouldn't be used in lowerings")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||||
// no-op — irFunction from lowering should already have necessary parameters
|
// no-op — irFunction from lowering should already have necessary parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? {
|
override fun getProperty(irValueParameter: IrValueParameter?): IrProperty {
|
||||||
error("Descriptor API shouldn't be used in lowerings")
|
error("This API shouldn't be used in lowerings")
|
||||||
}
|
|
||||||
|
|
||||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType {
|
|
||||||
error("Descriptor API shouldn't be used in lowerings")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo {
|
override fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo {
|
||||||
|
|||||||
+105
-12
@@ -20,13 +20,19 @@ import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
|
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irExprBody
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
|
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
@@ -74,8 +80,10 @@ internal class DataClassMembersGenerator(
|
|||||||
val origin: IrDeclarationOrigin
|
val origin: IrDeclarationOrigin
|
||||||
) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) {
|
) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) {
|
||||||
|
|
||||||
private val irDataClassMembersGenerator = object : DataClassMembersGenerator(
|
private val irDataClassMembersGenerator = object : DescriptorBasedDataClassMembersGenerator(
|
||||||
context, context.symbolTable, irClass, ktClassOrObject.fqName, origin, generateBodies = generateBodies
|
context, context.symbolTable, irClass, ktClassOrObject.fqName, origin,
|
||||||
|
forbidDirectFieldAccess = false,
|
||||||
|
generateBodies = generateBodies
|
||||||
) {
|
) {
|
||||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction =
|
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction =
|
||||||
declareSimpleFunction(startOffset, endOffset, origin, functionDescriptor)
|
declareSimpleFunction(startOffset, endOffset, origin, functionDescriptor)
|
||||||
@@ -84,14 +92,10 @@ internal class DataClassMembersGenerator(
|
|||||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? =
|
override fun getProperty(parameter: ValueParameterDescriptor): IrProperty {
|
||||||
parameter?.let {
|
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
|
||||||
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
|
return getIrProperty(property)
|
||||||
return getIrProperty(property)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType =
|
|
||||||
typeParameterDescriptor.defaultType.toIrType()
|
|
||||||
|
|
||||||
private fun MemberScope.findHashCodeFunctionOrNull() =
|
private fun MemberScope.findHashCodeFunctionOrNull() =
|
||||||
getContributedFunctions(Name.identifier("hashCode"), NoLookupLocation.FROM_BACKEND)
|
getContributedFunctions(Name.identifier("hashCode"), NoLookupLocation.FROM_BACKEND)
|
||||||
@@ -139,12 +143,16 @@ internal class DataClassMembersGenerator(
|
|||||||
}
|
}
|
||||||
return Psi2IrHashCodeFunctionInfo(symbol, substituted ?: symbol.descriptor)
|
return Psi2IrHashCodeFunctionInfo(symbol, substituted ?: symbol.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType> {
|
||||||
|
return descriptor.typeParameters.map { it.defaultType.toIrType() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
|
||||||
if (!irClass.isData) return
|
if (!irClass.isData) return
|
||||||
|
|
||||||
val irProperty = irDataClassMembersGenerator.getProperty(parameter, null) ?: return
|
val irProperty = irDataClassMembersGenerator.getProperty(parameter)
|
||||||
irDataClassMembersGenerator.generateComponentFunction(function, irProperty)
|
irDataClassMembersGenerator.generateComponentFunction(function, irProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,3 +176,88 @@ internal class DataClassMembersGenerator(
|
|||||||
irDataClassMembersGenerator.generateToStringMethod(function, properties)
|
irDataClassMembersGenerator.generateToStringMethod(function, properties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
|
private abstract class DescriptorBasedDataClassMembersGenerator(
|
||||||
|
context: IrGeneratorContext,
|
||||||
|
symbolTable: ReferenceSymbolTable,
|
||||||
|
irClass: IrClass,
|
||||||
|
fqName: FqName?,
|
||||||
|
origin: IrDeclarationOrigin,
|
||||||
|
forbidDirectFieldAccess: Boolean,
|
||||||
|
val generateBodies: Boolean
|
||||||
|
) : DataClassMembersGenerator(context, symbolTable, irClass, fqName, origin, forbidDirectFieldAccess) {
|
||||||
|
private val irPropertiesByDescriptor: Map<PropertyDescriptor, IrProperty> =
|
||||||
|
irClass.properties.associateBy { it.descriptor }
|
||||||
|
|
||||||
|
fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
|
buildMember(function) {
|
||||||
|
generateEqualsMethodBody(properties.map { getIrProperty(it) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateComponentFunction(function: FunctionDescriptor, irProperty: IrProperty) {
|
||||||
|
buildMember(function) {
|
||||||
|
generateComponentFunction(irProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateCopyFunction(function: FunctionDescriptor, constructorSymbol: IrConstructorSymbol) {
|
||||||
|
buildMember(function) {
|
||||||
|
if (generateBodies) {
|
||||||
|
function.valueParameters.forEach { parameter ->
|
||||||
|
putDefault(parameter, irGetProperty(irThis(), getProperty(parameter)))
|
||||||
|
}
|
||||||
|
generateCopyFunction(constructorSymbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
|
buildMember(function) {
|
||||||
|
generateHashCodeMethodBody(
|
||||||
|
properties.map { getIrProperty(it) },
|
||||||
|
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
|
buildMember(function) {
|
||||||
|
generateToStringMethodBody(properties.map { getIrProperty(it) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIrProperty(property: PropertyDescriptor): IrProperty {
|
||||||
|
return irPropertiesByDescriptor[property]
|
||||||
|
?: error("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction
|
||||||
|
abstract fun getProperty(parameter: ValueParameterDescriptor): IrProperty
|
||||||
|
|
||||||
|
// Build a member from a descriptor (psi2ir) as well as its body.
|
||||||
|
private inline fun buildMember(
|
||||||
|
function: FunctionDescriptor,
|
||||||
|
startOffset: Int = SYNTHETIC_OFFSET,
|
||||||
|
endOffset: Int = SYNTHETIC_OFFSET,
|
||||||
|
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
||||||
|
) {
|
||||||
|
MemberFunctionBuilder(startOffset, endOffset, declareSimpleFunction(startOffset, endOffset, function)).addToClass { irFunction ->
|
||||||
|
irFunction.buildWithScope {
|
||||||
|
irFunction.parent = irClass
|
||||||
|
generateSyntheticFunctionParameterDeclarations(irFunction)
|
||||||
|
body(irFunction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MemberFunctionBuilder.putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
|
||||||
|
irFunction.putDefault(parameter, irExprBody(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean {
|
||||||
|
return descriptor.dispatchReceiverParameter != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+73
-131
@@ -5,19 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.util
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.addArgument
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.putArgument
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.defaultType
|
||||||
import org.jetbrains.kotlin.ir.types.isNullable
|
import org.jetbrains.kotlin.ir.types.isNullable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -29,7 +32,6 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
|||||||
*
|
*
|
||||||
* Generating synthetic members of inline class can use this as well, in particular, members from Any: equals, hashCode, and toString.
|
* Generating synthetic members of inline class can use this as well, in particular, members from Any: equals, hashCode, and toString.
|
||||||
*/
|
*/
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
|
||||||
abstract class DataClassMembersGenerator(
|
abstract class DataClassMembersGenerator(
|
||||||
val context: IrGeneratorContext,
|
val context: IrGeneratorContext,
|
||||||
val symbolTable: ReferenceSymbolTable,
|
val symbolTable: ReferenceSymbolTable,
|
||||||
@@ -37,11 +39,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
val fqName: FqName?,
|
val fqName: FqName?,
|
||||||
val origin: IrDeclarationOrigin,
|
val origin: IrDeclarationOrigin,
|
||||||
val forbidDirectFieldAccess: Boolean = false,
|
val forbidDirectFieldAccess: Boolean = false,
|
||||||
val generateBodies: Boolean = false
|
|
||||||
) {
|
) {
|
||||||
private val irPropertiesByDescriptor: Map<PropertyDescriptor, IrProperty> =
|
|
||||||
irClass.properties.associateBy { it.descriptor }
|
|
||||||
|
|
||||||
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
||||||
also { irDeclaration ->
|
also { irDeclaration ->
|
||||||
symbolTable.withReferenceScope(irDeclaration) {
|
symbolTable.withReferenceScope(irDeclaration) {
|
||||||
@@ -52,7 +50,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
protected val IrProperty.type
|
protected val IrProperty.type
|
||||||
get() = this.backingField?.type ?: this.getter?.returnType ?: error("Can't find type of ${this.render()}")
|
get() = this.backingField?.type ?: this.getter?.returnType ?: error("Can't find type of ${this.render()}")
|
||||||
|
|
||||||
private inner class MemberFunctionBuilder(
|
protected inner class MemberFunctionBuilder(
|
||||||
startOffset: Int = SYNTHETIC_OFFSET,
|
startOffset: Int = SYNTHETIC_OFFSET,
|
||||||
endOffset: Int = SYNTHETIC_OFFSET,
|
endOffset: Int = SYNTHETIC_OFFSET,
|
||||||
val irFunction: IrFunction
|
val irFunction: IrFunction
|
||||||
@@ -79,7 +77,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun irOther(): IrExpression {
|
private fun irOther(): IrExpression {
|
||||||
val irFirstParameter = irFunction.valueParameters[0]
|
val irFirstParameter = irFunction.valueParameters[0]
|
||||||
return IrGetValueImpl(
|
return IrGetValueImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
@@ -102,10 +100,6 @@ abstract class DataClassMembersGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
|
|
||||||
irFunction.putDefault(parameter, irExprBody(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun generateComponentFunction(irProperty: IrProperty) {
|
fun generateComponentFunction(irProperty: IrProperty) {
|
||||||
+irReturn(irGetProperty(irThis(), irProperty))
|
+irReturn(irGetProperty(irThis(), irProperty))
|
||||||
}
|
}
|
||||||
@@ -117,8 +111,8 @@ abstract class DataClassMembersGenerator(
|
|||||||
irClass.defaultType,
|
irClass.defaultType,
|
||||||
constructedClass = irClass
|
constructedClass = irClass
|
||||||
).apply {
|
).apply {
|
||||||
for ((i, typeParameter) in constructorSymbol.descriptor.typeParameters.withIndex()) {
|
for ((i, typeParameterType) in constructorSymbol.typesOfTypeParameters().withIndex()) {
|
||||||
putTypeArgument(i, transform(typeParameter))
|
putTypeArgument(i, typeParameterType)
|
||||||
}
|
}
|
||||||
for ((i, valueParameter) in irFunction.valueParameters.withIndex()) {
|
for ((i, valueParameter) in irFunction.valueParameters.withIndex()) {
|
||||||
putValueArgument(i, irGet(valueParameter.type, valueParameter.symbol))
|
putValueArgument(i, irGet(valueParameter.type, valueParameter.symbol))
|
||||||
@@ -246,7 +240,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
||||||
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
||||||
val hashCodeFunctionSymbol = hashCodeFunctionInfo.symbol
|
val hashCodeFunctionSymbol = hashCodeFunctionInfo.symbol
|
||||||
val hasDispatchReceiver = hashCodeFunctionSymbol.descriptor.dispatchReceiverParameter != null
|
val hasDispatchReceiver = hashCodeFunctionSymbol.hasDispatchReceiver()
|
||||||
return irCall(
|
return irCall(
|
||||||
hashCodeFunctionSymbol,
|
hashCodeFunctionSymbol,
|
||||||
context.irBuiltIns.intType,
|
context.irBuiltIns.intType,
|
||||||
@@ -262,35 +256,69 @@ abstract class DataClassMembersGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getIrProperty(property: PropertyDescriptor): IrProperty =
|
|
||||||
irPropertiesByDescriptor[property]
|
|
||||||
?: throw AssertionError("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
|
||||||
|
|
||||||
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
|
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
|
||||||
get() = isArrayOrPrimitiveArray(context.irBuiltIns)
|
get() = isArrayOrPrimitiveArray(context.irBuiltIns)
|
||||||
|
|
||||||
abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction
|
|
||||||
|
|
||||||
abstract fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction)
|
abstract fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction)
|
||||||
|
|
||||||
// Build a member from a descriptor (psi2ir) as well as its body.
|
interface HashCodeFunctionInfo {
|
||||||
private inline fun buildMember(
|
val symbol: IrSimpleFunctionSymbol
|
||||||
function: FunctionDescriptor,
|
fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>)
|
||||||
startOffset: Int = SYNTHETIC_OFFSET,
|
}
|
||||||
endOffset: Int = SYNTHETIC_OFFSET,
|
|
||||||
body: MemberFunctionBuilder.(IrFunction) -> Unit
|
abstract fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo
|
||||||
) {
|
|
||||||
MemberFunctionBuilder(startOffset, endOffset, declareSimpleFunction(startOffset, endOffset, function)).addToClass { irFunction ->
|
open fun IrClass.classNameForToString(): String = irClass.name.asString()
|
||||||
irFunction.buildWithScope {
|
|
||||||
irFunction.parent = irClass
|
protected abstract fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean
|
||||||
generateSyntheticFunctionParameterDeclarations(irFunction)
|
protected abstract fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType>
|
||||||
body(irFunction)
|
}
|
||||||
}
|
|
||||||
|
abstract class IrBasedDataClassMembersGenerator(
|
||||||
|
context: IrGeneratorContext,
|
||||||
|
symbolTable: ReferenceSymbolTable,
|
||||||
|
irClass: IrClass,
|
||||||
|
fqName: FqName?,
|
||||||
|
origin: IrDeclarationOrigin,
|
||||||
|
forbidDirectFieldAccess: Boolean,
|
||||||
|
) : DataClassMembersGenerator(context, symbolTable, irClass, fqName, origin, forbidDirectFieldAccess) {
|
||||||
|
fun generateComponentFunction(irFunction: IrFunction, irProperty: IrProperty) {
|
||||||
|
buildMember(irFunction) {
|
||||||
|
generateComponentFunction(irProperty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a prebuilt member (fir2ir) and build a member body for it.
|
fun generateCopyFunction(irFunction: IrFunction, constructorSymbol: IrConstructorSymbol) {
|
||||||
|
buildMember(irFunction) {
|
||||||
|
irFunction.valueParameters.forEach { irValueParameter ->
|
||||||
|
irValueParameter.defaultValue = irExprBody(irGetProperty(irThis(), getProperty(irValueParameter)))
|
||||||
|
}
|
||||||
|
generateCopyFunction(constructorSymbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateEqualsMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||||
|
buildMember(irFunction) {
|
||||||
|
generateEqualsMethodBody(properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateHashCodeMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||||
|
buildMember(irFunction) {
|
||||||
|
generateHashCodeMethodBody(
|
||||||
|
properties,
|
||||||
|
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateToStringMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
||||||
|
buildMember(irFunction) {
|
||||||
|
generateToStringMethodBody(properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use a prebuilt member and build a member body for it.
|
||||||
private inline fun buildMember(
|
private inline fun buildMember(
|
||||||
irFunction: IrFunction,
|
irFunction: IrFunction,
|
||||||
startOffset: Int = SYNTHETIC_OFFSET,
|
startOffset: Int = SYNTHETIC_OFFSET,
|
||||||
@@ -305,100 +333,14 @@ abstract class DataClassMembersGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry for psi2ir
|
abstract fun getProperty(irValueParameter: IrValueParameter?): IrProperty
|
||||||
fun generateComponentFunction(function: FunctionDescriptor, irProperty: IrProperty) {
|
|
||||||
buildMember(function) {
|
override fun IrSimpleFunctionSymbol.hasDispatchReceiver(): Boolean {
|
||||||
generateComponentFunction(irProperty)
|
return owner.dispatchReceiverParameter != null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry for fir2ir
|
override fun IrConstructorSymbol.typesOfTypeParameters(): List<IrType> {
|
||||||
fun generateComponentFunction(irFunction: IrFunction, irProperty: IrProperty) {
|
val allParameters = owner.constructedClass.typeParameters + owner.typeParameters
|
||||||
buildMember(irFunction) {
|
return allParameters.map { it.defaultType }
|
||||||
generateComponentFunction(irProperty)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty?
|
|
||||||
|
|
||||||
abstract fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType
|
|
||||||
|
|
||||||
// Entry for psi2ir
|
|
||||||
fun generateCopyFunction(function: FunctionDescriptor, constructorSymbol: IrConstructorSymbol) {
|
|
||||||
buildMember(function) {
|
|
||||||
if (generateBodies) {
|
|
||||||
function.valueParameters.forEach { parameter ->
|
|
||||||
putDefault(parameter, irGetProperty(irThis(), getProperty(parameter, null)!!))
|
|
||||||
}
|
|
||||||
generateCopyFunction(constructorSymbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for fir2ir
|
|
||||||
fun generateCopyFunction(irFunction: IrFunction, constructorSymbol: IrConstructorSymbol) {
|
|
||||||
buildMember(irFunction) {
|
|
||||||
irFunction.valueParameters.forEach { irValueParameter ->
|
|
||||||
irValueParameter.defaultValue = irExprBody(irGetProperty(irThis(), getProperty(null, irValueParameter)!!))
|
|
||||||
}
|
|
||||||
generateCopyFunction(constructorSymbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for psi2ir
|
|
||||||
fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
|
||||||
buildMember(function) {
|
|
||||||
generateEqualsMethodBody(properties.map { getIrProperty(it) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for fir2ir
|
|
||||||
fun generateEqualsMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
|
||||||
buildMember(irFunction) {
|
|
||||||
generateEqualsMethodBody(properties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HashCodeFunctionInfo {
|
|
||||||
val symbol: IrSimpleFunctionSymbol
|
|
||||||
fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo
|
|
||||||
|
|
||||||
// Entry for psi2ir
|
|
||||||
fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
|
||||||
buildMember(function) {
|
|
||||||
generateHashCodeMethodBody(
|
|
||||||
properties.map { getIrProperty(it) },
|
|
||||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for fir2ir
|
|
||||||
fun generateHashCodeMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
|
||||||
buildMember(irFunction) {
|
|
||||||
generateHashCodeMethodBody(
|
|
||||||
properties,
|
|
||||||
if (irClass.kind == ClassKind.OBJECT && irClass.isData) fqName.hashCode() else 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for psi2ir
|
|
||||||
fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
|
||||||
buildMember(function) {
|
|
||||||
generateToStringMethodBody(properties.map { getIrProperty(it) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for fir2ir
|
|
||||||
fun generateToStringMethod(irFunction: IrFunction, properties: List<IrProperty>) {
|
|
||||||
buildMember(irFunction) {
|
|
||||||
generateToStringMethodBody(properties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun IrClass.classNameForToString(): String = irClass.name.asString()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -493,7 +493,7 @@ FILE fqName:<root> fileName:/dataClassWithArrayMembers.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (genericArray: kotlin.Array<T of <root>.Test2>): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
RETURN type=kotlin.Nothing from='public final fun copy (genericArray: kotlin.Array<T of <root>.Test2>): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (genericArray: kotlin.Array<T of <root>.Test2>) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (genericArray: kotlin.Array<T of <root>.Test2>) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Test2
|
||||||
genericArray: GET_VAR 'genericArray: kotlin.Array<T of <root>.Test2> declared in <root>.Test2.copy' type=kotlin.Array<T of <root>.Test2> origin=null
|
genericArray: GET_VAR 'genericArray: kotlin.Array<T of <root>.Test2> declared in <root>.Test2.copy' type=kotlin.Array<T of <root>.Test2> origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
|
|||||||
+1
-1
@@ -154,7 +154,7 @@ data class Test2<T : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(genericArray: Array<T> = <this>.#genericArray): Test2<T> {
|
fun copy(genericArray: Array<T> = <this>.#genericArray): Test2<T> {
|
||||||
return Test2<Any>(genericArray = genericArray)
|
return Test2<T>(genericArray = genericArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
+3
-3
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test1): <root>.Test1<T of <root>.Test1> declared in <root>.Test1'
|
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test1): <root>.Test1<T of <root>.Test1> declared in <root>.Test1'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test1) declared in <root>.Test1' type=<root>.Test1<T of <root>.Test1> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test1) declared in <root>.Test1' type=<root>.Test1<T of <root>.Test1> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Test1
|
||||||
x: GET_VAR 'x: T of <root>.Test1 declared in <root>.Test1.copy' type=T of <root>.Test1 origin=null
|
x: GET_VAR 'x: T of <root>.Test1 declared in <root>.Test1.copy' type=T of <root>.Test1 origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test1<T of <root>.Test1>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test1<T of <root>.Test1>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
@@ -133,7 +133,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test2): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test2): <root>.Test2<T of <root>.Test2> declared in <root>.Test2'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test2) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test2) declared in <root>.Test2' type=<root>.Test2<T of <root>.Test2> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Test2
|
||||||
x: GET_VAR 'x: T of <root>.Test2 declared in <root>.Test2.copy' type=T of <root>.Test2 origin=null
|
x: GET_VAR 'x: T of <root>.Test2 declared in <root>.Test2.copy' type=T of <root>.Test2 origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test2<T of <root>.Test2>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
@@ -224,7 +224,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (x: kotlin.collections.List<T of <root>.Test3>): <root>.Test3<T of <root>.Test3> declared in <root>.Test3'
|
RETURN type=kotlin.Nothing from='public final fun copy (x: kotlin.collections.List<T of <root>.Test3>): <root>.Test3<T of <root>.Test3> declared in <root>.Test3'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (x: kotlin.collections.List<T of <root>.Test3>) declared in <root>.Test3' type=<root>.Test3<T of <root>.Test3> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (x: kotlin.collections.List<T of <root>.Test3>) declared in <root>.Test3' type=<root>.Test3<T of <root>.Test3> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Test3
|
||||||
x: GET_VAR 'x: kotlin.collections.List<T of <root>.Test3> declared in <root>.Test3.copy' type=kotlin.collections.List<T of <root>.Test3> origin=null
|
x: GET_VAR 'x: kotlin.collections.List<T of <root>.Test3> declared in <root>.Test3.copy' type=kotlin.collections.List<T of <root>.Test3> origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test3<T of <root>.Test3>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test3<T of <root>.Test3>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ data class Test1<T : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(x: T = <this>.#x): Test1<T> {
|
fun copy(x: T = <this>.#x): Test1<T> {
|
||||||
return Test1<Any>(x = x)
|
return Test1<T>(x = x)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
@@ -60,7 +60,7 @@ data class Test2<T : Number> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(x: T = <this>.#x): Test2<T> {
|
fun copy(x: T = <this>.#x): Test2<T> {
|
||||||
return Test2<Any>(x = x)
|
return Test2<T>(x = x)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
@@ -103,7 +103,7 @@ data class Test3<T : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(x: List<T> = <this>.#x): Test3<T> {
|
fun copy(x: List<T> = <this>.#x): Test3<T> {
|
||||||
return Test3<Any>(x = x)
|
return Test3<T>(x = x)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
+2
-2
@@ -56,8 +56,8 @@ FILE fqName:<root> fileName:/compareTo.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (first: A of <root>.Pair, second: B of <root>.Pair): <root>.Pair<A of <root>.Pair, B of <root>.Pair> declared in <root>.Pair'
|
RETURN type=kotlin.Nothing from='public final fun copy (first: A of <root>.Pair, second: B of <root>.Pair): <root>.Pair<A of <root>.Pair, B of <root>.Pair> declared in <root>.Pair'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (first: A of <root>.Pair, second: B of <root>.Pair) declared in <root>.Pair' type=<root>.Pair<A of <root>.Pair, B of <root>.Pair> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (first: A of <root>.Pair, second: B of <root>.Pair) declared in <root>.Pair' type=<root>.Pair<A of <root>.Pair, B of <root>.Pair> origin=null
|
||||||
<class: A>: kotlin.Any
|
<class: A>: A of <root>.Pair
|
||||||
<class: B>: kotlin.Any
|
<class: B>: B of <root>.Pair
|
||||||
first: GET_VAR 'first: A of <root>.Pair declared in <root>.Pair.copy' type=A of <root>.Pair origin=null
|
first: GET_VAR 'first: A of <root>.Pair declared in <root>.Pair.copy' type=A of <root>.Pair origin=null
|
||||||
second: GET_VAR 'second: B of <root>.Pair declared in <root>.Pair.copy' type=B of <root>.Pair origin=null
|
second: GET_VAR 'second: B of <root>.Pair declared in <root>.Pair.copy' type=B of <root>.Pair origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Pair<A of <root>.Pair, B of <root>.Pair>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Pair<A of <root>.Pair, B of <root>.Pair>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ data class Pair<A : Any?, B : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(first: A = <this>.#first, second: B = <this>.#second): Pair<A, B> {
|
fun copy(first: A = <this>.#first, second: B = <this>.#second): Pair<A, B> {
|
||||||
return Pair<Any, Any>(first = first, second = second)
|
return Pair<A, B>(first = first, second = second)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ FILE fqName:<root> fileName:/dataClassMembers.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test, y: kotlin.String): <root>.Test<T of <root>.Test> declared in <root>.Test'
|
RETURN type=kotlin.Nothing from='public final fun copy (x: T of <root>.Test, y: kotlin.String): <root>.Test<T of <root>.Test> declared in <root>.Test'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test, y: kotlin.String) declared in <root>.Test' type=<root>.Test<T of <root>.Test> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (x: T of <root>.Test, y: kotlin.String) declared in <root>.Test' type=<root>.Test<T of <root>.Test> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Test
|
||||||
x: GET_VAR 'x: T of <root>.Test declared in <root>.Test.copy' type=T of <root>.Test origin=null
|
x: GET_VAR 'x: T of <root>.Test declared in <root>.Test.copy' type=T of <root>.Test origin=null
|
||||||
y: GET_VAR 'y: kotlin.String declared in <root>.Test.copy' type=kotlin.String origin=null
|
y: GET_VAR 'y: kotlin.String declared in <root>.Test.copy' type=kotlin.String origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test<T of <root>.Test>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Test<T of <root>.Test>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ data class Test<T : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(x: T = <this>.#x, y: String = <this>.#y): Test<T> {
|
fun copy(x: T = <this>.#x, y: String = <this>.#y): Test<T> {
|
||||||
return Test<Any>(x = x, y = y)
|
return Test<T>(x = x, y = y)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ FILE fqName:<root> fileName:/ArrayMap.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry): <root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> declared in <root>.ArrayMapImpl.Entry'
|
RETURN type=kotlin.Nothing from='public final fun copy (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry): <root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> declared in <root>.ArrayMapImpl.Entry'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry) declared in <root>.ArrayMapImpl.Entry' type=<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (key: kotlin.Int, value: T of <root>.ArrayMapImpl.Entry) declared in <root>.ArrayMapImpl.Entry' type=<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.ArrayMapImpl.Entry
|
||||||
key: GET_VAR 'key: kotlin.Int declared in <root>.ArrayMapImpl.Entry.copy' type=kotlin.Int origin=null
|
key: GET_VAR 'key: kotlin.Int declared in <root>.ArrayMapImpl.Entry.copy' type=kotlin.Int origin=null
|
||||||
value: GET_VAR 'value: T of <root>.ArrayMapImpl.Entry declared in <root>.ArrayMapImpl.Entry.copy' type=T of <root>.ArrayMapImpl.Entry origin=null
|
value: GET_VAR 'value: T of <root>.ArrayMapImpl.Entry declared in <root>.ArrayMapImpl.Entry.copy' type=T of <root>.ArrayMapImpl.Entry origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.ArrayMapImpl.Entry<T of <root>.ArrayMapImpl.Entry>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ internal class ArrayMapImpl<T : Any> : ArrayMap<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(key: Int = <this>.#key, value: T = <this>.#value): Entry<T> {
|
fun copy(key: Int = <this>.#key, value: T = <this>.#value): Entry<T> {
|
||||||
return Entry<Any>(key = key, value = value)
|
return Entry<T>(key = key, value = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/MultiList.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (value: T of <root>.Some): <root>.Some<T of <root>.Some> declared in <root>.Some'
|
RETURN type=kotlin.Nothing from='public final fun copy (value: T of <root>.Some): <root>.Some<T of <root>.Some> declared in <root>.Some'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (value: T of <root>.Some) declared in <root>.Some' type=<root>.Some<T of <root>.Some> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (value: T of <root>.Some) declared in <root>.Some' type=<root>.Some<T of <root>.Some> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.Some
|
||||||
value: GET_VAR 'value: T of <root>.Some declared in <root>.Some.copy' type=T of <root>.Some origin=null
|
value: GET_VAR 'value: T of <root>.Some declared in <root>.Some.copy' type=T of <root>.Some origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Some<T of <root>.Some>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Some<T of <root>.Some>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ data class Some<T : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(value: T = <this>.#value): Some<T> {
|
fun copy(value: T = <this>.#value): Some<T> {
|
||||||
return Some<Any>(value = value)
|
return Some<T>(value = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ FILE fqName:<root> fileName:/kt45236.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?): <root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> declared in <root>.NetRequestStatus.Error'
|
RETURN type=kotlin.Nothing from='public final fun copy (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?): <root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> declared in <root>.NetRequestStatus.Error'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?) declared in <root>.NetRequestStatus.Error' type=<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (error: kotlin.Throwable, value: T of <root>.NetRequestStatus.Error?) declared in <root>.NetRequestStatus.Error' type=<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error> origin=null
|
||||||
<class: T>: kotlin.Any
|
<class: T>: T of <root>.NetRequestStatus.Error
|
||||||
error: GET_VAR 'error: kotlin.Throwable declared in <root>.NetRequestStatus.Error.copy' type=kotlin.Throwable origin=null
|
error: GET_VAR 'error: kotlin.Throwable declared in <root>.NetRequestStatus.Error.copy' type=kotlin.Throwable origin=null
|
||||||
value: GET_VAR 'value: T of <root>.NetRequestStatus.Error? declared in <root>.NetRequestStatus.Error.copy' type=T of <root>.NetRequestStatus.Error? origin=null
|
value: GET_VAR 'value: T of <root>.NetRequestStatus.Error? declared in <root>.NetRequestStatus.Error.copy' type=T of <root>.NetRequestStatus.Error? origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.NetRequestStatus.Error<T of <root>.NetRequestStatus.Error>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ FILE fqName:<root> fileName:/typeAliasWithUnsafeVariance.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun copy (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>): <root>.Tag<RenderingT of <root>.Tag> declared in <root>.Tag'
|
RETURN type=kotlin.Nothing from='public final fun copy (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>): <root>.Tag<RenderingT of <root>.Tag> declared in <root>.Tag'
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>) declared in <root>.Tag' type=<root>.Tag<RenderingT of <root>.Tag> origin=null
|
CONSTRUCTOR_CALL 'public constructor <init> (action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit>) declared in <root>.Tag' type=<root>.Tag<RenderingT of <root>.Tag> origin=null
|
||||||
<class: RenderingT>: kotlin.Any
|
<class: RenderingT>: RenderingT of <root>.Tag
|
||||||
action: GET_VAR 'action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> declared in <root>.Tag.copy' type=kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> origin=null
|
action: GET_VAR 'action: kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> declared in <root>.Tag.copy' type=kotlin.Function1<RenderingT of <root>.Tag, kotlin.Unit> origin=null
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Tag<RenderingT of <root>.Tag>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:<root>.Tag<RenderingT of <root>.Tag>, other:kotlin.Any?) returnType:kotlin.Boolean [operator]
|
||||||
overridden:
|
overridden:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ data class Tag<out RenderingT : Any?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy(action: Function1<RenderingT, Unit> = <this>.#action): Tag<RenderingT> {
|
fun copy(action: Function1<RenderingT, Unit> = <this>.#action): Tag<RenderingT> {
|
||||||
return Tag<Any>(action = action)
|
return Tag<RenderingT>(action = action)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun equals(other: Any?): Boolean {
|
override operator fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user