bridge: add ScopeFacade receiver overloads for binder callbacks
This commit is contained in:
1 parent
65edf9fe67
commit
8a32ffe655
6 files changed
+212
-62
No files matched your search
@@ -60,12 +60,54 @@ interface ClassBridgeBinder {
|
||||
/** Register an initialization hook that runs for each instance. */
|
||||
fun init(block: suspend BridgeInstanceContext.(ScopeFacade) -> Unit)
|
||||
/** Register an initialization hook with direct access to the instance. */
|
||||
fun initWithInstance(block: suspend ScopeFacade.() -> Unit)
|
||||
/**
|
||||
* Legacy initWithInstance form.
|
||||
* Prefer [initWithInstance] with [ScopeFacade] receiver and use [ScopeFacade.thisObj].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use initWithInstance { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("initWithInstance { block(this, thisObj) }")
|
||||
)
|
||||
fun initWithInstance(block: suspend (ScopeFacade, Obj) -> Unit)
|
||||
/** Bind a Lyng function/member to a Kotlin implementation (requires `extern` in Lyng). */
|
||||
fun addFun(name: String, impl: suspend ScopeFacade.() -> Obj)
|
||||
/**
|
||||
* Legacy addFun form.
|
||||
* Prefer [addFun] with [ScopeFacade] receiver and use [ScopeFacade.thisObj]/[ScopeFacade.args].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use addFun(name) { ... } with ScopeFacade receiver; use thisObj/args from scope",
|
||||
replaceWith = ReplaceWith("addFun(name) { impl(this, thisObj, args) }")
|
||||
)
|
||||
fun addFun(name: String, impl: suspend (ScopeFacade, Obj, Arguments) -> Obj)
|
||||
/** Bind a read-only member (val/property getter) declared as `extern`. */
|
||||
fun addVal(name: String, impl: suspend ScopeFacade.() -> Obj)
|
||||
/**
|
||||
* Legacy addVal form.
|
||||
* Prefer [addVal] with [ScopeFacade] receiver and use [ScopeFacade.thisObj].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use addVal(name) { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("addVal(name) { impl(this, thisObj) }")
|
||||
)
|
||||
fun addVal(name: String, impl: suspend (ScopeFacade, Obj) -> Obj)
|
||||
/** Bind a mutable member (var/property getter/setter) declared as `extern`. */
|
||||
fun addVar(
|
||||
name: String,
|
||||
get: suspend ScopeFacade.() -> Obj,
|
||||
set: suspend ScopeFacade.(Obj) -> Unit
|
||||
)
|
||||
/**
|
||||
* Legacy addVar form.
|
||||
* Prefer [addVar] with [ScopeFacade] receiver and use [ScopeFacade.thisObj].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use addVar(name, get, set) with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith(
|
||||
"addVar(name, get = { get(this, thisObj) }, set = { value -> set(this, thisObj, value) })"
|
||||
)
|
||||
)
|
||||
fun addVar(
|
||||
name: String,
|
||||
get: suspend (ScopeFacade, Obj) -> Obj,
|
||||
@@ -234,17 +276,27 @@ private class ClassBridgeBinderImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun initWithInstance(block: suspend ScopeFacade.() -> Unit) {
|
||||
initHooks.add { scope, _ ->
|
||||
scope.block()
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use initWithInstance { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("initWithInstance { block(this, thisObj) }")
|
||||
)
|
||||
override fun initWithInstance(block: suspend (ScopeFacade, Obj) -> Unit) {
|
||||
initHooks.add { scope, inst ->
|
||||
block(scope, inst)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addFun(name: String, impl: suspend (ScopeFacade, Obj, Arguments) -> Obj) {
|
||||
override fun addFun(name: String, impl: suspend ScopeFacade.() -> Obj) {
|
||||
ensureTemplateNotBuilt()
|
||||
val target = findMember(name)
|
||||
val callable = ObjExternCallable.fromBridge {
|
||||
impl(this, thisObj, args)
|
||||
impl()
|
||||
}
|
||||
val methodId = cls.ensureMethodIdForBridge(name, target.record)
|
||||
val newRecord = target.record.copy(
|
||||
@@ -255,14 +307,24 @@ private class ClassBridgeBinderImpl(
|
||||
replaceMember(target, newRecord)
|
||||
}
|
||||
|
||||
override fun addVal(name: String, impl: suspend (ScopeFacade, Obj) -> Obj) {
|
||||
@Deprecated(
|
||||
message = "Use addFun(name) { ... } with ScopeFacade receiver; use thisObj/args from scope",
|
||||
replaceWith = ReplaceWith("addFun(name) { impl(this, thisObj, args) }")
|
||||
)
|
||||
override fun addFun(name: String, impl: suspend (ScopeFacade, Obj, Arguments) -> Obj) {
|
||||
addFun(name) {
|
||||
impl(this, thisObj, args)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVal(name: String, impl: suspend ScopeFacade.() -> Obj) {
|
||||
ensureTemplateNotBuilt()
|
||||
val target = findMember(name)
|
||||
if (target.record.isMutable) {
|
||||
throw ScriptError(Pos.builtIn, "extern val $name is mutable in class ${cls.className}")
|
||||
}
|
||||
val getter = ObjExternCallable.fromBridge {
|
||||
impl(this, thisObj)
|
||||
impl()
|
||||
}
|
||||
val prop = ObjProperty(name, getter, null)
|
||||
val isFieldLike = target.record.type == ObjRecord.Type.Field ||
|
||||
@@ -287,10 +349,20 @@ private class ClassBridgeBinderImpl(
|
||||
replaceMember(target, newRecord)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use addVal(name) { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("addVal(name) { impl(this, thisObj) }")
|
||||
)
|
||||
override fun addVal(name: String, impl: suspend (ScopeFacade, Obj) -> Obj) {
|
||||
addVal(name) {
|
||||
impl(this, thisObj)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVar(
|
||||
name: String,
|
||||
get: suspend (ScopeFacade, Obj) -> Obj,
|
||||
set: suspend (ScopeFacade, Obj, Obj) -> Unit
|
||||
get: suspend ScopeFacade.() -> Obj,
|
||||
set: suspend ScopeFacade.(Obj) -> Unit
|
||||
) {
|
||||
ensureTemplateNotBuilt()
|
||||
val target = findMember(name)
|
||||
@@ -298,11 +370,11 @@ private class ClassBridgeBinderImpl(
|
||||
throw ScriptError(Pos.builtIn, "extern var $name is readonly in class ${cls.className}")
|
||||
}
|
||||
val getter = ObjExternCallable.fromBridge {
|
||||
get(this, thisObj)
|
||||
get()
|
||||
}
|
||||
val setter = ObjExternCallable.fromBridge {
|
||||
val value = requiredArg<Obj>(0)
|
||||
set(this, thisObj, value)
|
||||
set(value)
|
||||
ObjVoid
|
||||
}
|
||||
val prop = ObjProperty(name, getter, setter)
|
||||
@@ -328,6 +400,24 @@ private class ClassBridgeBinderImpl(
|
||||
replaceMember(target, newRecord)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use addVar(name, get, set) with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith(
|
||||
"addVar(name, get = { get(this, thisObj) }, set = { value -> set(this, thisObj, value) })"
|
||||
)
|
||||
)
|
||||
override fun addVar(
|
||||
name: String,
|
||||
get: suspend (ScopeFacade, Obj) -> Obj,
|
||||
set: suspend (ScopeFacade, Obj, Obj) -> Unit
|
||||
) {
|
||||
addVar(
|
||||
name,
|
||||
get = { get(this, thisObj) },
|
||||
set = { value -> set(this, thisObj, value) }
|
||||
)
|
||||
}
|
||||
|
||||
fun commit() {
|
||||
if (initHooks.isNotEmpty()) {
|
||||
val target = cls.bridgeInitHooks ?: mutableListOf<suspend (ScopeFacade, ObjInstance) -> Unit>().also {
|
||||
@@ -399,16 +489,26 @@ private class ObjectBridgeBinderImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun initWithInstance(block: suspend ScopeFacade.() -> Unit) {
|
||||
initHooks.add { scope, _ ->
|
||||
scope.block()
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use initWithInstance { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("initWithInstance { block(this, thisObj) }")
|
||||
)
|
||||
override fun initWithInstance(block: suspend (ScopeFacade, Obj) -> Unit) {
|
||||
initHooks.add { scope, inst ->
|
||||
block(scope, inst)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addFun(name: String, impl: suspend (ScopeFacade, Obj, Arguments) -> Obj) {
|
||||
override fun addFun(name: String, impl: suspend ScopeFacade.() -> Obj) {
|
||||
val target = findMember(name)
|
||||
val callable = ObjExternCallable.fromBridge {
|
||||
impl(this, thisObj, args)
|
||||
impl()
|
||||
}
|
||||
val methodId = cls.ensureMethodIdForBridge(name, target.record)
|
||||
val newRecord = target.record.copy(
|
||||
@@ -420,13 +520,23 @@ private class ObjectBridgeBinderImpl(
|
||||
updateInstanceMember(target, newRecord)
|
||||
}
|
||||
|
||||
override fun addVal(name: String, impl: suspend (ScopeFacade, Obj) -> Obj) {
|
||||
@Deprecated(
|
||||
message = "Use addFun(name) { ... } with ScopeFacade receiver; use thisObj/args from scope",
|
||||
replaceWith = ReplaceWith("addFun(name) { impl(this, thisObj, args) }")
|
||||
)
|
||||
override fun addFun(name: String, impl: suspend (ScopeFacade, Obj, Arguments) -> Obj) {
|
||||
addFun(name) {
|
||||
impl(this, thisObj, args)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVal(name: String, impl: suspend ScopeFacade.() -> Obj) {
|
||||
val target = findMember(name)
|
||||
if (target.record.isMutable) {
|
||||
throw ScriptError(Pos.builtIn, "extern val $name is mutable in class ${cls.className}")
|
||||
}
|
||||
val getter = ObjExternCallable.fromBridge {
|
||||
impl(this, thisObj)
|
||||
impl()
|
||||
}
|
||||
val prop = ObjProperty(name, getter, null)
|
||||
val isFieldLike = target.record.type == ObjRecord.Type.Field ||
|
||||
@@ -452,21 +562,31 @@ private class ObjectBridgeBinderImpl(
|
||||
updateInstanceMember(target, newRecord)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use addVal(name) { ... } with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith("addVal(name) { impl(this, thisObj) }")
|
||||
)
|
||||
override fun addVal(name: String, impl: suspend (ScopeFacade, Obj) -> Obj) {
|
||||
addVal(name) {
|
||||
impl(this, thisObj)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVar(
|
||||
name: String,
|
||||
get: suspend (ScopeFacade, Obj) -> Obj,
|
||||
set: suspend (ScopeFacade, Obj, Obj) -> Unit
|
||||
get: suspend ScopeFacade.() -> Obj,
|
||||
set: suspend ScopeFacade.(Obj) -> Unit
|
||||
) {
|
||||
val target = findMember(name)
|
||||
if (!target.record.isMutable) {
|
||||
throw ScriptError(Pos.builtIn, "extern var $name is readonly in class ${cls.className}")
|
||||
}
|
||||
val getter = ObjExternCallable.fromBridge {
|
||||
get(this, thisObj)
|
||||
get()
|
||||
}
|
||||
val setter = ObjExternCallable.fromBridge {
|
||||
val value = requiredArg<Obj>(0)
|
||||
set(this, thisObj, value)
|
||||
set(value)
|
||||
ObjVoid
|
||||
}
|
||||
val prop = ObjProperty(name, getter, setter)
|
||||
@@ -493,6 +613,24 @@ private class ObjectBridgeBinderImpl(
|
||||
updateInstanceMember(target, newRecord)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Use addVar(name, get, set) with ScopeFacade receiver; use thisObj from scope",
|
||||
replaceWith = ReplaceWith(
|
||||
"addVar(name, get = { get(this, thisObj) }, set = { value -> set(this, thisObj, value) })"
|
||||
)
|
||||
)
|
||||
override fun addVar(
|
||||
name: String,
|
||||
get: suspend (ScopeFacade, Obj) -> Obj,
|
||||
set: suspend (ScopeFacade, Obj, Obj) -> Unit
|
||||
) {
|
||||
addVar(
|
||||
name,
|
||||
get = { get(this, thisObj) },
|
||||
set = { value -> set(this, thisObj, value) }
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun commit() {
|
||||
if (initHooks.isNotEmpty()) {
|
||||
val target = cls.bridgeInitHooks ?: mutableListOf<suspend (ScopeFacade, ObjInstance) -> Unit>().also {
|
||||
|
||||
@@ -45,18 +45,18 @@ class ObjKotlinIterator(val iterator: Iterator<Any?>) : Obj() {
|
||||
}
|
||||
boundType = cls
|
||||
LyngClassBridge.bind(cls) {
|
||||
addFun("next") { scope, self, _ ->
|
||||
when (self) {
|
||||
addFun("next") {
|
||||
when (val self = thisObj) {
|
||||
is ObjKotlinIterator -> self.iterator.next().toObj()
|
||||
is ObjKotlinObjIterator -> self.iterator.next()
|
||||
else -> scope.raiseClassCastError("Expected KotlinIterator, got ${self.objClass.className}")
|
||||
else -> raiseClassCastError("Expected KotlinIterator, got ${self.objClass.className}")
|
||||
}
|
||||
}
|
||||
addFun("hasNext") { scope, self, _ ->
|
||||
when (self) {
|
||||
addFun("hasNext") {
|
||||
when (val self = thisObj) {
|
||||
is ObjKotlinIterator -> self.iterator.hasNext().toObj()
|
||||
is ObjKotlinObjIterator -> self.iterator.hasNext().toObj()
|
||||
else -> scope.raiseClassCastError("Expected KotlinIterator, got ${self.objClass.className}")
|
||||
else -> raiseClassCastError("Expected KotlinIterator, got ${self.objClass.className}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user