tryCreateInterfaceProxyWithVisitor<T> static method
T?
tryCreateInterfaceProxyWithVisitor<T>(
- InterpretedInstance instance,
- InterpreterVisitor visitor
Try to create an interface proxy with a visitor context.
This is the full version that can actually create proxies. Called from contexts where the visitor is available.
Implementation
static T? tryCreateInterfaceProxyWithVisitor<T>(
InterpretedInstance instance,
InterpreterVisitor visitor,
) {
// Walk hierarchy starting from `instance.klass` and recursively traverse
// the interpreted superclass chain plus all interpreted mixins and
// interpreted interfaces. At every level collect:
// - the bridgedSuperclass name (direct)
// - bridgedInterfaces / bridgedMixins names
// - transitively registered supertypes of each (Bug-102b)
// Then try each candidate against the interface-proxy registry.
//
// Prior to Bug-102c, only the outermost klass's bridgedSuperclass
// was considered — so a script like
// abstract class _BaseDelegate extends MultiChildLayoutDelegate { ... }
// class _DashboardDelegate extends _BaseDelegate { ... }
// failed to resolve because _DashboardDelegate.bridgedSuperclass is
// null (its bridged super is one interpreted hop away).
//
// Cluster-18 (bucket #8) extends this further: scripts may use an
// interpreted mixin to satisfy a bridged interface, e.g.
// mixin _TickerProviderShim<T extends StatefulWidget> on State<T>
// implements TickerProvider { ... }
// class _DemoState extends State<...> with _TickerProviderShim
// Without recursing into `walk.mixins` and `walk.interfaces`, the
// bridged contributions of the interpreted mixin (here TickerProvider)
// are invisible to proxy resolution.
final seen = <String>{};
final candidates = <String>[];
void add(String n) {
if (seen.add(n)) candidates.add(n);
}
void addBridged(BridgedClass bc) {
add(bc.name);
for (final s in BridgedClass.transitiveSupertypeNames(bc.name)) {
add(s);
}
}
final visitedClasses = <InterpretedClass>{};
void collectFromInterpreted(InterpretedClass? c) {
if (c == null) return;
if (!visitedClasses.add(c)) return;
if (c.bridgedSuperclass != null) {
addBridged(c.bridgedSuperclass!);
}
for (final iface in c.bridgedInterfaces) {
addBridged(iface);
}
for (final mixin in c.bridgedMixins) {
addBridged(mixin);
}
// Recurse into interpreted ancestors so an interpreted mixin's or
// interface's bridged contributions are also discovered.
collectFromInterpreted(c.superclass);
for (final m in c.mixins) {
collectFromInterpreted(m);
}
for (final i in c.interfaces) {
collectFromInterpreted(i);
}
}
collectFromInterpreted(instance.klass);
for (final name in candidates) {
final factory = _interfaceProxies[name];
if (factory != null) {
final proxy = factory(visitor, instance);
if (proxy is T) return proxy;
}
}
return null;
}