callInterpreterCallback static method
Call an interpreter callback that may be either an InterpretedFunction or a NativeFunction.
G-DCLI-07 FIX: When bridge code needs to invoke a callback parameter
(e.g., forEach(print)), the callback may be a NativeFunction (like print)
or an InterpretedFunction (user-defined lambda). This method handles both.
The result is automatically unwrapped: BridgedInstance returns its
BridgedInstance.nativeObject, BridgedEnumValue returns its
BridgedEnumValue.nativeValue, and all other values pass through.
This ensures generated bridge code casts (e.g., as Widget) succeed
when the interpreter returns wrapped bridge values.
Returns the unwrapped native result of calling the callback.
Implementation
static Object? callInterpreterCallback(
InterpreterVisitor visitor,
Object? callback,
List<Object?> args, [
Map<String, Object?> namedArgs = const {},
]) {
final Object? result;
if (callback is InterpretedFunction) {
result = callback.call(visitor, args, namedArgs);
} else if (callback is NativeFunction) {
result = callback.call(visitor, args, namedArgs);
} else if (callback is Callable) {
result = callback.call(visitor, args, namedArgs);
} else if (callback is Function) {
// 1401-TODO #8 (F5/F6): plain native Dart function. Happens when
// the framework hands a typed callback (e.g. `TickerCallback =
// void Function(Duration)`) to a script method via the bridge,
// and the script forwards it unchanged to another bridge
// constructor (e.g. `Ticker(onTick)`). The Ticker bridge wraps
// it in `callInterpreterCallback`, which at tick time receives
// the original native Dart closure — not wrapped as
// InterpretedFunction/NativeFunction/Callable. `Function.apply`
// dispatches by Dart Function signature; named args are
// re-keyed to Symbols (Dart's `Function.apply` requires
// `Map<Symbol, dynamic>?`).
final Map<Symbol, dynamic>? symbolNamedArgs;
if (namedArgs.isEmpty) {
symbolNamedArgs = null;
} else {
symbolNamedArgs = {
for (final entry in namedArgs.entries) Symbol(entry.key): entry.value,
};
}
result = Function.apply(callback, args, symbolNamedArgs);
} else {
throw ArgumentD4rtException(
'Expected a callable function, got ${callback?.runtimeType}',
);
}
return unwrapInterpreterValue(result);
}