Implemented delegated properties.
This commit is contained in:
+4
-2
@@ -4,7 +4,6 @@ import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
import org.jetbrains.kotlin.backend.konan.lower.*
|
import org.jetbrains.kotlin.backend.konan.lower.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
|
|
||||||
internal class KonanLower(val context: Context) {
|
internal class KonanLower(val context: Context) {
|
||||||
|
|
||||||
@@ -39,6 +38,10 @@ internal class KonanLower(val context: Context) {
|
|||||||
phaser.phase(KonanPhase.LOWER_INITIALIZERS) {
|
phaser.phase(KonanPhase.LOWER_INITIALIZERS) {
|
||||||
InitializersLowering(context).runOnFilePostfix(irFile)
|
InitializersLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
|
phaser.phase(KonanPhase.LOWER_DELEGATION) {
|
||||||
|
ClassDelegationLowering(context).runOnFilePostfix(irFile)
|
||||||
|
PropertyDelegationLowering(context).lower(irFile)
|
||||||
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
||||||
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
@@ -58,7 +61,6 @@ internal class KonanLower(val context: Context) {
|
|||||||
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.BRIDGES_BUILDING) {
|
phaser.phase(KonanPhase.BRIDGES_BUILDING) {
|
||||||
DelegationLowering(context).runOnFilePostfix(irFile)
|
|
||||||
BridgesBuilding(context).runOnFilePostfix(irFile)
|
BridgesBuilding(context).runOnFilePostfix(irFile)
|
||||||
DirectBridgesCallsLowering(context).runOnFilePostfix(irFile)
|
DirectBridgesCallsLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -25,6 +25,7 @@ enum class KonanPhase(val description: String,
|
|||||||
/* ... ... */ LOWER_STRING_CONCAT("String concatenation lowering"),
|
/* ... ... */ LOWER_STRING_CONCAT("String concatenation lowering"),
|
||||||
/* ... ... */ LOWER_INITIALIZERS("Initializers lowering"),
|
/* ... ... */ LOWER_INITIALIZERS("Initializers lowering"),
|
||||||
/* ... ... */ BRIDGES_BUILDING("Bridges building"),
|
/* ... ... */ BRIDGES_BUILDING("Bridges building"),
|
||||||
|
/* ... ... */ LOWER_DELEGATION("Delegation lowering"),
|
||||||
/* ... */ BITCODE("LLVM BitCode Generation"),
|
/* ... */ BITCODE("LLVM BitCode Generation"),
|
||||||
/* ... ... */ RTTI("RTTI Generation"),
|
/* ... ... */ RTTI("RTTI Generation"),
|
||||||
/* ... ... */ CODEGEN("Code Generation"),
|
/* ... ... */ CODEGEN("Code Generation"),
|
||||||
|
|||||||
+5
-2
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptorBase
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptorBase
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -1226,7 +1227,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
context.log("evaluateGetField : ${ir2string(value)}")
|
context.log("evaluateGetField : ${ir2string(value)}")
|
||||||
if (value.descriptor.dispatchReceiverParameter != null
|
if (value.descriptor.dispatchReceiverParameter != null
|
||||||
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
||||||
|| value.descriptor is IrImplementingDelegateDescriptorImpl) {
|
|| value.descriptor is IrImplementingDelegateDescriptorImpl
|
||||||
|
|| (value.descriptor is IrPropertyDelegateDescriptorImpl && value.descriptor.containingDeclaration is ClassDescriptor)) {
|
||||||
val thisPtr = evaluateExpression(value.receiver!!)
|
val thisPtr = evaluateExpression(value.receiver!!)
|
||||||
return codegen.loadSlot(
|
return codegen.loadSlot(
|
||||||
fieldPtrOfClass(thisPtr, value.descriptor), value.descriptor.isVar())
|
fieldPtrOfClass(thisPtr, value.descriptor), value.descriptor.isVar())
|
||||||
@@ -1258,7 +1260,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
if (value.descriptor.dispatchReceiverParameter != null
|
if (value.descriptor.dispatchReceiverParameter != null
|
||||||
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
||||||
|| value.descriptor is IrImplementingDelegateDescriptorImpl) {
|
|| value.descriptor is IrImplementingDelegateDescriptorImpl
|
||||||
|
|| (value.descriptor is IrPropertyDelegateDescriptorImpl && value.descriptor.containingDeclaration is ClassDescriptor)) {
|
||||||
val thisPtr = evaluateExpression(value.receiver!!)
|
val thisPtr = evaluateExpression(value.receiver!!)
|
||||||
codegen.storeAnyGlobal(valueToAssign, fieldPtrOfClass(thisPtr, value.descriptor))
|
codegen.storeAnyGlobal(valueToAssign, fieldPtrOfClass(thisPtr, value.descriptor))
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -125,7 +125,7 @@ private fun ContextUtils.getDeclaredFields(classDescriptor: ClassDescriptor): Li
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ContextUtils.createClassBodyType(name: String, fields: List<PropertyDescriptor>): LLVMTypeRef {
|
private fun ContextUtils.createClassBodyType(name: String, fields: List<PropertyDescriptor>): LLVMTypeRef {
|
||||||
val fieldTypes = fields.map { getLLVMType(it.type) }.toTypedArray()
|
val fieldTypes = fields.map { getLLVMType(if (it.isDelegated) context.builtIns.nullableAnyType else it.type) }.toTypedArray()
|
||||||
|
|
||||||
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!!
|
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!!
|
||||||
|
|
||||||
@@ -300,7 +300,8 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
|||||||
val dispatchReceiverParameter = descriptor.dispatchReceiverParameter
|
val dispatchReceiverParameter = descriptor.dispatchReceiverParameter
|
||||||
if (dispatchReceiverParameter != null
|
if (dispatchReceiverParameter != null
|
||||||
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
||||||
|| descriptor is IrImplementingDelegateDescriptorImpl) {
|
|| descriptor is IrImplementingDelegateDescriptorImpl
|
||||||
|
|| (descriptor is IrPropertyDelegateDescriptorImpl && descriptor.containingDeclaration is ClassDescriptor)) {
|
||||||
val containingClass = dispatchReceiverParameter?.containingDeclaration
|
val containingClass = dispatchReceiverParameter?.containingDeclaration
|
||||||
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
// TODO: hack because of IR bug: https://github.com/JetBrains/kotlin/tree/rr/dispatch_receiver_for_delegate_descriptor.
|
||||||
?: descriptor.containingDeclaration
|
?: descriptor.containingDeclaration
|
||||||
|
|||||||
+1
-1
@@ -131,7 +131,7 @@ internal class MetadataGenerator(override val context: Context): ContextUtils {
|
|||||||
|
|
||||||
internal fun property(declaration: IrProperty) {
|
internal fun property(declaration: IrProperty) {
|
||||||
if (declaration.backingField == null) return
|
if (declaration.backingField == null) return
|
||||||
assert(declaration.backingField!!.descriptor == declaration.descriptor)
|
assert(declaration.backingField!!.descriptor == declaration.descriptor || declaration.isDelegated)
|
||||||
|
|
||||||
context.ir.propertiesWithBackingFields.add(declaration.descriptor)
|
context.ir.propertiesWithBackingFields.add(declaration.descriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-67
@@ -13,8 +13,10 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -66,71 +68,6 @@ internal class DirectBridgesCallsLowering(val context: Context) : BodyLoweringPa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object DECLARATION_ORIGIN_BRIDGE_METHOD :
|
|
||||||
IrDeclarationOriginImpl("BRIDGE_METHOD")
|
|
||||||
|
|
||||||
internal class DelegationLowering(val context: Context) : ClassLoweringPass {
|
|
||||||
override fun lower(irClass: IrClass) {
|
|
||||||
irClass.declarations.transformFlat {
|
|
||||||
when (it) {
|
|
||||||
is IrFunction -> {
|
|
||||||
val transformedFun = transformBridgeToDelegatedMethod(irClass, it)
|
|
||||||
if (transformedFun == null) null
|
|
||||||
else listOf(transformedFun)
|
|
||||||
}
|
|
||||||
is IrProperty -> {
|
|
||||||
val getter = transformBridgeToDelegatedMethod(irClass, it.getter)
|
|
||||||
val setter = transformBridgeToDelegatedMethod(irClass, it.setter)
|
|
||||||
if (getter != null) it.getter = getter
|
|
||||||
if (setter != null) it.setter = setter
|
|
||||||
null
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: hack because of broken IR for synthesized delegated members: https://youtrack.jetbrains.com/issue/KT-16486.
|
|
||||||
private fun transformBridgeToDelegatedMethod(irClass: IrClass, irFunction: IrFunction?): IrFunction? {
|
|
||||||
if (irFunction == null || irFunction.descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION) return null
|
|
||||||
|
|
||||||
val body = irFunction.body as? IrBlockBody
|
|
||||||
?: throw AssertionError("Unexpected method body: ${irFunction.body}")
|
|
||||||
val statement = body.statements.single()
|
|
||||||
val delegatedCall = ((statement as? IrReturn)?.value ?: statement) as? IrCall
|
|
||||||
?: throw AssertionError("Unexpected method body: $statement")
|
|
||||||
val propertyGetter = delegatedCall.dispatchReceiver as? IrGetValue
|
|
||||||
?: throw AssertionError("Unexpected dispatch receiver: ${delegatedCall.dispatchReceiver}")
|
|
||||||
val propertyDescriptor = propertyGetter.descriptor as? PropertyDescriptor
|
|
||||||
?: throw AssertionError("Unexpected dispatch receiver descriptor: ${propertyGetter.descriptor}")
|
|
||||||
val delegated = context.specialDescriptorsFactory.getBridgeDescriptor(
|
|
||||||
OverriddenFunctionDescriptor(irFunction.descriptor, delegatedCall.descriptor as FunctionDescriptor))
|
|
||||||
val newFunction = IrFunctionImpl(irFunction.startOffset, irFunction.endOffset, DECLARATION_ORIGIN_BRIDGE_METHOD, delegated)
|
|
||||||
|
|
||||||
val irBlockBody = IrBlockBodyImpl(irFunction.startOffset, irFunction.endOffset)
|
|
||||||
val returnType = delegatedCall.descriptor.returnType!!
|
|
||||||
val irCall = IrCallImpl(irFunction.startOffset, irFunction.endOffset, returnType, delegatedCall.descriptor, null)
|
|
||||||
val receiver = IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, irClass.descriptor.thisAsReceiverParameter)
|
|
||||||
irCall.dispatchReceiver = IrGetFieldImpl(irFunction.startOffset, irFunction.endOffset, propertyDescriptor, receiver)
|
|
||||||
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
|
|
||||||
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, extensionReceiver)
|
|
||||||
}
|
|
||||||
irCall.mapValueParameters { overriddenValueParameter ->
|
|
||||||
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
|
|
||||||
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, delegatedValueParameter)
|
|
||||||
}
|
|
||||||
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
|
||||||
irBlockBody.statements.add(irCall)
|
|
||||||
} else {
|
|
||||||
val irReturn = IrReturnImpl(irFunction.startOffset, irFunction.endOffset, context.builtIns.nothingType, delegated, irCall)
|
|
||||||
irBlockBody.statements.add(irReturn)
|
|
||||||
}
|
|
||||||
|
|
||||||
newFunction.body = irBlockBody
|
|
||||||
return newFunction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
|
internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
val functions = mutableSetOf<FunctionDescriptor?>()
|
val functions = mutableSetOf<FunctionDescriptor?>()
|
||||||
@@ -160,6 +97,9 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object DECLARATION_ORIGIN_BRIDGE_METHOD :
|
||||||
|
IrDeclarationOriginImpl("BRIDGE_METHOD")
|
||||||
|
|
||||||
private fun buildBridge(descriptor: OverriddenFunctionDescriptor, irClass: IrClass) {
|
private fun buildBridge(descriptor: OverriddenFunctionDescriptor, irClass: IrClass) {
|
||||||
val bridgeDescriptor = context.specialDescriptorsFactory.getBridgeDescriptor(descriptor)
|
val bridgeDescriptor = context.specialDescriptorsFactory.getBridgeDescriptor(descriptor)
|
||||||
val target = descriptor.descriptor.target
|
val target = descriptor.descriptor.target
|
||||||
|
|||||||
+149
@@ -0,0 +1,149 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.OverriddenFunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||||
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
|
internal class ClassDelegationLowering(val context: Context) : DeclarationContainerLoweringPass {
|
||||||
|
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||||
|
irDeclarationContainer.declarations.transformFlat {
|
||||||
|
when (it) {
|
||||||
|
is IrFunction -> {
|
||||||
|
val transformedFun = transformBridgeToDelegatedMethod(irDeclarationContainer, it)
|
||||||
|
if (transformedFun == null) null
|
||||||
|
else listOf(transformedFun)
|
||||||
|
}
|
||||||
|
is IrProperty -> {
|
||||||
|
val getter = transformBridgeToDelegatedMethod(irDeclarationContainer, it.getter)
|
||||||
|
val setter = transformBridgeToDelegatedMethod(irDeclarationContainer, it.setter)
|
||||||
|
if (getter != null) it.getter = getter
|
||||||
|
if (setter != null) it.setter = setter
|
||||||
|
null
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformBridgeToDelegatedMethod(irDeclarationContainer: IrDeclarationContainer, irFunction: IrFunction?): IrFunction? {
|
||||||
|
if (irFunction == null) return null
|
||||||
|
val descriptor = irFunction.descriptor
|
||||||
|
|
||||||
|
if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION) return null
|
||||||
|
|
||||||
|
// TODO: hack because of broken IR for synthesized delegated members: https://youtrack.jetbrains.com/issue/KT-16486.
|
||||||
|
val body = irFunction.body as? IrBlockBody
|
||||||
|
?: throw AssertionError("Unexpected method body: ${irFunction.body}")
|
||||||
|
val statement = body.statements.single()
|
||||||
|
val delegatedCall = ((statement as? IrReturn)?.value ?: statement) as? IrCall
|
||||||
|
?: throw AssertionError("Unexpected method body: $statement")
|
||||||
|
val propertyGetter = delegatedCall.dispatchReceiver as? IrGetValue
|
||||||
|
?: throw AssertionError("Unexpected dispatch receiver: ${delegatedCall.dispatchReceiver}")
|
||||||
|
val propertyDescriptor = propertyGetter.descriptor as? PropertyDescriptor
|
||||||
|
?: throw AssertionError("Unexpected dispatch receiver descriptor: ${propertyGetter.descriptor}")
|
||||||
|
val delegated = context.specialDescriptorsFactory.getBridgeDescriptor(
|
||||||
|
OverriddenFunctionDescriptor(descriptor, delegatedCall.descriptor as FunctionDescriptor))
|
||||||
|
val newFunction = IrFunctionImpl(irFunction.startOffset, irFunction.endOffset, irFunction.origin, delegated)
|
||||||
|
|
||||||
|
val irBlockBody = IrBlockBodyImpl(irFunction.startOffset, irFunction.endOffset)
|
||||||
|
val returnType = delegatedCall.descriptor.returnType!!
|
||||||
|
val irCall = IrCallImpl(irFunction.startOffset, irFunction.endOffset, returnType, delegatedCall.descriptor, null)
|
||||||
|
val receiver = IrGetValueImpl(irFunction.startOffset, irFunction.endOffset,
|
||||||
|
(irDeclarationContainer as IrClass).descriptor.thisAsReceiverParameter)
|
||||||
|
irCall.dispatchReceiver = IrGetFieldImpl(irFunction.startOffset, irFunction.endOffset, propertyDescriptor, receiver)
|
||||||
|
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
|
||||||
|
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, extensionReceiver)
|
||||||
|
}
|
||||||
|
irCall.mapValueParameters { overriddenValueParameter ->
|
||||||
|
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
|
||||||
|
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, delegatedValueParameter)
|
||||||
|
}
|
||||||
|
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
|
||||||
|
irBlockBody.statements.add(irCall)
|
||||||
|
} else {
|
||||||
|
val irReturn = IrReturnImpl(irFunction.startOffset, irFunction.endOffset, context.builtIns.nothingType, delegated, irCall)
|
||||||
|
irBlockBody.statements.add(irReturn)
|
||||||
|
}
|
||||||
|
|
||||||
|
newFunction.body = irBlockBody
|
||||||
|
return newFunction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass {
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
|
return super.visitFunction(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement {
|
||||||
|
declaration.transformChildrenVoid(this)
|
||||||
|
val name = declaration.descriptor.name.asString()
|
||||||
|
val type = declaration.descriptor.type
|
||||||
|
|
||||||
|
val initializer = declaration.delegate.initializer!!
|
||||||
|
return IrVariableImpl(declaration.startOffset, declaration.endOffset,
|
||||||
|
declaration.origin, declaration.delegate.descriptor,
|
||||||
|
IrBlockImpl(initializer.startOffset, initializer.endOffset, initializer.type, null,
|
||||||
|
listOf(
|
||||||
|
transformBridgeToDelegate(name, type, declaration.getter),
|
||||||
|
transformBridgeToDelegate(name, type, declaration.setter),
|
||||||
|
initializer
|
||||||
|
).filterNotNull())
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(declaration: IrProperty): IrStatement {
|
||||||
|
declaration.transformChildrenVoid(this)
|
||||||
|
if (declaration.isDelegated) {
|
||||||
|
val name = declaration.descriptor.name.asString()
|
||||||
|
val type = declaration.descriptor.returnType!!
|
||||||
|
declaration.getter = transformBridgeToDelegate(name, type, declaration.getter)
|
||||||
|
declaration.setter = transformBridgeToDelegate(name, type, declaration.setter)
|
||||||
|
}
|
||||||
|
return declaration
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName.fromSegments(listOf("kotlin", "reflect")))
|
||||||
|
private val genericKPropertyImplType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("KPropertyImpl"),
|
||||||
|
NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||||
|
|
||||||
|
private fun transformBridgeToDelegate(name: String, type: KotlinType, irFunction: IrFunction?): IrFunction? {
|
||||||
|
irFunction?.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
|
||||||
|
val typeParameterT = genericKPropertyImplType.declaredTypeParameters[0]
|
||||||
|
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(type)))
|
||||||
|
val kPropertyImplType = genericKPropertyImplType.substitute(typeSubstitutor)
|
||||||
|
return IrCallImpl(expression.startOffset, expression.endOffset,
|
||||||
|
kPropertyImplType.defaultType, kPropertyImplType.unsubstitutedPrimaryConstructor!!, null).apply {
|
||||||
|
putValueArgument(0, IrConstImpl<String>(expression.startOffset, expression.endOffset,
|
||||||
|
context.builtIns.stringType, IrConstKind.String, name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return irFunction
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -54,6 +54,16 @@ public annotation class FixmeVariance
|
|||||||
*/
|
*/
|
||||||
public annotation class FixmeRegex
|
public annotation class FixmeRegex
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Need to be fixed because of reflection.
|
||||||
|
*/
|
||||||
|
public annotation class FixmeReflection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Need to be fixed because of concurrency.
|
||||||
|
*/
|
||||||
|
public annotation class FixmeConcurrency
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Need to be fixed.
|
* Need to be fixed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
package kotlin
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a value with lazy initialization.
|
||||||
|
*
|
||||||
|
* To create an instance of [Lazy] use the [lazy] function.
|
||||||
|
*/
|
||||||
|
public interface Lazy<out T> {
|
||||||
|
/**
|
||||||
|
* Gets the lazily initialized value of the current Lazy instance.
|
||||||
|
* Once the value was initialized it must not change during the rest of lifetime of this Lazy instance.
|
||||||
|
*/
|
||||||
|
public val value: T
|
||||||
|
/**
|
||||||
|
* Returns `true` if a value for this Lazy instance has been already initialized, and `false` otherwise.
|
||||||
|
* Once this function has returned `true` it stays `true` for the rest of lifetime of this Lazy instance.
|
||||||
|
*/
|
||||||
|
public fun isInitialized(): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the [Lazy] that is already initialized with the specified [value].
|
||||||
|
*/
|
||||||
|
public fun <T> lazyOf(value: T): Lazy<T> = InitializedLazyImpl(value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer]
|
||||||
|
* and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED].
|
||||||
|
*
|
||||||
|
* If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access.
|
||||||
|
*
|
||||||
|
* Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on
|
||||||
|
* the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future.
|
||||||
|
*/
|
||||||
|
@FixmeConcurrency
|
||||||
|
public fun <T> lazy(initializer: () -> T): Lazy<T> = UnsafeLazyImpl(initializer)//SynchronizedLazyImpl(initializer)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer]
|
||||||
|
* and thread-safety [mode].
|
||||||
|
*
|
||||||
|
* If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access.
|
||||||
|
*
|
||||||
|
* Note that when the [LazyThreadSafetyMode.SYNCHRONIZED] mode is specified the returned instance uses itself
|
||||||
|
* to synchronize on. Do not synchronize from external code on the returned instance as it may cause accidental deadlock.
|
||||||
|
* Also this behavior can be changed in the future.
|
||||||
|
*/
|
||||||
|
@FixmeConcurrency
|
||||||
|
public fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
|
||||||
|
when (mode) {
|
||||||
|
LazyThreadSafetyMode.SYNCHRONIZED -> TODO()//SynchronizedLazyImpl(initializer)
|
||||||
|
LazyThreadSafetyMode.PUBLICATION -> TODO()//SafePublicationLazyImpl(initializer)
|
||||||
|
LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer]
|
||||||
|
* and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED].
|
||||||
|
*
|
||||||
|
* If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access.
|
||||||
|
*
|
||||||
|
* The returned instance uses the specified [lock] object to synchronize on.
|
||||||
|
* When the [lock] is not specified the instance uses itself to synchronize on,
|
||||||
|
* in this case do not synchronize from external code on the returned instance as it may cause accidental deadlock.
|
||||||
|
* Also this behavior can be changed in the future.
|
||||||
|
*/
|
||||||
|
@FixmeConcurrency
|
||||||
|
public fun <T> lazy(lock: Any?, initializer: () -> T): Lazy<T> = TODO()//SynchronizedLazyImpl(initializer, lock)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An extension to delegate a read-only property of type [T] to an instance of [Lazy].
|
||||||
|
*
|
||||||
|
* This extension allows to use instances of Lazy for property delegation:
|
||||||
|
* `val property: String by lazy { initializer }`
|
||||||
|
*/
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies how a [Lazy] instance synchronizes access among multiple threads.
|
||||||
|
*/
|
||||||
|
public enum class LazyThreadSafetyMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks are used to ensure that only a single thread can initialize the [Lazy] instance.
|
||||||
|
*/
|
||||||
|
SYNCHRONIZED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializer function can be called several times on concurrent access to uninitialized [Lazy] instance value,
|
||||||
|
* but only first returned value will be used as the value of [Lazy] instance.
|
||||||
|
*/
|
||||||
|
PUBLICATION,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No locks are used to synchronize the access to the [Lazy] instance value; if the instance is accessed from multiple threads, its behavior is undefined.
|
||||||
|
*
|
||||||
|
* This mode should be used only when high performance is crucial and the [Lazy] instance is guaranteed never to be initialized from more than one thread.
|
||||||
|
*/
|
||||||
|
NONE,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private object UNINITIALIZED_VALUE
|
||||||
|
|
||||||
|
//private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>, Serializable {
|
||||||
|
// private var initializer: (() -> T)? = initializer
|
||||||
|
// @Volatile private var _value: Any? = UNINITIALIZED_VALUE
|
||||||
|
// // final field is required to enable safe publication of constructed instance
|
||||||
|
// private val lock = lock ?: this
|
||||||
|
//
|
||||||
|
// override val value: T
|
||||||
|
// get() {
|
||||||
|
// val _v1 = _value
|
||||||
|
// if (_v1 !== UNINITIALIZED_VALUE) {
|
||||||
|
// @Suppress("UNCHECKED_CAST")
|
||||||
|
// return _v1 as T
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return synchronized(lock) {
|
||||||
|
// val _v2 = _value
|
||||||
|
// if (_v2 !== UNINITIALIZED_VALUE) {
|
||||||
|
// @Suppress("UNCHECKED_CAST") (_v2 as T)
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// val typedValue = initializer!!()
|
||||||
|
// _value = typedValue
|
||||||
|
// initializer = null
|
||||||
|
// typedValue
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
|
||||||
|
//
|
||||||
|
// override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
|
||||||
|
//
|
||||||
|
// private fun writeReplace(): Any = InitializedLazyImpl(value)
|
||||||
|
//}
|
||||||
|
|
||||||
|
internal class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T>/*, Serializable*/ {
|
||||||
|
private var initializer: (() -> T)? = initializer
|
||||||
|
private var _value: Any? = UNINITIALIZED_VALUE
|
||||||
|
|
||||||
|
override val value: T
|
||||||
|
get() {
|
||||||
|
if (_value === UNINITIALIZED_VALUE) {
|
||||||
|
_value = initializer!!()
|
||||||
|
initializer = null
|
||||||
|
}
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return _value as T
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
|
||||||
|
|
||||||
|
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
|
||||||
|
|
||||||
|
private fun writeReplace(): Any = InitializedLazyImpl(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InitializedLazyImpl<out T>(override val value: T) : Lazy<T>/*, Serializable*/ {
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean = true
|
||||||
|
|
||||||
|
override fun toString(): String = value.toString()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//private class SafePublicationLazyImpl<out T>(initializer: () -> T) : Lazy<T>, Serializable {
|
||||||
|
// private var initializer: (() -> T)? = initializer
|
||||||
|
// @Volatile private var _value: Any? = UNINITIALIZED_VALUE
|
||||||
|
// // this final field is required to enable safe publication of constructed instance
|
||||||
|
// private val final: Any = UNINITIALIZED_VALUE
|
||||||
|
//
|
||||||
|
// override val value: T
|
||||||
|
// get() {
|
||||||
|
// if (_value === UNINITIALIZED_VALUE) {
|
||||||
|
// val initializerValue = initializer
|
||||||
|
// // if we see null in initializer here, it means that the value is already set by another thread
|
||||||
|
// if (initializerValue != null) {
|
||||||
|
// val newValue = initializerValue()
|
||||||
|
// if (valueUpdater.compareAndSet(this, UNINITIALIZED_VALUE, newValue)) {
|
||||||
|
// initializer = null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// @Suppress("UNCHECKED_CAST")
|
||||||
|
// return _value as T
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
|
||||||
|
//
|
||||||
|
// override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
|
||||||
|
//
|
||||||
|
// private fun writeReplace(): Any = InitializedLazyImpl(value)
|
||||||
|
//
|
||||||
|
// companion object {
|
||||||
|
// private val valueUpdater = java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(
|
||||||
|
// SafePublicationLazyImpl::class.java,
|
||||||
|
// Any::class.java,
|
||||||
|
// "_value")
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package kotlin.properties
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard property delegates.
|
||||||
|
*/
|
||||||
|
public object Delegates {
|
||||||
|
/**
|
||||||
|
* Returns a property delegate for a read/write property with a non-`null` value that is initialized not during
|
||||||
|
* object construction time but at a later time. Trying to read the property before the initial value has been
|
||||||
|
* assigned results in an exception.
|
||||||
|
*/
|
||||||
|
public fun <T: Any> notNull(): ReadWriteProperty<Any?, T> = NotNullVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a property delegate for a read/write property that calls a specified callback function when changed.
|
||||||
|
* @param initialValue the initial value of the property.
|
||||||
|
* @param onChange the callback which is called after the change of the property is made. The value of the property
|
||||||
|
* has already been changed when this callback is invoked.
|
||||||
|
*/
|
||||||
|
public inline fun <T> observable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Unit):
|
||||||
|
ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
|
||||||
|
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a property delegate for a read/write property that calls a specified callback function when changed,
|
||||||
|
* allowing the callback to veto the modification.
|
||||||
|
* @param initialValue the initial value of the property.
|
||||||
|
* @param onChange the callback which is called before a change to the property value is attempted.
|
||||||
|
* The value of the property hasn't been changed yet, when this callback is invoked.
|
||||||
|
* If the callback returns `true` the value of the property is being set to the new value,
|
||||||
|
* and if the callback returns `false` the new value is discarded and the property remains its old value.
|
||||||
|
*/
|
||||||
|
public inline fun <T> vetoable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean):
|
||||||
|
ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
|
||||||
|
override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class NotNullVar<T: Any>() : ReadWriteProperty<Any?, T> {
|
||||||
|
private var value: T? = null
|
||||||
|
|
||||||
|
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package kotlin.properties
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface that can be used for implementing property delegates of read-only properties.
|
||||||
|
*
|
||||||
|
* This is provided only for convenience; you don't have to extend this interface
|
||||||
|
* as long as your property delegate has methods with the same signatures.
|
||||||
|
*
|
||||||
|
* @param R the type of object which owns the delegated property.
|
||||||
|
* @param T the type of the property value.
|
||||||
|
*/
|
||||||
|
public interface ReadOnlyProperty<in R, out T> {
|
||||||
|
/**
|
||||||
|
* Returns the value of the property for the given object.
|
||||||
|
* @param thisRef the object for which the value is requested.
|
||||||
|
* @param property the metadata for the property.
|
||||||
|
* @return the property value.
|
||||||
|
*/
|
||||||
|
public operator fun getValue(thisRef: R, property: KProperty<*>): T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface that can be used for implementing property delegates of read-write properties.
|
||||||
|
*
|
||||||
|
* This is provided only for convenience; you don't have to extend this interface
|
||||||
|
* as long as your property delegate has methods with the same signatures.
|
||||||
|
*
|
||||||
|
* @param R the type of object which owns the delegated property.
|
||||||
|
* @param T the type of the property value.
|
||||||
|
*/
|
||||||
|
public interface ReadWriteProperty<in R, T> {
|
||||||
|
/**
|
||||||
|
* Returns the value of the property for the given object.
|
||||||
|
* @param thisRef the object for which the value is requested.
|
||||||
|
* @param property the metadata for the property.
|
||||||
|
* @return the property value.
|
||||||
|
*/
|
||||||
|
public operator fun getValue(thisRef: R, property: KProperty<*>): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the property for the given object.
|
||||||
|
* @param thisRef the object for which the value is requested.
|
||||||
|
* @param property the metadata for the property.
|
||||||
|
* @param value the value to set.
|
||||||
|
*/
|
||||||
|
public operator fun setValue(thisRef: R, property: KProperty<*>, value: T)
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package kotlin.properties
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the core logic of a property delegate for a read/write property that calls callback functions when changed.
|
||||||
|
* @param initialValue the initial value of the property.
|
||||||
|
*/
|
||||||
|
public abstract class ObservableProperty<T>(initialValue: T) : ReadWriteProperty<Any?, T> {
|
||||||
|
private var value = initialValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback which is called before a change to the property value is attempted.
|
||||||
|
* The value of the property hasn't been changed yet, when this callback is invoked.
|
||||||
|
* If the callback returns `true` the value of the property is being set to the new value,
|
||||||
|
* and if the callback returns `false` the new value is discarded and the property remains its old value.
|
||||||
|
*/
|
||||||
|
protected open fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback which is called after the change of the property is made. The value of the property
|
||||||
|
* has already been changed when this callback is invoked.
|
||||||
|
*/
|
||||||
|
protected open fun afterChange (property: KProperty<*>, oldValue: T, newValue: T): Unit {}
|
||||||
|
|
||||||
|
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
|
val oldValue = this.value
|
||||||
|
if (!beforeChange(property, oldValue, value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.value = value
|
||||||
|
afterChange(property, oldValue, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an annotated element and allows to obtain its annotations.
|
||||||
|
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/annotations.html)
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
|
@FixmeReflection
|
||||||
|
public interface KAnnotatedElement {
|
||||||
|
// /**
|
||||||
|
// * Annotations which are present on this element.
|
||||||
|
// */
|
||||||
|
// public val annotations: List<Annotation>
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a callable entity, such as a function or a property.
|
||||||
|
*
|
||||||
|
* @param R return type of the callable.
|
||||||
|
*/
|
||||||
|
@FixmeReflection
|
||||||
|
public interface KCallable<out R> : KAnnotatedElement {
|
||||||
|
/**
|
||||||
|
* The name of this callable as it was declared in the source code.
|
||||||
|
* If the callable has no name, a special invented name is created.
|
||||||
|
* Nameless callables include:
|
||||||
|
* - constructors have the name "<init>",
|
||||||
|
* - property accessors: the getter for a property named "foo" will have the name "<get-foo>",
|
||||||
|
* the setter, similarly, will have the name "<set-foo>".
|
||||||
|
*/
|
||||||
|
public val name: String
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Parameters required to make a call to this callable.
|
||||||
|
// * If this callable requires a `this` instance or an extension receiver parameter,
|
||||||
|
// * they come first in the list in that order.
|
||||||
|
// */
|
||||||
|
// public val parameters: List<KParameter>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * The type of values returned by this callable.
|
||||||
|
// */
|
||||||
|
// public val returnType: KType
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * The list of type parameters of this callable.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val typeParameters: List<KTypeParameter>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Calls this callable with the specified list of arguments and returns the result.
|
||||||
|
// * Throws an exception if the number of specified arguments is not equal to the size of [parameters],
|
||||||
|
// * or if their types do not match the types of the parameters.
|
||||||
|
// */
|
||||||
|
// public fun call(vararg args: Any?): R
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Calls this callable with the specified mapping of parameters to arguments and returns the result.
|
||||||
|
// * If a parameter is not found in the mapping and is not optional (as per [KParameter.isOptional]),
|
||||||
|
// * or its type does not match the type of the provided value, an exception is thrown.
|
||||||
|
// */
|
||||||
|
// public fun callBy(args: Map<KParameter, Any?>): R
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Visibility of this callable, or `null` if its visibility cannot be represented in Kotlin.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val visibility: KVisibility?
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this callable is `final`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isFinal: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this callable is `open`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isOpen: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this callable is `abstract`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isAbstract: Boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a property, such as a named `val` or `var` declaration.
|
||||||
|
* Instances of this class are obtainable by the `::` operator.
|
||||||
|
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/reflection.html)
|
||||||
|
* for more information.
|
||||||
|
*
|
||||||
|
* @param R the type of the property.
|
||||||
|
*/
|
||||||
|
@FixmeReflection
|
||||||
|
public interface KProperty<out R> : KCallable<R> {
|
||||||
|
// /**
|
||||||
|
// * `true` if this property is `lateinit`.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isLateinit: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this property is `const`.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/properties.html#compile-time-constants)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isConst: Boolean
|
||||||
|
//
|
||||||
|
// /** The getter of this property, used to obtain the value of the property. */
|
||||||
|
// public val getter: Getter<R>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Represents a property accessor, which is a `get` or `set` method declared alongside the property.
|
||||||
|
// * See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/properties.html#getters-and-setters)
|
||||||
|
// * for more information.
|
||||||
|
// *
|
||||||
|
// * @param R the type of the property, which it is an accessor of.
|
||||||
|
// */
|
||||||
|
// public interface Accessor<out R> {
|
||||||
|
// /** The property which this accessor is originated from. */
|
||||||
|
// public val property: KProperty<R>
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Getter of the property is a `get` method declared alongside the property.
|
||||||
|
// */
|
||||||
|
// public interface Getter<out R> : Accessor<R>, KFunction<R>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a property declared as a `var`.
|
||||||
|
*/
|
||||||
|
@FixmeReflection
|
||||||
|
public interface KMutableProperty<R> : KProperty<R> {
|
||||||
|
// /** The setter of this mutable property, used to change the value of the property. */
|
||||||
|
// public val setter: Setter<R>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Setter of the property is a `set` method declared alongside the property.
|
||||||
|
// */
|
||||||
|
// public interface Setter<R> : KProperty.Accessor<R>, KFunction<Unit>
|
||||||
|
}
|
||||||
|
|
||||||
|
@FixmeReflection
|
||||||
|
public class KPropertyImpl<out R>(override val name: String) : KProperty<R> {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user