-
Notifications
You must be signed in to change notification settings - Fork 38
Bridge classes
A bridge class allows one to extend, implement, or mixin a Dart class inside of the Eval environment. It also allows for instantiation of the original, unmodified class.
Bridge classes are used, for example, when building Flutter widgets. In Eval you might write:
class MyWidget extends StatelessWidget {
MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(child: Text("MyWidget"));
}
}
which would make use of the following bridge class (abridged for clarity):
class $StatelessWidget$bridge extends StatelessWidget with $Bridge {
const $StatelessWidget$bridge({Key? key}): super(key: key);
@override
EvalValue? $bridgeGet(String identifier) {
switch (identifier) {
case 'build':
return EvalFunctionImpl((rt, target, args) => $Widget.wrap(super.build(args[0].$value)));
default:
throw UnimplementedError();
}
}
@override
Widget build(BuildContext context) => $_invoke('build', [$BuildContext.wrap(context)]);
}
In order to create an instance of MyWidget
, the Eval environment will use the following steps:
- Instantiate a bridge super shim, which allows a bridge subclass to access superclass fields with
super
; - Instantiate the
MyWidget
subclass (which contains an override of only thebuild
function) using the super shim from step 1 as its superclass; - Instantiate a bridge data object (which holds data about a specific bridge instance) using the active runtime, the
MyWidget
subclass as its subclass, and the MyWidget runtime type ID; - Instantiate the
$StatelessWidget$bridge
bridge via its constructor from the bridge static function map; - Assign the bridge data instance to the newly created bridge class via the global
bridgeData
Expando; - Set the super shim's bridge class to the newly created bridge class;
- Return the
$StatelessWidget$bridge
bridge class.
This resulting instance is able to serve dual roles. Inside the Eval environment, the $bridgeGet
method will be called to lookup fields and methods using a String. However if the bridge class is returned from the Eval environment, it will fully conform to the basic StatelessWidget
type; and if the build
method is called, since we've overridden it with $invoke
, Eval will be able to redirect the invocation into a bridge call so that our custom build
code is called.