[IR] Support object-like interaction with MFVC function references
Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com> #KT-1179
This commit is contained in:
committed by
Space Team
parent
1660dc21b9
commit
c6e54e6433
+61
-62
@@ -46,10 +46,9 @@ import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT
|
|||||||
import org.jetbrains.kotlin.name.JvmNames.JVM_PACKAGE_NAME_SHORT
|
import org.jetbrains.kotlin.name.JvmNames.JVM_PACKAGE_NAME_SHORT
|
||||||
import org.jetbrains.kotlin.name.JvmNames.MULTIFILE_PART_NAME_DELIMITER
|
import org.jetbrains.kotlin.name.JvmNames.MULTIFILE_PART_NAME_DELIMITER
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal val fileClassPhase = makeIrModulePhase(
|
internal val fileClassPhase = makeIrModulePhase(
|
||||||
@@ -82,78 +81,78 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
|
|||||||
// TODO FirMetadataSource.File
|
// TODO FirMetadataSource.File
|
||||||
if (fileClassMembers.isEmpty() && (irFile.metadata as? DescriptorMetadataSource.File)?.descriptors.isNullOrEmpty()) return
|
if (fileClassMembers.isEmpty() && (irFile.metadata as? DescriptorMetadataSource.File)?.descriptors.isNullOrEmpty()) return
|
||||||
|
|
||||||
val irFileClass = createFileClass(irFile, fileClassMembers)
|
val irFileClass = createFileClass(context, irFile, fileClassMembers)
|
||||||
classes.add(irFileClass)
|
classes.add(irFileClass)
|
||||||
|
|
||||||
irFile.declarations.clear()
|
irFile.declarations.clear()
|
||||||
irFile.declarations.addAll(classes)
|
irFile.declarations.addAll(classes)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createFileClass(irFile: IrFile, fileClassMembers: List<IrDeclaration>): IrClass {
|
internal fun createFileClass(context: JvmBackendContext, irFile: IrFile, fileClassMembers: List<IrDeclaration>): IrClass {
|
||||||
val fileEntry = irFile.fileEntry
|
val fileEntry = irFile.fileEntry
|
||||||
val fileClassInfo = irFile.getFileClassInfo()
|
val fileClassInfo = irFile.getFileClassInfo()
|
||||||
val isMultifilePart = fileClassInfo.withJvmMultifileClass
|
val isMultifilePart = fileClassInfo.withJvmMultifileClass
|
||||||
|
|
||||||
val onlyPrivateDeclarationsAndFeatureIsEnabled =
|
val onlyPrivateDeclarationsAndFeatureIsEnabled =
|
||||||
context.state.languageVersionSettings.supportsFeature(LanguageFeature.PackagePrivateFileClassesWithAllPrivateMembers) && fileClassMembers
|
context.state.languageVersionSettings.supportsFeature(LanguageFeature.PackagePrivateFileClassesWithAllPrivateMembers) && fileClassMembers
|
||||||
.all {
|
.all {
|
||||||
val isPrivate = it is IrDeclarationWithVisibility && DescriptorVisibilities.isPrivate(it.visibility)
|
val isPrivate = it is IrDeclarationWithVisibility && DescriptorVisibilities.isPrivate(it.visibility)
|
||||||
val isInlineOnly = it.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
val isInlineOnly = it.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
||||||
isPrivate || isInlineOnly
|
isPrivate || isInlineOnly
|
||||||
}
|
|
||||||
|
|
||||||
val fileClassOrigin =
|
|
||||||
if (!isMultifilePart || context.state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts))
|
|
||||||
IrDeclarationOrigin.FILE_CLASS
|
|
||||||
else
|
|
||||||
IrDeclarationOrigin.SYNTHETIC_FILE_CLASS
|
|
||||||
return IrClassImpl(
|
|
||||||
0, fileEntry.maxOffset,
|
|
||||||
fileClassOrigin,
|
|
||||||
symbol = IrClassSymbolImpl(),
|
|
||||||
name = fileClassInfo.fileClassFqName.shortName(),
|
|
||||||
kind = ClassKind.CLASS,
|
|
||||||
visibility = if (isMultifilePart || onlyPrivateDeclarationsAndFeatureIsEnabled)
|
|
||||||
JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
|
||||||
else
|
|
||||||
DescriptorVisibilities.PUBLIC,
|
|
||||||
modality = Modality.FINAL
|
|
||||||
).apply {
|
|
||||||
superTypes = listOf(context.irBuiltIns.anyType)
|
|
||||||
parent = irFile
|
|
||||||
declarations.addAll(fileClassMembers)
|
|
||||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
|
||||||
for (member in fileClassMembers) {
|
|
||||||
member.parent = this
|
|
||||||
if (member is IrProperty) {
|
|
||||||
member.getter?.let { it.parent = this }
|
|
||||||
member.setter?.let { it.parent = this }
|
|
||||||
member.backingField?.let { it.parent = this }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
annotations =
|
val fileClassOrigin =
|
||||||
if (isMultifilePart) irFile.annotations.filterNot {
|
if (!isMultifilePart || context.state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts))
|
||||||
it.symbol.owner.parentAsClass.hasEqualFqName(JvmFileClassUtil.JVM_NAME)
|
IrDeclarationOrigin.FILE_CLASS
|
||||||
}
|
else
|
||||||
else irFile.annotations
|
IrDeclarationOrigin.SYNTHETIC_FILE_CLASS
|
||||||
|
return IrClassImpl(
|
||||||
metadata = irFile.metadata
|
0, fileEntry.maxOffset,
|
||||||
|
fileClassOrigin,
|
||||||
val partClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.fileClassFqName)
|
symbol = IrClassSymbolImpl(),
|
||||||
val facadeClassType =
|
name = fileClassInfo.fileClassFqName.shortName(),
|
||||||
if (isMultifilePart) AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.facadeClassFqName)
|
kind = ClassKind.CLASS,
|
||||||
else null
|
visibility = if (isMultifilePart || onlyPrivateDeclarationsAndFeatureIsEnabled)
|
||||||
context.state.factory.packagePartRegistry.addPart(irFile.fqName, partClassType.internalName, facadeClassType?.internalName)
|
JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
||||||
|
else
|
||||||
if (fileClassInfo.fileClassFqName != fqNameWhenAvailable) {
|
DescriptorVisibilities.PUBLIC,
|
||||||
context.classNameOverride[this] = JvmClassName.byInternalName(partClassType.internalName)
|
modality = Modality.FINAL
|
||||||
|
).apply {
|
||||||
|
superTypes = listOf(context.irBuiltIns.anyType)
|
||||||
|
parent = irFile
|
||||||
|
declarations.addAll(fileClassMembers)
|
||||||
|
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||||
|
for (member in fileClassMembers) {
|
||||||
|
member.parent = this
|
||||||
|
if (member is IrProperty) {
|
||||||
|
member.getter?.let { it.parent = this }
|
||||||
|
member.setter?.let { it.parent = this }
|
||||||
|
member.backingField?.let { it.parent = this }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (facadeClassType != null) {
|
annotations =
|
||||||
val jvmClassName = JvmClassName.byInternalName(facadeClassType.internalName)
|
if (isMultifilePart) irFile.annotations.filterNot {
|
||||||
context.multifileFacadesToAdd.getOrPut(jvmClassName) { ArrayList() }.add(this)
|
it.symbol.owner.parentAsClass.hasEqualFqName(JvmFileClassUtil.JVM_NAME)
|
||||||
}
|
}
|
||||||
|
else irFile.annotations
|
||||||
|
|
||||||
|
metadata = irFile.metadata
|
||||||
|
|
||||||
|
val partClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.fileClassFqName)
|
||||||
|
val facadeClassType =
|
||||||
|
if (isMultifilePart) AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.facadeClassFqName)
|
||||||
|
else null
|
||||||
|
context.state.factory.packagePartRegistry.addPart(irFile.fqName, partClassType.internalName, facadeClassType?.internalName)
|
||||||
|
|
||||||
|
if (fileClassInfo.fileClassFqName != fqNameWhenAvailable) {
|
||||||
|
context.classNameOverride[this] = JvmClassName.byInternalName(partClassType.internalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (facadeClassType != null) {
|
||||||
|
val jvmClassName = JvmClassName.byInternalName(facadeClassType.internalName)
|
||||||
|
context.multifileFacadesToAdd.getOrPut(jvmClassName) { ArrayList() }.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-22
@@ -25,8 +25,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
||||||
@@ -595,7 +595,7 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
allScopes.pop()
|
allScopes.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunctionAccessExpression.passTypeArgumentsWithOffsets(
|
private fun IrMemberAccessExpression<*>.passTypeArgumentsWithOffsets(
|
||||||
target: IrFunction, source: IrFunction, forCommonTypeParameters: (targetIndex: Int) -> IrType
|
target: IrFunction, source: IrFunction, forCommonTypeParameters: (targetIndex: Int) -> IrType
|
||||||
) {
|
) {
|
||||||
val passedTypeParametersSize = minOf(target.typeParameters.size, source.typeParameters.size)
|
val passedTypeParametersSize = minOf(target.typeParameters.size, source.typeParameters.size)
|
||||||
@@ -707,6 +707,8 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
mfvc.declarations.removeIf { it is IrAnonymousInitializer }
|
mfvc.declarations.removeIf { it is IrAnonymousInitializer }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val mfvcConstructorRefReplacements = mutableMapOf<Pair<IrFile, MfvcNode>, IrSimpleFunction>()
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||||
val function = expression.symbol.owner
|
val function = expression.symbol.owner
|
||||||
val replacement = function.let {
|
val replacement = function.let {
|
||||||
@@ -715,29 +717,53 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
}
|
}
|
||||||
} ?: return super.visitFunctionReference(expression)
|
} ?: return super.visitFunctionReference(expression)
|
||||||
return if (function is IrConstructor && function.isPrimary && function.constructedClass.isMultiFieldValueClass) {
|
return if (function is IrConstructor && function.isPrimary && function.constructedClass.isMultiFieldValueClass) {
|
||||||
expression.run {
|
val rootNode = replacements.getRootMfvcNode(function.constructedClass)
|
||||||
IrConstructorCallImpl(
|
val newFunction: IrSimpleFunction = mfvcConstructorRefReplacements.getOrPut(currentFile to rootNode) {
|
||||||
startOffset, endOffset, type, function.symbol, typeArgumentsCount, typeArgumentsCount, valueArgumentsCount, origin
|
createMfvcPrimaryConstructorReferenceHelperFunction(rootNode)
|
||||||
)
|
}
|
||||||
}.transform(this, null)
|
IrFunctionReferenceImpl(
|
||||||
|
expression.startOffset, expression.endOffset,
|
||||||
|
newFunction.returnType, newFunction.symbol, function.typeParameters.size, replacement.valueParameters.size,
|
||||||
|
newFunction.symbol, expression.origin
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
context.createJvmIrBuilder(getCurrentScopeSymbol()).irBlock {
|
context.createJvmIrBuilder(getCurrentScopeSymbol()).irBlock {
|
||||||
expression.run {
|
expression.apply {
|
||||||
IrFunctionReferenceImpl(
|
buildReplacement(function, expression, replacement) {
|
||||||
startOffset,
|
IrFunctionReferenceImpl(
|
||||||
endOffset,
|
startOffset, endOffset,
|
||||||
type,
|
type, it, function.typeParameters.size, replacement.valueParameters.size,
|
||||||
replacement.symbol,
|
reflectionTarget, origin
|
||||||
function.typeParameters.size,
|
)
|
||||||
replacement.valueParameters.size,
|
}.copyAttributes(expression)
|
||||||
reflectionTarget,
|
}
|
||||||
origin
|
|
||||||
)
|
|
||||||
}.apply { buildReplacement(function, expression, replacement) }.copyAttributes(expression)
|
|
||||||
}.unwrapBlock()
|
}.unwrapBlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val fileClassNewDeclarations = mutableMapOf<IrFile, MutableList<IrSimpleFunction>>()
|
||||||
|
|
||||||
|
private fun createMfvcPrimaryConstructorReferenceHelperFunction(rootNode: RootMfvcNode) = context.irFactory.buildFun {
|
||||||
|
name = Name.identifier("mfvcConstructorReferenceHelper\$${fileClassNewDeclarations[currentFile]?.size ?: 0}")
|
||||||
|
origin = JvmLoweredDeclarationOrigin.MFVC_PRIMARY_CONSTRUCTOR_REFERENCE_HELPER
|
||||||
|
}.apply function@{
|
||||||
|
fileClassNewDeclarations.getOrPut(currentFile) { mutableListOf() }.add(this)
|
||||||
|
copyParameterDeclarationsFrom(rootNode.primaryConstructorImpl)
|
||||||
|
returnType = rootNode.type.substitute(rootNode.mfvc.typeParameters, typeParameters.map { it.defaultType })
|
||||||
|
body = context.createJvmIrBuilder(this.symbol).run {
|
||||||
|
irExprBody(irBlock {
|
||||||
|
for (callee in listOf(rootNode.primaryConstructorImpl, rootNode.boxMethod)) {
|
||||||
|
+irCall(callee).apply {
|
||||||
|
passTypeArgumentsFrom(this@function)
|
||||||
|
for ((index, parameter) in this@function.valueParameters.withIndex()) {
|
||||||
|
putValueArgument(index, irGet(parameter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||||
val function = expression.symbol.owner
|
val function = expression.symbol.owner
|
||||||
val replacement = replacements.getReplacementFunction(function)
|
val replacement = replacements.getReplacementFunction(function)
|
||||||
@@ -856,21 +882,24 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
|
|||||||
private fun IrBlockBuilder.buildReplacement(
|
private fun IrBlockBuilder.buildReplacement(
|
||||||
originalFunction: IrFunction,
|
originalFunction: IrFunction,
|
||||||
original: IrMemberAccessExpression<*>,
|
original: IrMemberAccessExpression<*>,
|
||||||
replacement: IrFunction
|
replacement: IrFunction,
|
||||||
) {
|
makeMemberAccessExpression: (IrFunctionSymbol) -> IrMemberAccessExpression<*> = ::irCall,
|
||||||
|
): IrMemberAccessExpression<*> {
|
||||||
val parameter2expression = typedArgumentList(originalFunction, original)
|
val parameter2expression = typedArgumentList(originalFunction, original)
|
||||||
val structure = replacements.bindingOldFunctionToParameterTemplateStructure[originalFunction]!!
|
val structure = replacements.bindingOldFunctionToParameterTemplateStructure[originalFunction]!!
|
||||||
require(parameter2expression.size == structure.size)
|
require(parameter2expression.size == structure.size)
|
||||||
require(structure.sumOf { it.valueParameters.size } == replacement.explicitParametersCount)
|
require(structure.sumOf { it.valueParameters.size } == replacement.explicitParametersCount)
|
||||||
val newArguments: List<IrExpression?> =
|
val newArguments: List<IrExpression?> =
|
||||||
makeNewArguments(parameter2expression.map { (_, argument) -> argument }, structure.map { it.valueParameters })
|
makeNewArguments(parameter2expression.map { (_, argument) -> argument }, structure.map { it.valueParameters })
|
||||||
+irCall(replacement.symbol).apply {
|
val resultExpression = makeMemberAccessExpression(replacement.symbol).apply {
|
||||||
passTypeArgumentsWithOffsets(replacement, originalFunction) { original.getTypeArgument(it)!! }
|
passTypeArgumentsWithOffsets(replacement, originalFunction) { original.getTypeArgument(it)!! }
|
||||||
for ((parameter, argument) in replacement.explicitParameters zip newArguments) {
|
for ((parameter, argument) in replacement.explicitParameters zip newArguments) {
|
||||||
if (argument == null) continue
|
if (argument == null) continue
|
||||||
putArgument(replacement, parameter, argument.transform(this@JvmMultiFieldValueClassLowering, null))
|
putArgument(replacement, parameter, argument.transform(this@JvmMultiFieldValueClassLowering, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+resultExpression
|
||||||
|
return resultExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression {
|
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression {
|
||||||
|
|||||||
+13
-1
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.transformStatement
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendContext) : FileLoweringPass,
|
internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendContext) : FileLoweringPass,
|
||||||
@@ -26,7 +27,16 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
|||||||
abstract val replacements: MemoizedValueClassAbstractReplacements
|
abstract val replacements: MemoizedValueClassAbstractReplacements
|
||||||
|
|
||||||
final override fun lower(irFile: IrFile) {
|
final override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid()
|
withinScope(irFile) {
|
||||||
|
irFile.transformChildrenVoid()
|
||||||
|
fileClassNewDeclarations[irFile]?.let { newDeclarations ->
|
||||||
|
val oldFileClass = irFile.declarations.filterIsInstanceAnd<IrClass> { it.isFileClass }.singleOrNull()
|
||||||
|
val allFileDeclarations = (oldFileClass?.declarations ?: listOf()) + newDeclarations
|
||||||
|
val newClass = createFileClass(context, irFile, allFileDeclarations)
|
||||||
|
oldFileClass?.let { irFile.declarations.remove(it) }
|
||||||
|
irFile.addChild(newClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun IrClass.isSpecificLoweringLogicApplicable(): Boolean
|
abstract fun IrClass.isSpecificLoweringLogicApplicable(): Boolean
|
||||||
@@ -246,4 +256,6 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
|||||||
abstract fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction
|
abstract fun createBridgeDeclaration(source: IrSimpleFunction, replacement: IrSimpleFunction, mangledName: Name): IrSimpleFunction
|
||||||
|
|
||||||
protected abstract fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean)
|
protected abstract fun createBridgeBody(source: IrSimpleFunction, target: IrSimpleFunction, original: IrFunction, inverted: Boolean)
|
||||||
|
|
||||||
|
protected open val fileClassNewDeclarations: Map<IrFile, List<IrSimpleFunction>> = emptyMap()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -15,6 +15,8 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
|||||||
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||||
object LAMBDA_IMPL : IrDeclarationOriginImpl("LAMBDA_IMPL")
|
object LAMBDA_IMPL : IrDeclarationOriginImpl("LAMBDA_IMPL")
|
||||||
object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL", isSynthetic = true)
|
object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL", isSynthetic = true)
|
||||||
|
object MFVC_PRIMARY_CONSTRUCTOR_REFERENCE_HELPER :
|
||||||
|
IrDeclarationOriginImpl("MFVC_PRIMARY_CONSTRUCTOR_REFERENCE_HELPER", isSynthetic = true)
|
||||||
object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR", isSynthetic = true)
|
object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR", isSynthetic = true)
|
||||||
object SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR :
|
object SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR :
|
||||||
IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR", isSynthetic = true)
|
IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR", isSynthetic = true)
|
||||||
|
|||||||
@@ -15,6 +15,16 @@ class A(val point: DPoint) {
|
|||||||
fun f(otherDPoint: DPoint, z: Double) = point.f(z) * otherDPoint.f(z)
|
fun f(otherDPoint: DPoint, z: Double) = point.f(z) * otherDPoint.f(z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun consume(point1: DPoint, point2: DPoint, f: (DPoint, DPoint) -> DPoint) = f(point1, point2)
|
||||||
|
|
||||||
|
inline fun consumeInline(point1: DPoint, point2: DPoint, f: (DPoint, DPoint) -> DPoint) = f(point1, point2)
|
||||||
|
|
||||||
|
operator fun DPoint.plus(other: DPoint) = DPoint(this.x + other.x, this.y + other.y)
|
||||||
|
|
||||||
|
fun makeDPoint(x: Double, y: Double, maker: (Double, Double) -> DPoint) = maker(x, y)
|
||||||
|
|
||||||
|
inline fun makeDPointInline(x: Double, y: Double, maker: (Double, Double) -> DPoint) = maker(x, y)
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val dPoint = DPoint(1.0, 2.0)
|
val dPoint = DPoint(1.0, 2.0)
|
||||||
val a = A(dPoint)
|
val a = A(dPoint)
|
||||||
@@ -29,5 +39,17 @@ fun box(): String {
|
|||||||
require((::g)(dPoint, DPoint(1.0, 3.0).y) == 6.0)
|
require((::g)(dPoint, DPoint(1.0, 3.0).y) == 6.0)
|
||||||
require((a::f)(dPoint, DPoint(1.0, 3.0).y) == 36.0)
|
require((a::f)(dPoint, DPoint(1.0, 3.0).y) == 36.0)
|
||||||
|
|
||||||
|
require(consume(DPoint(1.0, 2.0), DPoint(3.0, 4.0), DPoint::plus) == DPoint(4.0, 6.0))
|
||||||
|
require(consumeInline(DPoint(1.0, 2.0), DPoint(3.0, 4.0), DPoint::plus) == DPoint(4.0, 6.0))
|
||||||
|
|
||||||
|
require(makeDPoint(1.0, 2.0, ::DPoint) == DPoint(1.0, 2.0))
|
||||||
|
require(makeDPointInline(1.0, 2.0, ::DPoint) == DPoint(1.0, 2.0))
|
||||||
|
|
||||||
|
require(::DPoint == ::DPoint)
|
||||||
|
require(dPoint::f == dPoint::f)
|
||||||
|
require(::g == ::g)
|
||||||
|
require(a::f == a::f)
|
||||||
|
require(DPoint::plus == DPoint::plus)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,163 @@ public final class DPoint {
|
|||||||
public synthetic final method unbox-impl-1(): double
|
public synthetic final method unbox-impl-1(): double
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$11 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$11
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$11
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(p0: double, p1: double): DPoint
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$13 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$13
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$13
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(p0: double, p1: double): DPoint
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$14 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$14
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$14
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(p0: double, p1: double): DPoint
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$15 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$15
|
||||||
|
method <init>(p0: java.lang.Object): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(p0: double): java.lang.Double
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$16 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$16
|
||||||
|
method <init>(p0: java.lang.Object): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(p0: double): java.lang.Double
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$17 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$17
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$17
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double): java.lang.Double
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$18 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$18
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$18
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double): java.lang.Double
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$19 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$19
|
||||||
|
method <init>(p0: java.lang.Object): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double): java.lang.Double
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$20 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$20
|
||||||
|
method <init>(p0: java.lang.Object): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double): java.lang.Double
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$21 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$21
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$21
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double, p3: double): DPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$22 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$22
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$22
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double, p3: double): DPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
synthetic final class FunctionReferencesKt$box$9 {
|
||||||
|
// source: 'functionReferences.kt'
|
||||||
|
enclosing method FunctionReferencesKt.box()Ljava/lang/String;
|
||||||
|
public final static field INSTANCE: FunctionReferencesKt$box$9
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$9
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public synthetic bridge method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke-GPBa7dw(p0: double, p1: double, p2: double, p3: double): DPoint
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class FunctionReferencesKt {
|
public final class FunctionReferencesKt {
|
||||||
// source: 'functionReferences.kt'
|
// source: 'functionReferences.kt'
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$11
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$13
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$14
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$15
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$16
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$17
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$18
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$19
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$20
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$21
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$22
|
||||||
|
inner (anonymous) class FunctionReferencesKt$box$9
|
||||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method consume-lIoT8es(p0: double, p1: double, p2: double, p3: double, @org.jetbrains.annotations.NotNull p4: kotlin.jvm.functions.Function2): DPoint
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method consumeInline-lIoT8es(p0: double, p1: double, p2: double, p3: double, @org.jetbrains.annotations.NotNull p4: kotlin.jvm.functions.Function2): DPoint
|
||||||
public final static method g-GPBa7dw(p0: double, p1: double, p2: double): double
|
public final static method g-GPBa7dw(p0: double, p1: double, p2: double): double
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method makeDPoint(p0: double, p1: double, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function2): DPoint
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method makeDPointInline(p0: double, p1: double, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function2): DPoint
|
||||||
|
public synthetic final static method mfvcConstructorReferenceHelper$0(p0: double, p1: double): DPoint
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method plus-GPBa7dw(p0: double, p1: double, p2: double, p3: double): DPoint
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user