From 93d05539c5afde8bb7e8616bfeff52b18c77311b Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Fri, 16 Feb 2024 20:54:52 -0800 Subject: [PATCH 01/22] Add support for widget builders. --- packages/rfw/lib/src/dart/binary.dart | 23 ++ packages/rfw/lib/src/dart/model.dart | 45 ++ packages/rfw/lib/src/dart/text.dart | 147 +++++-- packages/rfw/lib/src/flutter/runtime.dart | 479 +++++++++++++++++++--- packages/rfw/test/binary_test.dart | 13 + packages/rfw/test/runtime_test.dart | 152 +++++++ packages/rfw/test/text_test.dart | 83 ++++ 7 files changed, 860 insertions(+), 82 deletions(-) diff --git a/packages/rfw/lib/src/dart/binary.dart b/packages/rfw/lib/src/dart/binary.dart index f36690f2c7d0..f6de28026d0b 100644 --- a/packages/rfw/lib/src/dart/binary.dart +++ b/packages/rfw/lib/src/dart/binary.dart @@ -298,6 +298,8 @@ const int _msEvent = 0x0E; const int _msSwitch = 0x0F; const int _msDefault = 0x10; const int _msSetState = 0x11; +const int _msWidgetBuilder = 0x12; +const int _msWidgetBuilderArgReference = 0x13; /// API for decoding Remote Flutter Widgets binary blobs. /// @@ -453,6 +455,10 @@ class _BlobDecoder { return _readSwitch(); case _msSetState: return SetStateHandler(StateReference(_readPartList()), _readArgument()); + case _msWidgetBuilder: + return _readWidgetBuilder(); + case _msWidgetBuilderArgReference: + return WidgetBuilderArgReference(_readString(), _readPartList()); default: return _parseValue(type, _readArgument); } @@ -468,6 +474,14 @@ class _BlobDecoder { return ConstructorCall(name, _readMap(_readArgument)!); } + WidgetBuilderDeclaration _readWidgetBuilder() { + final String argumentName = _readString(); + final int type = _readByte(); + assert(type == _msWidget || type == _msSwitch); + final BlobNode widget = type == _msWidget ? _readWidget() : _readSwitch(); + return WidgetBuilderDeclaration(argumentName, widget); + } + WidgetDeclaration _readDeclaration() { final String name = _readString(); final DynamicMap? initialState = _readMap(readValue, nullIfEmpty: true); @@ -613,6 +627,10 @@ class _BlobEncoder { bytes.addByte(_msWidget); _writeString(value.name); _writeMap(value.arguments, _writeArgument); + } else if (value is WidgetBuilderDeclaration) { + bytes.addByte(_msWidgetBuilder); + _writeString(value.argumentName); + _writeArgument(value.widget); } else if (value is ArgsReference) { bytes.addByte(_msArgsReference); _writeInt64(value.parts.length); @@ -621,6 +639,11 @@ class _BlobEncoder { bytes.addByte(_msDataReference); _writeInt64(value.parts.length); value.parts.forEach(_writePart); + } else if (value is WidgetBuilderArgReference) { + bytes.addByte(_msWidgetBuilderArgReference); + _writeString(value.argumentName); + _writeInt64(value.parts.length); + value.parts.forEach(_writePart); } else if (value is LoopReference) { bytes.addByte(_msLoopReference); _writeInt64(value.loop); diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index b6a6b9921263..03399174b7a7 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -439,6 +439,26 @@ class ConstructorCall extends BlobNode { String toString() => '$name($arguments)'; } +/// Representation of functions that return widgets in Remote Flutter library blobs. +class WidgetBuilderDeclaration extends BlobNode { + /// Creates a [WidgetBuilderDeclaration]. + const WidgetBuilderDeclaration(this.argumentName, this.widget); + + /// The name associated with the passed [DynamicMap]. + final String argumentName; + + /// The widget that will be returned when the builder is called. + /// + /// This is usually a [ConstructorCall], but may be a [Switch] (so long as + /// that [Switch] resolves to a [ConstructorCall]. Other values (or a [Switch] + /// that does not resolve to a constructor call) will result in an + /// [ErrorWidget] being used. + final BlobNode widget; + + @override + String toString() => '($argumentName) => $widget'; +} + /// Base class for various kinds of references in the RFW data structures. abstract class Reference extends BlobNode { /// Abstract const constructor. This constructor enables subclasses to provide @@ -534,6 +554,31 @@ class DataReference extends Reference { String toString() => 'data.${parts.join(".")}'; } +/// Reference to the [DynamicMap] passed into the widget builder. +/// +/// This class is used to represent references to a function argument. +/// In "(scope) => Container(width: scope.width)" this represents "scope.width". +/// +/// See also: +/// +/// * [WidgetBuilderDeclaration] which represents a widget builder definition. +class WidgetBuilderArgReference extends Reference { + /// Wraps the given [parts] associated to the [argumentName] as an [WidgetBuilderArgReference]. + /// + /// The parts must not be mutated after the object is created. + const WidgetBuilderArgReference(this.argumentName, super.parts); + + /// References the function argument name. + final String argumentName; + + WidgetBuilderArgReference constructReference(List moreParts) { + return WidgetBuilderArgReference(argumentName, parts + moreParts); + } + + @override + String toString() => '$argumentName.${parts.join('.')}'; +} + /// Unbound reference to a [Loop]. class LoopReference extends Reference { /// Wraps the given [loop] and [parts] as a [LoopReference]. diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 88e0843ef3dd..d8d4f1c2485c 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -272,8 +272,8 @@ DynamicMap parseDataFile(String file) { /// declaration, along with its arguments. Arguments are a map of key-value /// pairs, where the values can be any of the types in the data model defined /// above plus any of the types defined below in this section, such as -/// references to arguments, the data model, loops, state, switches, or -/// event handlers. +/// references to arguments, the data model, widget builders, loops, state, +/// switches or event handlers. /// /// In this example, several constructor calls are nested together: /// @@ -283,6 +283,9 @@ DynamicMap parseDataFile(String file) { /// Container( /// child: Text(text: "Hello"), /// ), +/// Builder( +/// builder: (scope) => Text(text: scope.world), +/// ), /// ], /// ); /// ``` @@ -293,6 +296,35 @@ DynamicMap parseDataFile(String file) { /// constructor call also has only one argument, `child`, whose value, again, is /// a constructor call, in this case creating a `Text` widget. /// +/// ### Widget Builders +/// +/// Widget builders take a single argument and return a widget. +/// The [DynamicMap] argument consists of key-value pairs where values +/// can be of any types in the data model. Widget builders arguments are lexically +/// scoped so a given constructor call has access to any arguments where it is +/// defined plus arguments defined by its parents (if any). +/// +/// In this example several widget builders are nested together: +/// +/// ``` +/// widget Foo {text: 'this is cool'} = Builder( +/// builder: (foo) => Builder( +/// builder: (bar) => Builder( +/// builder: (baz) => Text( +/// text: [ +/// args.text, +/// state.text, +/// data.text, +/// foo.text, +/// bar.text, +/// baz.text, +/// ], +/// ), +/// ), +/// ), +/// ); +/// ``` +/// /// ### References /// /// Remote widget libraries typically contain _references_, e.g. to the @@ -610,6 +642,12 @@ const Set _reservedWords = { 'true', }; +void _checkIsNotReservedWord(String identifier, _Token identifierToken) { + if (_reservedWords.contains(identifier)) { + throw ParserException._fromToken('$identifier is a reserved word', identifierToken); + } +} + sealed class _Token { _Token(this.line, this.column, this.start, this.end); final int line; @@ -630,6 +668,7 @@ class _SymbolToken extends _Token { static const int colon = 0x3A; // U+003A COLON character (:) static const int semicolon = 0x3B; // U+003B SEMICOLON character (;) static const int equals = 0x3D; // U+003D EQUALS SIGN character (=) + static const int greatherThan = 0x3E; // U+003D GREATHER THAN character (>) static const int openBracket = 0x5B; // U+005B LEFT SQUARE BRACKET character ([) static const int closeBracket = 0x5D; // U+005D RIGHT SQUARE BRACKET character (]) static const int openBrace = 0x7B; // U+007B LEFT CURLY BRACKET character ({) @@ -812,6 +851,7 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x3A: // U+003A COLON character (:) case 0x3B: // U+003B SEMICOLON character (;) case 0x3D: // U+003D EQUALS SIGN character (=) + case 0x3E: // U+003E GREATHER THAN SIGN character (>) case 0x5B: // U+005B LEFT SQUARE BRACKET character ([) case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) @@ -2132,14 +2172,23 @@ class _Parser { return _readString(); } - DynamicMap _readMap({ required bool extended }) { + DynamicMap _readMap({ + required bool extended, + List widgetBuilderScope = const [], + }) { _expectSymbol(_SymbolToken.openBrace); - final DynamicMap results = _readMapBody(extended: extended); + final DynamicMap results = _readMapBody( + widgetBuilderScope: widgetBuilderScope, + extended: extended, + ); _expectSymbol(_SymbolToken.closeBrace); return results; } - DynamicMap _readMapBody({ required bool extended }) { + DynamicMap _readMapBody({ + required bool extended, + List widgetBuilderScope = const [], + }) { final DynamicMap results = DynamicMap(); // ignore: prefer_collection_literals while (_source.current is! _SymbolToken) { final String key = _readKey(); @@ -2147,7 +2196,11 @@ class _Parser { throw ParserException._fromToken('Duplicate key "$key" in map', _source.current); } _expectSymbol(_SymbolToken.colon); - final Object value = _readValue(extended: extended, nullOk: true); + final Object value = _readValue( + extended: extended, + nullOk: true, + widgetBuilderScope: widgetBuilderScope, + ); if (value != missing) { results[key] = value; } @@ -2162,7 +2215,10 @@ class _Parser { final List _loopIdentifiers = []; - DynamicList _readList({ required bool extended }) { + DynamicList _readList({ + required bool extended, + List widgetBuilderScope = const [], + }) { final DynamicList results = DynamicList.empty(growable: true); _expectSymbol(_SymbolToken.openBracket); while (!_foundSymbol(_SymbolToken.closeBracket)) { @@ -2172,19 +2228,26 @@ class _Parser { _expectIdentifier('for'); final _Token loopIdentifierToken = _source.current; final String loopIdentifier = _readIdentifier(); - if (_reservedWords.contains(loopIdentifier)) { - throw ParserException._fromToken('$loopIdentifier is a reserved word', loopIdentifierToken); - } + _checkIsNotReservedWord(loopIdentifier, loopIdentifierToken); _expectIdentifier('in'); - final Object collection = _readValue(extended: true); + final Object collection = _readValue( + widgetBuilderScope: widgetBuilderScope, + extended: true, + ); _expectSymbol(_SymbolToken.colon); _loopIdentifiers.add(loopIdentifier); - final Object template = _readValue(extended: extended); + final Object template = _readValue( + widgetBuilderScope: widgetBuilderScope, + extended: extended, + ); assert(_loopIdentifiers.last == loopIdentifier); _loopIdentifiers.removeLast(); results.add(_withSourceRange(Loop(collection, template), start)); } else { - final Object value = _readValue(extended: extended); + final Object value = _readValue( + widgetBuilderScope: widgetBuilderScope, + extended: extended, + ); results.add(value); } if (_foundSymbol(_SymbolToken.comma)) { @@ -2197,8 +2260,10 @@ class _Parser { return results; } - Switch _readSwitch(SourceLocation? start) { - final Object value = _readValue(extended: true); + Switch _readSwitch(SourceLocation? start, { + List widgetBuilderScope = const [], + }) { + final Object value = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); final Map cases = {}; _expectSymbol(_SymbolToken.openBrace); while (_source.current is! _SymbolToken) { @@ -2210,13 +2275,13 @@ class _Parser { key = null; _advance(); } else { - key = _readValue(extended: true); + key = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); if (cases.containsKey(key)) { throw ParserException._fromToken('Switch has duplicate cases for key $key', _source.current); } } _expectSymbol(_SymbolToken.colon); - final Object value = _readValue(extended: true); + final Object value = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); cases[key] = value; if (_foundSymbol(_SymbolToken.comma)) { _advance(); @@ -2249,13 +2314,19 @@ class _Parser { return results; } - Object _readValue({ required bool extended, bool nullOk = false }) { + Object _readValue({ + required bool extended, + bool nullOk = false, + List widgetBuilderScope = const [], + }) { if (_source.current is _SymbolToken) { switch ((_source.current as _SymbolToken).symbol) { case _SymbolToken.openBracket: - return _readList(extended: extended); + return _readList(widgetBuilderScope: widgetBuilderScope, extended: extended); case _SymbolToken.openBrace: - return _readMap(extended: extended); + return _readMap(widgetBuilderScope: widgetBuilderScope, extended: extended); + case _SymbolToken.openParen: + return _readWidgetBuilderDeclaration(widgetBuilderScope: widgetBuilderScope); } } else if (_source.current is _IntegerToken) { final Object result = (_source.current as _IntegerToken).value; @@ -2306,10 +2377,15 @@ class _Parser { _advance(); return _withSourceRange(StateReference(_readParts()), start); } + if (widgetBuilderScope.contains(identifier)) { + final SourceLocation? start = _getSourceLocation(); + _advance(); + return _withSourceRange(WidgetBuilderArgReference(identifier, _readParts()), start); + } if (identifier == 'switch') { final SourceLocation? start = _getSourceLocation(); _advance(); - return _readSwitch(start); + return _readSwitch(start, widgetBuilderScope: widgetBuilderScope); } if (identifier == 'set') { final SourceLocation? start = _getSourceLocation(); @@ -2327,16 +2403,39 @@ class _Parser { _advance(); return _withSourceRange(LoopReference(_loopIdentifiers.length - index, _readParts(optional: true)), start); } - return _readConstructorCall(); + return _readConstructorCall(widgetBuilderScope: widgetBuilderScope); } throw ParserException._unexpected(_source.current); } - ConstructorCall _readConstructorCall() { + WidgetBuilderDeclaration _readWidgetBuilderDeclaration({ + List widgetBuilderScope = const [], + }) { + _expectSymbol(_SymbolToken.openParen); + final _Token argumentNameToken = _source.current; + final String argumentName = _readIdentifier(); + _checkIsNotReservedWord(argumentName, argumentNameToken); + _expectSymbol(_SymbolToken.closeParen); + _expectSymbol(_SymbolToken.equals); + _expectSymbol(_SymbolToken.greatherThan); + final Object widget = _readValue( + extended: true, + widgetBuilderScope: [...widgetBuilderScope, argumentName], + ); + assert(widget is ConstructorCall || widget is Switch); + return WidgetBuilderDeclaration(argumentName, widget as BlobNode); + } + + ConstructorCall _readConstructorCall({ + List widgetBuilderScope = const [], + }) { final SourceLocation? start = _getSourceLocation(); final String name = _readIdentifier(); _expectSymbol(_SymbolToken.openParen); - final DynamicMap arguments = _readMapBody(extended: true); + final DynamicMap arguments = _readMapBody( + extended: true, + widgetBuilderScope: widgetBuilderScope, + ); _expectSymbol(_SymbolToken.closeParen); return _withSourceRange(ConstructorCall(name, arguments), start); } diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index 7d874e78e8b2..f5def8f25cf3 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -19,6 +19,9 @@ import 'content.dart'; /// [LocalWidgetBuilder] callbacks. typedef LocalWidgetBuilder = Widget Function(BuildContext context, DataSource source); +/// Signature of builders for remote widgets. +typedef _RemoteWidgetBuilder = _CurriedWidget Function(DynamicMap builderArg); + /// Signature of the callback passed to a [RemoteWidget]. /// /// This is used by [RemoteWidget] and [Runtime.build] as the callback for @@ -126,6 +129,25 @@ abstract class DataSource { /// non-widget nodes replaced by [ErrorWidget]. List childList(List argsKey); + /// Build the builder at the given key. + /// + /// If the node specified is not a widget, returns an [ErrorWidget]. + /// + /// See also: + /// + /// * [optionalBuilder], which returns null if the widget is missing. + Widget builder(List argsKey, DynamicMap builderArg); + + /// Build the builder at the given key. + /// + /// If the node specified is not a widget, returns null. + /// + /// See also: + /// + /// * [builder], which returns an [ErrorWidget] instead of null if the widget + /// is missing. + Widget? optionalBuilder(List argsKey, DynamicMap builderArg); + /// Gets a [VoidCallback] event handler at the given key. /// /// If the node specified is an [AnyEventHandler] or a [DynamicList] of @@ -284,11 +306,23 @@ class Runtime extends ChangeNotifier { /// /// The `remoteEventTarget` argument is the callback that the RFW runtime will /// invoke whenever a remote widget event handler is triggered. - Widget build(BuildContext context, FullyQualifiedWidgetName widget, DynamicContent data, RemoteEventHandler remoteEventTarget) { + Widget build( + BuildContext context, + FullyQualifiedWidgetName widget, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + ) { _CurriedWidget? boundWidget = _widgets[widget]; if (boundWidget == null) { _checkForImportLoops(widget.library); - boundWidget = _applyConstructorAndBindArguments(widget, const {}, -1, {}, null); + boundWidget = _applyConstructorAndBindArguments( + widget, + const {}, + const {}, + -1, + {}, + null, + ); _widgets[widget] = boundWidget; } return boundWidget.build(context, data, remoteEventTarget, const <_WidgetState>[]); @@ -410,13 +444,22 @@ class Runtime extends ChangeNotifier { /// [LocalWidgetBuilder] rather than a [WidgetDeclaration], and is used to /// provide source information for local widgets (which otherwise could not be /// associated with a part of the source). See also [Runtime.blobNodeFor]. - _CurriedWidget _applyConstructorAndBindArguments(FullyQualifiedWidgetName fullName, DynamicMap arguments, int stateDepth, Set usedWidgets, BlobNode? source) { + _CurriedWidget _applyConstructorAndBindArguments( + FullyQualifiedWidgetName fullName, + DynamicMap arguments, + DynamicMap widgetBuilderScope, + int stateDepth, + Set usedWidgets, + BlobNode? source, + ) { final _ResolvedConstructor? widget = _findConstructor(fullName); if (widget != null) { if (widget.constructor is WidgetDeclaration) { if (usedWidgets.contains(widget.fullName)) { - return _CurriedLocalWidget.error(fullName, 'Widget loop: Tried to call ${widget.fullName} constructor reentrantly.') - ..propagateSource(source); + return _CurriedLocalWidget.error( + fullName, + 'Widget loop: Tried to call ${widget.fullName} constructor reentrantly.', + )..propagateSource(source); } usedWidgets = usedWidgets.toSet()..add(widget.fullName); final WidgetDeclaration constructor = widget.constructor as WidgetDeclaration; @@ -426,22 +469,38 @@ class Runtime extends ChangeNotifier { } else { newDepth = stateDepth; } - Object result = _bindArguments(widget.fullName, constructor.root, arguments, newDepth, usedWidgets); + Object result = _bindArguments( + widget.fullName, + constructor.root, + arguments, + widgetBuilderScope, + newDepth, + usedWidgets, + ); if (result is Switch) { result = _CurriedSwitch(widget.fullName, result, arguments, constructor.initialState) ..propagateSource(result); } else { result as _CurriedWidget; if (constructor.initialState != null) { - result = _CurriedRemoteWidget(widget.fullName, result, arguments, constructor.initialState) - ..propagateSource(result); + result = _CurriedRemoteWidget( + widget.fullName, + result, + arguments, + widgetBuilderScope, + constructor.initialState, + )..propagateSource(result); } } return result as _CurriedWidget; } assert(widget.constructor is LocalWidgetBuilder); - return _CurriedLocalWidget(widget.fullName, widget.constructor as LocalWidgetBuilder, arguments) - ..propagateSource(source); + return _CurriedLocalWidget( + widget.fullName, + widget.constructor as LocalWidgetBuilder, + arguments, + widgetBuilderScope, + )..propagateSource(source); } final Set missingLibraries = _findMissingLibraries(fullName.library).toSet(); if (missingLibraries.isNotEmpty) { @@ -455,37 +514,88 @@ class Runtime extends ChangeNotifier { ..propagateSource(source); } - Object _bindArguments(FullyQualifiedWidgetName context, Object node, Object arguments, int stateDepth, Set usedWidgets) { + Object _bindArguments( + FullyQualifiedWidgetName context, + Object node, Object arguments, + DynamicMap widgetBuilderScope, + int stateDepth, + Set usedWidgets, + ) { if (node is ConstructorCall) { - final DynamicMap subArguments = _bindArguments(context, node.arguments, arguments, stateDepth, usedWidgets) as DynamicMap; - return _applyConstructorAndBindArguments(FullyQualifiedWidgetName(context.library, node.name), subArguments, stateDepth, usedWidgets, node); + final DynamicMap subArguments = _bindArguments( + context, + node.arguments, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ) as DynamicMap; + return _applyConstructorAndBindArguments( + FullyQualifiedWidgetName(context.library, node.name), + subArguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + node, + ); } + if (node is WidgetBuilderDeclaration) { + return (DynamicMap widgetBuilderArg) { + final Object result = _bindArguments( + context, + node.widget, + arguments, + {...widgetBuilderScope, node.argumentName: widgetBuilderArg}, + stateDepth, + usedWidgets, + ); + if (result is Switch) { + return _CurriedSwitch( + FullyQualifiedWidgetName(context.library, ''), + result, + arguments as DynamicMap, + const {}, + )..propagateSource(result); + } + return result as _CurriedWidget; + }; + } if (node is DynamicMap) { return node.map( - (String name, Object? value) => MapEntry(name, _bindArguments(context, value!, arguments, stateDepth, usedWidgets)), + (String name, Object? value) => MapEntry( + name, + _bindArguments(context, value!, arguments, widgetBuilderScope, stateDepth, usedWidgets), + ), ); } if (node is DynamicList) { return List.generate( node.length, - (int index) => _bindArguments(context, node[index]!, arguments, stateDepth, usedWidgets), + (int index) => _bindArguments( + context, + node[index]!, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ), growable: false, ); } if (node is Loop) { - final Object input = _bindArguments(context, node.input, arguments, stateDepth, usedWidgets); - final Object output = _bindArguments(context, node.output, arguments, stateDepth, usedWidgets); + final Object input = _bindArguments(context, node.input, arguments, widgetBuilderScope, stateDepth, usedWidgets); + final Object output = _bindArguments(context, node.output, arguments, widgetBuilderScope, stateDepth, usedWidgets); return Loop(input, output) ..propagateSource(node); } if (node is Switch) { return Switch( - _bindArguments(context, node.input, arguments, stateDepth, usedWidgets), + _bindArguments(context, node.input, arguments, widgetBuilderScope, stateDepth, usedWidgets), node.outputs.map( (Object? key, Object value) { return MapEntry( - key == null ? key : _bindArguments(context, key, arguments, stateDepth, usedWidgets), - _bindArguments(context, value, arguments, stateDepth, usedWidgets), + key == null ? key : _bindArguments(context, key, arguments, widgetBuilderScope, stateDepth, usedWidgets), + _bindArguments(context, value, arguments, widgetBuilderScope, stateDepth, usedWidgets), ); }, ), @@ -498,14 +608,25 @@ class Runtime extends ChangeNotifier { return node.bind(stateDepth)..propagateSource(node); } if (node is EventHandler) { - return EventHandler(node.eventName, _bindArguments(context, node.eventArguments, arguments, stateDepth, usedWidgets) as DynamicMap) - ..propagateSource(node); + return EventHandler( + node.eventName, + _bindArguments( + context, + node.eventArguments, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ) as DynamicMap, + )..propagateSource(node); } if (node is SetStateHandler) { assert(node.stateReference is StateReference); final BoundStateReference stateReference = (node.stateReference as StateReference).bind(stateDepth); - return SetStateHandler(stateReference, _bindArguments(context, node.value, arguments, stateDepth, usedWidgets)) - ..propagateSource(node); + return SetStateHandler( + stateReference, + _bindArguments(context, node.value, arguments, widgetBuilderScope, stateDepth, usedWidgets), + )..propagateSource(node); } assert(node is! WidgetDeclaration); return node; @@ -528,12 +649,19 @@ class _ResolvedDynamicList { typedef _DataResolverCallback = Object Function(List dataKey); typedef _StateResolverCallback = Object Function(List stateKey, int depth); +typedef _WidgetBuilderArgResolverCallback = Object Function(List argKey); abstract class _CurriedWidget extends BlobNode { - const _CurriedWidget(this.fullName, this.arguments, this.initialState); + const _CurriedWidget( + this.fullName, + this.arguments, + this.widgetBuilderScope, + this.initialState, + ); final FullyQualifiedWidgetName fullName; final DynamicMap arguments; + final DynamicMap widgetBuilderScope; final DynamicMap? initialState; static Object _bindLoopVariable(Object node, Object argument, int depth) { @@ -569,6 +697,7 @@ abstract class _CurriedWidget extends BlobNode { node.fullName, node.child, _bindLoopVariable(node.arguments, argument, depth) as DynamicMap, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) as DynamicMap, )..propagateSource(node); } if (node is _CurriedRemoteWidget) { @@ -576,6 +705,7 @@ abstract class _CurriedWidget extends BlobNode { node.fullName, _bindLoopVariable(node.child, argument, depth) as _CurriedWidget, _bindLoopVariable(node.arguments, argument, depth) as DynamicMap, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) as DynamicMap, node.initialState, )..propagateSource(node); } @@ -615,7 +745,13 @@ abstract class _CurriedWidget extends BlobNode { // // TODO(ianh): This really should have some sort of caching. Right now, evaluating a whole list // ends up being around O(N^2) since we have to walk the list from the start for every entry. - static _ResolvedDynamicList _listLookup(DynamicList list, int targetEffectiveIndex, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { + static _ResolvedDynamicList _listLookup( + DynamicList list, + int targetEffectiveIndex, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { int currentIndex = 0; // where we are in `list` (some entries of which might represent multiple values, because they are themselves loops) int effectiveIndex = 0; // where we are in the fully expanded list (the coordinate space in which we're aiming for `targetEffectiveIndex`) while ((effectiveIndex <= targetEffectiveIndex || targetEffectiveIndex < 0) && currentIndex < list.length) { @@ -624,22 +760,46 @@ abstract class _CurriedWidget extends BlobNode { Object inputList = node.input; while (inputList is! DynamicList) { if (inputList is BoundArgsReference) { - inputList = _resolveFrom(inputList.arguments, inputList.parts, stateResolver, dataResolver); + inputList = _resolveFrom( + inputList.arguments, + inputList.parts, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); } else if (inputList is DataReference) { inputList = dataResolver(inputList.parts); } else if (inputList is BoundStateReference) { inputList = stateResolver(inputList.parts, inputList.depth); } else if (inputList is BoundLoopReference) { - inputList = _resolveFrom(inputList.value, inputList.parts, stateResolver, dataResolver); + inputList = _resolveFrom( + inputList.value, + inputList.parts, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); } else if (inputList is Switch) { - inputList = _resolveFrom(inputList, const [], stateResolver, dataResolver); + inputList = _resolveFrom( + inputList, + const [], + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); } else { // e.g. it's a map or something else that isn't indexable inputList = DynamicList.empty(); } assert(inputList is! _ResolvedDynamicList); } - final _ResolvedDynamicList entry = _listLookup(inputList, targetEffectiveIndex >= 0 ? targetEffectiveIndex - effectiveIndex : -1, stateResolver, dataResolver); + final _ResolvedDynamicList entry = _listLookup( + inputList, + targetEffectiveIndex >= 0 ? targetEffectiveIndex - effectiveIndex : -1, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); if (entry.result != null) { final Object boundResult = _bindLoopVariable(node.output, entry.result!, 0); return _ResolvedDynamicList(null, boundResult, null); @@ -656,7 +816,13 @@ abstract class _CurriedWidget extends BlobNode { return _ResolvedDynamicList(list, null, effectiveIndex); } - static Object _resolveFrom(Object root, List parts, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { + static Object _resolveFrom( + Object root, + List parts, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { int index = 0; Object current = root; while (true) { @@ -667,6 +833,13 @@ abstract class _CurriedWidget extends BlobNode { } current = dataResolver(current.parts); continue; + } else if (current is WidgetBuilderArgReference) { + if (index < parts.length) { + current = current.constructReference(parts.sublist(index)); + index = parts.length; + } + current = widgetBuilderArgResolver([current.argumentName, ...current.parts]); + continue; } else if (current is BoundArgsReference) { List nextParts = current.parts; if (index < parts.length) { @@ -693,7 +866,13 @@ abstract class _CurriedWidget extends BlobNode { index = 0; continue; } else if (current is Switch) { - final Object key = _resolveFrom(current.input, const [], stateResolver, dataResolver); + final Object key = _resolveFrom( + current.input, + const [], + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); Object? value = current.outputs[key]; if (value == null) { value = current.outputs[null]; @@ -707,9 +886,15 @@ abstract class _CurriedWidget extends BlobNode { // We've reached the end of the line. // We handle some special leaf cases that still need processing before we return. if (current is EventHandler) { - current = EventHandler(current.eventName, _fix(current.eventArguments, stateResolver, dataResolver) as DynamicMap); + current = EventHandler( + current.eventName, + _fix(current.eventArguments, stateResolver, dataResolver, widgetBuilderArgResolver) as DynamicMap, + ); } else if (current is SetStateHandler) { - current = SetStateHandler(current.stateReference, _fix(current.value, stateResolver, dataResolver)); + current = SetStateHandler( + current.stateReference, + _fix(current.value, stateResolver, dataResolver, widgetBuilderArgResolver), + ); } // else `current` is nothing special, and we'll just return it below. break; // This is where the loop ends. @@ -725,7 +910,13 @@ abstract class _CurriedWidget extends BlobNode { if (parts[index] is! int) { return missing; } - current = _listLookup(current, parts[index] as int, stateResolver, dataResolver).result ?? missing; + current = _listLookup( + current, + parts[index] as int, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ).result ?? missing; } else { assert(current is! ArgsReference); assert(current is! StateReference); @@ -740,27 +931,60 @@ abstract class _CurriedWidget extends BlobNode { return current; } - static Object _fix(Object root, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { + static Object _fix( + Object root, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { if (root is DynamicMap) { - return root.map((String key, Object? value) => MapEntry(key, _fix(root[key]!, stateResolver, dataResolver))); + return root.map((String key, Object? value) => + MapEntry( + key, + _fix(root[key]!, stateResolver, dataResolver, widgetBuilderArgResolver), + ), + ); } else if (root is DynamicList) { if (root.any((Object? entry) => entry is Loop)) { - final int length = _listLookup(root, -1, stateResolver, dataResolver).length!; - return DynamicList.generate(length, (int index) => _fix(_listLookup(root, index, stateResolver, dataResolver).result!, stateResolver, dataResolver)); + final int length = _listLookup( + root, + -1, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ).length!; + return DynamicList.generate( + length, + (int index) => _fix( + _listLookup(root, index, stateResolver, dataResolver, widgetBuilderArgResolver).result!, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ), + ); } else { - return DynamicList.generate(root.length, (int index) => _fix(root[index]!, stateResolver, dataResolver)); + return DynamicList.generate( + root.length, + (int index) => _fix(root[index]!, stateResolver, dataResolver, widgetBuilderArgResolver), + ); } } else if (root is BlobNode) { - return _resolveFrom(root, const [], stateResolver, dataResolver); + return _resolveFrom(root, const [], stateResolver, dataResolver, widgetBuilderArgResolver); } else { return root; } } - Object resolve(List parts, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver, { required bool expandLists }) { - Object result = _resolveFrom(arguments, parts, stateResolver, dataResolver); + Object resolve( + List parts, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, { + required bool expandLists, + }) { + Object result = _resolveFrom(arguments, parts, stateResolver, dataResolver, widgetBuilderArgResolver); if (result is DynamicList && expandLists) { - result = _listLookup(result, -1, stateResolver, dataResolver); + result = _listLookup(result, -1, stateResolver, dataResolver, widgetBuilderArgResolver); } assert(result is! Reference); assert(result is! Switch); @@ -768,38 +992,92 @@ abstract class _CurriedWidget extends BlobNode { return result; } - Widget build(BuildContext context, DynamicContent data, RemoteEventHandler remoteEventTarget, List<_WidgetState> states) { - return _Widget(curriedWidget: this, data: data, remoteEventTarget: remoteEventTarget, states: states); + Widget build( + BuildContext context, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + List<_WidgetState> states, + ) { + return _Widget( + curriedWidget: this, + data: data, + widgetBuilderScope: DynamicContent(widgetBuilderScope), + remoteEventTarget: remoteEventTarget, + states: states, + ); } - Widget buildChild(BuildContext context, DataSource source, DynamicContent data, RemoteEventHandler remoteEventTarget, List<_WidgetState> states, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver); + Widget buildChild( + BuildContext context, + DataSource source, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + List<_WidgetState> states, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ); @override String toString() => '$fullName ${initialState ?? "{}"} $arguments'; } class _CurriedLocalWidget extends _CurriedWidget { - const _CurriedLocalWidget(FullyQualifiedWidgetName fullName, this.child, DynamicMap arguments) : super(fullName, arguments, null); + const _CurriedLocalWidget( + FullyQualifiedWidgetName fullName, + this.child, + DynamicMap arguments, + DynamicMap widgetBuilderScope, + ) : super(fullName, arguments, widgetBuilderScope, null); factory _CurriedLocalWidget.error(FullyQualifiedWidgetName fullName, String message) { - return _CurriedLocalWidget(fullName, (BuildContext context, DataSource data) => _buildErrorWidget(message), const {}); + return _CurriedLocalWidget( + fullName, + (BuildContext context, DataSource data) => _buildErrorWidget(message), + const {}, + const {}, + ); } final LocalWidgetBuilder child; @override - Widget buildChild(BuildContext context, DataSource source, DynamicContent data, RemoteEventHandler remoteEventTarget, List<_WidgetState> states, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { + Widget buildChild( + BuildContext context, + DataSource source, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + List<_WidgetState> states, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { return child(context, source); } } class _CurriedRemoteWidget extends _CurriedWidget { - const _CurriedRemoteWidget(FullyQualifiedWidgetName fullName, this.child, DynamicMap arguments, DynamicMap? initialState) : super(fullName, arguments, initialState); + const _CurriedRemoteWidget( + FullyQualifiedWidgetName fullName, + this.child, + DynamicMap arguments, + DynamicMap widgetBuilderScope, + DynamicMap? initialState, + ) : super(fullName, arguments, widgetBuilderScope, initialState); final _CurriedWidget child; @override - Widget buildChild(BuildContext context, DataSource source, DynamicContent data, RemoteEventHandler remoteEventTarget, List<_WidgetState> states, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { + Widget buildChild( + BuildContext context, + DataSource source, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + List<_WidgetState> states, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { return child.build(context, data, remoteEventTarget, states); } @@ -808,13 +1086,33 @@ class _CurriedRemoteWidget extends _CurriedWidget { } class _CurriedSwitch extends _CurriedWidget { - const _CurriedSwitch(FullyQualifiedWidgetName fullName, this.root, DynamicMap arguments, DynamicMap? initialState) : super(fullName, arguments, initialState); + const _CurriedSwitch( + FullyQualifiedWidgetName fullName, + this.root, + DynamicMap arguments, + DynamicMap? initialState, + ) : super(fullName, arguments, const {}, initialState); final Switch root; @override - Widget buildChild(BuildContext context, DataSource source, DynamicContent data, RemoteEventHandler remoteEventTarget, List<_WidgetState> states, _StateResolverCallback stateResolver, _DataResolverCallback dataResolver) { - final Object resolvedWidget = _CurriedWidget._resolveFrom(root, const [], stateResolver, dataResolver); + Widget buildChild( + BuildContext context, + DataSource source, + DynamicContent data, + RemoteEventHandler remoteEventTarget, + List<_WidgetState> states, + _StateResolverCallback stateResolver, + _DataResolverCallback dataResolver, + _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, + ) { + final Object resolvedWidget = _CurriedWidget._resolveFrom( + root, + const [], + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); if (resolvedWidget is _CurriedWidget) { return resolvedWidget.build(context, data, remoteEventTarget, states); } @@ -826,12 +1124,20 @@ class _CurriedSwitch extends _CurriedWidget { } class _Widget extends StatefulWidget { - const _Widget({ required this.curriedWidget, required this.data, required this.remoteEventTarget, required this.states }); + const _Widget({ + required this.curriedWidget, + required this.data, + required this.widgetBuilderScope, + required this.remoteEventTarget, + required this.states, + }); final _CurriedWidget curriedWidget; final DynamicContent data; + final DynamicContent widgetBuilderScope; + final RemoteEventHandler remoteEventTarget; final List<_WidgetState> states; @@ -1014,6 +1320,36 @@ class _WidgetState extends State<_Widget> implements DataSource { ]; } + @override + Widget builder(List argsKey, DynamicMap builderArg) { + return _fetchBuilder(argsKey, builderArg, optional: false)!; + } + + @override + Widget? optionalBuilder(List argsKey, DynamicMap builderArg) { + return _fetchBuilder(argsKey, builderArg); + } + + Widget? _fetchBuilder( + List argsKey, + DynamicMap builderArg, { + bool optional = true, + }) { + final Object value = _fetch(argsKey, expandLists: false); + if (value is _RemoteWidgetBuilder) { + final _CurriedWidget curriedWidget = value(builderArg) as _CurriedWidget; + return curriedWidget.build( + context, + widget.data, + widget.remoteEventTarget, + widget.states, + ); + } + return optional + ? null + : _buildErrorWidget('Not a builder at $argsKey (got $value) for ${widget.curriedWidget.fullName}.'); + } + @override VoidCallback? voidHandler(List argsKey, [ DynamicMap? extraArguments ]) { return handler(argsKey, (HandlerTrigger callback) => () => callback(extraArguments)); @@ -1064,7 +1400,13 @@ class _WidgetState extends State<_Widget> implements DataSource { assert(!_debugFetching); try { _debugFetching = true; - final Object result = widget.curriedWidget.resolve(argsKey, _stateResolver, _dataResolver, expandLists: expandLists); + final Object result = widget.curriedWidget.resolve( + argsKey, + _stateResolver, + _dataResolver, + _widgetBuilderArgResolver, + expandLists: expandLists, + ); for (final _Subscription subscription in _dependencies) { subscription.addClient(key); } @@ -1095,6 +1437,17 @@ class _WidgetState extends State<_Widget> implements DataSource { return subscription.value; } + Object _widgetBuilderArgResolver(List rawDataKey) { + final _Key widgetBuilderArgKey = _Key(_kWidgetBuilderArgSection, rawDataKey); + final _Subscription subscription = _subscriptions[widgetBuilderArgKey] ??= _Subscription( + widget.widgetBuilderScope, + this, + rawDataKey, + ); + _dependencies.add(subscription); + return subscription.value; + } + Object _stateResolver(List rawStateKey, int depth) { final _Key stateKey = _Key(depth, rawStateKey); final _Subscription subscription; @@ -1126,7 +1479,16 @@ class _WidgetState extends State<_Widget> implements DataSource { @override Widget build(BuildContext context) { // TODO(ianh): what if this creates some _dependencies? - return widget.curriedWidget.buildChild(context, this, widget.data, widget.remoteEventTarget, _states, _stateResolver, _dataResolver); + return widget.curriedWidget.buildChild( + context, + this, + widget.data, + widget.remoteEventTarget, + _states, + _stateResolver, + _dataResolver, + _widgetBuilderArgResolver, + ); } @override @@ -1138,6 +1500,7 @@ class _WidgetState extends State<_Widget> implements DataSource { const int _kDataSection = -1; const int _kArgsSection = -2; +const int _kWidgetBuilderArgSection = -3; @immutable class _Key { diff --git a/packages/rfw/test/binary_test.dart b/packages/rfw/test/binary_test.dart index 0eca7888bbe9..9c91e34552cf 100644 --- a/packages/rfw/test/binary_test.dart +++ b/packages/rfw/test/binary_test.dart @@ -503,4 +503,17 @@ void main() { expect((value.widgets.first.root as ConstructorCall).name, 'c'); expect((value.widgets.first.root as ConstructorCall).arguments, isEmpty); }); + + testWidgets('Library encoder: widget builders', (WidgetTester tester) async { + final String source = ''' + widget Foo = Builder( + builder: (scope) => Text(text: scope.text), + ); + '''; + final RemoteWidgetLibrary library = parseLibraryFile(source); + final Uint8List encoded = encodeLibraryBlob(library); + final RemoteWidgetLibrary decoded = decodeLibraryBlob(encoded); + + expect(library.toString(), decoded.toString()); + }); } diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 89cb96d62d51..c68851d2a7ab 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1088,4 +1088,156 @@ void main() { data.update('c', 'test'); expect(log, ['leaf: 2', 'root: {a: [2, 3], b: [q, r]}', 'root: {a: [2, 3], b: [q, r], c: test}']); }); + + group('Widget Builders', () { + Widget _setUp(String library) { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final DynamicContent data = DynamicContent(); + final Runtime runtime = Runtime(); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(remoteLibraryName, parseLibraryFile(library)); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'CoolText': (BuildContext context, DataSource source) { + final int count = source.length(['text']); + String buffer = ''; + for (int i = 0; i < count; i++) { + final List key = ['text', i]; + final Object? text = source.v(key) ?? source.v(key); + buffer += text.toString(); + } + return Text(buffer, textDirection: TextDirection.ltr); + }, + 'Builder': (BuildContext context, DataSource source) { + return source.builder(['builder'], {}); + }, + 'Calculator': (BuildContext context, DataSource source) { + final int operand1 = source.v(['operand1'])!; + final int operand2 = source.v(['operand2'])!; + final String operation = source.v(['operation'])!; + final int result; + switch (operation) { + case 'sum': + result = operand1 + operand2; + case 'multiply': + result = operand1 * operand2; + default: + throw Exception('operation not supported'); + } + return source.builder(['builder'], { + 'result': result, + }); + }, + })); + return RemoteWidget( + runtime: runtime, + data: data, + widget: FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ); + } + + testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test = Builder( + builder: (scope) => CoolText(text: ['Hello Widget Builders!']), + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Hello Widget Builders!'); + }); + + testWidgets('Widget builders - work when scope is used', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test = Calculator( + operand1: 1, + operand2: 2, + operation: 'sum', + builder: (result) => CoolText(text: ['1 + 2 = ', result.result]), + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '1 + 2 = 3'); + }); + + testWidgets('Widget builders - works nested', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test = Calculator( + operand1: 1, + operand2: 2, + operation: 'sum', + builder: (result1) => Calculator( + operand1: result1.result, + operand2: 3, + operation: 'multiply', + builder: (result2) => CoolText(text: ['(1 + 2) * 3 = ', result2.result]), + ), + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '(1 + 2) * 3 = 9'); + }); + + testWidgets('Widget builders - swich works with builder', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test {justResult: true} = Calculator( + operand1: 1, + operand2: 2, + operation: 'sum', + builder: switch state.justResult { + true: (result) => CoolText(text: [result.result]), + }, + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '3'); + }); + + testWidgets('Widget builders - builder works with switch', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test = Calculator( + operand1: 1, + operand2: 2, + operation: 'sum', + builder: (result) => switch result.result { + 0: CoolText(text: ['The result is zero']), + default: CoolText(text: ['The result is not zero']), + }, + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'The result is not zero'); + }); + }); } diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index 8fe51d75a3d9..19fb27dfe184 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -340,4 +340,87 @@ void main() { final RemoteWidgetLibrary result = parseLibraryFile('widget a {b: 0} = c();'); expect(result.widgets.single.initialState, {'b': 0}); }); + + testWidgets('parseLibraryFile: functions work', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = Builder(builder: (scope) => Container()); + '''); + expect(libraryFile.toString(), 'widget a = Builder({builder: (scope) => Container({})});'); + }); + + testWidgets('parseLibraryFile: functions work with arguments', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = Builder(builder: (scope) => Container(width: scope.width)); + '''); + expect(libraryFile.toString(), 'widget a = Builder({builder: (scope) => Container({width: scope.width})});'); + }); + + testWidgets('parseLibraryFile: function arguments are lexical scoped', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + a: (s1) => B( + b: (s2) => T(s1: s1.s1, s2: s2.s2), + ), + ); + '''); + expect(libraryFile.toString(), 'widget a = A({a: (s1) => B({b: (s2) => T({s1: s1.s1, s2: s2.s2})})});'); + }); + + testWidgets('parseLibraryFile: function arguments can be shadowed', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + a: (s1) => B( + b: (s1) => T(t: s1.foo), + ), + ); + '''); + expect(libraryFile.toString(), 'widget a = A({a: (s1) => B({b: (s1) => T({t: s1.foo})})});'); + }); + + testWidgets('parseLibraryFile: function check reserved words', (WidgetTester tester) async { + const String library = 'widget a = Builder(builder: (args) => Container(width: args.width));'; + expect(() => parseLibraryFile(library), throwsA(isA())); + }); + + testWidgets('parseLibraryFile: switch works with functions', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + b: switch args.down { + true: (foo) => B(), + false: (bar) => C(), + } + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: switch args.down {true: (foo) => B({}), false: (bar) => C({})}});'); + }); + + testWidgets('parseLibraryFile: function works with switch', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + b: (foo) => switch foo.letter { + 'a': A(), + 'b': B(), + }, + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: (foo) => switch foo.letter {a: A({}), b: B({})}});'); + }); + + testWidgets('parseLibraryFile: function works with lists', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + b: (s1) => B(c: [s1.c]), + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: [s1.c]})});' ); + }); + + testWidgets('parseLibraryFile: function works with maps', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a = A( + b: (s1) => B(c: {d: s1.d}), + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: {d: s1.d}})});'); + }); } From 167861c2b6ff17e80cf2f9caaf82a6cc063afe97 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 13:19:56 -0800 Subject: [PATCH 02/22] Apply reviewers feedback --- packages/rfw/lib/src/dart/text.dart | 2 +- packages/rfw/test/runtime_test.dart | 93 +++++++++++++++++++++++++++-- packages/rfw/test/text_test.dart | 28 +++++++-- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index d8d4f1c2485c..89154f538c53 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -2394,7 +2394,7 @@ class _Parser { _expectIdentifier('state'); final StateReference stateReference = _withSourceRange(StateReference(_readParts()), innerStart); _expectSymbol(_SymbolToken.equals); - final Object value = _readValue(extended: true); + final Object value = _readValue(widgetBuilderScope: widgetBuilderScope, extended: true); return _withSourceRange(SetStateHandler(stateReference, value), start); } final int index = _loopIdentifiers.lastIndexOf(identifier) + 1; diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index c68851d2a7ab..6b359abc77de 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1090,12 +1090,14 @@ void main() { }); group('Widget Builders', () { + late DynamicContent data; + Widget _setUp(String library) { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); - final DynamicContent data = DynamicContent(); final Runtime runtime = Runtime(); + data = DynamicContent(); runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(remoteLibraryName, parseLibraryFile(library)); @@ -1108,14 +1110,17 @@ void main() { final Object? text = source.v(key) ?? source.v(key); buffer += text.toString(); } - return Text(buffer, textDirection: TextDirection.ltr); + return GestureDetector( + onTap: source.voidHandler(['onPressed']), + child: Text(buffer, textDirection: TextDirection.ltr) + ); }, 'Builder': (BuildContext context, DataSource source) { return source.builder(['builder'], {}); }, 'Calculator': (BuildContext context, DataSource source) { - final int operand1 = source.v(['operand1'])!; - final int operand2 = source.v(['operand2'])!; + final int operand1 = source.v(['operand1']) ?? 0; + final int operand2 = source.v(['operand2']) ?? 0; final String operation = source.v(['operation'])!; final int result; switch (operation) { @@ -1173,6 +1178,84 @@ void main() { expect(tester.widget(textFinder).data, '1 + 2 = 3'); }); + testWidgets('Widget builders - work with state', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test {counter: 0} = Calculator( + operand1: state.counter, + operand2: 1, + operation: 'sum', + builder: (result) => CoolText( + text: ['Counter: ', result.result], + onPressed: set state.counter = result.result, + ), + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Counter: 1'); + + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 2'); + + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 3'); + }); + + testWidgets('Widget builders - work with data', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test {counter: 0} = Calculator( + operand1: state.counter, + operand2: data.increment, + operation: 'sum', + builder: (result) => CoolText( + text: ['Counter: ', result.result], + onPressed: set state.counter = result.result, + ), + ); + '''); + await tester.pumpWidget(widget); + + final Finder textFinder = find.byType(Text); + + data.update('increment', 1); + await tester.pump(); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Counter: 1'); + + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 2'); + + data.update('increment', 10); + await tester.pump(); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Counter: 10'); + + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 11'); + + + data.update('increment', 100); + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 100'); + + await tester.tap(textFinder); + await tester.pump(); + expect(tester.widget(textFinder).data, 'Counter: 200'); + }); + testWidgets('Widget builders - works nested', (WidgetTester tester) async { final Widget widget = _setUp(''' import core; @@ -1197,7 +1280,7 @@ void main() { expect(tester.widget(textFinder).data, '(1 + 2) * 3 = 9'); }); - testWidgets('Widget builders - swich works with builder', (WidgetTester tester) async { + testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { final Widget widget = _setUp(''' import core; import local; diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index 19fb27dfe184..ae181a54fd54 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -378,8 +378,17 @@ void main() { }); testWidgets('parseLibraryFile: function check reserved words', (WidgetTester tester) async { - const String library = 'widget a = Builder(builder: (args) => Container(width: args.width));'; - expect(() => parseLibraryFile(library), throwsA(isA())); + void test(String input, String expectedMessage) { + try { + parseDataFile(input); + fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + } on ParserException catch (e) { + expect('$e', expectedMessage); + } + } + + const expectedErrorMessage = 'Expected symbol "{" but found widget at line 1 column 7.'; + test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); }); testWidgets('parseLibraryFile: switch works with functions', (WidgetTester tester) async { @@ -394,7 +403,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: switch args.down {true: (foo) => B({}), false: (bar) => C({})}});'); }); - testWidgets('parseLibraryFile: function works with switch', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilder works with switch', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (foo) => switch foo.letter { @@ -406,7 +415,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: (foo) => switch foo.letter {a: A({}), b: B({})}});'); }); - testWidgets('parseLibraryFile: function works with lists', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilder works with lists', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (s1) => B(c: [s1.c]), @@ -415,7 +424,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: [s1.c]})});' ); }); - testWidgets('parseLibraryFile: function works with maps', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilder works with maps', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (s1) => B(c: {d: s1.d}), @@ -423,4 +432,13 @@ void main() { '''); expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: {d: s1.d}})});'); }); + + testWidgets('parseLibraryFile: widgetBuilder works with setters', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a {foo: 0} = A( + b: (s1) => B(onTap: set state.foo = s1.foo), + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({onTap: set state.foo = s1.foo})});'); + }); } From f42e136152aaa40d6b2354d8473f65cd1200ef00 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 13:52:11 -0800 Subject: [PATCH 03/22] Apply reviewers feedback --- packages/rfw/lib/src/dart/binary.dart | 4 +++- packages/rfw/lib/src/dart/model.dart | 4 ++-- packages/rfw/test/runtime_test.dart | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/rfw/lib/src/dart/binary.dart b/packages/rfw/lib/src/dart/binary.dart index f6de28026d0b..cd999377f207 100644 --- a/packages/rfw/lib/src/dart/binary.dart +++ b/packages/rfw/lib/src/dart/binary.dart @@ -477,7 +477,9 @@ class _BlobDecoder { WidgetBuilderDeclaration _readWidgetBuilder() { final String argumentName = _readString(); final int type = _readByte(); - assert(type == _msWidget || type == _msSwitch); + if (type != _msWidget && type != _msSwitch) { + throw FormatException('Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding widget builder blob.'); + } final BlobNode widget = type == _msWidget ? _readWidget() : _readSwitch(); return WidgetBuilderDeclaration(argumentName, widget); } diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index 03399174b7a7..44d9da4b1d65 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -439,7 +439,7 @@ class ConstructorCall extends BlobNode { String toString() => '$name($arguments)'; } -/// Representation of functions that return widgets in Remote Flutter library blobs. +/// Representation of functions that return widgets in Remote Flutter Widgets library blobs. class WidgetBuilderDeclaration extends BlobNode { /// Creates a [WidgetBuilderDeclaration]. const WidgetBuilderDeclaration(this.argumentName, this.widget); @@ -561,7 +561,7 @@ class DataReference extends Reference { /// /// See also: /// -/// * [WidgetBuilderDeclaration] which represents a widget builder definition. +/// * [WidgetBuilderDeclaration], which represents a widget builder definition. class WidgetBuilderArgReference extends Reference { /// Wraps the given [parts] associated to the [argumentName] as an [WidgetBuilderArgReference]. /// diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 6b359abc77de..2c4225e3ffd4 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1092,12 +1092,12 @@ void main() { group('Widget Builders', () { late DynamicContent data; - Widget _setUp(String library) { + Widget _setUp(String library, {Map? initialData}) { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); final Runtime runtime = Runtime(); - data = DynamicContent(); + data = initialData == null ? DynamicContent() : DynamicContent(initialData); runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(remoteLibraryName, parseLibraryFile(library)); @@ -1218,42 +1218,43 @@ void main() { operand2: data.increment, operation: 'sum', builder: (result) => CoolText( - text: ['Counter: ', result.result], + text: [state.counter, ' + ', data.increment, ' = ', result.result], onPressed: set state.counter = result.result, ), ); - '''); + ''', initialData: {'increment': 0}); await tester.pumpWidget(widget); final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '0 + 0 = 0'); data.update('increment', 1); await tester.pump(); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'Counter: 1'); + expect(tester.widget(textFinder).data, '0 + 1 = 1'); await tester.tap(textFinder); await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 2'); + expect(tester.widget(textFinder).data, '1 + 1 = 2'); data.update('increment', 10); await tester.pump(); expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'Counter: 10'); + expect(tester.widget(textFinder).data, '1 + 10 = 11'); await tester.tap(textFinder); await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 11'); + expect(tester.widget(textFinder).data, '11 + 10 = 21'); data.update('increment', 100); await tester.tap(textFinder); await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 100'); + expect(tester.widget(textFinder).data, '21 + 100 = 121'); await tester.tap(textFinder); await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 200'); + expect(tester.widget(textFinder).data, '121 + 100 = 221'); }); testWidgets('Widget builders - works nested', (WidgetTester tester) async { From 0447cc39908ac7d4be2f9caaea938bc739c194d5 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 13:53:58 -0800 Subject: [PATCH 04/22] Do not infer required values --- packages/rfw/test/runtime_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 2c4225e3ffd4..190785f04675 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1119,8 +1119,8 @@ void main() { return source.builder(['builder'], {}); }, 'Calculator': (BuildContext context, DataSource source) { - final int operand1 = source.v(['operand1']) ?? 0; - final int operand2 = source.v(['operand2']) ?? 0; + final int operand1 = source.v(['operand1'])!; + final int operand2 = source.v(['operand2'])!; final String operation = source.v(['operation'])!; final int result; switch (operation) { From 1ef16c4d5bad59d6ce60083f73fdbbdefb661045 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 14:04:19 -0800 Subject: [PATCH 05/22] Apply reviewers feedback --- packages/rfw/lib/src/dart/text.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 89154f538c53..c675de0f9946 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -2377,11 +2377,6 @@ class _Parser { _advance(); return _withSourceRange(StateReference(_readParts()), start); } - if (widgetBuilderScope.contains(identifier)) { - final SourceLocation? start = _getSourceLocation(); - _advance(); - return _withSourceRange(WidgetBuilderArgReference(identifier, _readParts()), start); - } if (identifier == 'switch') { final SourceLocation? start = _getSourceLocation(); _advance(); @@ -2397,6 +2392,11 @@ class _Parser { final Object value = _readValue(widgetBuilderScope: widgetBuilderScope, extended: true); return _withSourceRange(SetStateHandler(stateReference, value), start); } + if (widgetBuilderScope.contains(identifier)) { + final SourceLocation? start = _getSourceLocation(); + _advance(); + return _withSourceRange(WidgetBuilderArgReference(identifier, _readParts()), start); + } final int index = _loopIdentifiers.lastIndexOf(identifier) + 1; if (index > 0) { final SourceLocation? start = _getSourceLocation(); From e9323047558da9aad6461bf4fea31f3edab220dd Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 15:48:54 -0800 Subject: [PATCH 06/22] Fix tests --- packages/rfw/lib/src/dart/text.dart | 5 ++- packages/rfw/test/text_test.dart | 48 +++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index c675de0f9946..16f43fac4b92 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -2418,11 +2418,14 @@ class _Parser { _expectSymbol(_SymbolToken.closeParen); _expectSymbol(_SymbolToken.equals); _expectSymbol(_SymbolToken.greatherThan); + final _Token valueToken = _source.current; final Object widget = _readValue( extended: true, widgetBuilderScope: [...widgetBuilderScope, argumentName], ); - assert(widget is ConstructorCall || widget is Switch); + if (widget is! ConstructorCall && widget is! Switch) { + throw ParserException._fromToken('Expecting a switch or constructor call got $widget', _source.current); + } return WidgetBuilderDeclaration(argumentName, widget as BlobNode); } diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index ae181a54fd54..7aa1513feb01 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -341,21 +341,21 @@ void main() { expect(result.widgets.single.initialState, {'b': 0}); }); - testWidgets('parseLibraryFile: functions work', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = Builder(builder: (scope) => Container()); '''); expect(libraryFile.toString(), 'widget a = Builder({builder: (scope) => Container({})});'); }); - testWidgets('parseLibraryFile: functions work with arguments', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work with arguments', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = Builder(builder: (scope) => Container(width: scope.width)); '''); expect(libraryFile.toString(), 'widget a = Builder({builder: (scope) => Container({width: scope.width})});'); }); - testWidgets('parseLibraryFile: function arguments are lexical scoped', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilder arguments are lexical scoped', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( a: (s1) => B( @@ -366,7 +366,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({a: (s1) => B({b: (s2) => T({s1: s1.s1, s2: s2.s2})})});'); }); - testWidgets('parseLibraryFile: function arguments can be shadowed', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilder arguments can be shadowed', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( a: (s1) => B( @@ -377,7 +377,35 @@ void main() { expect(libraryFile.toString(), 'widget a = A({a: (s1) => B({b: (s1) => T({t: s1.foo})})});'); }); - testWidgets('parseLibraryFile: function check reserved words', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders check the returned value', (WidgetTester tester) async { + void test(String input, String expectedMessage) { + try { + parseLibraryFile(input); + fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + } on ParserException catch (e) { + expect('$e', expectedMessage); + } + } + + const expectedErrorMessage = 'Expecting a switch or constructor call got 1 at line 1 column 27.'; + test('widget a = B(b: (foo) => 1);', expectedErrorMessage); + }); + + testWidgets('parseLibraryFile: widgetBuilders check reserved words', (WidgetTester tester) async { + void test(String input, String expectedMessage) { + try { + parseLibraryFile(input); + fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + } on ParserException catch (e) { + expect('$e', expectedMessage); + } + } + + const expectedErrorMessage = 'args is a reserved word at line 1 column 34.'; + test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); + }); + + testWidgets('parseLibraryFile: widgetBuilders check reserved words', (WidgetTester tester) async { void test(String input, String expectedMessage) { try { parseDataFile(input); @@ -391,7 +419,7 @@ void main() { test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); }); - testWidgets('parseLibraryFile: switch works with functions', (WidgetTester tester) async { + testWidgets('parseLibraryFile: switch works with widgetBuilders', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: switch args.down { @@ -403,7 +431,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: switch args.down {true: (foo) => B({}), false: (bar) => C({})}});'); }); - testWidgets('parseLibraryFile: widgetBuilder works with switch', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work with switch', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (foo) => switch foo.letter { @@ -415,7 +443,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: (foo) => switch foo.letter {a: A({}), b: B({})}});'); }); - testWidgets('parseLibraryFile: widgetBuilder works with lists', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work with lists', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (s1) => B(c: [s1.c]), @@ -424,7 +452,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: [s1.c]})});' ); }); - testWidgets('parseLibraryFile: widgetBuilder works with maps', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work with maps', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: (s1) => B(c: {d: s1.d}), @@ -433,7 +461,7 @@ void main() { expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: {d: s1.d}})});'); }); - testWidgets('parseLibraryFile: widgetBuilder works with setters', (WidgetTester tester) async { + testWidgets('parseLibraryFile: widgetBuilders work with setters', (WidgetTester tester) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a {foo: 0} = A( b: (s1) => B(onTap: set state.foo = s1.foo), From cefb0960bfdc21fa93bce83c21aa74f4987fddeb Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 15:54:46 -0800 Subject: [PATCH 07/22] Apply reviewers feedback --- packages/rfw/test/runtime_test.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 190785f04675..837376a91ba4 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1270,7 +1270,17 @@ void main() { operand1: result1.result, operand2: 3, operation: 'multiply', - builder: (result2) => CoolText(text: ['(1 + 2) * 3 = ', result2.result]), + builder: (result2) => CoolText( + text: [ + '1 + 2 = ', + result1.result, + '; ', + result1.result, + ' * 3 = ', + result2.result, + ';', + ], + ), ), ); '''); @@ -1278,7 +1288,7 @@ void main() { final Finder textFinder = find.byType(Text); expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '(1 + 2) * 3 = 9'); + expect(tester.widget(textFinder).data, '1 + 2 = 3; 3 * 3 = 9;'); }); testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { From 8ed0a438f32aab270d565103576279721c663efb Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 16:17:56 -0800 Subject: [PATCH 08/22] Supports events --- packages/rfw/lib/src/dart/text.dart | 8 ++++++- packages/rfw/test/runtime_test.dart | 36 +++++++++++++++++++++++++++++ packages/rfw/test/text_test.dart | 9 ++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 16f43fac4b92..3e159c10b264 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -2360,7 +2360,13 @@ class _Parser { if (identifier == 'event') { final SourceLocation? start = _getSourceLocation(); _advance(); - return _withSourceRange(EventHandler(_readString(), _readMap(extended: true)), start); + return _withSourceRange( + EventHandler( + _readString(), + _readMap(widgetBuilderScope: widgetBuilderScope, extended: true), + ), + start, + ); } if (identifier == 'args') { final SourceLocation? start = _getSourceLocation(); diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 837376a91ba4..cad354fa19a7 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1091,6 +1091,7 @@ void main() { group('Widget Builders', () { late DynamicContent data; + late List dispatchedEvents; Widget _setUp(String library, {Map? initialData}) { const LibraryName coreLibraryName = LibraryName(['core']); @@ -1098,6 +1099,7 @@ void main() { const LibraryName remoteLibraryName = LibraryName(['remote']); final Runtime runtime = Runtime(); data = initialData == null ? DynamicContent() : DynamicContent(initialData); + dispatchedEvents = []; runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(remoteLibraryName, parseLibraryFile(library)); @@ -1140,6 +1142,8 @@ void main() { runtime: runtime, data: data, widget: FullyQualifiedWidgetName(remoteLibraryName, 'test'), + onEvent: (String eventName, DynamicMap eventArguments) => + dispatchedEvents.add(RfwEvent(eventName, eventArguments)), ); } @@ -1257,6 +1261,31 @@ void main() { expect(tester.widget(textFinder).data, '121 + 100 = 221'); }); + testWidgets('Widget builders - work with events', (WidgetTester tester) async { + final Widget widget = _setUp(''' + import core; + import local; + + widget test = Calculator( + operand1: 1, + operand2: 2, + operation: 'sum', + builder: (result) => CoolText( + text: ['Press this button'], + onPressed: event "works" {result: result.result}, + ), + ); + '''); + await tester.pumpWidget(widget); + final Finder textFinder = find.byType(Text); + await tester.tap(textFinder); + await tester.pump(); + + expect(dispatchedEvents, hasLength(1)); + expect(dispatchedEvents.single.name, 'works'); + expect(dispatchedEvents.single.arguments['result'], 3); + }); + testWidgets('Widget builders - works nested', (WidgetTester tester) async { final Widget widget = _setUp(''' import core; @@ -1335,3 +1364,10 @@ void main() { }); }); } + +final class RfwEvent { + RfwEvent(this.name, this.arguments); + + final String name; + final DynamicMap arguments; +} diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index 7aa1513feb01..c86cf22ff3d3 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -469,4 +469,13 @@ void main() { '''); expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({onTap: set state.foo = s1.foo})});'); }); + + testWidgets('parseLibraryFile: widgetBuilders work with events', (WidgetTester tester) async { + final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' + widget a {foo: 0} = A( + b: (s1) => B(onTap: event "foo" {result: s1.result}) + ); + '''); + expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({onTap: event foo {result: s1.result}})});'); + }); } From 09cc332de78eeb687efd17ece465e0c5a59ad4fd Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 16:24:13 -0800 Subject: [PATCH 09/22] Fix docs --- packages/rfw/lib/src/flutter/runtime.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index f5def8f25cf3..fc4acd9ae394 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -129,23 +129,23 @@ abstract class DataSource { /// non-widget nodes replaced by [ErrorWidget]. List childList(List argsKey); - /// Build the builder at the given key. + /// Builds the widget builder at the given key. /// - /// If the node specified is not a widget, returns an [ErrorWidget]. + /// If the node is not a widget builder, returns an [ErrorWidget]. /// /// See also: /// - /// * [optionalBuilder], which returns null if the widget is missing. + /// * [optionalBuilder], which returns null if the widget builder is missing. Widget builder(List argsKey, DynamicMap builderArg); - /// Build the builder at the given key. + /// Builds the widget builder at the given key. /// - /// If the node specified is not a widget, returns null. + /// If the node is not a widget builder, returns null. /// /// See also: /// /// * [builder], which returns an [ErrorWidget] instead of null if the widget - /// is missing. + /// builder is missing. Widget? optionalBuilder(List argsKey, DynamicMap builderArg); /// Gets a [VoidCallback] event handler at the given key. From 4ff5572feab57867f8701011f33c7004cdc45cee Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 16:41:30 -0800 Subject: [PATCH 10/22] Fix docs --- packages/rfw/lib/src/dart/model.dart | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index 44d9da4b1d65..f735ed8a09ec 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -441,13 +441,15 @@ class ConstructorCall extends BlobNode { /// Representation of functions that return widgets in Remote Flutter Widgets library blobs. class WidgetBuilderDeclaration extends BlobNode { - /// Creates a [WidgetBuilderDeclaration]. + /// Represents a callback that takes a single argument [argumentName] and returns the [widget]. const WidgetBuilderDeclaration(this.argumentName, this.widget); - /// The name associated with the passed [DynamicMap]. + /// The callback single argument name. + /// + /// In `Builder(builder: (scope) => Container());` [argumentName] is "scope". final String argumentName; - /// The widget that will be returned when the builder is called. + /// The widget that will be returned when the builder callback is called. /// /// This is usually a [ConstructorCall], but may be a [Switch] (so long as /// that [Switch] resolves to a [ConstructorCall]. Other values (or a [Switch] @@ -554,21 +556,25 @@ class DataReference extends Reference { String toString() => 'data.${parts.join(".")}'; } -/// Reference to the [DynamicMap] passed into the widget builder. +/// Reference to the single argument of type [DynamicMap] passed into the widget builder. /// /// This class is used to represent references to a function argument. -/// In "(scope) => Container(width: scope.width)" this represents "scope.width". +/// In `(scope) => Container(width: scope.width)` this represents "scope.width". /// /// See also: /// /// * [WidgetBuilderDeclaration], which represents a widget builder definition. class WidgetBuilderArgReference extends Reference { - /// Wraps the given [parts] associated to the [argumentName] as an [WidgetBuilderArgReference]. + /// Wraps the given [argumentName] and [parts] as a [WidgetBuilderArgReference]. /// /// The parts must not be mutated after the object is created. const WidgetBuilderArgReference(this.argumentName, super.parts); - /// References the function argument name. + /// A reference to a [WidgetBuilderDeclaration.argumentName]. + /// + /// In `Builder(builder: (scope) => Text(text: scope.result.text));` + /// "scope.result.text" is the [WidgetBuilderArgReference]. + /// The [argumentName] is "scope" and its [parts] are `["result", "text"]`. final String argumentName; WidgetBuilderArgReference constructReference(List moreParts) { From 6911f904fdefe2765a81194aa46cffcf7e0208bf Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 16:53:17 -0800 Subject: [PATCH 11/22] Remove trailing spaces --- packages/rfw/lib/src/dart/model.dart | 4 ++-- packages/rfw/lib/src/dart/text.dart | 10 +++++----- packages/rfw/lib/src/flutter/runtime.dart | 18 +++++++++--------- packages/rfw/test/runtime_test.dart | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index f735ed8a09ec..6e14542be29c 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -562,7 +562,7 @@ class DataReference extends Reference { /// In `(scope) => Container(width: scope.width)` this represents "scope.width". /// /// See also: -/// +/// /// * [WidgetBuilderDeclaration], which represents a widget builder definition. class WidgetBuilderArgReference extends Reference { /// Wraps the given [argumentName] and [parts] as a [WidgetBuilderArgReference]. @@ -572,7 +572,7 @@ class WidgetBuilderArgReference extends Reference { /// A reference to a [WidgetBuilderDeclaration.argumentName]. /// - /// In `Builder(builder: (scope) => Text(text: scope.result.text));` + /// In `Builder(builder: (scope) => Text(text: scope.result.text));` /// "scope.result.text" is the [WidgetBuilderArgReference]. /// The [argumentName] is "scope" and its [parts] are `["result", "text"]`. final String argumentName; diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 3e159c10b264..1a8069605453 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -298,10 +298,10 @@ DynamicMap parseDataFile(String file) { /// /// ### Widget Builders /// -/// Widget builders take a single argument and return a widget. +/// Widget builders take a single argument and return a widget. /// The [DynamicMap] argument consists of key-value pairs where values -/// can be of any types in the data model. Widget builders arguments are lexically -/// scoped so a given constructor call has access to any arguments where it is +/// can be of any types in the data model. Widget builders arguments are lexically +/// scoped so a given constructor call has access to any arguments where it is /// defined plus arguments defined by its parents (if any). /// /// In this example several widget builders are nested together: @@ -2197,7 +2197,7 @@ class _Parser { } _expectSymbol(_SymbolToken.colon); final Object value = _readValue( - extended: extended, + extended: extended, nullOk: true, widgetBuilderScope: widgetBuilderScope, ); @@ -2237,7 +2237,7 @@ class _Parser { _expectSymbol(_SymbolToken.colon); _loopIdentifiers.add(loopIdentifier); final Object template = _readValue( - widgetBuilderScope: widgetBuilderScope, + widgetBuilderScope: widgetBuilderScope, extended: extended, ); assert(_loopIdentifiers.last == loopIdentifier); diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index fc4acd9ae394..4ac403153398 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -515,7 +515,7 @@ class Runtime extends ChangeNotifier { } Object _bindArguments( - FullyQualifiedWidgetName context, + FullyQualifiedWidgetName context, Object node, Object arguments, DynamicMap widgetBuilderScope, int stateDepth, @@ -938,9 +938,9 @@ abstract class _CurriedWidget extends BlobNode { _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, ) { if (root is DynamicMap) { - return root.map((String key, Object? value) => + return root.map((String key, Object? value) => MapEntry( - key, + key, _fix(root[key]!, stateResolver, dataResolver, widgetBuilderArgResolver), ), ); @@ -954,7 +954,7 @@ abstract class _CurriedWidget extends BlobNode { widgetBuilderArgResolver, ).length!; return DynamicList.generate( - length, + length, (int index) => _fix( _listLookup(root, index, stateResolver, dataResolver, widgetBuilderArgResolver).result!, stateResolver, @@ -964,7 +964,7 @@ abstract class _CurriedWidget extends BlobNode { ); } else { return DynamicList.generate( - root.length, + root.length, (int index) => _fix(root[index]!, stateResolver, dataResolver, widgetBuilderArgResolver), ); } @@ -978,7 +978,7 @@ abstract class _CurriedWidget extends BlobNode { Object resolve( List parts, _StateResolverCallback stateResolver, - _DataResolverCallback dataResolver, + _DataResolverCallback dataResolver, _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, { required bool expandLists, }) { @@ -1027,13 +1027,13 @@ class _CurriedLocalWidget extends _CurriedWidget { FullyQualifiedWidgetName fullName, this.child, DynamicMap arguments, - DynamicMap widgetBuilderScope, + DynamicMap widgetBuilderScope, ) : super(fullName, arguments, widgetBuilderScope, null); factory _CurriedLocalWidget.error(FullyQualifiedWidgetName fullName, String message) { return _CurriedLocalWidget( - fullName, - (BuildContext context, DataSource data) => _buildErrorWidget(message), + fullName, + (BuildContext context, DataSource data) => _buildErrorWidget(message), const {}, const {}, ); diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index cad354fa19a7..7cddc2f2197f 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1103,7 +1103,7 @@ void main() { runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(remoteLibraryName, parseLibraryFile(library)); - runtime.update(localLibraryName, LocalWidgetLibrary( { + runtime.update(localLibraryName, LocalWidgetLibrary( { 'CoolText': (BuildContext context, DataSource source) { final int count = source.length(['text']); String buffer = ''; @@ -1128,7 +1128,7 @@ void main() { switch (operation) { case 'sum': result = operand1 + operand2; - case 'multiply': + case 'multiply': result = operand1 * operand2; default: throw Exception('operation not supported'); @@ -1142,7 +1142,7 @@ void main() { runtime: runtime, data: data, widget: FullyQualifiedWidgetName(remoteLibraryName, 'test'), - onEvent: (String eventName, DynamicMap eventArguments) => + onEvent: (String eventName, DynamicMap eventArguments) => dispatchedEvents.add(RfwEvent(eventName, eventArguments)), ); } From b2aad1261ad17338af31fe96fcffe3604ffddbb3 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 17:13:37 -0800 Subject: [PATCH 12/22] Fixes docs --- packages/rfw/lib/src/dart/model.dart | 8 ++++++++ packages/rfw/lib/src/dart/text.dart | 2 +- packages/rfw/lib/src/flutter/runtime.dart | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index 6e14542be29c..d1a0d37b9eac 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -577,6 +577,14 @@ class WidgetBuilderArgReference extends Reference { /// The [argumentName] is "scope" and its [parts] are `["result", "text"]`. final String argumentName; + /// Creates a new [WidgetBuilderArgReference] that indexes even deeper than this one. + /// + /// For example, suppose a widget's arguments consisted of a map with one key, + /// "a", whose value was a [WidgetBuilderArgReference] referencing "scope.foo.bar". + /// Now suppose that the widget itself has an [ArgsReference] that references + /// "args.a.baz". The "args.a" part identifies the aforementioned + /// [WidgetBuilderArgReference], and so the resulting reference is actually to + /// "scope.foo.bar.baz". WidgetBuilderArgReference constructReference(List moreParts) { return WidgetBuilderArgReference(argumentName, parts + moreParts); } diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 1a8069605453..4db42dcfbe0d 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -2430,7 +2430,7 @@ class _Parser { widgetBuilderScope: [...widgetBuilderScope, argumentName], ); if (widget is! ConstructorCall && widget is! Switch) { - throw ParserException._fromToken('Expecting a switch or constructor call got $widget', _source.current); + throw ParserException._fromToken('Expecting a switch or constructor call got $widget', valueToken); } return WidgetBuilderDeclaration(argumentName, widget as BlobNode); } diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index 4ac403153398..428747c4b8ce 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -545,7 +545,7 @@ class Runtime extends ChangeNotifier { context, node.widget, arguments, - {...widgetBuilderScope, node.argumentName: widgetBuilderArg}, + {...widgetBuilderScope, node.argumentName: widgetBuilderArg}, stateDepth, usedWidgets, ); @@ -838,7 +838,7 @@ abstract class _CurriedWidget extends BlobNode { current = current.constructReference(parts.sublist(index)); index = parts.length; } - current = widgetBuilderArgResolver([current.argumentName, ...current.parts]); + current = widgetBuilderArgResolver([current.argumentName, ...current.parts]); continue; } else if (current is BoundArgsReference) { List nextParts = current.parts; @@ -1337,7 +1337,7 @@ class _WidgetState extends State<_Widget> implements DataSource { }) { final Object value = _fetch(argsKey, expandLists: false); if (value is _RemoteWidgetBuilder) { - final _CurriedWidget curriedWidget = value(builderArg) as _CurriedWidget; + final _CurriedWidget curriedWidget = value(builderArg); return curriedWidget.build( context, widget.data, From 2d3b120d2630a50d20a4e76ead57adb1f74c7b05 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 17:18:18 -0800 Subject: [PATCH 13/22] Add version changes --- packages/rfw/CHANGELOG.md | 3 +++ packages/rfw/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/rfw/CHANGELOG.md b/packages/rfw/CHANGELOG.md index 5b2b6cbbfd61..b34abdb06489 100644 --- a/packages/rfw/CHANGELOG.md +++ b/packages/rfw/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.25 +* Adds support for wildget builders. + ## 1.0.24 * Adds `InkResponse` material widget. diff --git a/packages/rfw/pubspec.yaml b/packages/rfw/pubspec.yaml index 6056af37679b..310d7bd6535c 100644 --- a/packages/rfw/pubspec.yaml +++ b/packages/rfw/pubspec.yaml @@ -2,7 +2,7 @@ name: rfw description: "Remote Flutter widgets: a library for rendering declarative widget description files at runtime." repository: https://github.com/flutter/packages/tree/main/packages/rfw issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+rfw%22 -version: 1.0.24 +version: 1.0.25 environment: sdk: ^3.2.0 From 6584379ab4a36912a942e8e41e9e75420ed94f30 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 27 Feb 2024 17:27:52 -0800 Subject: [PATCH 14/22] Fix analyzer issues --- packages/rfw/test/binary_test.dart | 2 +- packages/rfw/test/runtime_test.dart | 26 +++++++++++++------------- packages/rfw/test/text_test.dart | 9 ++++++--- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/rfw/test/binary_test.dart b/packages/rfw/test/binary_test.dart index 9c91e34552cf..91153c47ff50 100644 --- a/packages/rfw/test/binary_test.dart +++ b/packages/rfw/test/binary_test.dart @@ -505,7 +505,7 @@ void main() { }); testWidgets('Library encoder: widget builders', (WidgetTester tester) async { - final String source = ''' + const String source = ''' widget Foo = Builder( builder: (scope) => Text(text: scope.text), ); diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 7cddc2f2197f..bfeebb908468 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1093,7 +1093,7 @@ void main() { late DynamicContent data; late List dispatchedEvents; - Widget _setUp(String library, {Map? initialData}) { + Widget rwfWidget(String library, {Map? initialData}) { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); @@ -1105,7 +1105,7 @@ void main() { runtime.update(remoteLibraryName, parseLibraryFile(library)); runtime.update(localLibraryName, LocalWidgetLibrary( { 'CoolText': (BuildContext context, DataSource source) { - final int count = source.length(['text']); + final int count = source.length(['text']); String buffer = ''; for (int i = 0; i < count; i++) { final List key = ['text', i]; @@ -1113,7 +1113,7 @@ void main() { buffer += text.toString(); } return GestureDetector( - onTap: source.voidHandler(['onPressed']), + onTap: source.voidHandler(['onPressed']), child: Text(buffer, textDirection: TextDirection.ltr) ); }, @@ -1141,14 +1141,14 @@ void main() { return RemoteWidget( runtime: runtime, data: data, - widget: FullyQualifiedWidgetName(remoteLibraryName, 'test'), + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), onEvent: (String eventName, DynamicMap eventArguments) => dispatchedEvents.add(RfwEvent(eventName, eventArguments)), ); } testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1164,7 +1164,7 @@ void main() { }); testWidgets('Widget builders - work when scope is used', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1183,7 +1183,7 @@ void main() { }); testWidgets('Widget builders - work with state', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1213,7 +1213,7 @@ void main() { }); testWidgets('Widget builders - work with data', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1226,7 +1226,7 @@ void main() { onPressed: set state.counter = result.result, ), ); - ''', initialData: {'increment': 0}); + ''', initialData: {'increment': 0}); await tester.pumpWidget(widget); final Finder textFinder = find.byType(Text); @@ -1262,7 +1262,7 @@ void main() { }); testWidgets('Widget builders - work with events', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1287,7 +1287,7 @@ void main() { }); testWidgets('Widget builders - works nested', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1321,7 +1321,7 @@ void main() { }); testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; @@ -1342,7 +1342,7 @@ void main() { }); testWidgets('Widget builders - builder works with switch', (WidgetTester tester) async { - final Widget widget = _setUp(''' + final Widget widget = rwfWidget(''' import core; import local; diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index c86cf22ff3d3..2dac169fb874 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -387,7 +387,8 @@ void main() { } } - const expectedErrorMessage = 'Expecting a switch or constructor call got 1 at line 1 column 27.'; + const String expectedErrorMessage = + 'Expecting a switch or constructor call got 1 at line 1 column 27.'; test('widget a = B(b: (foo) => 1);', expectedErrorMessage); }); @@ -401,7 +402,8 @@ void main() { } } - const expectedErrorMessage = 'args is a reserved word at line 1 column 34.'; + const String expectedErrorMessage = + 'args is a reserved word at line 1 column 34.'; test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); }); @@ -415,7 +417,8 @@ void main() { } } - const expectedErrorMessage = 'Expected symbol "{" but found widget at line 1 column 7.'; + const String expectedErrorMessage = + 'Expected symbol "{" but found widget at line 1 column 7.'; test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); }); From 939a14907eaea55cd4366b0af2d79e1b4a3731cb Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 5 Mar 2024 14:45:38 -0800 Subject: [PATCH 15/22] Fix typo --- packages/rfw/test/runtime_test.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index bfeebb908468..ef67ab8ee639 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1093,7 +1093,7 @@ void main() { late DynamicContent data; late List dispatchedEvents; - Widget rwfWidget(String library, {Map? initialData}) { + Widget rfwWidget(String library, {Map? initialData}) { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); @@ -1148,7 +1148,7 @@ void main() { } testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1164,7 +1164,7 @@ void main() { }); testWidgets('Widget builders - work when scope is used', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1183,7 +1183,7 @@ void main() { }); testWidgets('Widget builders - work with state', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1213,7 +1213,7 @@ void main() { }); testWidgets('Widget builders - work with data', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1262,7 +1262,7 @@ void main() { }); testWidgets('Widget builders - work with events', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1287,7 +1287,7 @@ void main() { }); testWidgets('Widget builders - works nested', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1321,7 +1321,7 @@ void main() { }); testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; @@ -1342,7 +1342,7 @@ void main() { }); testWidgets('Widget builders - builder works with switch', (WidgetTester tester) async { - final Widget widget = rwfWidget(''' + final Widget widget = rfwWidget(''' import core; import local; From 95158b923c866dd184772f811a079c3c1fd14e1e Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Tue, 5 Mar 2024 14:47:45 -0800 Subject: [PATCH 16/22] Apply grammar suggestions --- packages/rfw/lib/src/dart/model.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index d1a0d37b9eac..77078b88e1bb 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -446,7 +446,7 @@ class WidgetBuilderDeclaration extends BlobNode { /// The callback single argument name. /// - /// In `Builder(builder: (scope) => Container());` [argumentName] is "scope". + /// In `Builder(builder: (scope) => Container());`, [argumentName] is "scope". final String argumentName; /// The widget that will be returned when the builder callback is called. @@ -559,7 +559,7 @@ class DataReference extends Reference { /// Reference to the single argument of type [DynamicMap] passed into the widget builder. /// /// This class is used to represent references to a function argument. -/// In `(scope) => Container(width: scope.width)` this represents "scope.width". +/// In `(scope) => Container(width: scope.width)`, this represents "scope.width". /// /// See also: /// @@ -572,7 +572,7 @@ class WidgetBuilderArgReference extends Reference { /// A reference to a [WidgetBuilderDeclaration.argumentName]. /// - /// In `Builder(builder: (scope) => Text(text: scope.result.text));` + /// In `Builder(builder: (scope) => Text(text: scope.result.text));`, /// "scope.result.text" is the [WidgetBuilderArgReference]. /// The [argumentName] is "scope" and its [parts] are `["result", "text"]`. final String argumentName; From a4934ff126e5b86839d8503999636ce8f1b559e6 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 08:28:58 -0800 Subject: [PATCH 17/22] update tests --- packages/rfw/coverage/lcov.info | 3519 +++++++++++++++++++++++++++ packages/rfw/test/runtime_test.dart | 614 +++-- 2 files changed, 3885 insertions(+), 248 deletions(-) create mode 100644 packages/rfw/coverage/lcov.info diff --git a/packages/rfw/coverage/lcov.info b/packages/rfw/coverage/lcov.info new file mode 100644 index 000000000000..fa253d6a4a14 --- /dev/null +++ b/packages/rfw/coverage/lcov.info @@ -0,0 +1,3519 @@ +SF:lib/src/dart/binary.dart +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,2 +DA:67,2 +DA:68,10 +DA:69,2 +DA:70,2 +DA:71,2 +DA:85,2 +DA:86,2 +DA:87,2 +DA:88,2 +DA:89,4 +DA:266,2 +DA:267,10 +DA:268,2 +DA:269,2 +DA:270,2 +DA:313,2 +DA:319,10 +DA:321,2 +DA:322,10 +DA:323,3 +DA:325,4 +DA:328,2 +DA:329,2 +DA:330,2 +DA:331,4 +DA:334,2 +DA:335,2 +DA:336,2 +DA:338,4 +DA:342,0 +DA:343,0 +DA:344,0 +DA:347,1 +DA:348,1 +DA:349,1 +DA:350,2 +DA:353,2 +DA:354,2 +DA:355,2 +DA:356,2 +DA:357,14 +DA:360,1 +DA:361,3 +DA:362,1 +DA:364,1 +DA:365,1 +DA:366,1 +DA:367,1 +DA:369,5 +DA:374,2 +DA:375,2 +DA:376,2 +DA:379,2 +DA:380,2 +DA:382,4 +DA:383,2 +DA:384,2 +DA:390,1 +DA:391,1 +DA:392,1 +DA:395,1 +DA:398,1 +DA:399,1 +DA:400,1 +DA:401,1 +DA:402,1 +DA:404,2 +DA:405,1 +DA:406,1 +DA:410,1 +DA:413,2 +DA:415,2 +DA:417,2 +DA:419,2 +DA:420,2 +DA:421,2 +DA:422,1 +DA:423,2 +DA:424,1 +DA:425,2 +DA:426,4 +DA:427,2 +DA:428,2 +DA:429,5 +DA:433,2 +DA:434,2 +DA:435,4 +DA:438,2 +DA:440,2 +DA:441,3 +DA:442,2 +DA:443,1 +DA:444,2 +DA:445,2 +DA:446,2 +DA:447,2 +DA:448,2 +DA:449,3 +DA:450,2 +DA:451,2 +DA:452,2 +DA:453,4 +DA:454,2 +DA:455,1 +DA:456,2 +DA:457,4 +DA:458,2 +DA:459,1 +DA:460,2 +DA:461,3 +DA:463,4 +DA:467,2 +DA:468,2 +DA:469,2 +DA:472,2 +DA:473,2 +DA:474,6 +DA:477,1 +DA:478,1 +DA:479,1 +DA:480,1 +DA:481,0 +DA:483,2 +DA:484,1 +DA:487,2 +DA:488,2 +DA:489,4 +DA:490,2 +DA:493,2 +DA:494,1 +DA:495,2 +DA:496,2 +DA:498,5 +DA:500,2 +DA:503,2 +DA:504,8 +DA:507,2 +DA:508,12 +DA:511,2 +DA:512,8 +DA:515,2 +DA:516,6 +DA:519,2 +DA:520,6 +DA:521,2 +DA:523,4 +DA:524,2 +DA:525,2 +DA:526,2 +DA:531,2 +DA:533,6 +DA:534,6 +DA:548,2 +DA:550,6 +DA:551,18 +DA:555,2 +DA:557,4 +DA:561,0 +DA:562,0 +DA:563,0 +DA:565,0 +DA:566,0 +DA:569,6 +DA:572,2 +DA:573,2 +DA:574,4 +DA:575,4 +DA:578,2 +DA:579,4 +DA:580,4 +DA:581,2 +DA:582,2 +DA:586,2 +DA:587,2 +DA:588,4 +DA:589,2 +DA:590,1 +DA:591,2 +DA:592,1 +DA:594,3 +DA:598,2 +DA:599,2 +DA:600,2 +DA:601,2 +DA:602,2 +DA:603,3 +DA:604,2 +DA:605,2 +DA:606,3 +DA:607,2 +DA:608,2 +DA:609,2 +DA:610,1 +DA:611,2 +DA:612,2 +DA:613,1 +DA:615,2 +DA:619,1 +DA:620,2 +DA:623,2 +DA:624,2 +DA:625,2 +DA:626,2 +DA:627,2 +DA:628,2 +DA:629,4 +DA:630,4 +DA:631,6 +DA:632,2 +DA:633,2 +DA:634,2 +DA:635,2 +DA:636,2 +DA:637,2 +DA:638,3 +DA:639,3 +DA:640,2 +DA:641,2 +DA:642,3 +DA:643,3 +DA:644,2 +DA:645,2 +DA:646,2 +DA:647,3 +DA:648,3 +DA:649,2 +DA:650,2 +DA:651,2 +DA:652,3 +DA:653,3 +DA:654,2 +DA:655,2 +DA:656,3 +DA:657,3 +DA:658,2 +DA:659,2 +DA:660,2 +DA:661,3 +DA:662,2 +DA:663,2 +DA:664,2 +DA:665,3 +DA:666,3 +DA:668,2 +DA:670,1 +DA:672,1 +DA:674,2 +DA:675,2 +DA:676,1 +DA:677,3 +DA:678,3 +DA:679,2 +DA:681,4 +DA:682,4 +DA:686,2 +DA:687,4 +DA:688,4 +DA:689,4 +DA:690,2 +DA:691,3 +DA:693,2 +DA:695,4 +DA:699,2 +DA:700,4 +DA:701,4 +DA:702,8 +DA:703,8 +DA:707,2 +DA:708,4 +DA:709,4 +DA:712,2 +DA:713,6 +DA:714,4 +LF:278 +LH:269 +end_of_record +SF:lib/src/dart/model.dart +DA:40,2 +DA:51,1 +DA:53,3 +DA:54,1 +DA:56,3 +DA:59,1 +DA:61,2 +DA:64,1 +DA:65,3 +DA:66,3 +DA:69,1 +DA:70,3 +DA:75,2 +DA:76,6 +DA:77,1 +DA:79,6 +DA:85,1 +DA:86,3 +DA:87,1 +DA:89,3 +DA:96,1 +DA:97,3 +DA:98,1 +DA:100,3 +DA:107,1 +DA:108,3 +DA:109,1 +DA:111,3 +DA:114,1 +DA:116,3 +DA:139,2 +DA:140,8 +DA:141,4 +DA:155,1 +DA:157,2 +DA:160,1 +DA:161,3 +DA:162,3 +DA:165,1 +DA:166,3 +DA:168,1 +DA:170,7 +DA:188,22 +DA:197,21 +DA:208,1 +DA:209,2 +DA:221,1 +DA:222,2 +DA:233,7 +DA:237,14 +DA:239,2 +DA:244,9 +DA:248,27 +DA:251,27 +DA:252,27 +DA:271,19 +DA:276,9 +DA:278,27 +DA:281,9 +DA:282,27 +DA:285,8 +DA:286,16 +DA:288,5 +DA:289,10 +DA:291,1 +DA:293,4 +DA:294,3 +DA:297,5 +DA:298,1 +DA:302,6 +DA:303,5 +DA:313,14 +DA:321,6 +DA:323,18 +DA:326,6 +DA:327,33 +DA:330,8 +DA:331,24 +DA:333,2 +DA:334,6 +DA:336,1 +DA:338,3 +DA:339,1 +DA:342,3 +DA:351,10 +DA:353,2 +DA:373,7 +DA:385,2 +DA:386,6 +DA:397,6 +DA:413,3 +DA:414,9 +DA:424,11 +DA:438,3 +DA:439,9 +DA:445,3 +DA:460,2 +DA:461,6 +DA:470,8 +DA:487,7 +DA:493,3 +DA:494,6 +DA:497,2 +DA:498,6 +DA:517,7 +DA:525,1 +DA:526,4 +DA:535,8 +DA:551,2 +DA:552,6 +DA:555,2 +DA:556,6 +DA:571,3 +DA:588,0 +DA:589,0 +DA:592,2 +DA:593,8 +DA:601,14 +DA:626,1 +DA:627,4 +DA:635,3 +DA:636,6 +DA:639,2 +DA:640,8 +DA:658,7 +DA:684,1 +DA:685,4 +DA:688,1 +DA:689,4 +DA:701,6 +DA:711,5 +DA:717,2 +DA:718,4 +DA:721,2 +DA:722,6 +DA:739,5 +DA:768,2 +DA:769,8 +DA:772,1 +DA:773,4 +DA:783,9 +DA:795,9 +DA:805,2 +DA:806,6 +DA:819,5 +DA:827,2 +DA:828,6 +DA:839,11 +DA:844,2 +DA:845,4 +DA:864,33 +DA:883,3 +DA:884,9 +DA:891,11 +DA:901,11 +DA:914,3 +DA:915,15 +LF:157 +LH:155 +end_of_record +SF:lib/src/dart/text.dart +DA:171,3 +DA:172,6 +DA:173,3 +DA:630,9 +DA:631,18 +DA:632,9 +DA:645,5 +DA:646,5 +DA:647,2 +DA:652,9 +DA:660,18 +DA:677,1 +DA:678,2 +DA:682,12 +DA:685,1 +DA:686,2 +DA:690,12 +DA:693,1 +DA:694,2 +DA:698,18 +DA:701,1 +DA:702,1 +DA:706,12 +DA:709,1 +DA:710,2 +DA:714,9 +DA:716,1 +DA:735,1 +DA:737,1 +DA:738,3 +DA:741,1 +DA:742,4 +DA:745,1 +DA:746,4 +DA:766,1 +DA:767,4 +DA:806,1 +DA:807,2 +DA:808,2 +DA:809,1 +DA:810,5 +DA:812,4 +DA:815,9 +DA:816,18 +DA:821,9 +DA:822,9 +DA:826,18 +DA:827,9 +DA:829,9 +DA:830,9 +DA:831,9 +DA:834,9 +DA:837,9 +DA:840,9 +DA:842,9 +DA:843,9 +DA:845,9 +DA:846,9 +DA:848,9 +DA:849,9 +DA:850,9 +DA:851,9 +DA:852,9 +DA:853,9 +DA:854,9 +DA:855,9 +DA:856,9 +DA:857,9 +DA:858,9 +DA:859,9 +DA:861,9 +DA:862,10 +DA:864,9 +DA:865,12 +DA:867,9 +DA:868,6 +DA:870,3 +DA:871,9 +DA:873,9 +DA:875,9 +DA:876,11 +DA:878,6 +DA:879,9 +DA:880,9 +DA:881,9 +DA:882,9 +DA:883,9 +DA:884,9 +DA:885,9 +DA:886,9 +DA:887,9 +DA:888,12 +DA:890,6 +DA:891,9 +DA:892,9 +DA:893,9 +DA:894,9 +DA:895,9 +DA:896,9 +DA:897,9 +DA:898,9 +DA:899,9 +DA:900,9 +DA:901,9 +DA:902,9 +DA:903,9 +DA:904,9 +DA:905,9 +DA:906,9 +DA:907,9 +DA:908,9 +DA:909,9 +DA:910,9 +DA:911,9 +DA:912,9 +DA:913,9 +DA:914,9 +DA:915,9 +DA:916,9 +DA:917,9 +DA:918,9 +DA:919,9 +DA:920,9 +DA:921,9 +DA:922,9 +DA:923,9 +DA:924,9 +DA:925,9 +DA:926,9 +DA:927,9 +DA:928,9 +DA:929,9 +DA:930,9 +DA:931,9 +DA:932,9 +DA:933,9 +DA:934,9 +DA:935,9 +DA:936,9 +DA:937,9 +DA:938,9 +DA:939,9 +DA:940,2 +DA:941,2 +DA:942,1 +DA:943,1 +DA:944,18 +DA:946,9 +DA:948,3 +DA:951,9 +DA:952,15 +DA:954,3 +DA:955,1 +DA:956,3 +DA:957,3 +DA:958,3 +DA:959,2 +DA:960,2 +DA:961,1 +DA:962,1 +DA:963,1 +DA:964,1 +DA:965,1 +DA:967,3 +DA:969,3 +DA:972,9 +DA:973,27 +DA:975,5 +DA:976,2 +DA:977,2 +DA:979,5 +DA:980,5 +DA:981,4 +DA:982,2 +DA:985,5 +DA:986,5 +DA:987,5 +DA:988,5 +DA:989,5 +DA:990,5 +DA:991,5 +DA:992,5 +DA:993,5 +DA:994,5 +DA:995,4 +DA:996,2 +DA:997,4 +DA:1000,5 +DA:1002,4 +DA:1003,4 +DA:1004,4 +DA:1005,4 +DA:1006,4 +DA:1007,4 +DA:1008,4 +DA:1009,4 +DA:1010,4 +DA:1011,4 +DA:1012,4 +DA:1014,1 +DA:1015,4 +DA:1016,4 +DA:1018,1 +DA:1019,4 +DA:1020,4 +DA:1022,5 +DA:1024,3 +DA:1027,9 +DA:1029,3 +DA:1030,4 +DA:1031,2 +DA:1033,3 +DA:1034,3 +DA:1035,4 +DA:1036,1 +DA:1039,3 +DA:1040,3 +DA:1041,3 +DA:1042,3 +DA:1043,3 +DA:1044,3 +DA:1045,3 +DA:1046,3 +DA:1047,3 +DA:1048,3 +DA:1049,4 +DA:1050,1 +DA:1051,2 +DA:1054,3 +DA:1056,3 +DA:1057,2 +DA:1058,1 +DA:1059,1 +DA:1060,1 +DA:1061,1 +DA:1062,1 +DA:1063,1 +DA:1064,1 +DA:1065,1 +DA:1066,1 +DA:1068,2 +DA:1069,1 +DA:1070,1 +DA:1072,1 +DA:1074,3 +DA:1077,9 +DA:1079,6 +DA:1080,4 +DA:1081,1 +DA:1082,2 +DA:1084,6 +DA:1085,6 +DA:1086,12 +DA:1087,3 +DA:1090,6 +DA:1091,6 +DA:1092,6 +DA:1093,6 +DA:1094,6 +DA:1095,6 +DA:1096,6 +DA:1097,6 +DA:1098,6 +DA:1099,6 +DA:1100,16 +DA:1101,5 +DA:1102,8 +DA:1105,6 +DA:1107,6 +DA:1108,6 +DA:1109,5 +DA:1110,5 +DA:1111,5 +DA:1112,5 +DA:1113,5 +DA:1114,4 +DA:1115,3 +DA:1116,2 +DA:1117,2 +DA:1118,6 +DA:1119,1 +DA:1120,1 +DA:1122,1 +DA:1124,3 +DA:1127,9 +DA:1129,3 +DA:1130,4 +DA:1131,1 +DA:1132,2 +DA:1134,3 +DA:1135,3 +DA:1136,12 +DA:1137,3 +DA:1140,3 +DA:1141,3 +DA:1142,2 +DA:1143,2 +DA:1144,2 +DA:1145,2 +DA:1146,2 +DA:1147,2 +DA:1148,2 +DA:1149,2 +DA:1150,12 +DA:1151,3 +DA:1152,6 +DA:1155,2 +DA:1156,8 +DA:1157,2 +DA:1160,1 +DA:1161,1 +DA:1162,1 +DA:1163,1 +DA:1164,1 +DA:1165,1 +DA:1166,1 +DA:1167,1 +DA:1168,1 +DA:1169,1 +DA:1170,1 +DA:1172,3 +DA:1175,9 +DA:1177,6 +DA:1178,1 +DA:1179,6 +DA:1180,4 +DA:1181,4 +DA:1182,3 +DA:1183,3 +DA:1184,3 +DA:1185,3 +DA:1186,3 +DA:1187,3 +DA:1188,2 +DA:1190,6 +DA:1192,3 +DA:1195,9 +DA:1197,6 +DA:1198,4 +DA:1199,2 +DA:1201,6 +DA:1202,6 +DA:1203,12 +DA:1204,3 +DA:1207,6 +DA:1208,6 +DA:1209,6 +DA:1210,5 +DA:1211,5 +DA:1212,5 +DA:1213,5 +DA:1214,5 +DA:1215,3 +DA:1216,3 +DA:1217,20 +DA:1218,5 +DA:1219,10 +DA:1222,3 +DA:1223,3 +DA:1224,3 +DA:1225,3 +DA:1226,3 +DA:1227,3 +DA:1228,2 +DA:1229,2 +DA:1230,2 +DA:1231,2 +DA:1232,3 +DA:1233,1 +DA:1234,1 +DA:1236,1 +DA:1238,3 +DA:1241,9 +DA:1243,1 +DA:1244,1 +DA:1245,1 +DA:1247,1 +DA:1248,1 +DA:1249,1 +DA:1250,1 +DA:1251,1 +DA:1252,1 +DA:1253,1 +DA:1254,1 +DA:1255,1 +DA:1256,1 +DA:1257,1 +DA:1259,1 +DA:1261,3 +DA:1264,9 +DA:1266,1 +DA:1267,1 +DA:1268,1 +DA:1269,1 +DA:1270,1 +DA:1271,1 +DA:1272,1 +DA:1273,1 +DA:1274,1 +DA:1275,1 +DA:1276,1 +DA:1277,1 +DA:1279,1 +DA:1281,3 +DA:1284,9 +DA:1286,1 +DA:1287,4 +DA:1288,2 +DA:1290,1 +DA:1291,1 +DA:1292,4 +DA:1293,1 +DA:1296,1 +DA:1297,1 +DA:1298,1 +DA:1299,1 +DA:1300,1 +DA:1301,1 +DA:1302,1 +DA:1303,1 +DA:1304,1 +DA:1305,1 +DA:1306,4 +DA:1307,1 +DA:1308,2 +DA:1311,1 +DA:1312,1 +DA:1313,1 +DA:1314,1 +DA:1315,1 +DA:1316,1 +DA:1317,1 +DA:1318,1 +DA:1319,1 +DA:1320,1 +DA:1321,1 +DA:1323,3 +DA:1326,9 +DA:1328,4 +DA:1329,1 +DA:1330,4 +DA:1331,4 +DA:1332,4 +DA:1333,4 +DA:1334,4 +DA:1335,4 +DA:1336,4 +DA:1337,4 +DA:1338,4 +DA:1339,4 +DA:1340,4 +DA:1341,4 +DA:1342,4 +DA:1343,4 +DA:1344,4 +DA:1345,4 +DA:1346,1 +DA:1347,1 +DA:1348,1 +DA:1349,1 +DA:1350,1 +DA:1351,1 +DA:1353,5 +DA:1355,3 +DA:1358,9 +DA:1360,4 +DA:1361,4 +DA:1362,2 +DA:1364,4 +DA:1365,4 +DA:1366,12 +DA:1367,3 +DA:1370,4 +DA:1371,4 +DA:1372,4 +DA:1373,4 +DA:1374,4 +DA:1375,4 +DA:1376,4 +DA:1377,4 +DA:1378,4 +DA:1379,4 +DA:1380,12 +DA:1381,4 +DA:1382,6 +DA:1385,4 +DA:1386,4 +DA:1387,4 +DA:1388,4 +DA:1389,4 +DA:1390,4 +DA:1391,4 +DA:1392,4 +DA:1393,4 +DA:1394,4 +DA:1395,4 +DA:1396,4 +DA:1397,4 +DA:1398,4 +DA:1399,4 +DA:1400,4 +DA:1401,1 +DA:1402,1 +DA:1403,1 +DA:1404,1 +DA:1405,1 +DA:1406,1 +DA:1407,5 +DA:1409,3 +DA:1412,9 +DA:1414,5 +DA:1415,2 +DA:1416,2 +DA:1418,5 +DA:1419,5 +DA:1420,2 +DA:1423,5 +DA:1424,1 +DA:1425,2 +DA:1428,5 +DA:1429,1 +DA:1430,2 +DA:1433,5 +DA:1434,5 +DA:1435,5 +DA:1436,5 +DA:1437,5 +DA:1438,5 +DA:1439,5 +DA:1440,5 +DA:1441,5 +DA:1442,5 +DA:1443,2 +DA:1444,2 +DA:1447,5 +DA:1449,5 +DA:1450,5 +DA:1451,5 +DA:1452,5 +DA:1453,5 +DA:1454,5 +DA:1455,5 +DA:1456,5 +DA:1457,5 +DA:1458,5 +DA:1459,6 +DA:1460,6 +DA:1461,3 +DA:1463,3 +DA:1464,5 +DA:1465,5 +DA:1466,5 +DA:1467,5 +DA:1468,5 +DA:1469,5 +DA:1470,5 +DA:1471,5 +DA:1472,5 +DA:1473,5 +DA:1474,5 +DA:1475,5 +DA:1476,5 +DA:1477,5 +DA:1478,5 +DA:1479,5 +DA:1480,5 +DA:1481,5 +DA:1482,5 +DA:1483,5 +DA:1484,5 +DA:1485,5 +DA:1486,5 +DA:1487,5 +DA:1488,5 +DA:1489,5 +DA:1490,5 +DA:1491,5 +DA:1492,5 +DA:1493,5 +DA:1494,5 +DA:1495,5 +DA:1496,5 +DA:1497,5 +DA:1498,5 +DA:1499,5 +DA:1500,5 +DA:1501,5 +DA:1502,5 +DA:1503,5 +DA:1504,5 +DA:1505,5 +DA:1506,5 +DA:1507,5 +DA:1508,5 +DA:1509,4 +DA:1510,3 +DA:1511,3 +DA:1512,1 +DA:1513,1 +DA:1514,1 +DA:1515,1 +DA:1516,1 +DA:1517,10 +DA:1518,10 +DA:1519,5 +DA:1521,5 +DA:1523,3 +DA:1526,9 +DA:1528,4 +DA:1529,1 +DA:1530,4 +DA:1531,4 +DA:1535,3 +DA:1538,9 +DA:1540,9 +DA:1541,3 +DA:1542,2 +DA:1544,9 +DA:1545,9 +DA:1546,27 +DA:1547,9 +DA:1550,9 +DA:1551,9 +DA:1552,9 +DA:1553,9 +DA:1554,9 +DA:1555,9 +DA:1556,9 +DA:1557,9 +DA:1558,9 +DA:1559,9 +DA:1560,27 +DA:1561,9 +DA:1562,18 +DA:1565,9 +DA:1566,10 +DA:1567,5 +DA:1570,9 +DA:1571,9 +DA:1572,9 +DA:1573,9 +DA:1574,9 +DA:1575,9 +DA:1576,9 +DA:1577,9 +DA:1578,9 +DA:1579,9 +DA:1580,9 +DA:1581,9 +DA:1582,9 +DA:1583,9 +DA:1584,9 +DA:1585,9 +DA:1586,9 +DA:1587,9 +DA:1588,9 +DA:1589,9 +DA:1590,9 +DA:1591,9 +DA:1592,9 +DA:1593,9 +DA:1594,9 +DA:1595,9 +DA:1596,9 +DA:1597,9 +DA:1598,9 +DA:1599,9 +DA:1600,9 +DA:1601,9 +DA:1602,9 +DA:1603,9 +DA:1604,9 +DA:1605,9 +DA:1606,9 +DA:1607,9 +DA:1608,9 +DA:1609,9 +DA:1610,9 +DA:1611,9 +DA:1612,9 +DA:1613,9 +DA:1614,9 +DA:1615,9 +DA:1616,9 +DA:1617,9 +DA:1618,9 +DA:1619,9 +DA:1620,9 +DA:1621,9 +DA:1622,9 +DA:1623,9 +DA:1624,9 +DA:1625,9 +DA:1626,8 +DA:1627,8 +DA:1628,8 +DA:1629,8 +DA:1630,7 +DA:1631,7 +DA:1632,1 +DA:1633,9 +DA:1635,3 +DA:1638,6 +DA:1640,6 +DA:1641,1 +DA:1642,6 +DA:1643,1 +DA:1644,6 +DA:1645,12 +DA:1646,6 +DA:1649,6 +DA:1652,6 +DA:1655,6 +DA:1657,1 +DA:1658,1 +DA:1659,1 +DA:1660,1 +DA:1661,1 +DA:1662,1 +DA:1663,1 +DA:1665,1 +DA:1666,1 +DA:1668,1 +DA:1669,1 +DA:1671,1 +DA:1672,1 +DA:1674,1 +DA:1675,1 +DA:1677,1 +DA:1678,1 +DA:1680,1 +DA:1681,2 +DA:1684,3 +DA:1687,6 +DA:1689,1 +DA:1690,1 +DA:1691,1 +DA:1692,1 +DA:1693,1 +DA:1694,1 +DA:1695,1 +DA:1696,1 +DA:1697,1 +DA:1698,1 +DA:1699,1 +DA:1700,1 +DA:1701,1 +DA:1702,1 +DA:1703,1 +DA:1704,1 +DA:1705,1 +DA:1706,1 +DA:1707,1 +DA:1708,1 +DA:1709,1 +DA:1710,1 +DA:1711,1 +DA:1712,1 +DA:1713,1 +DA:1716,3 +DA:1719,6 +DA:1721,1 +DA:1722,1 +DA:1723,1 +DA:1724,1 +DA:1725,1 +DA:1726,1 +DA:1727,1 +DA:1728,1 +DA:1729,1 +DA:1730,1 +DA:1731,1 +DA:1732,1 +DA:1733,1 +DA:1734,1 +DA:1735,1 +DA:1736,1 +DA:1737,1 +DA:1738,1 +DA:1739,1 +DA:1740,1 +DA:1741,1 +DA:1742,1 +DA:1743,1 +DA:1744,1 +DA:1745,1 +DA:1748,3 +DA:1751,6 +DA:1753,1 +DA:1754,1 +DA:1755,1 +DA:1756,1 +DA:1757,1 +DA:1758,1 +DA:1759,1 +DA:1760,1 +DA:1761,1 +DA:1762,1 +DA:1763,1 +DA:1764,1 +DA:1765,1 +DA:1766,1 +DA:1767,1 +DA:1768,1 +DA:1769,1 +DA:1770,1 +DA:1771,1 +DA:1772,1 +DA:1773,1 +DA:1774,1 +DA:1775,1 +DA:1776,1 +DA:1777,1 +DA:1780,3 +DA:1783,6 +DA:1785,1 +DA:1786,1 +DA:1787,1 +DA:1788,1 +DA:1789,1 +DA:1790,1 +DA:1791,1 +DA:1792,1 +DA:1793,1 +DA:1794,1 +DA:1795,1 +DA:1796,1 +DA:1797,1 +DA:1798,1 +DA:1799,1 +DA:1800,1 +DA:1801,1 +DA:1802,1 +DA:1803,1 +DA:1804,1 +DA:1805,1 +DA:1806,1 +DA:1807,1 +DA:1808,1 +DA:1809,1 +DA:1810,3 +DA:1811,1 +DA:1814,3 +DA:1817,6 +DA:1819,5 +DA:1820,1 +DA:1821,5 +DA:1822,1 +DA:1823,5 +DA:1824,10 +DA:1825,5 +DA:1828,5 +DA:1831,5 +DA:1834,6 +DA:1836,1 +DA:1837,1 +DA:1838,1 +DA:1839,1 +DA:1840,1 +DA:1841,1 +DA:1842,1 +DA:1844,1 +DA:1845,1 +DA:1847,1 +DA:1848,1 +DA:1850,1 +DA:1851,1 +DA:1853,1 +DA:1854,1 +DA:1856,1 +DA:1857,1 +DA:1859,1 +DA:1860,2 +DA:1863,3 +DA:1866,6 +DA:1868,1 +DA:1869,1 +DA:1870,1 +DA:1871,1 +DA:1872,1 +DA:1873,1 +DA:1874,1 +DA:1875,1 +DA:1876,1 +DA:1877,1 +DA:1878,1 +DA:1879,1 +DA:1880,1 +DA:1881,1 +DA:1882,1 +DA:1883,1 +DA:1884,1 +DA:1885,1 +DA:1886,1 +DA:1887,1 +DA:1888,1 +DA:1889,1 +DA:1890,1 +DA:1891,1 +DA:1892,1 +DA:1895,3 +DA:1898,6 +DA:1900,1 +DA:1901,1 +DA:1902,1 +DA:1903,1 +DA:1904,1 +DA:1905,1 +DA:1906,1 +DA:1907,1 +DA:1908,1 +DA:1909,1 +DA:1910,1 +DA:1911,1 +DA:1912,1 +DA:1913,1 +DA:1914,1 +DA:1915,1 +DA:1916,1 +DA:1917,1 +DA:1918,1 +DA:1919,1 +DA:1920,1 +DA:1921,1 +DA:1922,1 +DA:1923,1 +DA:1924,1 +DA:1927,3 +DA:1930,6 +DA:1932,1 +DA:1933,1 +DA:1934,1 +DA:1935,1 +DA:1936,1 +DA:1937,1 +DA:1938,1 +DA:1939,1 +DA:1940,1 +DA:1941,1 +DA:1942,1 +DA:1943,1 +DA:1944,1 +DA:1945,1 +DA:1946,1 +DA:1947,1 +DA:1948,1 +DA:1949,1 +DA:1950,1 +DA:1951,1 +DA:1952,1 +DA:1953,1 +DA:1954,1 +DA:1955,1 +DA:1956,1 +DA:1959,3 +DA:1962,6 +DA:1964,1 +DA:1965,1 +DA:1966,1 +DA:1967,1 +DA:1968,1 +DA:1969,1 +DA:1970,1 +DA:1971,1 +DA:1972,1 +DA:1973,1 +DA:1974,1 +DA:1975,1 +DA:1976,1 +DA:1977,1 +DA:1978,1 +DA:1979,1 +DA:1980,1 +DA:1981,1 +DA:1982,1 +DA:1983,1 +DA:1984,1 +DA:1985,1 +DA:1986,1 +DA:1987,1 +DA:1988,1 +DA:1989,3 +DA:1990,1 +DA:1993,3 +DA:1996,6 +DA:1998,6 +DA:1999,1 +DA:2001,6 +DA:2002,6 +DA:2005,6 +DA:2006,6 +DA:2007,6 +DA:2008,3 +DA:2009,3 +DA:2010,3 +DA:2011,3 +DA:2012,3 +DA:2013,1 +DA:2014,1 +DA:2015,6 +DA:2018,1 +DA:2021,3 +DA:2024,4 +DA:2026,4 +DA:2027,1 +DA:2028,4 +DA:2030,4 +DA:2033,3 +DA:2036,4 +DA:2038,4 +DA:2039,1 +DA:2041,3 +DA:2048,1 +DA:2050,1 +DA:2051,1 +DA:2052,1 +DA:2059,1 +DA:2061,1 +DA:2062,1 +DA:2063,1 +DA:2081,27 +DA:2088,9 +DA:2089,27 +DA:2090,36 +DA:2091,18 +DA:2092,9 +DA:2095,9 +DA:2096,9 +DA:2097,5 +DA:2102,9 +DA:2103,9 +DA:2104,2 +DA:2106,3 +DA:2112,9 +DA:2113,27 +DA:2114,36 +DA:2117,9 +DA:2118,27 +DA:2119,3 +DA:2121,36 +DA:2122,3 +DA:2124,9 +DA:2127,9 +DA:2128,27 +DA:2129,3 +DA:2131,27 +DA:2132,9 +DA:2136,6 +DA:2137,18 +DA:2138,3 +DA:2140,18 +DA:2141,6 +DA:2145,9 +DA:2146,27 +DA:2147,36 +DA:2150,8 +DA:2151,8 +DA:2152,1 +DA:2158,9 +DA:2159,27 +DA:2160,5 +DA:2162,36 +DA:2163,5 +DA:2165,9 +DA:2168,9 +DA:2169,27 +DA:2170,9 +DA:2172,3 +DA:2175,7 +DA:2179,7 +DA:2180,7 +DA:2184,7 +DA:2188,9 +DA:2192,9 +DA:2193,27 +DA:2194,8 +DA:2195,8 +DA:2196,4 +DA:2198,8 +DA:2199,8 +DA:2204,8 +DA:2205,8 +DA:2207,8 +DA:2208,8 +DA:2218,7 +DA:2222,7 +DA:2223,7 +DA:2224,7 +DA:2225,7 +DA:2226,4 +DA:2227,4 +DA:2228,4 +DA:2229,8 +DA:2230,4 +DA:2231,4 +DA:2232,4 +DA:2233,4 +DA:2237,4 +DA:2238,8 +DA:2239,4 +DA:2243,12 +DA:2244,8 +DA:2245,12 +DA:2247,6 +DA:2251,6 +DA:2253,7 +DA:2254,7 +DA:2255,6 +DA:2256,3 +DA:2259,7 +DA:2263,3 +DA:2266,3 +DA:2267,3 +DA:2268,3 +DA:2269,9 +DA:2271,3 +DA:2272,3 +DA:2273,3 +DA:2276,3 +DA:2278,3 +DA:2279,3 +DA:2280,4 +DA:2283,3 +DA:2284,3 +DA:2285,3 +DA:2286,3 +DA:2287,3 +DA:2292,3 +DA:2293,6 +DA:2296,5 +DA:2297,4 +DA:2300,5 +DA:2302,5 +DA:2303,15 +DA:2304,12 +DA:2305,15 +DA:2306,4 +DA:2307,15 +DA:2308,20 +DA:2310,3 +DA:2312,5 +DA:2313,5 +DA:2317,8 +DA:2322,24 +DA:2323,24 +DA:2324,8 +DA:2325,7 +DA:2326,6 +DA:2327,5 +DA:2328,3 +DA:2329,3 +DA:2331,24 +DA:2332,18 +DA:2333,6 +DA:2335,24 +DA:2336,18 +DA:2337,6 +DA:2339,24 +DA:2340,18 +DA:2341,6 +DA:2343,24 +DA:2344,24 +DA:2345,8 +DA:2346,5 +DA:2349,8 +DA:2350,5 +DA:2353,8 +DA:2354,1 +DA:2358,3 +DA:2360,8 +DA:2361,6 +DA:2362,6 +DA:2363,6 +DA:2364,6 +DA:2365,6 +DA:2366,6 +DA:2371,8 +DA:2372,4 +DA:2373,4 +DA:2374,12 +DA:2376,8 +DA:2377,4 +DA:2378,4 +DA:2379,12 +DA:2381,8 +DA:2382,2 +DA:2383,2 +DA:2384,6 +DA:2386,8 +DA:2387,2 +DA:2388,2 +DA:2389,2 +DA:2391,8 +DA:2392,2 +DA:2393,2 +DA:2394,2 +DA:2395,2 +DA:2396,6 +DA:2397,2 +DA:2398,2 +DA:2399,4 +DA:2401,8 +DA:2402,3 +DA:2403,3 +DA:2404,9 +DA:2406,24 +DA:2407,8 +DA:2408,4 +DA:2409,4 +DA:2410,24 +DA:2412,8 +DA:2414,3 +DA:2417,3 +DA:2420,3 +DA:2421,6 +DA:2422,3 +DA:2423,3 +DA:2424,3 +DA:2425,3 +DA:2426,3 +DA:2427,6 +DA:2428,3 +DA:2430,6 +DA:2432,5 +DA:2433,2 +DA:2435,3 +DA:2438,9 +DA:2441,9 +DA:2442,9 +DA:2443,9 +DA:2444,9 +DA:2448,9 +DA:2449,18 +DA:2452,9 +DA:2453,9 +DA:2454,9 +DA:2455,9 +DA:2457,9 +DA:2458,3 +DA:2460,9 +DA:2462,9 +DA:2463,3 +DA:2464,3 +DA:2465,3 +DA:2467,9 +DA:2469,9 +DA:2470,18 +DA:2473,9 +DA:2474,9 +DA:2475,9 +DA:2479,8 +DA:2480,8 +DA:2481,8 +DA:2482,8 +DA:2484,16 +DA:2485,8 +DA:2486,8 +DA:2487,24 +DA:2490,9 +DA:2491,9 +DA:2492,8 +DA:2496,3 +DA:2497,3 +DA:2498,3 +DA:2502,9 +DA:2503,9 +DA:2504,18 +DA:2505,18 +DA:2507,18 +DA:2508,2 +DA:2510,9 +DA:2515,9 +DA:2516,27 +DA:2517,3 +DA:2519,18 +DA:2520,9 +LF:1276 +LH:1276 +end_of_record +SF:lib/src/flutter/argument_decoders.dart +DA:30,1 +DA:50,4 +DA:51,5 +DA:57,4 +DA:58,5 +DA:61,1 +DA:62,6 +DA:81,7 +DA:94,4 +DA:95,4 +DA:98,3 +DA:99,3 +DA:100,3 +DA:108,1 +DA:111,1 +DA:118,4 +DA:119,4 +DA:122,1 +DA:123,3 +DA:124,3 +DA:125,3 +DA:126,3 +DA:142,1 +DA:143,3 +DA:147,3 +DA:148,3 +DA:149,3 +DA:150,1 +DA:170,3 +DA:171,9 +DA:175,6 +DA:176,6 +DA:177,6 +DA:178,2 +DA:194,2 +DA:195,2 +DA:198,2 +DA:199,6 +DA:200,6 +DA:201,6 +DA:213,1 +DA:214,1 +DA:217,1 +DA:218,3 +DA:219,3 +DA:220,3 +DA:221,3 +DA:229,6 +DA:230,6 +DA:234,4 +DA:257,1 +DA:258,3 +DA:260,1 +DA:262,1 +DA:264,1 +DA:265,3 +DA:269,1 +DA:270,1 +DA:271,1 +DA:272,3 +DA:273,3 +DA:275,1 +DA:278,2 +DA:282,1 +DA:287,3 +DA:297,1 +DA:298,1 +DA:301,1 +DA:302,3 +DA:303,3 +DA:304,3 +DA:305,3 +DA:306,3 +DA:307,3 +DA:308,3 +DA:309,3 +DA:310,3 +DA:311,3 +DA:312,3 +DA:313,3 +DA:314,3 +DA:315,3 +DA:316,3 +DA:317,3 +DA:318,3 +DA:319,3 +DA:320,3 +DA:321,3 +DA:333,1 +DA:334,1 +DA:345,4 +DA:346,4 +DA:348,4 +DA:350,4 +DA:352,4 +DA:354,4 +DA:356,4 +DA:358,4 +DA:360,4 +DA:362,4 +DA:364,4 +DA:366,4 +DA:368,4 +DA:370,4 +DA:372,4 +DA:374,4 +DA:376,4 +DA:378,4 +DA:380,4 +DA:382,4 +DA:384,4 +DA:386,4 +DA:388,4 +DA:390,4 +DA:392,4 +DA:394,4 +DA:396,4 +DA:398,4 +DA:400,4 +DA:402,4 +DA:404,4 +DA:406,4 +DA:408,4 +DA:410,4 +DA:412,4 +DA:414,4 +DA:416,4 +DA:418,4 +DA:420,4 +DA:422,4 +DA:424,4 +DA:426,4 +DA:428,4 +DA:430,4 +DA:434,2 +DA:436,1 +DA:439,4 +DA:449,3 +DA:479,4 +DA:480,12 +DA:482,4 +DA:484,1 +DA:485,1 +DA:486,3 +DA:487,3 +DA:488,3 +DA:489,3 +DA:490,3 +DA:491,3 +DA:492,3 +DA:493,3 +DA:495,1 +DA:496,1 +DA:497,3 +DA:498,3 +DA:499,4 +DA:501,1 +DA:502,1 +DA:503,3 +DA:504,3 +DA:505,3 +DA:506,3 +DA:507,3 +DA:510,2 +DA:514,1 +DA:519,3 +DA:534,1 +DA:535,1 +DA:539,1 +DA:541,1 +DA:542,6 +DA:544,1 +DA:547,3 +DA:548,3 +DA:549,3 +DA:550,3 +DA:551,3 +DA:552,3 +DA:563,1 +DA:564,1 +DA:572,4 +DA:573,4 +DA:575,4 +DA:577,2 +DA:592,4 +DA:593,12 +DA:597,9 +DA:598,9 +DA:599,9 +DA:600,3 +DA:620,5 +DA:621,5 +DA:625,12 +DA:626,20 +DA:627,4 +DA:640,1 +DA:641,7 +DA:681,1 +DA:682,3 +DA:684,1 +DA:686,1 +DA:687,1 +DA:688,3 +DA:689,3 +DA:690,3 +DA:691,3 +DA:692,3 +DA:695,1 +DA:696,1 +DA:697,3 +DA:698,3 +DA:699,3 +DA:700,3 +DA:701,3 +DA:702,3 +DA:703,3 +DA:706,1 +DA:707,1 +DA:708,3 +DA:709,3 +DA:710,4 +DA:711,3 +DA:712,3 +DA:713,3 +DA:717,2 +DA:721,1 +DA:726,3 +DA:750,1 +DA:751,3 +DA:753,1 +DA:755,1 +DA:756,1 +DA:757,3 +DA:758,3 +DA:759,3 +DA:760,3 +DA:761,3 +DA:763,1 +DA:764,1 +DA:765,3 +DA:766,3 +DA:767,3 +DA:768,3 +DA:769,3 +DA:772,2 +DA:776,1 +DA:781,3 +DA:800,1 +DA:801,3 +DA:805,1 +DA:807,3 +DA:808,3 +DA:819,2 +DA:820,2 +DA:823,1 +DA:824,3 +DA:825,3 +DA:826,3 +DA:847,2 +DA:848,6 +DA:852,4 +DA:853,3 +DA:855,1 +DA:859,1 +DA:860,1 +DA:862,4 +DA:866,6 +DA:877,2 +DA:878,2 +DA:879,2 +DA:882,2 +DA:883,3 +DA:901,4 +DA:902,4 +DA:906,1 +DA:907,1 +DA:910,2 +DA:911,1 +DA:913,2 +DA:914,3 +DA:917,4 +DA:926,4 +DA:927,12 +DA:931,1 +DA:932,3 +DA:933,3 +DA:934,3 +DA:935,3 +DA:936,3 +DA:937,3 +DA:938,3 +DA:939,3 +DA:940,3 +DA:941,3 +DA:942,3 +DA:943,3 +DA:944,3 +DA:945,3 +DA:946,3 +DA:964,1 +DA:965,3 +DA:967,1 +DA:969,1 +DA:970,1 +DA:971,3 +DA:972,3 +DA:975,2 +DA:979,1 +DA:984,3 +DA:989,1 +DA:990,3 +DA:994,3 +DA:998,1 +DA:1026,2 +DA:1027,2 +DA:1030,1 +DA:1031,3 +DA:1033,1 +DA:1035,3 +DA:1037,1 +DA:1039,3 +DA:1041,1 +DA:1043,3 +DA:1045,1 +DA:1055,3 +DA:1057,1 +DA:1059,3 +DA:1061,1 +DA:1063,3 +DA:1065,1 +DA:1099,3 +DA:1100,9 +DA:1104,6 +DA:1105,2 +DA:1115,2 +DA:1116,2 +DA:1119,3 +DA:1120,3 +DA:1121,3 +DA:1122,3 +DA:1123,1 +DA:1169,2 +DA:1170,2 +DA:1172,5 +DA:1174,6 +DA:1176,2 +DA:1178,2 +DA:1179,3 +DA:1180,2 +DA:1181,1 +DA:1182,3 +DA:1183,3 +DA:1185,2 +DA:1186,2 +DA:1187,6 +DA:1189,1 +DA:1190,1 +DA:1191,3 +DA:1192,3 +DA:1194,1 +DA:1195,1 +DA:1196,3 +DA:1197,3 +DA:1199,1 +DA:1200,1 +DA:1201,3 +DA:1204,2 +DA:1208,1 +DA:1213,3 +DA:1229,1 +DA:1230,3 +DA:1232,1 +DA:1234,1 +DA:1235,1 +DA:1236,1 +DA:1237,2 +DA:1238,3 +DA:1239,2 +DA:1242,2 +DA:1246,1 +DA:1251,3 +DA:1260,1 +DA:1261,1 +DA:1274,4 +DA:1275,4 +DA:1278,1 +DA:1279,3 +DA:1280,3 +DA:1281,3 +DA:1282,3 +DA:1283,3 +DA:1284,3 +DA:1285,3 +DA:1286,3 +DA:1287,3 +DA:1300,4 +DA:1301,4 +DA:1304,1 +DA:1305,3 +DA:1306,3 +DA:1307,3 +DA:1323,2 +DA:1324,2 +DA:1326,1 +DA:1328,4 +DA:1329,2 +DA:1331,2 +DA:1333,2 +DA:1357,4 +DA:1358,4 +DA:1361,2 +DA:1362,6 +DA:1363,6 +DA:1364,6 +DA:1365,6 +DA:1366,6 +DA:1367,6 +DA:1368,6 +DA:1369,4 +DA:1370,6 +DA:1371,6 +DA:1372,6 +DA:1373,6 +DA:1374,6 +DA:1375,6 +DA:1376,6 +DA:1377,6 +DA:1378,6 +DA:1379,6 +DA:1380,6 +DA:1381,6 +DA:1382,6 +DA:1383,4 +DA:1402,1 +DA:1403,1 +DA:1405,1 +DA:1406,1 +DA:1407,1 +DA:1409,1 +DA:1411,1 +DA:1414,1 +DA:1417,1 +DA:1418,3 +DA:1419,3 +LF:444 +LH:444 +end_of_record +SF:lib/src/flutter/content.dart +DA:25,7 +DA:28,3 +DA:29,12 +DA:30,3 +DA:31,12 +DA:33,14 +DA:137,7 +DA:139,7 +DA:159,7 +DA:160,10 +DA:161,3 +DA:162,3 +DA:176,3 +DA:177,9 +DA:178,3 +DA:195,2 +DA:196,4 +DA:200,2 +DA:201,4 +DA:206,3 +DA:207,3 +DA:208,3 +DA:209,6 +DA:210,3 +DA:211,3 +DA:216,1 +DA:217,3 +DA:222,8 +DA:224,14 +DA:233,5 +DA:235,6 +DA:247,3 +DA:248,6 +DA:249,2 +DA:250,2 +DA:251,1 +DA:252,3 +DA:257,1 +DA:258,3 +DA:259,2 +DA:260,1 +DA:261,2 +DA:265,3 +DA:266,3 +DA:267,6 +DA:269,3 +DA:270,3 +DA:272,3 +DA:273,3 +DA:274,3 +DA:275,2 +DA:278,2 +DA:279,5 +DA:280,4 +DA:282,4 +DA:283,6 +DA:284,4 +DA:288,2 +DA:289,5 +DA:290,2 +DA:295,1 +DA:297,6 +DA:299,4 +DA:302,2 +DA:303,4 +DA:304,4 +DA:305,6 +DA:306,4 +DA:307,2 +DA:309,4 +DA:310,4 +DA:313,2 +DA:314,4 +DA:315,4 +DA:316,4 +DA:317,4 +DA:318,4 +DA:321,6 +DA:322,10 +DA:326,1 +DA:327,3 +DA:328,2 +DA:331,1 +DA:332,1 +DA:333,3 +DA:335,1 +DA:336,1 +DA:338,3 +DA:340,1 +DA:341,3 +DA:343,4 +DA:344,1 +DA:346,3 +DA:349,3 +DA:350,1 +DA:353,1 +DA:356,3 +DA:357,6 +DA:358,3 +DA:359,9 +DA:362,6 +DA:363,6 +DA:364,3 +DA:366,6 +DA:369,3 +DA:370,4 +DA:371,1 +DA:375,1 +DA:376,2 +LF:109 +LH:109 +end_of_record +SF:lib/src/flutter/core_widgets.dart +DA:230,21 +DA:233,14 +DA:238,1 +DA:239,1 +DA:240,2 +DA:241,2 +DA:242,2 +DA:246,1 +DA:247,1 +DA:248,2 +DA:249,2 +DA:250,2 +DA:251,2 +DA:252,2 +DA:253,2 +DA:254,2 +DA:258,1 +DA:259,1 +DA:260,2 +DA:261,2 +DA:265,2 +DA:266,2 +DA:267,4 +DA:268,4 +DA:269,4 +DA:273,1 +DA:274,1 +DA:275,2 +DA:277,2 +DA:278,2 +DA:282,4 +DA:283,4 +DA:284,8 +DA:285,8 +DA:289,2 +DA:290,2 +DA:291,4 +DA:292,4 +DA:293,4 +DA:294,4 +DA:295,4 +DA:296,4 +DA:297,4 +DA:301,4 +DA:302,4 +DA:303,8 +DA:304,8 +DA:305,8 +DA:306,8 +DA:307,8 +DA:308,8 +DA:309,8 +DA:310,8 +DA:311,8 +DA:312,8 +DA:313,8 +DA:314,8 +DA:315,8 +DA:316,8 +DA:317,8 +DA:318,8 +DA:322,1 +DA:323,1 +DA:324,2 +DA:325,2 +DA:326,2 +DA:327,2 +DA:328,2 +DA:329,2 +DA:330,2 +DA:331,2 +DA:332,2 +DA:333,2 +DA:334,2 +DA:338,2 +DA:339,2 +DA:340,4 +DA:341,4 +DA:345,1 +DA:346,1 +DA:347,2 +DA:348,2 +DA:352,1 +DA:353,1 +DA:354,2 +DA:355,2 +DA:356,2 +DA:357,2 +DA:361,1 +DA:362,1 +DA:363,2 +DA:364,2 +DA:365,2 +DA:366,2 +DA:370,3 +DA:371,3 +DA:372,6 +DA:373,9 +DA:374,9 +DA:375,6 +DA:376,6 +DA:377,6 +DA:378,6 +DA:379,6 +DA:383,1 +DA:384,1 +DA:385,2 +DA:386,2 +DA:388,2 +DA:390,2 +DA:391,2 +DA:392,2 +DA:393,3 +DA:394,2 +DA:395,2 +DA:396,2 +DA:397,2 +DA:398,2 +DA:399,2 +DA:400,2 +DA:401,2 +DA:402,2 +DA:403,2 +DA:407,1 +DA:408,1 +DA:409,2 +DA:410,2 +DA:411,2 +DA:412,2 +DA:413,2 +DA:417,1 +DA:418,1 +DA:419,2 +DA:420,2 +DA:424,1 +DA:425,1 +DA:426,2 +DA:430,1 +DA:431,1 +DA:432,2 +DA:433,2 +DA:434,2 +DA:438,1 +DA:439,1 +DA:440,2 +DA:444,2 +DA:445,2 +DA:446,2 +DA:447,2 +DA:448,2 +DA:450,2 +DA:451,2 +DA:452,2 +DA:453,2 +DA:454,2 +DA:455,2 +DA:456,2 +DA:457,2 +DA:458,2 +DA:462,2 +DA:463,2 +DA:464,4 +DA:465,4 +DA:466,4 +DA:470,2 +DA:471,2 +DA:472,4 +DA:473,4 +DA:475,4 +DA:477,4 +DA:478,4 +DA:479,4 +DA:480,4 +DA:481,4 +DA:482,6 +DA:483,4 +DA:484,4 +DA:485,4 +DA:486,4 +DA:487,4 +DA:488,4 +DA:489,4 +DA:490,4 +DA:491,4 +DA:495,1 +DA:496,1 +DA:497,2 +DA:498,2 +DA:499,2 +DA:500,2 +DA:501,2 +DA:502,2 +DA:506,2 +DA:507,2 +DA:508,4 +DA:509,4 +DA:510,4 +DA:511,4 +DA:512,4 +DA:516,4 +DA:517,4 +DA:518,8 +DA:519,8 +DA:520,8 +DA:521,8 +DA:525,1 +DA:526,1 +DA:527,2 +DA:528,2 +DA:529,2 +DA:530,2 +DA:531,2 +DA:532,2 +DA:533,2 +DA:534,2 +DA:535,2 +DA:536,2 +DA:540,1 +DA:541,1 +DA:542,2 +DA:543,2 +DA:544,2 +DA:545,4 +DA:546,2 +DA:547,2 +DA:548,2 +DA:554,2 +DA:555,2 +DA:556,4 +DA:557,4 +DA:558,4 +DA:559,4 +DA:560,4 +DA:561,4 +DA:562,4 +DA:567,1 +DA:568,1 +DA:569,2 +DA:570,2 +DA:571,2 +DA:572,2 +DA:573,4 +DA:574,2 +DA:575,2 +DA:579,1 +DA:580,1 +DA:581,2 +DA:582,2 +DA:583,2 +DA:584,4 +DA:585,2 +DA:586,2 +DA:587,2 +DA:591,1 +DA:592,1 +DA:593,2 +DA:594,2 +DA:595,2 +DA:596,2 +DA:597,2 +DA:598,2 +DA:599,2 +DA:600,2 +DA:603,2 +DA:607,6 +DA:608,6 +DA:609,12 +DA:610,12 +DA:611,12 +DA:615,1 +DA:616,1 +DA:617,2 +DA:621,3 +DA:622,3 +DA:623,6 +DA:627,1 +DA:628,1 +DA:629,2 +DA:633,1 +DA:634,1 +DA:635,2 +DA:636,2 +DA:637,2 +DA:638,2 +DA:639,2 +DA:643,4 +DA:644,8 +DA:646,2 +DA:647,4 +DA:648,4 +DA:649,6 +DA:651,2 +DA:653,8 +DA:654,4 +DA:656,8 +DA:657,8 +DA:658,8 +DA:659,8 +DA:660,8 +DA:661,8 +DA:662,8 +DA:663,1 +DA:664,8 +DA:665,8 +DA:666,8 +DA:667,8 +DA:671,1 +DA:672,1 +DA:673,2 +DA:674,2 +DA:675,2 +DA:676,2 +DA:677,2 +DA:678,2 +DA:679,2 +DA:680,2 +DA:681,2 +DA:682,2 +LF:318 +LH:318 +end_of_record +SF:lib/src/flutter/material_widgets.dart +DA:100,6 +DA:102,4 +DA:106,1 +DA:107,1 +DA:108,2 +DA:109,2 +DA:110,2 +DA:111,2 +DA:112,2 +DA:113,2 +DA:114,2 +DA:115,2 +DA:119,1 +DA:121,1 +DA:122,2 +DA:123,2 +DA:124,2 +DA:125,2 +DA:126,2 +DA:127,2 +DA:128,2 +DA:129,2 +DA:130,2 +DA:131,2 +DA:132,2 +DA:133,2 +DA:134,2 +DA:135,2 +DA:136,2 +DA:137,2 +DA:138,2 +DA:139,2 +DA:140,2 +DA:141,2 +DA:157,1 +DA:158,2 +DA:159,2 +DA:162,1 +DA:163,2 +DA:164,2 +DA:165,2 +DA:166,2 +DA:167,2 +DA:171,1 +DA:172,1 +DA:173,1 +DA:174,3 +DA:175,2 +DA:179,1 +DA:180,1 +DA:181,3 +DA:188,3 +DA:189,1 +DA:195,1 +DA:196,1 +DA:197,2 +DA:198,2 +DA:199,2 +DA:200,2 +DA:202,2 +DA:204,2 +DA:205,2 +DA:209,1 +DA:210,1 +DA:211,2 +DA:212,2 +DA:213,2 +DA:214,2 +DA:215,2 +DA:216,2 +DA:217,2 +DA:218,2 +DA:219,2 +DA:223,1 +DA:225,1 +DA:226,2 +DA:227,2 +DA:228,2 +DA:229,2 +DA:230,2 +DA:231,2 +DA:235,1 +DA:236,1 +DA:237,2 +DA:238,2 +DA:239,2 +DA:240,2 +DA:241,2 +DA:245,1 +DA:246,1 +DA:247,2 +DA:248,2 +DA:249,2 +DA:253,1 +DA:254,1 +DA:255,2 +DA:256,2 +DA:257,2 +DA:258,2 +DA:259,2 +DA:260,2 +DA:264,1 +DA:265,2 +DA:266,1 +DA:268,2 +DA:269,2 +DA:270,6 +DA:271,2 +DA:272,2 +DA:273,2 +DA:277,1 +DA:279,6 +DA:280,2 +DA:281,6 +DA:282,2 +DA:283,2 +DA:284,2 +DA:285,2 +DA:286,2 +DA:287,2 +DA:288,2 +DA:289,2 +DA:290,2 +DA:291,2 +DA:292,2 +DA:293,2 +DA:294,2 +DA:295,2 +DA:296,2 +DA:297,2 +DA:298,2 +DA:299,4 +DA:300,2 +DA:304,1 +DA:306,1 +DA:307,2 +DA:308,2 +DA:309,2 +DA:310,2 +DA:311,2 +DA:315,1 +DA:317,1 +DA:318,2 +DA:319,2 +DA:320,2 +DA:321,2 +DA:322,2 +DA:323,2 +DA:324,2 +DA:325,2 +DA:326,2 +DA:327,2 +DA:328,2 +DA:329,2 +DA:330,2 +DA:331,2 +DA:332,2 +DA:333,2 +DA:334,2 +DA:335,2 +DA:336,2 +DA:337,2 +DA:338,2 +DA:342,1 +DA:344,1 +DA:345,2 +DA:346,2 +DA:347,2 +DA:348,2 +DA:349,2 +DA:350,2 +DA:351,2 +DA:352,2 +DA:353,2 +DA:354,2 +DA:355,2 +DA:356,5 +DA:357,2 +DA:358,2 +DA:359,2 +DA:360,4 +DA:361,2 +DA:362,2 +DA:363,2 +DA:364,2 +DA:365,2 +DA:366,2 +DA:367,2 +DA:368,2 +DA:369,2 +DA:370,2 +DA:371,2 +DA:372,2 +DA:376,1 +DA:378,1 +DA:379,2 +DA:380,2 +DA:381,2 +DA:382,2 +DA:383,2 +DA:384,2 +DA:385,2 +DA:386,2 +DA:387,2 +DA:388,2 +DA:389,2 +DA:390,2 +DA:391,2 +DA:392,2 +DA:393,2 +DA:394,2 +DA:395,2 +DA:396,2 +DA:397,2 +DA:398,2 +DA:399,2 +DA:400,2 +DA:404,1 +DA:406,1 +DA:407,2 +DA:408,2 +DA:409,2 +DA:410,2 +DA:411,2 +DA:412,2 +DA:416,1 +DA:418,1 +DA:419,2 +DA:420,2 +DA:421,2 +DA:422,2 +DA:423,2 +DA:424,2 +DA:425,2 +DA:426,2 +DA:427,2 +DA:428,2 +DA:429,2 +DA:430,2 +DA:431,2 +DA:432,2 +DA:433,2 +DA:434,2 +DA:435,2 +DA:436,2 +DA:437,2 +DA:438,2 +DA:439,2 +DA:440,2 +DA:444,1 +DA:445,1 +DA:446,2 +DA:447,2 +DA:448,2 +DA:449,2 +DA:450,2 +DA:451,2 +DA:452,2 +DA:453,2 +DA:454,2 +DA:455,2 +DA:456,2 +DA:457,2 +DA:461,1 +DA:463,1 +DA:464,2 +DA:465,2 +DA:466,2 +DA:467,2 +DA:468,2 +DA:472,1 +DA:474,2 +DA:475,2 +DA:476,1 +DA:477,1 +DA:478,3 +DA:481,2 +DA:482,2 +DA:483,1 +DA:484,2 +DA:485,2 +DA:486,2 +DA:487,2 +DA:488,2 +DA:489,2 +DA:490,2 +DA:491,2 +DA:492,2 +DA:493,2 +DA:494,2 +DA:495,2 +DA:496,2 +DA:497,2 +DA:498,2 +DA:502,1 +DA:504,1 +DA:505,2 +DA:506,2 +DA:507,2 +DA:508,2 +DA:509,2 +DA:513,1 +DA:514,1 +DA:515,2 +DA:516,2 +DA:517,2 +DA:518,2 +DA:519,2 +LF:308 +LH:308 +end_of_record +SF:lib/src/flutter/remote_widget.dart +DA:23,7 +DA:59,7 +DA:60,7 +DA:64,7 +DA:66,7 +DA:67,28 +DA:70,3 +DA:72,3 +DA:73,12 +DA:74,3 +DA:75,4 +DA:79,7 +DA:81,28 +DA:82,7 +DA:85,5 +DA:86,10 +DA:89,4 +DA:90,8 +DA:91,12 +DA:95,7 +DA:97,56 +LF:21 +LH:21 +end_of_record +SF:lib/src/flutter/runtime.dart +DA:54,9 +DA:61,1 +DA:62,1 +DA:188,7 +DA:193,7 +DA:195,14 +DA:210,1 +DA:211,2 +DA:216,7 +DA:235,7 +DA:252,7 +DA:253,14 +DA:254,7 +DA:265,1 +DA:266,2 +DA:267,1 +DA:284,1 +DA:285,3 +DA:291,7 +DA:292,14 +DA:293,14 +DA:294,7 +DA:309,7 +DA:315,14 +DA:317,14 +DA:318,7 +DA:322,7 +DA:326,14 +DA:328,7 +DA:343,1 +DA:344,2 +DA:345,2 +DA:346,2 +DA:353,2 +DA:356,2 +DA:359,7 +DA:360,14 +DA:361,7 +DA:363,7 +DA:364,14 +DA:365,7 +DA:366,7 +DA:367,1 +DA:368,3 +DA:369,1 +DA:372,1 +DA:374,2 +DA:375,3 +DA:376,2 +DA:378,4 +DA:381,14 +DA:386,7 +DA:387,14 +DA:391,21 +DA:392,7 +DA:393,14 +DA:394,21 +DA:395,21 +DA:398,14 +DA:399,7 +DA:400,21 +DA:404,14 +DA:407,7 +DA:408,14 +DA:410,21 +DA:413,6 +DA:415,10 +DA:419,3 +DA:420,6 +DA:425,1 +DA:429,2 +DA:430,2 +DA:447,7 +DA:455,7 +DA:457,14 +DA:458,14 +DA:459,1 +DA:461,2 +DA:462,1 +DA:464,21 +DA:465,7 +DA:467,7 +DA:468,2 +DA:472,7 +DA:473,7 +DA:474,7 +DA:480,7 +DA:481,6 +DA:482,2 +DA:485,7 +DA:486,1 +DA:487,1 +DA:491,1 +DA:492,1 +DA:497,21 +DA:498,7 +DA:499,7 +DA:500,7 +DA:503,7 +DA:505,9 +DA:506,3 +DA:507,3 +DA:508,3 +DA:509,6 +DA:510,3 +DA:511,3 +DA:513,4 +DA:514,1 +DA:517,7 +DA:524,7 +DA:525,7 +DA:527,7 +DA:533,7 +DA:534,21 +DA:542,7 +DA:543,1 +DA:544,1 +DA:546,1 +DA:548,3 +DA:552,1 +DA:553,1 +DA:554,2 +DA:558,1 +DA:563,7 +DA:564,7 +DA:565,12 +DA:567,6 +DA:571,6 +DA:572,6 +DA:573,6 +DA:574,12 +DA:576,6 +DA:585,6 +DA:586,4 +DA:587,4 +DA:588,2 +DA:589,2 +DA:591,6 +DA:592,2 +DA:593,4 +DA:594,4 +DA:595,2 +DA:596,2 +DA:597,2 +DA:598,2 +DA:602,2 +DA:604,6 +DA:605,4 +DA:607,6 +DA:608,2 +DA:610,6 +DA:611,5 +DA:612,5 +DA:613,5 +DA:615,5 +DA:621,5 +DA:623,6 +DA:624,3 +DA:625,2 +DA:626,1 +DA:628,2 +DA:629,1 +DA:631,12 +DA:644,6 +DA:655,7 +DA:667,2 +DA:668,2 +DA:669,2 +DA:670,6 +DA:673,2 +DA:674,1 +DA:675,1 +DA:676,3 +DA:680,2 +DA:681,6 +DA:682,1 +DA:684,2 +DA:685,2 +DA:686,4 +DA:687,4 +DA:688,4 +DA:689,2 +DA:690,2 +DA:693,2 +DA:695,2 +DA:696,2 +DA:697,2 +DA:698,2 +DA:699,4 +DA:700,4 +DA:701,2 +DA:703,2 +DA:704,1 +DA:705,1 +DA:706,2 +DA:707,2 +DA:708,2 +DA:709,1 +DA:710,1 +DA:712,2 +DA:713,2 +DA:714,2 +DA:715,4 +DA:716,4 +DA:717,2 +DA:718,2 +DA:720,2 +DA:721,4 +DA:722,4 +DA:726,2 +DA:727,8 +DA:728,2 +DA:730,2 +DA:731,4 +DA:732,1 +DA:734,2 +DA:735,4 +DA:736,1 +DA:748,6 +DA:757,23 +DA:758,6 +DA:759,6 +DA:760,2 +DA:761,2 +DA:762,2 +DA:763,1 +DA:764,1 +DA:765,1 +DA:770,2 +DA:771,4 +DA:772,1 +DA:773,3 +DA:774,1 +DA:775,1 +DA:776,1 +DA:777,1 +DA:782,1 +DA:783,1 +DA:792,1 +DA:794,4 +DA:796,2 +DA:798,5 +DA:803,2 +DA:804,6 +DA:805,2 +DA:807,2 +DA:809,6 +DA:810,12 +DA:812,5 +DA:814,5 +DA:816,5 +DA:819,7 +DA:829,7 +DA:830,2 +DA:831,2 +DA:832,1 +DA:834,2 +DA:836,7 +DA:837,2 +DA:838,0 +DA:839,0 +DA:841,4 +DA:843,7 +DA:844,2 +DA:845,4 +DA:846,2 +DA:849,2 +DA:852,7 +DA:853,2 +DA:854,2 +DA:855,1 +DA:857,3 +DA:859,7 +DA:860,2 +DA:861,4 +DA:862,4 +DA:865,2 +DA:868,7 +DA:869,2 +DA:870,2 +DA:876,4 +DA:878,2 +DA:885,14 +DA:888,6 +DA:889,5 +DA:890,5 +DA:891,10 +DA:893,6 +DA:894,1 +DA:895,1 +DA:896,2 +DA:901,7 +DA:902,14 +DA:905,14 +DA:908,12 +DA:909,6 +DA:910,12 +DA:913,6 +DA:915,6 +DA:919,6 +DA:921,2 +DA:922,2 +DA:923,2 +DA:926,6 +DA:928,12 +DA:929,12 +DA:930,12 +DA:934,5 +DA:940,5 +DA:941,9 +DA:942,4 +DA:944,8 +DA:947,4 +DA:948,3 +DA:949,1 +DA:951,1 +DA:955,1 +DA:956,1 +DA:958,2 +DA:959,2 +DA:966,1 +DA:967,1 +DA:968,3 +DA:971,4 +DA:972,1 +DA:978,7 +DA:985,14 +DA:986,7 +DA:987,10 +DA:989,14 +DA:990,14 +DA:991,14 +DA:995,7 +DA:1001,7 +DA:1004,14 +DA:1021,1 +DA:1022,4 +DA:1026,7 +DA:1031,7 +DA:1033,3 +DA:1034,3 +DA:1036,6 +DA:1044,7 +DA:1055,14 +DA:1060,1 +DA:1066,1 +DA:1070,1 +DA:1081,2 +DA:1084,1 +DA:1085,3 +DA:1089,2 +DA:1094,2 +DA:1098,2 +DA:1109,2 +DA:1110,2 +DA:1116,2 +DA:1117,2 +DA:1119,3 +DA:1122,1 +DA:1123,3 +DA:1127,7 +DA:1145,7 +DA:1146,7 +DA:1154,7 +DA:1156,7 +DA:1157,7 +DA:1160,6 +DA:1162,6 +DA:1163,24 +DA:1164,6 +DA:1166,48 +DA:1167,6 +DA:1171,7 +DA:1173,7 +DA:1174,7 +DA:1177,7 +DA:1178,35 +DA:1179,7 +DA:1180,4 +DA:1181,6 +DA:1183,7 +DA:1185,21 +DA:1186,7 +DA:1187,8 +DA:1191,1 +DA:1192,3 +DA:1195,1 +DA:1196,2 +DA:1197,1 +DA:1199,1 +DA:1200,2 +DA:1201,1 +DA:1202,1 +DA:1203,1 +DA:1204,3 +DA:1206,1 +DA:1207,3 +DA:1209,3 +DA:1210,1 +DA:1212,2 +DA:1214,1 +DA:1215,1 +DA:1216,3 +DA:1218,3 +DA:1219,3 +DA:1221,3 +DA:1222,1 +DA:1224,1 +DA:1227,3 +DA:1229,1 +DA:1231,3 +DA:1239,7 +DA:1240,16 +DA:1241,2 +DA:1243,14 +DA:1244,14 +DA:1247,7 +DA:1249,33 +DA:1250,7 +DA:1251,7 +DA:1254,3 +DA:1256,3 +DA:1257,3 +DA:1258,3 +DA:1261,5 +DA:1263,5 +DA:1264,5 +DA:1265,5 +DA:1266,10 +DA:1267,5 +DA:1270,6 +DA:1274,6 +DA:1276,6 +DA:1277,6 +DA:1280,5 +DA:1282,5 +DA:1283,5 +DA:1284,32 +DA:1286,5 +DA:1289,7 +DA:1291,7 +DA:1292,7 +DA:1293,48 +DA:1298,4 +DA:1300,4 +DA:1301,4 +DA:1302,8 +DA:1303,8 +DA:1304,4 +DA:1305,4 +DA:1306,4 +DA:1307,4 +DA:1308,4 +DA:1309,28 +DA:1311,5 +DA:1315,3 +DA:1318,1 +DA:1319,5 +DA:1323,1 +DA:1325,1 +DA:1328,0 +DA:1330,0 +DA:1333,1 +DA:1338,1 +DA:1339,1 +DA:1340,1 +DA:1341,1 +DA:1342,1 +DA:1343,2 +DA:1344,2 +DA:1345,2 +DA:1350,0 +DA:1353,6 +DA:1355,19 +DA:1358,6 +DA:1360,6 +DA:1361,6 +DA:1362,5 +DA:1363,5 +DA:1364,2 +DA:1366,6 +DA:1367,10 +DA:1368,5 +DA:1369,9 +DA:1370,8 +DA:1371,4 +DA:1372,4 +DA:1374,12 +DA:1376,16 +DA:1377,1 +DA:1378,3 +DA:1379,6 +DA:1394,7 +DA:1395,7 +DA:1396,14 +DA:1397,4 +DA:1400,14 +DA:1402,7 +DA:1403,21 +DA:1405,7 +DA:1406,7 +DA:1407,7 +DA:1410,9 +DA:1411,2 +DA:1413,14 +DA:1416,14 +DA:1417,7 +DA:1421,4 +DA:1422,8 +DA:1423,12 +DA:1427,2 +DA:1428,2 +DA:1430,4 +DA:1431,6 +DA:1432,4 +DA:1434,2 +DA:1436,4 +DA:1437,2 +DA:1440,1 +DA:1441,1 +DA:1442,3 +DA:1443,2 +DA:1447,2 +DA:1448,1 +DA:1451,1 +DA:1452,1 +DA:1454,2 +DA:1455,3 +DA:1458,3 +DA:1462,1 +DA:1463,2 +DA:1465,2 +DA:1467,2 +DA:1468,1 +DA:1471,2 +DA:1472,4 +DA:1473,3 +DA:1474,2 +DA:1479,7 +DA:1482,21 +DA:1485,14 +DA:1486,14 +DA:1487,7 +DA:1488,7 +DA:1489,7 +DA:1490,7 +DA:1494,1 +DA:1496,1 +DA:1497,6 +DA:1507,14 +DA:1509,7 +DA:1510,28 +DA:1516,4 +DA:1518,4 +DA:1519,12 +DA:1520,12 +DA:1523,7 +DA:1524,28 +DA:1528,2 +DA:1529,10 +DA:1537,4 +DA:1540,2 +DA:1541,6 +DA:1542,2 +DA:1545,2 +DA:1546,4 +DA:1549,2 +DA:1550,8 +DA:1554,3 +DA:1555,6 +DA:1557,3 +DA:1560,3 +LF:572 +LH:567 +end_of_record diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index ef67ab8ee639..6c30a7fa5ec6 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1089,279 +1089,397 @@ void main() { expect(log, ['leaf: 2', 'root: {a: [2, 3], b: [q, r]}', 'root: {a: [2, 3], b: [q, r], c: test}']); }); - group('Widget Builders', () { - late DynamicContent data; - late List dispatchedEvents; - - Widget rfwWidget(String library, {Map? initialData}) { - const LibraryName coreLibraryName = LibraryName(['core']); - const LibraryName localLibraryName = LibraryName(['local']); - const LibraryName remoteLibraryName = LibraryName(['remote']); - final Runtime runtime = Runtime(); - data = initialData == null ? DynamicContent() : DynamicContent(initialData); - dispatchedEvents = []; - - runtime.update(coreLibraryName, createCoreWidgets()); - runtime.update(remoteLibraryName, parseLibraryFile(library)); - runtime.update(localLibraryName, LocalWidgetLibrary( { - 'CoolText': (BuildContext context, DataSource source) { - final int count = source.length(['text']); - String buffer = ''; - for (int i = 0; i < count; i++) { - final List key = ['text', i]; - final Object? text = source.v(key) ?? source.v(key); - buffer += text.toString(); - } - return GestureDetector( - onTap: source.voidHandler(['onPressed']), - child: Text(buffer, textDirection: TextDirection.ltr) - ); - }, - 'Builder': (BuildContext context, DataSource source) { - return source.builder(['builder'], {}); - }, - 'Calculator': (BuildContext context, DataSource source) { - final int operand1 = source.v(['operand1'])!; - final int operand2 = source.v(['operand2'])!; - final String operation = source.v(['operation'])!; - final int result; - switch (operation) { - case 'sum': - result = operand1 + operand2; - case 'multiply': - result = operand1 * operand2; - default: - throw Exception('operation not supported'); - } - return source.builder(['builder'], { - 'result': result, - }); - }, - })); - return RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - onEvent: (String eventName, DynamicMap eventArguments) => - dispatchedEvents.add(RfwEvent(eventName, eventArguments)), + testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Builder': (BuildContext context, DataSource source) { + return source.builder(['builder'], {}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test = Builder( + builder: (scope) => Text(text: 'Hello World!', textDirection: 'ltr'), ); - } - - testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test = Builder( - builder: (scope) => CoolText(text: ['Hello Widget Builders!']), - ); - '''); - await tester.pumpWidget(widget); - - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'Hello Widget Builders!'); - }); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); - testWidgets('Widget builders - work when scope is used', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test = Calculator( - operand1: 1, - operand2: 2, - operation: 'sum', - builder: (result) => CoolText(text: ['1 + 2 = ', result.result]), - ); - '''); - await tester.pumpWidget(widget); - - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '1 + 2 = 3'); - }); - testWidgets('Widget builders - work with state', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test {counter: 0} = Calculator( - operand1: state.counter, - operand2: 1, - operation: 'sum', - builder: (result) => CoolText( - text: ['Counter: ', result.result], - onPressed: set state.counter = result.result, - ), - ); - '''); - await tester.pumpWidget(widget); + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Hello World!'); + }); - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'Counter: 1'); + testWidgets('Widget builders - work when scope is used', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final Finder textFinder = find.byType(Text); - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 2'); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'HelloWorld': (BuildContext context, DataSource source) { + const String result = 'Hello World!'; + return source.builder(['builder'], {'result': result}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, 'Counter: 3'); - }); + widget test = HelloWorld( + builder: (result) => Text(text: result.result, textDirection: 'ltr'), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Hello World!'); + }); - testWidgets('Widget builders - work with data', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test {counter: 0} = Calculator( - operand1: state.counter, - operand2: data.increment, - operation: 'sum', - builder: (result) => CoolText( - text: [state.counter, ' + ', data.increment, ' = ', result.result], - onPressed: set state.counter = result.result, - ), - ); - ''', initialData: {'increment': 0}); - await tester.pumpWidget(widget); + testWidgets('Widget builders - work with state', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final Finder textFinder = find.byType(Text); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'IntToString': (BuildContext context, DataSource source) { + final int value = source.v(['value'])!; + final String result = value.toString(); + return source.builder(['builder'], {'result': result}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test {value: 0} = IntToString( + value: state.value, + builder: (result) => Text(text: result.result, textDirection: 'ltr'), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '0'); + }); + + + testWidgets('Widget builders - work with data', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent({'value': 0}); + final Finder textFinder = find.byType(Text); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'IntToString': (BuildContext context, DataSource source) { + final int value = source.v(['value'])!; + final String result = value.toString(); + return source.builder(['builder'], {'result': result}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '0 + 0 = 0'); + widget test = IntToString( + value: data.value, + builder: (result) => Text(text: result.result, textDirection: 'ltr'), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); - data.update('increment', 1); - await tester.pump(); - expect(tester.widget(textFinder).data, '0 + 1 = 1'); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '0'); - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, '1 + 1 = 2'); + data.update('value', 1); + await tester.pump(); + expect(tester.widget(textFinder).data, '1'); + }); - data.update('increment', 10); - await tester.pump(); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '1 + 10 = 11'); + testWidgets('Widget builders - work with events', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final List dispatchedEvents = []; + final Finder textFinder = find.byType(Text); - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, '11 + 10 = 21'); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Zero': (BuildContext context, DataSource source) { + return source.builder(['builder'], {'result': 0}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test = Zero( + builder: (result) => GestureDetector( + onTap: event 'works' {number: result.result}, + child: Text(text: 'Tap to trigger an event.', textDirection: 'ltr'), + ), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + onEvent: (String eventName, DynamicMap eventArguments) => + dispatchedEvents.add(RfwEvent(eventName, eventArguments)), + )); + + await tester.tap(textFinder); + await tester.pump(); + expect(dispatchedEvents, hasLength(1)); + expect(dispatchedEvents.single.name, 'works'); + expect(dispatchedEvents.single.arguments['number'], 0); + }); + testWidgets('Widget builders - works nested', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final Finder textFinder = find.byType(Text); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Sum': (BuildContext context, DataSource source) { + final int operand1 = source.v(['operand1'])!; + final int operand2 = source.v(['operand2'])!; + final int result = operand1 + operand2; + return source.builder(['builder'], {'result': result}); + }, + 'IntToString': (BuildContext context, DataSource source) { + final int value = source.v(['value'])!; + final String result = value.toString(); + return source.builder(['builder'], {'result': result}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; - data.update('increment', 100); - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, '21 + 100 = 121'); + widget test = Sum( + operand1: 1, + operand2: 2, + builder: (result1) => IntToString( + value: result1.result, + builder: (result2) => Text(text: ['1 + 2 = ', result2.result], textDirection: 'ltr'), + ), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, '1 + 2 = 3'); + }); - await tester.tap(textFinder); - await tester.pump(); - expect(tester.widget(textFinder).data, '121 + 100 = 221'); + testWidgets('Widget builders - works nested dynamically', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Map handlers = {}; + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent({ + 'a1': 'apricot', + 'b1': 'blueberry', }); + final Finder textFinder = find.byType(Text); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Builder': (BuildContext context, DataSource source) { + final String? id = source.v(['id']); + if (id != null) { + handlers[id] = source.voidHandler(['handler'])!; + } + return source.builder(['builder'], { + 'param1': source.v(['arg1']), + 'param2': source.v(['arg2']), + }); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; - testWidgets('Widget builders - work with events', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test = Calculator( - operand1: 1, - operand2: 2, - operation: 'sum', - builder: (result) => CoolText( - text: ['Press this button'], - onPressed: event "works" {result: result.result}, + widget test { state1: 'strawberry' } = Builder( + arg1: data.a1, + arg2: 'apple', + id: 'A', + handler: set state.state1 = 'STRAWBERRY', + builder: (builder1) => Builder( + arg1: data.b1, + arg2: 'banana', + builder: (builder2) => Text( + textDirection: 'ltr', + text: [ + state.state1, ' ', builder1.param1, ' ', builder1.param2, ' ', builder2.param1, ' ', builder2.param2, + ], ), - ); - '''); - await tester.pumpWidget(widget); - final Finder textFinder = find.byType(Text); - await tester.tap(textFinder); - await tester.pump(); - - expect(dispatchedEvents, hasLength(1)); - expect(dispatchedEvents.single.name, 'works'); - expect(dispatchedEvents.single.arguments['result'], 3); - }); + ), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); - testWidgets('Widget builders - works nested', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test = Calculator( - operand1: 1, - operand2: 2, - operation: 'sum', - builder: (result1) => Calculator( - operand1: result1.result, - operand2: 3, - operation: 'multiply', - builder: (result2) => CoolText( - text: [ - '1 + 2 = ', - result1.result, - '; ', - result1.result, - ' * 3 = ', - result2.result, - ';', - ], - ), + expect(tester.widget(textFinder).data, 'strawberry apricot apple blueberry banana'); + + data.update('a1', 'APRICOT'); + await tester.pump(); + expect(tester.widget(textFinder).data, 'strawberry APRICOT apple blueberry banana'); + + data.update('b1', 'BLUEBERRY'); + await tester.pump(); + expect(tester.widget(textFinder).data, 'strawberry APRICOT apple BLUEBERRY banana'); + + handlers['A']!(); + await tester.pump(); + expect(tester.widget(textFinder).data, 'STRAWBERRY APRICOT apple BLUEBERRY banana'); + }); + + testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final Finder textFinder = find.byType(Text); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Builder': (BuildContext context, DataSource source) { + return source.builder(['builder'], {}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test {enabled: false} = Builder( + value: state.value, + builder: switch state.enabled { + true: (scope) => GestureDetector( + onTap: set state.enabled = false, + child: Text(text: 'The builder is enabled.', textDirection: 'ltr'), + ), + false: (scope) => GestureDetector( + onTap: set state.enabled = true, + child: Text(text: 'The builder is disabled.', textDirection: 'ltr'), ), - ); - '''); - await tester.pumpWidget(widget); + }, + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '1 + 2 = 3; 3 * 3 = 9;'); - }); - testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test {justResult: true} = Calculator( - operand1: 1, - operand2: 2, - operation: 'sum', - builder: switch state.justResult { - true: (result) => CoolText(text: [result.result]), - }, - ); - '''); - await tester.pumpWidget(widget); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'The builder is disabled.'); - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, '3'); - }); + await tester.tap(textFinder); + await tester.pump(); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'The builder is enabled.'); + }); - testWidgets('Widget builders - builder works with switch', (WidgetTester tester) async { - final Widget widget = rfwWidget(''' - import core; - import local; - - widget test = Calculator( - operand1: 1, - operand2: 2, - operation: 'sum', - builder: (result) => switch result.result { - 0: CoolText(text: ['The result is zero']), - default: CoolText(text: ['The result is not zero']), - }, - ); - '''); - await tester.pumpWidget(widget); + testWidgets('Widget builders - builder works with switch', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + final Finder textFinder = find.byType(Text); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Inverter': (BuildContext context, DataSource source) { + final bool value = source.v(['value'])!; + return source.builder(['builder'], {'result': !value}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; - final Finder textFinder = find.byType(Text); - expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'The result is not zero'); - }); + widget test {value: false} = Inverter( + value: state.value, + builder: (result) => switch result.result { + true: GestureDetector( + onTap: set state.value = switch state.value { + true: false, + false: true, + }, + child: Text(text: 'The input is false, the output is true', textDirection: 'ltr'), + ), + false: GestureDetector( + onTap: set state.value = switch state.value { + true: false, + false: true, + }, + child: Text(text: 'The input is true, the output is false', textDirection: 'ltr'), + ), + }, + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'The input is false, the output is true'); + + await tester.tap(textFinder); + await tester.pump(); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'The input is true, the output is false'); }); } From c24389bab9101a092797168a635b09e236236b9f Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 08:34:47 -0800 Subject: [PATCH 18/22] Fix switch --- packages/rfw/lib/src/flutter/runtime.dart | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index 428747c4b8ce..cfcca7208b59 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -478,8 +478,13 @@ class Runtime extends ChangeNotifier { usedWidgets, ); if (result is Switch) { - result = _CurriedSwitch(widget.fullName, result, arguments, constructor.initialState) - ..propagateSource(result); + result = _CurriedSwitch( + widget.fullName, + result, + arguments, + widgetBuilderScope, + constructor.initialState, + )..propagateSource(result); } else { result as _CurriedWidget; if (constructor.initialState != null) { @@ -541,11 +546,15 @@ class Runtime extends ChangeNotifier { } if (node is WidgetBuilderDeclaration) { return (DynamicMap widgetBuilderArg) { + final DynamicMap newWidgetBuilderScope = { + ...widgetBuilderScope, + node.argumentName: widgetBuilderArg, + }; final Object result = _bindArguments( context, node.widget, arguments, - {...widgetBuilderScope, node.argumentName: widgetBuilderArg}, + newWidgetBuilderScope, stateDepth, usedWidgets, ); @@ -554,6 +563,7 @@ class Runtime extends ChangeNotifier { FullyQualifiedWidgetName(context.library, ''), result, arguments as DynamicMap, + newWidgetBuilderScope, const {}, )..propagateSource(result); } @@ -714,6 +724,7 @@ abstract class _CurriedWidget extends BlobNode { node.fullName, _bindLoopVariable(node.root, argument, depth) as Switch, _bindLoopVariable(node.arguments, argument, depth) as DynamicMap, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) as DynamicMap, node.initialState, )..propagateSource(node); } @@ -1090,8 +1101,9 @@ class _CurriedSwitch extends _CurriedWidget { FullyQualifiedWidgetName fullName, this.root, DynamicMap arguments, + DynamicMap widgetBuilderScope, DynamicMap? initialState, - ) : super(fullName, arguments, const {}, initialState); + ) : super(fullName, arguments, widgetBuilderScope, initialState); final Switch root; From 7cab0f297670c98f461ec9c4772a05ef64cfbab9 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 09:16:38 -0800 Subject: [PATCH 19/22] Increase binary coverage --- packages/rfw/coverage/lcov.info | 884 +++++++++++++++-------------- packages/rfw/test/binary_test.dart | 26 +- 2 files changed, 469 insertions(+), 441 deletions(-) diff --git a/packages/rfw/coverage/lcov.info b/packages/rfw/coverage/lcov.info index fa253d6a4a14..146ff806c659 100644 --- a/packages/rfw/coverage/lcov.info +++ b/packages/rfw/coverage/lcov.info @@ -124,8 +124,8 @@ DA:474,6 DA:477,1 DA:478,1 DA:479,1 -DA:480,1 -DA:481,0 +DA:480,2 +DA:481,5 DA:483,2 DA:484,1 DA:487,2 @@ -278,7 +278,7 @@ DA:712,2 DA:713,6 DA:714,4 LF:278 -LH:269 +LH:270 end_of_record SF:lib/src/dart/model.dart DA:40,2 @@ -376,7 +376,7 @@ DA:414,9 DA:424,11 DA:438,3 DA:439,9 -DA:445,3 +DA:445,4 DA:460,2 DA:461,6 DA:470,8 @@ -3029,491 +3029,495 @@ DA:472,7 DA:473,7 DA:474,7 DA:480,7 -DA:481,6 +DA:481,2 DA:482,2 -DA:485,7 -DA:486,1 -DA:487,1 +DA:486,2 +DA:487,2 +DA:490,7 DA:491,1 DA:492,1 -DA:497,21 -DA:498,7 -DA:499,7 -DA:500,7 +DA:496,1 +DA:497,1 +DA:502,21 DA:503,7 -DA:505,9 -DA:506,3 -DA:507,3 -DA:508,3 -DA:509,6 -DA:510,3 +DA:504,7 +DA:505,7 +DA:508,7 +DA:510,9 DA:511,3 -DA:513,4 -DA:514,1 -DA:517,7 -DA:524,7 -DA:525,7 -DA:527,7 -DA:533,7 -DA:534,21 -DA:542,7 -DA:543,1 -DA:544,1 -DA:546,1 -DA:548,3 -DA:552,1 +DA:512,3 +DA:513,3 +DA:514,6 +DA:515,3 +DA:516,3 +DA:518,4 +DA:519,1 +DA:522,7 +DA:529,7 +DA:530,7 +DA:532,7 +DA:538,7 +DA:539,21 +DA:547,7 +DA:548,1 +DA:549,1 +DA:551,2 DA:553,1 -DA:554,2 -DA:558,1 -DA:563,7 -DA:564,7 -DA:565,12 -DA:567,6 -DA:571,6 -DA:572,6 -DA:573,6 -DA:574,12 -DA:576,6 -DA:585,6 -DA:586,4 -DA:587,4 -DA:588,2 -DA:589,2 -DA:591,6 -DA:592,2 -DA:593,4 -DA:594,4 -DA:595,2 -DA:596,2 -DA:597,2 +DA:555,1 +DA:561,1 +DA:562,1 +DA:563,2 +DA:568,1 +DA:573,7 +DA:574,7 +DA:575,12 +DA:577,6 +DA:581,6 +DA:582,6 +DA:583,6 +DA:584,12 +DA:586,6 +DA:595,6 +DA:596,4 +DA:597,4 DA:598,2 +DA:599,2 +DA:601,6 DA:602,2 -DA:604,6 -DA:605,4 -DA:607,6 +DA:603,4 +DA:604,4 +DA:605,2 +DA:606,2 +DA:607,2 DA:608,2 -DA:610,6 -DA:611,5 -DA:612,5 -DA:613,5 -DA:615,5 +DA:612,2 +DA:614,6 +DA:615,4 +DA:617,6 +DA:618,2 +DA:620,6 DA:621,5 -DA:623,6 -DA:624,3 -DA:625,2 -DA:626,1 -DA:628,2 -DA:629,1 -DA:631,12 -DA:644,6 -DA:655,7 -DA:667,2 -DA:668,2 -DA:669,2 -DA:670,6 -DA:673,2 -DA:674,1 -DA:675,1 -DA:676,3 -DA:680,2 -DA:681,6 -DA:682,1 -DA:684,2 -DA:685,2 -DA:686,4 -DA:687,4 -DA:688,4 -DA:689,2 +DA:622,5 +DA:623,5 +DA:625,5 +DA:631,5 +DA:633,6 +DA:634,3 +DA:635,2 +DA:636,1 +DA:638,2 +DA:639,1 +DA:641,12 +DA:654,6 +DA:665,7 +DA:677,2 +DA:678,2 +DA:679,2 +DA:680,6 +DA:683,2 +DA:684,1 +DA:685,1 +DA:686,3 DA:690,2 -DA:693,2 +DA:691,6 +DA:692,1 +DA:694,2 DA:695,2 -DA:696,2 -DA:697,2 -DA:698,2 -DA:699,4 -DA:700,4 -DA:701,2 +DA:696,4 +DA:697,4 +DA:698,4 +DA:699,2 +DA:700,2 DA:703,2 -DA:704,1 -DA:705,1 +DA:705,2 DA:706,2 DA:707,2 DA:708,2 -DA:709,1 -DA:710,1 -DA:712,2 +DA:709,4 +DA:710,4 +DA:711,2 DA:713,2 -DA:714,2 -DA:715,4 -DA:716,4 +DA:714,1 +DA:715,1 +DA:716,2 DA:717,2 DA:718,2 -DA:720,2 -DA:721,4 -DA:722,4 -DA:726,2 -DA:727,8 +DA:719,1 +DA:720,1 +DA:722,2 +DA:723,2 +DA:724,2 +DA:725,4 +DA:726,4 +DA:727,4 DA:728,2 -DA:730,2 -DA:731,4 -DA:732,1 -DA:734,2 -DA:735,4 -DA:736,1 -DA:748,6 -DA:757,23 -DA:758,6 +DA:729,2 +DA:731,2 +DA:732,4 +DA:733,4 +DA:737,2 +DA:738,8 +DA:739,2 +DA:741,2 +DA:742,4 +DA:743,1 +DA:745,2 +DA:746,4 +DA:747,1 DA:759,6 -DA:760,2 -DA:761,2 -DA:762,2 -DA:763,1 -DA:764,1 -DA:765,1 -DA:770,2 -DA:771,4 -DA:772,1 -DA:773,3 +DA:768,23 +DA:769,6 +DA:770,6 +DA:771,2 +DA:772,2 +DA:773,2 DA:774,1 DA:775,1 DA:776,1 -DA:777,1 -DA:782,1 +DA:781,2 +DA:782,4 DA:783,1 -DA:792,1 -DA:794,4 -DA:796,2 -DA:798,5 -DA:803,2 -DA:804,6 -DA:805,2 +DA:784,3 +DA:785,1 +DA:786,1 +DA:787,1 +DA:788,1 +DA:793,1 +DA:794,1 +DA:803,1 +DA:805,4 DA:807,2 -DA:809,6 -DA:810,12 -DA:812,5 -DA:814,5 -DA:816,5 -DA:819,7 -DA:829,7 -DA:830,2 -DA:831,2 -DA:832,1 -DA:834,2 -DA:836,7 -DA:837,2 -DA:838,0 -DA:839,0 -DA:841,4 -DA:843,7 -DA:844,2 -DA:845,4 -DA:846,2 -DA:849,2 -DA:852,7 -DA:853,2 -DA:854,2 -DA:855,1 -DA:857,3 -DA:859,7 +DA:809,5 +DA:814,2 +DA:815,6 +DA:816,2 +DA:818,2 +DA:820,6 +DA:821,12 +DA:823,5 +DA:825,5 +DA:827,5 +DA:830,7 +DA:840,7 +DA:841,2 +DA:842,2 +DA:843,1 +DA:845,2 +DA:847,7 +DA:848,2 +DA:849,0 +DA:850,0 +DA:852,4 +DA:854,7 +DA:855,2 +DA:856,4 +DA:857,2 DA:860,2 -DA:861,4 -DA:862,4 +DA:863,7 +DA:864,2 DA:865,2 -DA:868,7 -DA:869,2 -DA:870,2 -DA:876,4 -DA:878,2 -DA:885,14 -DA:888,6 -DA:889,5 -DA:890,5 -DA:891,10 -DA:893,6 -DA:894,1 -DA:895,1 -DA:896,2 -DA:901,7 -DA:902,14 -DA:905,14 -DA:908,12 -DA:909,6 -DA:910,12 -DA:913,6 -DA:915,6 -DA:919,6 -DA:921,2 -DA:922,2 -DA:923,2 +DA:866,1 +DA:868,3 +DA:870,7 +DA:871,2 +DA:872,4 +DA:873,4 +DA:876,2 +DA:879,7 +DA:880,2 +DA:881,2 +DA:887,4 +DA:889,2 +DA:896,14 +DA:899,6 +DA:900,5 +DA:901,5 +DA:902,10 +DA:904,6 +DA:905,1 +DA:906,1 +DA:907,2 +DA:912,7 +DA:913,14 +DA:916,14 +DA:919,12 +DA:920,6 +DA:921,12 +DA:924,6 DA:926,6 -DA:928,12 -DA:929,12 -DA:930,12 -DA:934,5 -DA:940,5 -DA:941,9 -DA:942,4 -DA:944,8 -DA:947,4 -DA:948,3 -DA:949,1 -DA:951,1 -DA:955,1 -DA:956,1 -DA:958,2 -DA:959,2 +DA:930,6 +DA:932,2 +DA:933,2 +DA:934,2 +DA:937,6 +DA:939,12 +DA:940,12 +DA:941,12 +DA:945,5 +DA:951,5 +DA:952,9 +DA:953,4 +DA:955,8 +DA:958,4 +DA:959,3 +DA:960,1 +DA:962,1 DA:966,1 DA:967,1 -DA:968,3 -DA:971,4 -DA:972,1 -DA:978,7 -DA:985,14 -DA:986,7 -DA:987,10 -DA:989,14 -DA:990,14 -DA:991,14 -DA:995,7 -DA:1001,7 -DA:1004,14 -DA:1021,1 -DA:1022,4 -DA:1026,7 -DA:1031,7 -DA:1033,3 -DA:1034,3 -DA:1036,6 -DA:1044,7 -DA:1055,14 -DA:1060,1 -DA:1066,1 -DA:1070,1 -DA:1081,2 -DA:1084,1 -DA:1085,3 -DA:1089,2 -DA:1094,2 -DA:1098,2 -DA:1109,2 +DA:969,2 +DA:970,2 +DA:977,1 +DA:978,1 +DA:979,3 +DA:982,4 +DA:983,1 +DA:989,7 +DA:996,14 +DA:997,7 +DA:998,10 +DA:1000,14 +DA:1001,14 +DA:1002,14 +DA:1006,7 +DA:1012,7 +DA:1015,14 +DA:1032,1 +DA:1033,4 +DA:1037,7 +DA:1042,7 +DA:1044,3 +DA:1045,3 +DA:1047,6 +DA:1055,7 +DA:1066,14 +DA:1071,1 +DA:1077,1 +DA:1081,1 +DA:1092,2 +DA:1095,1 +DA:1096,3 +DA:1100,2 +DA:1106,2 DA:1110,2 -DA:1116,2 -DA:1117,2 -DA:1119,3 -DA:1122,1 -DA:1123,3 -DA:1127,7 -DA:1145,7 -DA:1146,7 -DA:1154,7 -DA:1156,7 +DA:1121,2 +DA:1122,2 +DA:1128,2 +DA:1129,2 +DA:1131,3 +DA:1134,1 +DA:1135,3 +DA:1139,7 DA:1157,7 -DA:1160,6 -DA:1162,6 -DA:1163,24 -DA:1164,6 -DA:1166,48 -DA:1167,6 -DA:1171,7 -DA:1173,7 -DA:1174,7 -DA:1177,7 -DA:1178,35 -DA:1179,7 -DA:1180,4 -DA:1181,6 +DA:1158,7 +DA:1166,7 +DA:1168,7 +DA:1169,7 +DA:1172,6 +DA:1174,6 +DA:1175,24 +DA:1176,6 +DA:1178,48 +DA:1179,6 DA:1183,7 -DA:1185,21 +DA:1185,7 DA:1186,7 -DA:1187,8 -DA:1191,1 -DA:1192,3 -DA:1195,1 -DA:1196,2 -DA:1197,1 -DA:1199,1 -DA:1200,2 -DA:1201,1 -DA:1202,1 +DA:1189,7 +DA:1190,35 +DA:1191,7 +DA:1192,4 +DA:1193,6 +DA:1195,7 +DA:1197,21 +DA:1198,7 +DA:1199,8 DA:1203,1 DA:1204,3 -DA:1206,1 -DA:1207,3 -DA:1209,3 -DA:1210,1 +DA:1207,1 +DA:1208,2 +DA:1209,1 +DA:1211,1 DA:1212,2 +DA:1213,1 DA:1214,1 DA:1215,1 DA:1216,3 -DA:1218,3 +DA:1218,1 DA:1219,3 DA:1221,3 DA:1222,1 -DA:1224,1 -DA:1227,3 -DA:1229,1 +DA:1224,2 +DA:1226,1 +DA:1227,1 +DA:1228,3 +DA:1230,3 DA:1231,3 -DA:1239,7 -DA:1240,16 -DA:1241,2 -DA:1243,14 -DA:1244,14 -DA:1247,7 -DA:1249,33 -DA:1250,7 +DA:1233,3 +DA:1234,1 +DA:1236,1 +DA:1239,3 +DA:1241,1 +DA:1243,3 DA:1251,7 -DA:1254,3 -DA:1256,3 -DA:1257,3 -DA:1258,3 -DA:1261,5 -DA:1263,5 -DA:1264,5 -DA:1265,5 -DA:1266,10 -DA:1267,5 -DA:1270,6 -DA:1274,6 -DA:1276,6 -DA:1277,6 -DA:1280,5 -DA:1282,5 -DA:1283,5 -DA:1284,32 -DA:1286,5 -DA:1289,7 -DA:1291,7 -DA:1292,7 -DA:1293,48 -DA:1298,4 -DA:1300,4 -DA:1301,4 -DA:1302,8 -DA:1303,8 -DA:1304,4 -DA:1305,4 -DA:1306,4 -DA:1307,4 -DA:1308,4 -DA:1309,28 -DA:1311,5 -DA:1315,3 -DA:1318,1 -DA:1319,5 -DA:1323,1 -DA:1325,1 -DA:1328,0 -DA:1330,0 -DA:1333,1 -DA:1338,1 -DA:1339,1 -DA:1340,1 -DA:1341,1 -DA:1342,1 -DA:1343,2 -DA:1344,2 -DA:1345,2 -DA:1350,0 -DA:1353,6 -DA:1355,19 -DA:1358,6 -DA:1360,6 -DA:1361,6 -DA:1362,5 -DA:1363,5 -DA:1364,2 -DA:1366,6 -DA:1367,10 -DA:1368,5 -DA:1369,9 -DA:1370,8 -DA:1371,4 -DA:1372,4 -DA:1374,12 -DA:1376,16 -DA:1377,1 -DA:1378,3 -DA:1379,6 -DA:1394,7 -DA:1395,7 -DA:1396,14 -DA:1397,4 -DA:1400,14 -DA:1402,7 -DA:1403,21 -DA:1405,7 +DA:1252,16 +DA:1253,2 +DA:1255,14 +DA:1256,14 +DA:1259,7 +DA:1261,33 +DA:1262,7 +DA:1263,7 +DA:1266,3 +DA:1268,3 +DA:1269,3 +DA:1270,3 +DA:1273,5 +DA:1275,5 +DA:1276,5 +DA:1277,5 +DA:1278,10 +DA:1279,5 +DA:1282,6 +DA:1286,6 +DA:1288,6 +DA:1289,6 +DA:1292,5 +DA:1294,5 +DA:1295,5 +DA:1296,32 +DA:1298,5 +DA:1301,7 +DA:1303,7 +DA:1304,7 +DA:1305,48 +DA:1310,4 +DA:1312,4 +DA:1313,4 +DA:1314,8 +DA:1315,8 +DA:1316,4 +DA:1317,4 +DA:1318,4 +DA:1319,4 +DA:1320,4 +DA:1321,28 +DA:1323,5 +DA:1327,3 +DA:1330,1 +DA:1331,5 +DA:1335,1 +DA:1337,1 +DA:1340,0 +DA:1342,0 +DA:1345,1 +DA:1350,1 +DA:1351,1 +DA:1352,1 +DA:1353,1 +DA:1354,1 +DA:1355,2 +DA:1356,2 +DA:1357,2 +DA:1362,0 +DA:1365,6 +DA:1367,19 +DA:1370,6 +DA:1372,6 +DA:1373,6 +DA:1374,5 +DA:1375,5 +DA:1376,2 +DA:1378,6 +DA:1379,10 +DA:1380,5 +DA:1381,9 +DA:1382,8 +DA:1383,4 +DA:1384,4 +DA:1386,12 +DA:1388,16 +DA:1389,1 +DA:1390,3 +DA:1391,6 DA:1406,7 DA:1407,7 -DA:1410,9 -DA:1411,2 -DA:1413,14 -DA:1416,14 +DA:1408,14 +DA:1409,4 +DA:1412,14 +DA:1414,7 +DA:1415,21 DA:1417,7 -DA:1421,4 -DA:1422,8 -DA:1423,12 -DA:1427,2 -DA:1428,2 -DA:1430,4 -DA:1431,6 -DA:1432,4 -DA:1434,2 -DA:1436,4 -DA:1437,2 -DA:1440,1 -DA:1441,1 -DA:1442,3 -DA:1443,2 -DA:1447,2 -DA:1448,1 -DA:1451,1 +DA:1418,7 +DA:1419,7 +DA:1422,9 +DA:1423,2 +DA:1425,14 +DA:1428,14 +DA:1429,7 +DA:1433,4 +DA:1434,8 +DA:1435,12 +DA:1439,2 +DA:1440,2 +DA:1442,4 +DA:1443,6 +DA:1444,4 +DA:1446,2 +DA:1448,4 +DA:1449,2 DA:1452,1 -DA:1454,2 -DA:1455,3 -DA:1458,3 -DA:1462,1 -DA:1463,2 -DA:1465,2 -DA:1467,2 -DA:1468,1 -DA:1471,2 -DA:1472,4 -DA:1473,3 -DA:1474,2 -DA:1479,7 -DA:1482,21 -DA:1485,14 -DA:1486,14 -DA:1487,7 -DA:1488,7 -DA:1489,7 -DA:1490,7 -DA:1494,1 -DA:1496,1 -DA:1497,6 -DA:1507,14 -DA:1509,7 -DA:1510,28 -DA:1516,4 -DA:1518,4 -DA:1519,12 -DA:1520,12 -DA:1523,7 -DA:1524,28 -DA:1528,2 -DA:1529,10 -DA:1537,4 +DA:1453,1 +DA:1454,3 +DA:1455,2 +DA:1459,2 +DA:1460,1 +DA:1463,1 +DA:1464,1 +DA:1466,2 +DA:1467,3 +DA:1470,3 +DA:1474,1 +DA:1475,2 +DA:1477,2 +DA:1479,2 +DA:1480,1 +DA:1483,2 +DA:1484,4 +DA:1485,3 +DA:1486,2 +DA:1491,7 +DA:1494,21 +DA:1497,14 +DA:1498,14 +DA:1499,7 +DA:1500,7 +DA:1501,7 +DA:1502,7 +DA:1506,1 +DA:1508,1 +DA:1509,6 +DA:1519,14 +DA:1521,7 +DA:1522,28 +DA:1528,4 +DA:1530,4 +DA:1531,12 +DA:1532,12 +DA:1535,7 +DA:1536,28 DA:1540,2 -DA:1541,6 -DA:1542,2 -DA:1545,2 -DA:1546,4 -DA:1549,2 -DA:1550,8 -DA:1554,3 -DA:1555,6 -DA:1557,3 -DA:1560,3 -LF:572 -LH:567 +DA:1541,10 +DA:1549,4 +DA:1552,2 +DA:1553,6 +DA:1554,2 +DA:1557,2 +DA:1558,4 +DA:1561,2 +DA:1562,8 +DA:1566,3 +DA:1567,6 +DA:1569,3 +DA:1572,3 +LF:576 +LH:571 end_of_record diff --git a/packages/rfw/test/binary_test.dart b/packages/rfw/test/binary_test.dart index 91153c47ff50..916f92bf15e5 100644 --- a/packages/rfw/test/binary_test.dart +++ b/packages/rfw/test/binary_test.dart @@ -504,7 +504,7 @@ void main() { expect((value.widgets.first.root as ConstructorCall).arguments, isEmpty); }); - testWidgets('Library encoder: widget builders', (WidgetTester tester) async { + testWidgets('Library encoder: widget builders work', (WidgetTester tester) async { const String source = ''' widget Foo = Builder( builder: (scope) => Text(text: scope.text), @@ -516,4 +516,28 @@ void main() { expect(library.toString(), decoded.toString()); }); + + testWidgets('Library encoder: widget builders throws', (WidgetTester tester) async { + const RemoteWidgetLibrary remoteWidgetLibrary = RemoteWidgetLibrary( + [], + [ + WidgetDeclaration( + 'a', + {}, + ConstructorCall( + 'c', + { + 'builder': WidgetBuilderDeclaration('scope', ArgsReference([])), + }, + ), + ), + ], + ); + try { + decodeLibraryBlob(encodeLibraryBlob(remoteWidgetLibrary)); + fail('did not throw exception'); + } on FormatException catch (e) { + expect('$e', contains('Unrecognized data type 0x0A while decoding widget builder blob.')); + } + }); } From 41db0954d6369036fa79f1414b6d5353a1c73c41 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 09:34:52 -0800 Subject: [PATCH 20/22] Improve runtime coverage --- packages/rfw/coverage/lcov.info | 549 +++++++++++----------- packages/rfw/lib/src/flutter/runtime.dart | 4 - packages/rfw/test/runtime_test.dart | 70 ++- 3 files changed, 341 insertions(+), 282 deletions(-) diff --git a/packages/rfw/coverage/lcov.info b/packages/rfw/coverage/lcov.info index 146ff806c659..0522ddd7fccf 100644 --- a/packages/rfw/coverage/lcov.info +++ b/packages/rfw/coverage/lcov.info @@ -3204,320 +3204,317 @@ DA:842,2 DA:843,1 DA:845,2 DA:847,7 -DA:848,2 -DA:849,0 -DA:850,0 +DA:848,4 +DA:850,7 +DA:851,2 DA:852,4 -DA:854,7 -DA:855,2 -DA:856,4 -DA:857,2 +DA:853,2 +DA:856,2 +DA:859,7 DA:860,2 -DA:863,7 -DA:864,2 -DA:865,2 -DA:866,1 -DA:868,3 -DA:870,7 -DA:871,2 -DA:872,4 -DA:873,4 +DA:861,2 +DA:862,1 +DA:864,3 +DA:866,7 +DA:867,2 +DA:868,4 +DA:869,4 +DA:872,2 +DA:875,7 DA:876,2 -DA:879,7 -DA:880,2 -DA:881,2 -DA:887,4 -DA:889,2 -DA:896,14 -DA:899,6 -DA:900,5 -DA:901,5 -DA:902,10 -DA:904,6 -DA:905,1 -DA:906,1 -DA:907,2 -DA:912,7 -DA:913,14 -DA:916,14 -DA:919,12 +DA:877,2 +DA:883,4 +DA:885,2 +DA:892,14 +DA:895,6 +DA:896,5 +DA:897,5 +DA:898,10 +DA:900,6 +DA:901,1 +DA:902,1 +DA:903,2 +DA:908,7 +DA:909,14 +DA:912,14 +DA:915,12 +DA:916,6 +DA:917,12 DA:920,6 -DA:921,12 -DA:924,6 +DA:922,6 DA:926,6 -DA:930,6 -DA:932,2 -DA:933,2 -DA:934,2 -DA:937,6 -DA:939,12 -DA:940,12 -DA:941,12 -DA:945,5 -DA:951,5 -DA:952,9 -DA:953,4 -DA:955,8 -DA:958,4 -DA:959,3 -DA:960,1 +DA:928,2 +DA:929,2 +DA:930,2 +DA:933,6 +DA:935,12 +DA:936,12 +DA:937,12 +DA:941,5 +DA:947,5 +DA:948,9 +DA:949,4 +DA:951,8 +DA:954,4 +DA:955,3 +DA:956,1 +DA:958,1 DA:962,1 -DA:966,1 -DA:967,1 -DA:969,2 -DA:970,2 -DA:977,1 -DA:978,1 -DA:979,3 -DA:982,4 -DA:983,1 -DA:989,7 +DA:963,1 +DA:965,2 +DA:966,2 +DA:973,1 +DA:974,1 +DA:975,3 +DA:978,4 +DA:979,1 +DA:985,7 +DA:992,14 +DA:993,7 +DA:994,10 DA:996,14 -DA:997,7 -DA:998,10 -DA:1000,14 -DA:1001,14 -DA:1002,14 -DA:1006,7 -DA:1012,7 -DA:1015,14 -DA:1032,1 -DA:1033,4 -DA:1037,7 -DA:1042,7 -DA:1044,3 -DA:1045,3 -DA:1047,6 -DA:1055,7 -DA:1066,14 -DA:1071,1 +DA:997,14 +DA:998,14 +DA:1002,7 +DA:1008,7 +DA:1011,14 +DA:1028,1 +DA:1029,4 +DA:1033,7 +DA:1038,7 +DA:1040,3 +DA:1041,3 +DA:1043,6 +DA:1051,7 +DA:1062,14 +DA:1067,1 +DA:1073,1 DA:1077,1 -DA:1081,1 -DA:1092,2 -DA:1095,1 -DA:1096,3 -DA:1100,2 +DA:1088,2 +DA:1091,1 +DA:1092,3 +DA:1096,2 +DA:1102,2 DA:1106,2 -DA:1110,2 -DA:1121,2 -DA:1122,2 -DA:1128,2 -DA:1129,2 +DA:1117,2 +DA:1118,2 +DA:1124,2 +DA:1125,2 +DA:1127,3 +DA:1130,1 DA:1131,3 -DA:1134,1 -DA:1135,3 -DA:1139,7 -DA:1157,7 -DA:1158,7 -DA:1166,7 -DA:1168,7 -DA:1169,7 +DA:1135,7 +DA:1153,7 +DA:1154,7 +DA:1162,7 +DA:1164,7 +DA:1165,7 +DA:1168,6 +DA:1170,6 +DA:1171,24 DA:1172,6 -DA:1174,6 -DA:1175,24 -DA:1176,6 -DA:1178,48 -DA:1179,6 -DA:1183,7 +DA:1174,48 +DA:1175,6 +DA:1179,7 +DA:1181,7 +DA:1182,7 DA:1185,7 -DA:1186,7 -DA:1189,7 -DA:1190,35 +DA:1186,35 +DA:1187,7 +DA:1188,4 +DA:1189,6 DA:1191,7 -DA:1192,4 -DA:1193,6 -DA:1195,7 -DA:1197,21 -DA:1198,7 -DA:1199,8 +DA:1193,21 +DA:1194,7 +DA:1195,8 +DA:1199,1 +DA:1200,3 DA:1203,1 -DA:1204,3 +DA:1204,2 +DA:1205,1 DA:1207,1 DA:1208,2 DA:1209,1 +DA:1210,1 DA:1211,1 -DA:1212,2 -DA:1213,1 +DA:1212,3 DA:1214,1 -DA:1215,1 -DA:1216,3 +DA:1215,3 +DA:1217,3 DA:1218,1 -DA:1219,3 -DA:1221,3 +DA:1220,2 DA:1222,1 -DA:1224,2 -DA:1226,1 -DA:1227,1 -DA:1228,3 -DA:1230,3 -DA:1231,3 -DA:1233,3 -DA:1234,1 -DA:1236,1 +DA:1223,1 +DA:1224,3 +DA:1226,3 +DA:1227,3 +DA:1229,3 +DA:1230,1 +DA:1232,1 +DA:1235,3 +DA:1237,1 DA:1239,3 -DA:1241,1 -DA:1243,3 -DA:1251,7 -DA:1252,16 -DA:1253,2 -DA:1255,14 -DA:1256,14 +DA:1247,7 +DA:1248,16 +DA:1249,2 +DA:1251,14 +DA:1252,14 +DA:1255,7 +DA:1257,33 +DA:1258,7 DA:1259,7 -DA:1261,33 -DA:1262,7 -DA:1263,7 +DA:1262,3 +DA:1264,3 +DA:1265,3 DA:1266,3 -DA:1268,3 -DA:1269,3 -DA:1270,3 +DA:1269,5 +DA:1271,5 +DA:1272,5 DA:1273,5 +DA:1274,10 DA:1275,5 -DA:1276,5 -DA:1277,5 -DA:1278,10 -DA:1279,5 +DA:1278,6 DA:1282,6 -DA:1286,6 -DA:1288,6 -DA:1289,6 -DA:1292,5 +DA:1284,6 +DA:1285,6 +DA:1288,5 +DA:1290,5 +DA:1291,5 +DA:1292,32 DA:1294,5 -DA:1295,5 -DA:1296,32 -DA:1298,5 -DA:1301,7 -DA:1303,7 -DA:1304,7 -DA:1305,48 -DA:1310,4 +DA:1297,7 +DA:1299,7 +DA:1300,7 +DA:1301,48 +DA:1306,4 +DA:1308,4 +DA:1309,4 +DA:1310,8 +DA:1311,8 DA:1312,4 DA:1313,4 -DA:1314,8 -DA:1315,8 +DA:1314,4 +DA:1315,4 DA:1316,4 -DA:1317,4 -DA:1318,4 -DA:1319,4 -DA:1320,4 -DA:1321,28 -DA:1323,5 -DA:1327,3 -DA:1330,1 -DA:1331,5 -DA:1335,1 -DA:1337,1 -DA:1340,0 -DA:1342,0 -DA:1345,1 +DA:1317,28 +DA:1319,5 +DA:1323,3 +DA:1326,1 +DA:1327,5 +DA:1331,1 +DA:1333,1 +DA:1336,1 +DA:1338,1 +DA:1341,1 +DA:1346,1 +DA:1347,1 +DA:1348,1 +DA:1349,1 DA:1350,1 -DA:1351,1 -DA:1352,1 -DA:1353,1 -DA:1354,1 -DA:1355,2 -DA:1356,2 -DA:1357,2 -DA:1362,0 -DA:1365,6 -DA:1367,19 -DA:1370,6 -DA:1372,6 -DA:1373,6 -DA:1374,5 -DA:1375,5 -DA:1376,2 -DA:1378,6 -DA:1379,10 -DA:1380,5 -DA:1381,9 -DA:1382,8 -DA:1383,4 -DA:1384,4 -DA:1386,12 -DA:1388,16 -DA:1389,1 -DA:1390,3 -DA:1391,6 -DA:1406,7 -DA:1407,7 +DA:1351,2 +DA:1352,2 +DA:1353,2 +DA:1358,5 +DA:1361,6 +DA:1363,19 +DA:1366,6 +DA:1368,6 +DA:1369,6 +DA:1370,5 +DA:1371,5 +DA:1372,2 +DA:1374,6 +DA:1375,10 +DA:1376,5 +DA:1377,9 +DA:1378,8 +DA:1379,4 +DA:1380,4 +DA:1382,12 +DA:1384,16 +DA:1385,1 +DA:1386,3 +DA:1387,6 +DA:1402,7 +DA:1403,7 +DA:1404,14 +DA:1405,4 DA:1408,14 -DA:1409,4 -DA:1412,14 +DA:1410,7 +DA:1411,21 +DA:1413,7 DA:1414,7 -DA:1415,21 -DA:1417,7 -DA:1418,7 -DA:1419,7 -DA:1422,9 -DA:1423,2 -DA:1425,14 -DA:1428,14 -DA:1429,7 -DA:1433,4 -DA:1434,8 -DA:1435,12 -DA:1439,2 -DA:1440,2 -DA:1442,4 -DA:1443,6 +DA:1415,7 +DA:1418,9 +DA:1419,2 +DA:1421,14 +DA:1424,14 +DA:1425,7 +DA:1429,4 +DA:1430,8 +DA:1431,12 +DA:1435,2 +DA:1436,2 +DA:1438,4 +DA:1439,6 +DA:1440,4 +DA:1442,2 DA:1444,4 -DA:1446,2 -DA:1448,4 -DA:1449,2 -DA:1452,1 -DA:1453,1 -DA:1454,3 +DA:1445,2 +DA:1448,1 +DA:1449,1 +DA:1450,3 +DA:1451,2 DA:1455,2 -DA:1459,2 +DA:1456,1 +DA:1459,1 DA:1460,1 -DA:1463,1 -DA:1464,1 -DA:1466,2 -DA:1467,3 -DA:1470,3 -DA:1474,1 +DA:1462,2 +DA:1463,3 +DA:1466,3 +DA:1470,1 +DA:1471,2 +DA:1473,2 DA:1475,2 -DA:1477,2 +DA:1476,1 DA:1479,2 -DA:1480,1 -DA:1483,2 -DA:1484,4 -DA:1485,3 -DA:1486,2 -DA:1491,7 -DA:1494,21 -DA:1497,14 -DA:1498,14 -DA:1499,7 -DA:1500,7 -DA:1501,7 -DA:1502,7 -DA:1506,1 -DA:1508,1 -DA:1509,6 -DA:1519,14 -DA:1521,7 -DA:1522,28 -DA:1528,4 -DA:1530,4 -DA:1531,12 -DA:1532,12 -DA:1535,7 -DA:1536,28 -DA:1540,2 -DA:1541,10 -DA:1549,4 -DA:1552,2 -DA:1553,6 -DA:1554,2 +DA:1480,4 +DA:1481,3 +DA:1482,2 +DA:1487,7 +DA:1490,21 +DA:1493,14 +DA:1494,14 +DA:1495,7 +DA:1496,7 +DA:1497,7 +DA:1498,7 +DA:1502,1 +DA:1504,1 +DA:1505,6 +DA:1515,14 +DA:1517,7 +DA:1518,28 +DA:1524,4 +DA:1526,4 +DA:1527,12 +DA:1528,12 +DA:1531,7 +DA:1532,28 +DA:1536,2 +DA:1537,10 +DA:1545,4 +DA:1548,2 +DA:1549,6 +DA:1550,2 +DA:1553,2 +DA:1554,4 DA:1557,2 -DA:1558,4 -DA:1561,2 -DA:1562,8 -DA:1566,3 -DA:1567,6 -DA:1569,3 -DA:1572,3 -LF:576 -LH:571 +DA:1558,8 +DA:1562,3 +DA:1563,6 +DA:1565,3 +DA:1568,3 +LF:573 +LH:573 end_of_record diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index cfcca7208b59..f66b7cd22547 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -845,10 +845,6 @@ abstract class _CurriedWidget extends BlobNode { current = dataResolver(current.parts); continue; } else if (current is WidgetBuilderArgReference) { - if (index < parts.length) { - current = current.constructReference(parts.sublist(index)); - index = parts.length; - } current = widgetBuilderArgResolver([current.argumentName, ...current.parts]); continue; } else if (current is BoundArgsReference) { diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 6c30a7fa5ec6..b368607aceb2 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1089,12 +1089,47 @@ void main() { expect(log, ['leaf: 2', 'root: {a: [2, 3], b: [q, r]}', 'root: {a: [2, 3], b: [q, r], c: test}']); }); - testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { + testWidgets('Data source - optional builder works', (WidgetTester tester) async { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); final Runtime runtime = Runtime(); final DynamicContent data = DynamicContent(); + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Builder': (BuildContext context, DataSource source) { + final Widget? builder = source.optionalBuilder(['builder'], {}); + return builder ?? Text('Hello World!', textDirection: TextDirection.ltr); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test = Builder( + builder: Text(text: 'Not a builder :/'), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + + + final Finder textFinder = find.byType(Text); + expect(textFinder, findsOneWidget); + expect(tester.widget(textFinder).data, 'Hello World!'); + }); + + testWidgets('Data source - builder returns an error widget', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); + const expectedErrorMessage = 'Not a builder at [builder] (got core:Text {} {text: Not a builder :/}) for local:Builder.'; + runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(localLibraryName, LocalWidgetLibrary( { 'Builder': (BuildContext context, DataSource source) { @@ -1106,7 +1141,7 @@ void main() { import local; widget test = Builder( - builder: (scope) => Text(text: 'Hello World!', textDirection: 'ltr'), + builder: Text(text: 'Not a builder :/'), ); ''')); await tester.pumpWidget(RemoteWidget( @@ -1115,8 +1150,39 @@ void main() { widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), )); + expect(tester.takeException().toString(), contains(expectedErrorMessage)); + expect(find.byType(ErrorWidget), findsOneWidget); + expect(tester.widget(find.byType(ErrorWidget)).message, expectedErrorMessage); + }); + testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { + const LibraryName coreLibraryName = LibraryName(['core']); + const LibraryName localLibraryName = LibraryName(['local']); + const LibraryName remoteLibraryName = LibraryName(['remote']); + final Runtime runtime = Runtime(); + final DynamicContent data = DynamicContent(); final Finder textFinder = find.byType(Text); + + runtime.update(coreLibraryName, createCoreWidgets()); + runtime.update(localLibraryName, LocalWidgetLibrary( { + 'Builder': (BuildContext context, DataSource source) { + return source.builder(['builder'], {}); + }, + })); + runtime.update(remoteLibraryName, parseLibraryFile(''' + import core; + import local; + + widget test = Builder( + builder: (scope) => Text(text: 'Hello World!', textDirection: 'ltr'), + ); + ''')); + await tester.pumpWidget(RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + )); + expect(textFinder, findsOneWidget); expect(tester.widget(textFinder).data, 'Hello World!'); }); From d0f2f3a537454060ff729536aa9f921261273852 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 09:39:50 -0800 Subject: [PATCH 21/22] Remove unused code --- packages/rfw/coverage/lcov.info | 3520 -------------------------- packages/rfw/lib/src/dart/model.dart | 12 - 2 files changed, 3532 deletions(-) delete mode 100644 packages/rfw/coverage/lcov.info diff --git a/packages/rfw/coverage/lcov.info b/packages/rfw/coverage/lcov.info deleted file mode 100644 index 0522ddd7fccf..000000000000 --- a/packages/rfw/coverage/lcov.info +++ /dev/null @@ -1,3520 +0,0 @@ -SF:lib/src/dart/binary.dart -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,2 -DA:67,2 -DA:68,10 -DA:69,2 -DA:70,2 -DA:71,2 -DA:85,2 -DA:86,2 -DA:87,2 -DA:88,2 -DA:89,4 -DA:266,2 -DA:267,10 -DA:268,2 -DA:269,2 -DA:270,2 -DA:313,2 -DA:319,10 -DA:321,2 -DA:322,10 -DA:323,3 -DA:325,4 -DA:328,2 -DA:329,2 -DA:330,2 -DA:331,4 -DA:334,2 -DA:335,2 -DA:336,2 -DA:338,4 -DA:342,0 -DA:343,0 -DA:344,0 -DA:347,1 -DA:348,1 -DA:349,1 -DA:350,2 -DA:353,2 -DA:354,2 -DA:355,2 -DA:356,2 -DA:357,14 -DA:360,1 -DA:361,3 -DA:362,1 -DA:364,1 -DA:365,1 -DA:366,1 -DA:367,1 -DA:369,5 -DA:374,2 -DA:375,2 -DA:376,2 -DA:379,2 -DA:380,2 -DA:382,4 -DA:383,2 -DA:384,2 -DA:390,1 -DA:391,1 -DA:392,1 -DA:395,1 -DA:398,1 -DA:399,1 -DA:400,1 -DA:401,1 -DA:402,1 -DA:404,2 -DA:405,1 -DA:406,1 -DA:410,1 -DA:413,2 -DA:415,2 -DA:417,2 -DA:419,2 -DA:420,2 -DA:421,2 -DA:422,1 -DA:423,2 -DA:424,1 -DA:425,2 -DA:426,4 -DA:427,2 -DA:428,2 -DA:429,5 -DA:433,2 -DA:434,2 -DA:435,4 -DA:438,2 -DA:440,2 -DA:441,3 -DA:442,2 -DA:443,1 -DA:444,2 -DA:445,2 -DA:446,2 -DA:447,2 -DA:448,2 -DA:449,3 -DA:450,2 -DA:451,2 -DA:452,2 -DA:453,4 -DA:454,2 -DA:455,1 -DA:456,2 -DA:457,4 -DA:458,2 -DA:459,1 -DA:460,2 -DA:461,3 -DA:463,4 -DA:467,2 -DA:468,2 -DA:469,2 -DA:472,2 -DA:473,2 -DA:474,6 -DA:477,1 -DA:478,1 -DA:479,1 -DA:480,2 -DA:481,5 -DA:483,2 -DA:484,1 -DA:487,2 -DA:488,2 -DA:489,4 -DA:490,2 -DA:493,2 -DA:494,1 -DA:495,2 -DA:496,2 -DA:498,5 -DA:500,2 -DA:503,2 -DA:504,8 -DA:507,2 -DA:508,12 -DA:511,2 -DA:512,8 -DA:515,2 -DA:516,6 -DA:519,2 -DA:520,6 -DA:521,2 -DA:523,4 -DA:524,2 -DA:525,2 -DA:526,2 -DA:531,2 -DA:533,6 -DA:534,6 -DA:548,2 -DA:550,6 -DA:551,18 -DA:555,2 -DA:557,4 -DA:561,0 -DA:562,0 -DA:563,0 -DA:565,0 -DA:566,0 -DA:569,6 -DA:572,2 -DA:573,2 -DA:574,4 -DA:575,4 -DA:578,2 -DA:579,4 -DA:580,4 -DA:581,2 -DA:582,2 -DA:586,2 -DA:587,2 -DA:588,4 -DA:589,2 -DA:590,1 -DA:591,2 -DA:592,1 -DA:594,3 -DA:598,2 -DA:599,2 -DA:600,2 -DA:601,2 -DA:602,2 -DA:603,3 -DA:604,2 -DA:605,2 -DA:606,3 -DA:607,2 -DA:608,2 -DA:609,2 -DA:610,1 -DA:611,2 -DA:612,2 -DA:613,1 -DA:615,2 -DA:619,1 -DA:620,2 -DA:623,2 -DA:624,2 -DA:625,2 -DA:626,2 -DA:627,2 -DA:628,2 -DA:629,4 -DA:630,4 -DA:631,6 -DA:632,2 -DA:633,2 -DA:634,2 -DA:635,2 -DA:636,2 -DA:637,2 -DA:638,3 -DA:639,3 -DA:640,2 -DA:641,2 -DA:642,3 -DA:643,3 -DA:644,2 -DA:645,2 -DA:646,2 -DA:647,3 -DA:648,3 -DA:649,2 -DA:650,2 -DA:651,2 -DA:652,3 -DA:653,3 -DA:654,2 -DA:655,2 -DA:656,3 -DA:657,3 -DA:658,2 -DA:659,2 -DA:660,2 -DA:661,3 -DA:662,2 -DA:663,2 -DA:664,2 -DA:665,3 -DA:666,3 -DA:668,2 -DA:670,1 -DA:672,1 -DA:674,2 -DA:675,2 -DA:676,1 -DA:677,3 -DA:678,3 -DA:679,2 -DA:681,4 -DA:682,4 -DA:686,2 -DA:687,4 -DA:688,4 -DA:689,4 -DA:690,2 -DA:691,3 -DA:693,2 -DA:695,4 -DA:699,2 -DA:700,4 -DA:701,4 -DA:702,8 -DA:703,8 -DA:707,2 -DA:708,4 -DA:709,4 -DA:712,2 -DA:713,6 -DA:714,4 -LF:278 -LH:270 -end_of_record -SF:lib/src/dart/model.dart -DA:40,2 -DA:51,1 -DA:53,3 -DA:54,1 -DA:56,3 -DA:59,1 -DA:61,2 -DA:64,1 -DA:65,3 -DA:66,3 -DA:69,1 -DA:70,3 -DA:75,2 -DA:76,6 -DA:77,1 -DA:79,6 -DA:85,1 -DA:86,3 -DA:87,1 -DA:89,3 -DA:96,1 -DA:97,3 -DA:98,1 -DA:100,3 -DA:107,1 -DA:108,3 -DA:109,1 -DA:111,3 -DA:114,1 -DA:116,3 -DA:139,2 -DA:140,8 -DA:141,4 -DA:155,1 -DA:157,2 -DA:160,1 -DA:161,3 -DA:162,3 -DA:165,1 -DA:166,3 -DA:168,1 -DA:170,7 -DA:188,22 -DA:197,21 -DA:208,1 -DA:209,2 -DA:221,1 -DA:222,2 -DA:233,7 -DA:237,14 -DA:239,2 -DA:244,9 -DA:248,27 -DA:251,27 -DA:252,27 -DA:271,19 -DA:276,9 -DA:278,27 -DA:281,9 -DA:282,27 -DA:285,8 -DA:286,16 -DA:288,5 -DA:289,10 -DA:291,1 -DA:293,4 -DA:294,3 -DA:297,5 -DA:298,1 -DA:302,6 -DA:303,5 -DA:313,14 -DA:321,6 -DA:323,18 -DA:326,6 -DA:327,33 -DA:330,8 -DA:331,24 -DA:333,2 -DA:334,6 -DA:336,1 -DA:338,3 -DA:339,1 -DA:342,3 -DA:351,10 -DA:353,2 -DA:373,7 -DA:385,2 -DA:386,6 -DA:397,6 -DA:413,3 -DA:414,9 -DA:424,11 -DA:438,3 -DA:439,9 -DA:445,4 -DA:460,2 -DA:461,6 -DA:470,8 -DA:487,7 -DA:493,3 -DA:494,6 -DA:497,2 -DA:498,6 -DA:517,7 -DA:525,1 -DA:526,4 -DA:535,8 -DA:551,2 -DA:552,6 -DA:555,2 -DA:556,6 -DA:571,3 -DA:588,0 -DA:589,0 -DA:592,2 -DA:593,8 -DA:601,14 -DA:626,1 -DA:627,4 -DA:635,3 -DA:636,6 -DA:639,2 -DA:640,8 -DA:658,7 -DA:684,1 -DA:685,4 -DA:688,1 -DA:689,4 -DA:701,6 -DA:711,5 -DA:717,2 -DA:718,4 -DA:721,2 -DA:722,6 -DA:739,5 -DA:768,2 -DA:769,8 -DA:772,1 -DA:773,4 -DA:783,9 -DA:795,9 -DA:805,2 -DA:806,6 -DA:819,5 -DA:827,2 -DA:828,6 -DA:839,11 -DA:844,2 -DA:845,4 -DA:864,33 -DA:883,3 -DA:884,9 -DA:891,11 -DA:901,11 -DA:914,3 -DA:915,15 -LF:157 -LH:155 -end_of_record -SF:lib/src/dart/text.dart -DA:171,3 -DA:172,6 -DA:173,3 -DA:630,9 -DA:631,18 -DA:632,9 -DA:645,5 -DA:646,5 -DA:647,2 -DA:652,9 -DA:660,18 -DA:677,1 -DA:678,2 -DA:682,12 -DA:685,1 -DA:686,2 -DA:690,12 -DA:693,1 -DA:694,2 -DA:698,18 -DA:701,1 -DA:702,1 -DA:706,12 -DA:709,1 -DA:710,2 -DA:714,9 -DA:716,1 -DA:735,1 -DA:737,1 -DA:738,3 -DA:741,1 -DA:742,4 -DA:745,1 -DA:746,4 -DA:766,1 -DA:767,4 -DA:806,1 -DA:807,2 -DA:808,2 -DA:809,1 -DA:810,5 -DA:812,4 -DA:815,9 -DA:816,18 -DA:821,9 -DA:822,9 -DA:826,18 -DA:827,9 -DA:829,9 -DA:830,9 -DA:831,9 -DA:834,9 -DA:837,9 -DA:840,9 -DA:842,9 -DA:843,9 -DA:845,9 -DA:846,9 -DA:848,9 -DA:849,9 -DA:850,9 -DA:851,9 -DA:852,9 -DA:853,9 -DA:854,9 -DA:855,9 -DA:856,9 -DA:857,9 -DA:858,9 -DA:859,9 -DA:861,9 -DA:862,10 -DA:864,9 -DA:865,12 -DA:867,9 -DA:868,6 -DA:870,3 -DA:871,9 -DA:873,9 -DA:875,9 -DA:876,11 -DA:878,6 -DA:879,9 -DA:880,9 -DA:881,9 -DA:882,9 -DA:883,9 -DA:884,9 -DA:885,9 -DA:886,9 -DA:887,9 -DA:888,12 -DA:890,6 -DA:891,9 -DA:892,9 -DA:893,9 -DA:894,9 -DA:895,9 -DA:896,9 -DA:897,9 -DA:898,9 -DA:899,9 -DA:900,9 -DA:901,9 -DA:902,9 -DA:903,9 -DA:904,9 -DA:905,9 -DA:906,9 -DA:907,9 -DA:908,9 -DA:909,9 -DA:910,9 -DA:911,9 -DA:912,9 -DA:913,9 -DA:914,9 -DA:915,9 -DA:916,9 -DA:917,9 -DA:918,9 -DA:919,9 -DA:920,9 -DA:921,9 -DA:922,9 -DA:923,9 -DA:924,9 -DA:925,9 -DA:926,9 -DA:927,9 -DA:928,9 -DA:929,9 -DA:930,9 -DA:931,9 -DA:932,9 -DA:933,9 -DA:934,9 -DA:935,9 -DA:936,9 -DA:937,9 -DA:938,9 -DA:939,9 -DA:940,2 -DA:941,2 -DA:942,1 -DA:943,1 -DA:944,18 -DA:946,9 -DA:948,3 -DA:951,9 -DA:952,15 -DA:954,3 -DA:955,1 -DA:956,3 -DA:957,3 -DA:958,3 -DA:959,2 -DA:960,2 -DA:961,1 -DA:962,1 -DA:963,1 -DA:964,1 -DA:965,1 -DA:967,3 -DA:969,3 -DA:972,9 -DA:973,27 -DA:975,5 -DA:976,2 -DA:977,2 -DA:979,5 -DA:980,5 -DA:981,4 -DA:982,2 -DA:985,5 -DA:986,5 -DA:987,5 -DA:988,5 -DA:989,5 -DA:990,5 -DA:991,5 -DA:992,5 -DA:993,5 -DA:994,5 -DA:995,4 -DA:996,2 -DA:997,4 -DA:1000,5 -DA:1002,4 -DA:1003,4 -DA:1004,4 -DA:1005,4 -DA:1006,4 -DA:1007,4 -DA:1008,4 -DA:1009,4 -DA:1010,4 -DA:1011,4 -DA:1012,4 -DA:1014,1 -DA:1015,4 -DA:1016,4 -DA:1018,1 -DA:1019,4 -DA:1020,4 -DA:1022,5 -DA:1024,3 -DA:1027,9 -DA:1029,3 -DA:1030,4 -DA:1031,2 -DA:1033,3 -DA:1034,3 -DA:1035,4 -DA:1036,1 -DA:1039,3 -DA:1040,3 -DA:1041,3 -DA:1042,3 -DA:1043,3 -DA:1044,3 -DA:1045,3 -DA:1046,3 -DA:1047,3 -DA:1048,3 -DA:1049,4 -DA:1050,1 -DA:1051,2 -DA:1054,3 -DA:1056,3 -DA:1057,2 -DA:1058,1 -DA:1059,1 -DA:1060,1 -DA:1061,1 -DA:1062,1 -DA:1063,1 -DA:1064,1 -DA:1065,1 -DA:1066,1 -DA:1068,2 -DA:1069,1 -DA:1070,1 -DA:1072,1 -DA:1074,3 -DA:1077,9 -DA:1079,6 -DA:1080,4 -DA:1081,1 -DA:1082,2 -DA:1084,6 -DA:1085,6 -DA:1086,12 -DA:1087,3 -DA:1090,6 -DA:1091,6 -DA:1092,6 -DA:1093,6 -DA:1094,6 -DA:1095,6 -DA:1096,6 -DA:1097,6 -DA:1098,6 -DA:1099,6 -DA:1100,16 -DA:1101,5 -DA:1102,8 -DA:1105,6 -DA:1107,6 -DA:1108,6 -DA:1109,5 -DA:1110,5 -DA:1111,5 -DA:1112,5 -DA:1113,5 -DA:1114,4 -DA:1115,3 -DA:1116,2 -DA:1117,2 -DA:1118,6 -DA:1119,1 -DA:1120,1 -DA:1122,1 -DA:1124,3 -DA:1127,9 -DA:1129,3 -DA:1130,4 -DA:1131,1 -DA:1132,2 -DA:1134,3 -DA:1135,3 -DA:1136,12 -DA:1137,3 -DA:1140,3 -DA:1141,3 -DA:1142,2 -DA:1143,2 -DA:1144,2 -DA:1145,2 -DA:1146,2 -DA:1147,2 -DA:1148,2 -DA:1149,2 -DA:1150,12 -DA:1151,3 -DA:1152,6 -DA:1155,2 -DA:1156,8 -DA:1157,2 -DA:1160,1 -DA:1161,1 -DA:1162,1 -DA:1163,1 -DA:1164,1 -DA:1165,1 -DA:1166,1 -DA:1167,1 -DA:1168,1 -DA:1169,1 -DA:1170,1 -DA:1172,3 -DA:1175,9 -DA:1177,6 -DA:1178,1 -DA:1179,6 -DA:1180,4 -DA:1181,4 -DA:1182,3 -DA:1183,3 -DA:1184,3 -DA:1185,3 -DA:1186,3 -DA:1187,3 -DA:1188,2 -DA:1190,6 -DA:1192,3 -DA:1195,9 -DA:1197,6 -DA:1198,4 -DA:1199,2 -DA:1201,6 -DA:1202,6 -DA:1203,12 -DA:1204,3 -DA:1207,6 -DA:1208,6 -DA:1209,6 -DA:1210,5 -DA:1211,5 -DA:1212,5 -DA:1213,5 -DA:1214,5 -DA:1215,3 -DA:1216,3 -DA:1217,20 -DA:1218,5 -DA:1219,10 -DA:1222,3 -DA:1223,3 -DA:1224,3 -DA:1225,3 -DA:1226,3 -DA:1227,3 -DA:1228,2 -DA:1229,2 -DA:1230,2 -DA:1231,2 -DA:1232,3 -DA:1233,1 -DA:1234,1 -DA:1236,1 -DA:1238,3 -DA:1241,9 -DA:1243,1 -DA:1244,1 -DA:1245,1 -DA:1247,1 -DA:1248,1 -DA:1249,1 -DA:1250,1 -DA:1251,1 -DA:1252,1 -DA:1253,1 -DA:1254,1 -DA:1255,1 -DA:1256,1 -DA:1257,1 -DA:1259,1 -DA:1261,3 -DA:1264,9 -DA:1266,1 -DA:1267,1 -DA:1268,1 -DA:1269,1 -DA:1270,1 -DA:1271,1 -DA:1272,1 -DA:1273,1 -DA:1274,1 -DA:1275,1 -DA:1276,1 -DA:1277,1 -DA:1279,1 -DA:1281,3 -DA:1284,9 -DA:1286,1 -DA:1287,4 -DA:1288,2 -DA:1290,1 -DA:1291,1 -DA:1292,4 -DA:1293,1 -DA:1296,1 -DA:1297,1 -DA:1298,1 -DA:1299,1 -DA:1300,1 -DA:1301,1 -DA:1302,1 -DA:1303,1 -DA:1304,1 -DA:1305,1 -DA:1306,4 -DA:1307,1 -DA:1308,2 -DA:1311,1 -DA:1312,1 -DA:1313,1 -DA:1314,1 -DA:1315,1 -DA:1316,1 -DA:1317,1 -DA:1318,1 -DA:1319,1 -DA:1320,1 -DA:1321,1 -DA:1323,3 -DA:1326,9 -DA:1328,4 -DA:1329,1 -DA:1330,4 -DA:1331,4 -DA:1332,4 -DA:1333,4 -DA:1334,4 -DA:1335,4 -DA:1336,4 -DA:1337,4 -DA:1338,4 -DA:1339,4 -DA:1340,4 -DA:1341,4 -DA:1342,4 -DA:1343,4 -DA:1344,4 -DA:1345,4 -DA:1346,1 -DA:1347,1 -DA:1348,1 -DA:1349,1 -DA:1350,1 -DA:1351,1 -DA:1353,5 -DA:1355,3 -DA:1358,9 -DA:1360,4 -DA:1361,4 -DA:1362,2 -DA:1364,4 -DA:1365,4 -DA:1366,12 -DA:1367,3 -DA:1370,4 -DA:1371,4 -DA:1372,4 -DA:1373,4 -DA:1374,4 -DA:1375,4 -DA:1376,4 -DA:1377,4 -DA:1378,4 -DA:1379,4 -DA:1380,12 -DA:1381,4 -DA:1382,6 -DA:1385,4 -DA:1386,4 -DA:1387,4 -DA:1388,4 -DA:1389,4 -DA:1390,4 -DA:1391,4 -DA:1392,4 -DA:1393,4 -DA:1394,4 -DA:1395,4 -DA:1396,4 -DA:1397,4 -DA:1398,4 -DA:1399,4 -DA:1400,4 -DA:1401,1 -DA:1402,1 -DA:1403,1 -DA:1404,1 -DA:1405,1 -DA:1406,1 -DA:1407,5 -DA:1409,3 -DA:1412,9 -DA:1414,5 -DA:1415,2 -DA:1416,2 -DA:1418,5 -DA:1419,5 -DA:1420,2 -DA:1423,5 -DA:1424,1 -DA:1425,2 -DA:1428,5 -DA:1429,1 -DA:1430,2 -DA:1433,5 -DA:1434,5 -DA:1435,5 -DA:1436,5 -DA:1437,5 -DA:1438,5 -DA:1439,5 -DA:1440,5 -DA:1441,5 -DA:1442,5 -DA:1443,2 -DA:1444,2 -DA:1447,5 -DA:1449,5 -DA:1450,5 -DA:1451,5 -DA:1452,5 -DA:1453,5 -DA:1454,5 -DA:1455,5 -DA:1456,5 -DA:1457,5 -DA:1458,5 -DA:1459,6 -DA:1460,6 -DA:1461,3 -DA:1463,3 -DA:1464,5 -DA:1465,5 -DA:1466,5 -DA:1467,5 -DA:1468,5 -DA:1469,5 -DA:1470,5 -DA:1471,5 -DA:1472,5 -DA:1473,5 -DA:1474,5 -DA:1475,5 -DA:1476,5 -DA:1477,5 -DA:1478,5 -DA:1479,5 -DA:1480,5 -DA:1481,5 -DA:1482,5 -DA:1483,5 -DA:1484,5 -DA:1485,5 -DA:1486,5 -DA:1487,5 -DA:1488,5 -DA:1489,5 -DA:1490,5 -DA:1491,5 -DA:1492,5 -DA:1493,5 -DA:1494,5 -DA:1495,5 -DA:1496,5 -DA:1497,5 -DA:1498,5 -DA:1499,5 -DA:1500,5 -DA:1501,5 -DA:1502,5 -DA:1503,5 -DA:1504,5 -DA:1505,5 -DA:1506,5 -DA:1507,5 -DA:1508,5 -DA:1509,4 -DA:1510,3 -DA:1511,3 -DA:1512,1 -DA:1513,1 -DA:1514,1 -DA:1515,1 -DA:1516,1 -DA:1517,10 -DA:1518,10 -DA:1519,5 -DA:1521,5 -DA:1523,3 -DA:1526,9 -DA:1528,4 -DA:1529,1 -DA:1530,4 -DA:1531,4 -DA:1535,3 -DA:1538,9 -DA:1540,9 -DA:1541,3 -DA:1542,2 -DA:1544,9 -DA:1545,9 -DA:1546,27 -DA:1547,9 -DA:1550,9 -DA:1551,9 -DA:1552,9 -DA:1553,9 -DA:1554,9 -DA:1555,9 -DA:1556,9 -DA:1557,9 -DA:1558,9 -DA:1559,9 -DA:1560,27 -DA:1561,9 -DA:1562,18 -DA:1565,9 -DA:1566,10 -DA:1567,5 -DA:1570,9 -DA:1571,9 -DA:1572,9 -DA:1573,9 -DA:1574,9 -DA:1575,9 -DA:1576,9 -DA:1577,9 -DA:1578,9 -DA:1579,9 -DA:1580,9 -DA:1581,9 -DA:1582,9 -DA:1583,9 -DA:1584,9 -DA:1585,9 -DA:1586,9 -DA:1587,9 -DA:1588,9 -DA:1589,9 -DA:1590,9 -DA:1591,9 -DA:1592,9 -DA:1593,9 -DA:1594,9 -DA:1595,9 -DA:1596,9 -DA:1597,9 -DA:1598,9 -DA:1599,9 -DA:1600,9 -DA:1601,9 -DA:1602,9 -DA:1603,9 -DA:1604,9 -DA:1605,9 -DA:1606,9 -DA:1607,9 -DA:1608,9 -DA:1609,9 -DA:1610,9 -DA:1611,9 -DA:1612,9 -DA:1613,9 -DA:1614,9 -DA:1615,9 -DA:1616,9 -DA:1617,9 -DA:1618,9 -DA:1619,9 -DA:1620,9 -DA:1621,9 -DA:1622,9 -DA:1623,9 -DA:1624,9 -DA:1625,9 -DA:1626,8 -DA:1627,8 -DA:1628,8 -DA:1629,8 -DA:1630,7 -DA:1631,7 -DA:1632,1 -DA:1633,9 -DA:1635,3 -DA:1638,6 -DA:1640,6 -DA:1641,1 -DA:1642,6 -DA:1643,1 -DA:1644,6 -DA:1645,12 -DA:1646,6 -DA:1649,6 -DA:1652,6 -DA:1655,6 -DA:1657,1 -DA:1658,1 -DA:1659,1 -DA:1660,1 -DA:1661,1 -DA:1662,1 -DA:1663,1 -DA:1665,1 -DA:1666,1 -DA:1668,1 -DA:1669,1 -DA:1671,1 -DA:1672,1 -DA:1674,1 -DA:1675,1 -DA:1677,1 -DA:1678,1 -DA:1680,1 -DA:1681,2 -DA:1684,3 -DA:1687,6 -DA:1689,1 -DA:1690,1 -DA:1691,1 -DA:1692,1 -DA:1693,1 -DA:1694,1 -DA:1695,1 -DA:1696,1 -DA:1697,1 -DA:1698,1 -DA:1699,1 -DA:1700,1 -DA:1701,1 -DA:1702,1 -DA:1703,1 -DA:1704,1 -DA:1705,1 -DA:1706,1 -DA:1707,1 -DA:1708,1 -DA:1709,1 -DA:1710,1 -DA:1711,1 -DA:1712,1 -DA:1713,1 -DA:1716,3 -DA:1719,6 -DA:1721,1 -DA:1722,1 -DA:1723,1 -DA:1724,1 -DA:1725,1 -DA:1726,1 -DA:1727,1 -DA:1728,1 -DA:1729,1 -DA:1730,1 -DA:1731,1 -DA:1732,1 -DA:1733,1 -DA:1734,1 -DA:1735,1 -DA:1736,1 -DA:1737,1 -DA:1738,1 -DA:1739,1 -DA:1740,1 -DA:1741,1 -DA:1742,1 -DA:1743,1 -DA:1744,1 -DA:1745,1 -DA:1748,3 -DA:1751,6 -DA:1753,1 -DA:1754,1 -DA:1755,1 -DA:1756,1 -DA:1757,1 -DA:1758,1 -DA:1759,1 -DA:1760,1 -DA:1761,1 -DA:1762,1 -DA:1763,1 -DA:1764,1 -DA:1765,1 -DA:1766,1 -DA:1767,1 -DA:1768,1 -DA:1769,1 -DA:1770,1 -DA:1771,1 -DA:1772,1 -DA:1773,1 -DA:1774,1 -DA:1775,1 -DA:1776,1 -DA:1777,1 -DA:1780,3 -DA:1783,6 -DA:1785,1 -DA:1786,1 -DA:1787,1 -DA:1788,1 -DA:1789,1 -DA:1790,1 -DA:1791,1 -DA:1792,1 -DA:1793,1 -DA:1794,1 -DA:1795,1 -DA:1796,1 -DA:1797,1 -DA:1798,1 -DA:1799,1 -DA:1800,1 -DA:1801,1 -DA:1802,1 -DA:1803,1 -DA:1804,1 -DA:1805,1 -DA:1806,1 -DA:1807,1 -DA:1808,1 -DA:1809,1 -DA:1810,3 -DA:1811,1 -DA:1814,3 -DA:1817,6 -DA:1819,5 -DA:1820,1 -DA:1821,5 -DA:1822,1 -DA:1823,5 -DA:1824,10 -DA:1825,5 -DA:1828,5 -DA:1831,5 -DA:1834,6 -DA:1836,1 -DA:1837,1 -DA:1838,1 -DA:1839,1 -DA:1840,1 -DA:1841,1 -DA:1842,1 -DA:1844,1 -DA:1845,1 -DA:1847,1 -DA:1848,1 -DA:1850,1 -DA:1851,1 -DA:1853,1 -DA:1854,1 -DA:1856,1 -DA:1857,1 -DA:1859,1 -DA:1860,2 -DA:1863,3 -DA:1866,6 -DA:1868,1 -DA:1869,1 -DA:1870,1 -DA:1871,1 -DA:1872,1 -DA:1873,1 -DA:1874,1 -DA:1875,1 -DA:1876,1 -DA:1877,1 -DA:1878,1 -DA:1879,1 -DA:1880,1 -DA:1881,1 -DA:1882,1 -DA:1883,1 -DA:1884,1 -DA:1885,1 -DA:1886,1 -DA:1887,1 -DA:1888,1 -DA:1889,1 -DA:1890,1 -DA:1891,1 -DA:1892,1 -DA:1895,3 -DA:1898,6 -DA:1900,1 -DA:1901,1 -DA:1902,1 -DA:1903,1 -DA:1904,1 -DA:1905,1 -DA:1906,1 -DA:1907,1 -DA:1908,1 -DA:1909,1 -DA:1910,1 -DA:1911,1 -DA:1912,1 -DA:1913,1 -DA:1914,1 -DA:1915,1 -DA:1916,1 -DA:1917,1 -DA:1918,1 -DA:1919,1 -DA:1920,1 -DA:1921,1 -DA:1922,1 -DA:1923,1 -DA:1924,1 -DA:1927,3 -DA:1930,6 -DA:1932,1 -DA:1933,1 -DA:1934,1 -DA:1935,1 -DA:1936,1 -DA:1937,1 -DA:1938,1 -DA:1939,1 -DA:1940,1 -DA:1941,1 -DA:1942,1 -DA:1943,1 -DA:1944,1 -DA:1945,1 -DA:1946,1 -DA:1947,1 -DA:1948,1 -DA:1949,1 -DA:1950,1 -DA:1951,1 -DA:1952,1 -DA:1953,1 -DA:1954,1 -DA:1955,1 -DA:1956,1 -DA:1959,3 -DA:1962,6 -DA:1964,1 -DA:1965,1 -DA:1966,1 -DA:1967,1 -DA:1968,1 -DA:1969,1 -DA:1970,1 -DA:1971,1 -DA:1972,1 -DA:1973,1 -DA:1974,1 -DA:1975,1 -DA:1976,1 -DA:1977,1 -DA:1978,1 -DA:1979,1 -DA:1980,1 -DA:1981,1 -DA:1982,1 -DA:1983,1 -DA:1984,1 -DA:1985,1 -DA:1986,1 -DA:1987,1 -DA:1988,1 -DA:1989,3 -DA:1990,1 -DA:1993,3 -DA:1996,6 -DA:1998,6 -DA:1999,1 -DA:2001,6 -DA:2002,6 -DA:2005,6 -DA:2006,6 -DA:2007,6 -DA:2008,3 -DA:2009,3 -DA:2010,3 -DA:2011,3 -DA:2012,3 -DA:2013,1 -DA:2014,1 -DA:2015,6 -DA:2018,1 -DA:2021,3 -DA:2024,4 -DA:2026,4 -DA:2027,1 -DA:2028,4 -DA:2030,4 -DA:2033,3 -DA:2036,4 -DA:2038,4 -DA:2039,1 -DA:2041,3 -DA:2048,1 -DA:2050,1 -DA:2051,1 -DA:2052,1 -DA:2059,1 -DA:2061,1 -DA:2062,1 -DA:2063,1 -DA:2081,27 -DA:2088,9 -DA:2089,27 -DA:2090,36 -DA:2091,18 -DA:2092,9 -DA:2095,9 -DA:2096,9 -DA:2097,5 -DA:2102,9 -DA:2103,9 -DA:2104,2 -DA:2106,3 -DA:2112,9 -DA:2113,27 -DA:2114,36 -DA:2117,9 -DA:2118,27 -DA:2119,3 -DA:2121,36 -DA:2122,3 -DA:2124,9 -DA:2127,9 -DA:2128,27 -DA:2129,3 -DA:2131,27 -DA:2132,9 -DA:2136,6 -DA:2137,18 -DA:2138,3 -DA:2140,18 -DA:2141,6 -DA:2145,9 -DA:2146,27 -DA:2147,36 -DA:2150,8 -DA:2151,8 -DA:2152,1 -DA:2158,9 -DA:2159,27 -DA:2160,5 -DA:2162,36 -DA:2163,5 -DA:2165,9 -DA:2168,9 -DA:2169,27 -DA:2170,9 -DA:2172,3 -DA:2175,7 -DA:2179,7 -DA:2180,7 -DA:2184,7 -DA:2188,9 -DA:2192,9 -DA:2193,27 -DA:2194,8 -DA:2195,8 -DA:2196,4 -DA:2198,8 -DA:2199,8 -DA:2204,8 -DA:2205,8 -DA:2207,8 -DA:2208,8 -DA:2218,7 -DA:2222,7 -DA:2223,7 -DA:2224,7 -DA:2225,7 -DA:2226,4 -DA:2227,4 -DA:2228,4 -DA:2229,8 -DA:2230,4 -DA:2231,4 -DA:2232,4 -DA:2233,4 -DA:2237,4 -DA:2238,8 -DA:2239,4 -DA:2243,12 -DA:2244,8 -DA:2245,12 -DA:2247,6 -DA:2251,6 -DA:2253,7 -DA:2254,7 -DA:2255,6 -DA:2256,3 -DA:2259,7 -DA:2263,3 -DA:2266,3 -DA:2267,3 -DA:2268,3 -DA:2269,9 -DA:2271,3 -DA:2272,3 -DA:2273,3 -DA:2276,3 -DA:2278,3 -DA:2279,3 -DA:2280,4 -DA:2283,3 -DA:2284,3 -DA:2285,3 -DA:2286,3 -DA:2287,3 -DA:2292,3 -DA:2293,6 -DA:2296,5 -DA:2297,4 -DA:2300,5 -DA:2302,5 -DA:2303,15 -DA:2304,12 -DA:2305,15 -DA:2306,4 -DA:2307,15 -DA:2308,20 -DA:2310,3 -DA:2312,5 -DA:2313,5 -DA:2317,8 -DA:2322,24 -DA:2323,24 -DA:2324,8 -DA:2325,7 -DA:2326,6 -DA:2327,5 -DA:2328,3 -DA:2329,3 -DA:2331,24 -DA:2332,18 -DA:2333,6 -DA:2335,24 -DA:2336,18 -DA:2337,6 -DA:2339,24 -DA:2340,18 -DA:2341,6 -DA:2343,24 -DA:2344,24 -DA:2345,8 -DA:2346,5 -DA:2349,8 -DA:2350,5 -DA:2353,8 -DA:2354,1 -DA:2358,3 -DA:2360,8 -DA:2361,6 -DA:2362,6 -DA:2363,6 -DA:2364,6 -DA:2365,6 -DA:2366,6 -DA:2371,8 -DA:2372,4 -DA:2373,4 -DA:2374,12 -DA:2376,8 -DA:2377,4 -DA:2378,4 -DA:2379,12 -DA:2381,8 -DA:2382,2 -DA:2383,2 -DA:2384,6 -DA:2386,8 -DA:2387,2 -DA:2388,2 -DA:2389,2 -DA:2391,8 -DA:2392,2 -DA:2393,2 -DA:2394,2 -DA:2395,2 -DA:2396,6 -DA:2397,2 -DA:2398,2 -DA:2399,4 -DA:2401,8 -DA:2402,3 -DA:2403,3 -DA:2404,9 -DA:2406,24 -DA:2407,8 -DA:2408,4 -DA:2409,4 -DA:2410,24 -DA:2412,8 -DA:2414,3 -DA:2417,3 -DA:2420,3 -DA:2421,6 -DA:2422,3 -DA:2423,3 -DA:2424,3 -DA:2425,3 -DA:2426,3 -DA:2427,6 -DA:2428,3 -DA:2430,6 -DA:2432,5 -DA:2433,2 -DA:2435,3 -DA:2438,9 -DA:2441,9 -DA:2442,9 -DA:2443,9 -DA:2444,9 -DA:2448,9 -DA:2449,18 -DA:2452,9 -DA:2453,9 -DA:2454,9 -DA:2455,9 -DA:2457,9 -DA:2458,3 -DA:2460,9 -DA:2462,9 -DA:2463,3 -DA:2464,3 -DA:2465,3 -DA:2467,9 -DA:2469,9 -DA:2470,18 -DA:2473,9 -DA:2474,9 -DA:2475,9 -DA:2479,8 -DA:2480,8 -DA:2481,8 -DA:2482,8 -DA:2484,16 -DA:2485,8 -DA:2486,8 -DA:2487,24 -DA:2490,9 -DA:2491,9 -DA:2492,8 -DA:2496,3 -DA:2497,3 -DA:2498,3 -DA:2502,9 -DA:2503,9 -DA:2504,18 -DA:2505,18 -DA:2507,18 -DA:2508,2 -DA:2510,9 -DA:2515,9 -DA:2516,27 -DA:2517,3 -DA:2519,18 -DA:2520,9 -LF:1276 -LH:1276 -end_of_record -SF:lib/src/flutter/argument_decoders.dart -DA:30,1 -DA:50,4 -DA:51,5 -DA:57,4 -DA:58,5 -DA:61,1 -DA:62,6 -DA:81,7 -DA:94,4 -DA:95,4 -DA:98,3 -DA:99,3 -DA:100,3 -DA:108,1 -DA:111,1 -DA:118,4 -DA:119,4 -DA:122,1 -DA:123,3 -DA:124,3 -DA:125,3 -DA:126,3 -DA:142,1 -DA:143,3 -DA:147,3 -DA:148,3 -DA:149,3 -DA:150,1 -DA:170,3 -DA:171,9 -DA:175,6 -DA:176,6 -DA:177,6 -DA:178,2 -DA:194,2 -DA:195,2 -DA:198,2 -DA:199,6 -DA:200,6 -DA:201,6 -DA:213,1 -DA:214,1 -DA:217,1 -DA:218,3 -DA:219,3 -DA:220,3 -DA:221,3 -DA:229,6 -DA:230,6 -DA:234,4 -DA:257,1 -DA:258,3 -DA:260,1 -DA:262,1 -DA:264,1 -DA:265,3 -DA:269,1 -DA:270,1 -DA:271,1 -DA:272,3 -DA:273,3 -DA:275,1 -DA:278,2 -DA:282,1 -DA:287,3 -DA:297,1 -DA:298,1 -DA:301,1 -DA:302,3 -DA:303,3 -DA:304,3 -DA:305,3 -DA:306,3 -DA:307,3 -DA:308,3 -DA:309,3 -DA:310,3 -DA:311,3 -DA:312,3 -DA:313,3 -DA:314,3 -DA:315,3 -DA:316,3 -DA:317,3 -DA:318,3 -DA:319,3 -DA:320,3 -DA:321,3 -DA:333,1 -DA:334,1 -DA:345,4 -DA:346,4 -DA:348,4 -DA:350,4 -DA:352,4 -DA:354,4 -DA:356,4 -DA:358,4 -DA:360,4 -DA:362,4 -DA:364,4 -DA:366,4 -DA:368,4 -DA:370,4 -DA:372,4 -DA:374,4 -DA:376,4 -DA:378,4 -DA:380,4 -DA:382,4 -DA:384,4 -DA:386,4 -DA:388,4 -DA:390,4 -DA:392,4 -DA:394,4 -DA:396,4 -DA:398,4 -DA:400,4 -DA:402,4 -DA:404,4 -DA:406,4 -DA:408,4 -DA:410,4 -DA:412,4 -DA:414,4 -DA:416,4 -DA:418,4 -DA:420,4 -DA:422,4 -DA:424,4 -DA:426,4 -DA:428,4 -DA:430,4 -DA:434,2 -DA:436,1 -DA:439,4 -DA:449,3 -DA:479,4 -DA:480,12 -DA:482,4 -DA:484,1 -DA:485,1 -DA:486,3 -DA:487,3 -DA:488,3 -DA:489,3 -DA:490,3 -DA:491,3 -DA:492,3 -DA:493,3 -DA:495,1 -DA:496,1 -DA:497,3 -DA:498,3 -DA:499,4 -DA:501,1 -DA:502,1 -DA:503,3 -DA:504,3 -DA:505,3 -DA:506,3 -DA:507,3 -DA:510,2 -DA:514,1 -DA:519,3 -DA:534,1 -DA:535,1 -DA:539,1 -DA:541,1 -DA:542,6 -DA:544,1 -DA:547,3 -DA:548,3 -DA:549,3 -DA:550,3 -DA:551,3 -DA:552,3 -DA:563,1 -DA:564,1 -DA:572,4 -DA:573,4 -DA:575,4 -DA:577,2 -DA:592,4 -DA:593,12 -DA:597,9 -DA:598,9 -DA:599,9 -DA:600,3 -DA:620,5 -DA:621,5 -DA:625,12 -DA:626,20 -DA:627,4 -DA:640,1 -DA:641,7 -DA:681,1 -DA:682,3 -DA:684,1 -DA:686,1 -DA:687,1 -DA:688,3 -DA:689,3 -DA:690,3 -DA:691,3 -DA:692,3 -DA:695,1 -DA:696,1 -DA:697,3 -DA:698,3 -DA:699,3 -DA:700,3 -DA:701,3 -DA:702,3 -DA:703,3 -DA:706,1 -DA:707,1 -DA:708,3 -DA:709,3 -DA:710,4 -DA:711,3 -DA:712,3 -DA:713,3 -DA:717,2 -DA:721,1 -DA:726,3 -DA:750,1 -DA:751,3 -DA:753,1 -DA:755,1 -DA:756,1 -DA:757,3 -DA:758,3 -DA:759,3 -DA:760,3 -DA:761,3 -DA:763,1 -DA:764,1 -DA:765,3 -DA:766,3 -DA:767,3 -DA:768,3 -DA:769,3 -DA:772,2 -DA:776,1 -DA:781,3 -DA:800,1 -DA:801,3 -DA:805,1 -DA:807,3 -DA:808,3 -DA:819,2 -DA:820,2 -DA:823,1 -DA:824,3 -DA:825,3 -DA:826,3 -DA:847,2 -DA:848,6 -DA:852,4 -DA:853,3 -DA:855,1 -DA:859,1 -DA:860,1 -DA:862,4 -DA:866,6 -DA:877,2 -DA:878,2 -DA:879,2 -DA:882,2 -DA:883,3 -DA:901,4 -DA:902,4 -DA:906,1 -DA:907,1 -DA:910,2 -DA:911,1 -DA:913,2 -DA:914,3 -DA:917,4 -DA:926,4 -DA:927,12 -DA:931,1 -DA:932,3 -DA:933,3 -DA:934,3 -DA:935,3 -DA:936,3 -DA:937,3 -DA:938,3 -DA:939,3 -DA:940,3 -DA:941,3 -DA:942,3 -DA:943,3 -DA:944,3 -DA:945,3 -DA:946,3 -DA:964,1 -DA:965,3 -DA:967,1 -DA:969,1 -DA:970,1 -DA:971,3 -DA:972,3 -DA:975,2 -DA:979,1 -DA:984,3 -DA:989,1 -DA:990,3 -DA:994,3 -DA:998,1 -DA:1026,2 -DA:1027,2 -DA:1030,1 -DA:1031,3 -DA:1033,1 -DA:1035,3 -DA:1037,1 -DA:1039,3 -DA:1041,1 -DA:1043,3 -DA:1045,1 -DA:1055,3 -DA:1057,1 -DA:1059,3 -DA:1061,1 -DA:1063,3 -DA:1065,1 -DA:1099,3 -DA:1100,9 -DA:1104,6 -DA:1105,2 -DA:1115,2 -DA:1116,2 -DA:1119,3 -DA:1120,3 -DA:1121,3 -DA:1122,3 -DA:1123,1 -DA:1169,2 -DA:1170,2 -DA:1172,5 -DA:1174,6 -DA:1176,2 -DA:1178,2 -DA:1179,3 -DA:1180,2 -DA:1181,1 -DA:1182,3 -DA:1183,3 -DA:1185,2 -DA:1186,2 -DA:1187,6 -DA:1189,1 -DA:1190,1 -DA:1191,3 -DA:1192,3 -DA:1194,1 -DA:1195,1 -DA:1196,3 -DA:1197,3 -DA:1199,1 -DA:1200,1 -DA:1201,3 -DA:1204,2 -DA:1208,1 -DA:1213,3 -DA:1229,1 -DA:1230,3 -DA:1232,1 -DA:1234,1 -DA:1235,1 -DA:1236,1 -DA:1237,2 -DA:1238,3 -DA:1239,2 -DA:1242,2 -DA:1246,1 -DA:1251,3 -DA:1260,1 -DA:1261,1 -DA:1274,4 -DA:1275,4 -DA:1278,1 -DA:1279,3 -DA:1280,3 -DA:1281,3 -DA:1282,3 -DA:1283,3 -DA:1284,3 -DA:1285,3 -DA:1286,3 -DA:1287,3 -DA:1300,4 -DA:1301,4 -DA:1304,1 -DA:1305,3 -DA:1306,3 -DA:1307,3 -DA:1323,2 -DA:1324,2 -DA:1326,1 -DA:1328,4 -DA:1329,2 -DA:1331,2 -DA:1333,2 -DA:1357,4 -DA:1358,4 -DA:1361,2 -DA:1362,6 -DA:1363,6 -DA:1364,6 -DA:1365,6 -DA:1366,6 -DA:1367,6 -DA:1368,6 -DA:1369,4 -DA:1370,6 -DA:1371,6 -DA:1372,6 -DA:1373,6 -DA:1374,6 -DA:1375,6 -DA:1376,6 -DA:1377,6 -DA:1378,6 -DA:1379,6 -DA:1380,6 -DA:1381,6 -DA:1382,6 -DA:1383,4 -DA:1402,1 -DA:1403,1 -DA:1405,1 -DA:1406,1 -DA:1407,1 -DA:1409,1 -DA:1411,1 -DA:1414,1 -DA:1417,1 -DA:1418,3 -DA:1419,3 -LF:444 -LH:444 -end_of_record -SF:lib/src/flutter/content.dart -DA:25,7 -DA:28,3 -DA:29,12 -DA:30,3 -DA:31,12 -DA:33,14 -DA:137,7 -DA:139,7 -DA:159,7 -DA:160,10 -DA:161,3 -DA:162,3 -DA:176,3 -DA:177,9 -DA:178,3 -DA:195,2 -DA:196,4 -DA:200,2 -DA:201,4 -DA:206,3 -DA:207,3 -DA:208,3 -DA:209,6 -DA:210,3 -DA:211,3 -DA:216,1 -DA:217,3 -DA:222,8 -DA:224,14 -DA:233,5 -DA:235,6 -DA:247,3 -DA:248,6 -DA:249,2 -DA:250,2 -DA:251,1 -DA:252,3 -DA:257,1 -DA:258,3 -DA:259,2 -DA:260,1 -DA:261,2 -DA:265,3 -DA:266,3 -DA:267,6 -DA:269,3 -DA:270,3 -DA:272,3 -DA:273,3 -DA:274,3 -DA:275,2 -DA:278,2 -DA:279,5 -DA:280,4 -DA:282,4 -DA:283,6 -DA:284,4 -DA:288,2 -DA:289,5 -DA:290,2 -DA:295,1 -DA:297,6 -DA:299,4 -DA:302,2 -DA:303,4 -DA:304,4 -DA:305,6 -DA:306,4 -DA:307,2 -DA:309,4 -DA:310,4 -DA:313,2 -DA:314,4 -DA:315,4 -DA:316,4 -DA:317,4 -DA:318,4 -DA:321,6 -DA:322,10 -DA:326,1 -DA:327,3 -DA:328,2 -DA:331,1 -DA:332,1 -DA:333,3 -DA:335,1 -DA:336,1 -DA:338,3 -DA:340,1 -DA:341,3 -DA:343,4 -DA:344,1 -DA:346,3 -DA:349,3 -DA:350,1 -DA:353,1 -DA:356,3 -DA:357,6 -DA:358,3 -DA:359,9 -DA:362,6 -DA:363,6 -DA:364,3 -DA:366,6 -DA:369,3 -DA:370,4 -DA:371,1 -DA:375,1 -DA:376,2 -LF:109 -LH:109 -end_of_record -SF:lib/src/flutter/core_widgets.dart -DA:230,21 -DA:233,14 -DA:238,1 -DA:239,1 -DA:240,2 -DA:241,2 -DA:242,2 -DA:246,1 -DA:247,1 -DA:248,2 -DA:249,2 -DA:250,2 -DA:251,2 -DA:252,2 -DA:253,2 -DA:254,2 -DA:258,1 -DA:259,1 -DA:260,2 -DA:261,2 -DA:265,2 -DA:266,2 -DA:267,4 -DA:268,4 -DA:269,4 -DA:273,1 -DA:274,1 -DA:275,2 -DA:277,2 -DA:278,2 -DA:282,4 -DA:283,4 -DA:284,8 -DA:285,8 -DA:289,2 -DA:290,2 -DA:291,4 -DA:292,4 -DA:293,4 -DA:294,4 -DA:295,4 -DA:296,4 -DA:297,4 -DA:301,4 -DA:302,4 -DA:303,8 -DA:304,8 -DA:305,8 -DA:306,8 -DA:307,8 -DA:308,8 -DA:309,8 -DA:310,8 -DA:311,8 -DA:312,8 -DA:313,8 -DA:314,8 -DA:315,8 -DA:316,8 -DA:317,8 -DA:318,8 -DA:322,1 -DA:323,1 -DA:324,2 -DA:325,2 -DA:326,2 -DA:327,2 -DA:328,2 -DA:329,2 -DA:330,2 -DA:331,2 -DA:332,2 -DA:333,2 -DA:334,2 -DA:338,2 -DA:339,2 -DA:340,4 -DA:341,4 -DA:345,1 -DA:346,1 -DA:347,2 -DA:348,2 -DA:352,1 -DA:353,1 -DA:354,2 -DA:355,2 -DA:356,2 -DA:357,2 -DA:361,1 -DA:362,1 -DA:363,2 -DA:364,2 -DA:365,2 -DA:366,2 -DA:370,3 -DA:371,3 -DA:372,6 -DA:373,9 -DA:374,9 -DA:375,6 -DA:376,6 -DA:377,6 -DA:378,6 -DA:379,6 -DA:383,1 -DA:384,1 -DA:385,2 -DA:386,2 -DA:388,2 -DA:390,2 -DA:391,2 -DA:392,2 -DA:393,3 -DA:394,2 -DA:395,2 -DA:396,2 -DA:397,2 -DA:398,2 -DA:399,2 -DA:400,2 -DA:401,2 -DA:402,2 -DA:403,2 -DA:407,1 -DA:408,1 -DA:409,2 -DA:410,2 -DA:411,2 -DA:412,2 -DA:413,2 -DA:417,1 -DA:418,1 -DA:419,2 -DA:420,2 -DA:424,1 -DA:425,1 -DA:426,2 -DA:430,1 -DA:431,1 -DA:432,2 -DA:433,2 -DA:434,2 -DA:438,1 -DA:439,1 -DA:440,2 -DA:444,2 -DA:445,2 -DA:446,2 -DA:447,2 -DA:448,2 -DA:450,2 -DA:451,2 -DA:452,2 -DA:453,2 -DA:454,2 -DA:455,2 -DA:456,2 -DA:457,2 -DA:458,2 -DA:462,2 -DA:463,2 -DA:464,4 -DA:465,4 -DA:466,4 -DA:470,2 -DA:471,2 -DA:472,4 -DA:473,4 -DA:475,4 -DA:477,4 -DA:478,4 -DA:479,4 -DA:480,4 -DA:481,4 -DA:482,6 -DA:483,4 -DA:484,4 -DA:485,4 -DA:486,4 -DA:487,4 -DA:488,4 -DA:489,4 -DA:490,4 -DA:491,4 -DA:495,1 -DA:496,1 -DA:497,2 -DA:498,2 -DA:499,2 -DA:500,2 -DA:501,2 -DA:502,2 -DA:506,2 -DA:507,2 -DA:508,4 -DA:509,4 -DA:510,4 -DA:511,4 -DA:512,4 -DA:516,4 -DA:517,4 -DA:518,8 -DA:519,8 -DA:520,8 -DA:521,8 -DA:525,1 -DA:526,1 -DA:527,2 -DA:528,2 -DA:529,2 -DA:530,2 -DA:531,2 -DA:532,2 -DA:533,2 -DA:534,2 -DA:535,2 -DA:536,2 -DA:540,1 -DA:541,1 -DA:542,2 -DA:543,2 -DA:544,2 -DA:545,4 -DA:546,2 -DA:547,2 -DA:548,2 -DA:554,2 -DA:555,2 -DA:556,4 -DA:557,4 -DA:558,4 -DA:559,4 -DA:560,4 -DA:561,4 -DA:562,4 -DA:567,1 -DA:568,1 -DA:569,2 -DA:570,2 -DA:571,2 -DA:572,2 -DA:573,4 -DA:574,2 -DA:575,2 -DA:579,1 -DA:580,1 -DA:581,2 -DA:582,2 -DA:583,2 -DA:584,4 -DA:585,2 -DA:586,2 -DA:587,2 -DA:591,1 -DA:592,1 -DA:593,2 -DA:594,2 -DA:595,2 -DA:596,2 -DA:597,2 -DA:598,2 -DA:599,2 -DA:600,2 -DA:603,2 -DA:607,6 -DA:608,6 -DA:609,12 -DA:610,12 -DA:611,12 -DA:615,1 -DA:616,1 -DA:617,2 -DA:621,3 -DA:622,3 -DA:623,6 -DA:627,1 -DA:628,1 -DA:629,2 -DA:633,1 -DA:634,1 -DA:635,2 -DA:636,2 -DA:637,2 -DA:638,2 -DA:639,2 -DA:643,4 -DA:644,8 -DA:646,2 -DA:647,4 -DA:648,4 -DA:649,6 -DA:651,2 -DA:653,8 -DA:654,4 -DA:656,8 -DA:657,8 -DA:658,8 -DA:659,8 -DA:660,8 -DA:661,8 -DA:662,8 -DA:663,1 -DA:664,8 -DA:665,8 -DA:666,8 -DA:667,8 -DA:671,1 -DA:672,1 -DA:673,2 -DA:674,2 -DA:675,2 -DA:676,2 -DA:677,2 -DA:678,2 -DA:679,2 -DA:680,2 -DA:681,2 -DA:682,2 -LF:318 -LH:318 -end_of_record -SF:lib/src/flutter/material_widgets.dart -DA:100,6 -DA:102,4 -DA:106,1 -DA:107,1 -DA:108,2 -DA:109,2 -DA:110,2 -DA:111,2 -DA:112,2 -DA:113,2 -DA:114,2 -DA:115,2 -DA:119,1 -DA:121,1 -DA:122,2 -DA:123,2 -DA:124,2 -DA:125,2 -DA:126,2 -DA:127,2 -DA:128,2 -DA:129,2 -DA:130,2 -DA:131,2 -DA:132,2 -DA:133,2 -DA:134,2 -DA:135,2 -DA:136,2 -DA:137,2 -DA:138,2 -DA:139,2 -DA:140,2 -DA:141,2 -DA:157,1 -DA:158,2 -DA:159,2 -DA:162,1 -DA:163,2 -DA:164,2 -DA:165,2 -DA:166,2 -DA:167,2 -DA:171,1 -DA:172,1 -DA:173,1 -DA:174,3 -DA:175,2 -DA:179,1 -DA:180,1 -DA:181,3 -DA:188,3 -DA:189,1 -DA:195,1 -DA:196,1 -DA:197,2 -DA:198,2 -DA:199,2 -DA:200,2 -DA:202,2 -DA:204,2 -DA:205,2 -DA:209,1 -DA:210,1 -DA:211,2 -DA:212,2 -DA:213,2 -DA:214,2 -DA:215,2 -DA:216,2 -DA:217,2 -DA:218,2 -DA:219,2 -DA:223,1 -DA:225,1 -DA:226,2 -DA:227,2 -DA:228,2 -DA:229,2 -DA:230,2 -DA:231,2 -DA:235,1 -DA:236,1 -DA:237,2 -DA:238,2 -DA:239,2 -DA:240,2 -DA:241,2 -DA:245,1 -DA:246,1 -DA:247,2 -DA:248,2 -DA:249,2 -DA:253,1 -DA:254,1 -DA:255,2 -DA:256,2 -DA:257,2 -DA:258,2 -DA:259,2 -DA:260,2 -DA:264,1 -DA:265,2 -DA:266,1 -DA:268,2 -DA:269,2 -DA:270,6 -DA:271,2 -DA:272,2 -DA:273,2 -DA:277,1 -DA:279,6 -DA:280,2 -DA:281,6 -DA:282,2 -DA:283,2 -DA:284,2 -DA:285,2 -DA:286,2 -DA:287,2 -DA:288,2 -DA:289,2 -DA:290,2 -DA:291,2 -DA:292,2 -DA:293,2 -DA:294,2 -DA:295,2 -DA:296,2 -DA:297,2 -DA:298,2 -DA:299,4 -DA:300,2 -DA:304,1 -DA:306,1 -DA:307,2 -DA:308,2 -DA:309,2 -DA:310,2 -DA:311,2 -DA:315,1 -DA:317,1 -DA:318,2 -DA:319,2 -DA:320,2 -DA:321,2 -DA:322,2 -DA:323,2 -DA:324,2 -DA:325,2 -DA:326,2 -DA:327,2 -DA:328,2 -DA:329,2 -DA:330,2 -DA:331,2 -DA:332,2 -DA:333,2 -DA:334,2 -DA:335,2 -DA:336,2 -DA:337,2 -DA:338,2 -DA:342,1 -DA:344,1 -DA:345,2 -DA:346,2 -DA:347,2 -DA:348,2 -DA:349,2 -DA:350,2 -DA:351,2 -DA:352,2 -DA:353,2 -DA:354,2 -DA:355,2 -DA:356,5 -DA:357,2 -DA:358,2 -DA:359,2 -DA:360,4 -DA:361,2 -DA:362,2 -DA:363,2 -DA:364,2 -DA:365,2 -DA:366,2 -DA:367,2 -DA:368,2 -DA:369,2 -DA:370,2 -DA:371,2 -DA:372,2 -DA:376,1 -DA:378,1 -DA:379,2 -DA:380,2 -DA:381,2 -DA:382,2 -DA:383,2 -DA:384,2 -DA:385,2 -DA:386,2 -DA:387,2 -DA:388,2 -DA:389,2 -DA:390,2 -DA:391,2 -DA:392,2 -DA:393,2 -DA:394,2 -DA:395,2 -DA:396,2 -DA:397,2 -DA:398,2 -DA:399,2 -DA:400,2 -DA:404,1 -DA:406,1 -DA:407,2 -DA:408,2 -DA:409,2 -DA:410,2 -DA:411,2 -DA:412,2 -DA:416,1 -DA:418,1 -DA:419,2 -DA:420,2 -DA:421,2 -DA:422,2 -DA:423,2 -DA:424,2 -DA:425,2 -DA:426,2 -DA:427,2 -DA:428,2 -DA:429,2 -DA:430,2 -DA:431,2 -DA:432,2 -DA:433,2 -DA:434,2 -DA:435,2 -DA:436,2 -DA:437,2 -DA:438,2 -DA:439,2 -DA:440,2 -DA:444,1 -DA:445,1 -DA:446,2 -DA:447,2 -DA:448,2 -DA:449,2 -DA:450,2 -DA:451,2 -DA:452,2 -DA:453,2 -DA:454,2 -DA:455,2 -DA:456,2 -DA:457,2 -DA:461,1 -DA:463,1 -DA:464,2 -DA:465,2 -DA:466,2 -DA:467,2 -DA:468,2 -DA:472,1 -DA:474,2 -DA:475,2 -DA:476,1 -DA:477,1 -DA:478,3 -DA:481,2 -DA:482,2 -DA:483,1 -DA:484,2 -DA:485,2 -DA:486,2 -DA:487,2 -DA:488,2 -DA:489,2 -DA:490,2 -DA:491,2 -DA:492,2 -DA:493,2 -DA:494,2 -DA:495,2 -DA:496,2 -DA:497,2 -DA:498,2 -DA:502,1 -DA:504,1 -DA:505,2 -DA:506,2 -DA:507,2 -DA:508,2 -DA:509,2 -DA:513,1 -DA:514,1 -DA:515,2 -DA:516,2 -DA:517,2 -DA:518,2 -DA:519,2 -LF:308 -LH:308 -end_of_record -SF:lib/src/flutter/remote_widget.dart -DA:23,7 -DA:59,7 -DA:60,7 -DA:64,7 -DA:66,7 -DA:67,28 -DA:70,3 -DA:72,3 -DA:73,12 -DA:74,3 -DA:75,4 -DA:79,7 -DA:81,28 -DA:82,7 -DA:85,5 -DA:86,10 -DA:89,4 -DA:90,8 -DA:91,12 -DA:95,7 -DA:97,56 -LF:21 -LH:21 -end_of_record -SF:lib/src/flutter/runtime.dart -DA:54,9 -DA:61,1 -DA:62,1 -DA:188,7 -DA:193,7 -DA:195,14 -DA:210,1 -DA:211,2 -DA:216,7 -DA:235,7 -DA:252,7 -DA:253,14 -DA:254,7 -DA:265,1 -DA:266,2 -DA:267,1 -DA:284,1 -DA:285,3 -DA:291,7 -DA:292,14 -DA:293,14 -DA:294,7 -DA:309,7 -DA:315,14 -DA:317,14 -DA:318,7 -DA:322,7 -DA:326,14 -DA:328,7 -DA:343,1 -DA:344,2 -DA:345,2 -DA:346,2 -DA:353,2 -DA:356,2 -DA:359,7 -DA:360,14 -DA:361,7 -DA:363,7 -DA:364,14 -DA:365,7 -DA:366,7 -DA:367,1 -DA:368,3 -DA:369,1 -DA:372,1 -DA:374,2 -DA:375,3 -DA:376,2 -DA:378,4 -DA:381,14 -DA:386,7 -DA:387,14 -DA:391,21 -DA:392,7 -DA:393,14 -DA:394,21 -DA:395,21 -DA:398,14 -DA:399,7 -DA:400,21 -DA:404,14 -DA:407,7 -DA:408,14 -DA:410,21 -DA:413,6 -DA:415,10 -DA:419,3 -DA:420,6 -DA:425,1 -DA:429,2 -DA:430,2 -DA:447,7 -DA:455,7 -DA:457,14 -DA:458,14 -DA:459,1 -DA:461,2 -DA:462,1 -DA:464,21 -DA:465,7 -DA:467,7 -DA:468,2 -DA:472,7 -DA:473,7 -DA:474,7 -DA:480,7 -DA:481,2 -DA:482,2 -DA:486,2 -DA:487,2 -DA:490,7 -DA:491,1 -DA:492,1 -DA:496,1 -DA:497,1 -DA:502,21 -DA:503,7 -DA:504,7 -DA:505,7 -DA:508,7 -DA:510,9 -DA:511,3 -DA:512,3 -DA:513,3 -DA:514,6 -DA:515,3 -DA:516,3 -DA:518,4 -DA:519,1 -DA:522,7 -DA:529,7 -DA:530,7 -DA:532,7 -DA:538,7 -DA:539,21 -DA:547,7 -DA:548,1 -DA:549,1 -DA:551,2 -DA:553,1 -DA:555,1 -DA:561,1 -DA:562,1 -DA:563,2 -DA:568,1 -DA:573,7 -DA:574,7 -DA:575,12 -DA:577,6 -DA:581,6 -DA:582,6 -DA:583,6 -DA:584,12 -DA:586,6 -DA:595,6 -DA:596,4 -DA:597,4 -DA:598,2 -DA:599,2 -DA:601,6 -DA:602,2 -DA:603,4 -DA:604,4 -DA:605,2 -DA:606,2 -DA:607,2 -DA:608,2 -DA:612,2 -DA:614,6 -DA:615,4 -DA:617,6 -DA:618,2 -DA:620,6 -DA:621,5 -DA:622,5 -DA:623,5 -DA:625,5 -DA:631,5 -DA:633,6 -DA:634,3 -DA:635,2 -DA:636,1 -DA:638,2 -DA:639,1 -DA:641,12 -DA:654,6 -DA:665,7 -DA:677,2 -DA:678,2 -DA:679,2 -DA:680,6 -DA:683,2 -DA:684,1 -DA:685,1 -DA:686,3 -DA:690,2 -DA:691,6 -DA:692,1 -DA:694,2 -DA:695,2 -DA:696,4 -DA:697,4 -DA:698,4 -DA:699,2 -DA:700,2 -DA:703,2 -DA:705,2 -DA:706,2 -DA:707,2 -DA:708,2 -DA:709,4 -DA:710,4 -DA:711,2 -DA:713,2 -DA:714,1 -DA:715,1 -DA:716,2 -DA:717,2 -DA:718,2 -DA:719,1 -DA:720,1 -DA:722,2 -DA:723,2 -DA:724,2 -DA:725,4 -DA:726,4 -DA:727,4 -DA:728,2 -DA:729,2 -DA:731,2 -DA:732,4 -DA:733,4 -DA:737,2 -DA:738,8 -DA:739,2 -DA:741,2 -DA:742,4 -DA:743,1 -DA:745,2 -DA:746,4 -DA:747,1 -DA:759,6 -DA:768,23 -DA:769,6 -DA:770,6 -DA:771,2 -DA:772,2 -DA:773,2 -DA:774,1 -DA:775,1 -DA:776,1 -DA:781,2 -DA:782,4 -DA:783,1 -DA:784,3 -DA:785,1 -DA:786,1 -DA:787,1 -DA:788,1 -DA:793,1 -DA:794,1 -DA:803,1 -DA:805,4 -DA:807,2 -DA:809,5 -DA:814,2 -DA:815,6 -DA:816,2 -DA:818,2 -DA:820,6 -DA:821,12 -DA:823,5 -DA:825,5 -DA:827,5 -DA:830,7 -DA:840,7 -DA:841,2 -DA:842,2 -DA:843,1 -DA:845,2 -DA:847,7 -DA:848,4 -DA:850,7 -DA:851,2 -DA:852,4 -DA:853,2 -DA:856,2 -DA:859,7 -DA:860,2 -DA:861,2 -DA:862,1 -DA:864,3 -DA:866,7 -DA:867,2 -DA:868,4 -DA:869,4 -DA:872,2 -DA:875,7 -DA:876,2 -DA:877,2 -DA:883,4 -DA:885,2 -DA:892,14 -DA:895,6 -DA:896,5 -DA:897,5 -DA:898,10 -DA:900,6 -DA:901,1 -DA:902,1 -DA:903,2 -DA:908,7 -DA:909,14 -DA:912,14 -DA:915,12 -DA:916,6 -DA:917,12 -DA:920,6 -DA:922,6 -DA:926,6 -DA:928,2 -DA:929,2 -DA:930,2 -DA:933,6 -DA:935,12 -DA:936,12 -DA:937,12 -DA:941,5 -DA:947,5 -DA:948,9 -DA:949,4 -DA:951,8 -DA:954,4 -DA:955,3 -DA:956,1 -DA:958,1 -DA:962,1 -DA:963,1 -DA:965,2 -DA:966,2 -DA:973,1 -DA:974,1 -DA:975,3 -DA:978,4 -DA:979,1 -DA:985,7 -DA:992,14 -DA:993,7 -DA:994,10 -DA:996,14 -DA:997,14 -DA:998,14 -DA:1002,7 -DA:1008,7 -DA:1011,14 -DA:1028,1 -DA:1029,4 -DA:1033,7 -DA:1038,7 -DA:1040,3 -DA:1041,3 -DA:1043,6 -DA:1051,7 -DA:1062,14 -DA:1067,1 -DA:1073,1 -DA:1077,1 -DA:1088,2 -DA:1091,1 -DA:1092,3 -DA:1096,2 -DA:1102,2 -DA:1106,2 -DA:1117,2 -DA:1118,2 -DA:1124,2 -DA:1125,2 -DA:1127,3 -DA:1130,1 -DA:1131,3 -DA:1135,7 -DA:1153,7 -DA:1154,7 -DA:1162,7 -DA:1164,7 -DA:1165,7 -DA:1168,6 -DA:1170,6 -DA:1171,24 -DA:1172,6 -DA:1174,48 -DA:1175,6 -DA:1179,7 -DA:1181,7 -DA:1182,7 -DA:1185,7 -DA:1186,35 -DA:1187,7 -DA:1188,4 -DA:1189,6 -DA:1191,7 -DA:1193,21 -DA:1194,7 -DA:1195,8 -DA:1199,1 -DA:1200,3 -DA:1203,1 -DA:1204,2 -DA:1205,1 -DA:1207,1 -DA:1208,2 -DA:1209,1 -DA:1210,1 -DA:1211,1 -DA:1212,3 -DA:1214,1 -DA:1215,3 -DA:1217,3 -DA:1218,1 -DA:1220,2 -DA:1222,1 -DA:1223,1 -DA:1224,3 -DA:1226,3 -DA:1227,3 -DA:1229,3 -DA:1230,1 -DA:1232,1 -DA:1235,3 -DA:1237,1 -DA:1239,3 -DA:1247,7 -DA:1248,16 -DA:1249,2 -DA:1251,14 -DA:1252,14 -DA:1255,7 -DA:1257,33 -DA:1258,7 -DA:1259,7 -DA:1262,3 -DA:1264,3 -DA:1265,3 -DA:1266,3 -DA:1269,5 -DA:1271,5 -DA:1272,5 -DA:1273,5 -DA:1274,10 -DA:1275,5 -DA:1278,6 -DA:1282,6 -DA:1284,6 -DA:1285,6 -DA:1288,5 -DA:1290,5 -DA:1291,5 -DA:1292,32 -DA:1294,5 -DA:1297,7 -DA:1299,7 -DA:1300,7 -DA:1301,48 -DA:1306,4 -DA:1308,4 -DA:1309,4 -DA:1310,8 -DA:1311,8 -DA:1312,4 -DA:1313,4 -DA:1314,4 -DA:1315,4 -DA:1316,4 -DA:1317,28 -DA:1319,5 -DA:1323,3 -DA:1326,1 -DA:1327,5 -DA:1331,1 -DA:1333,1 -DA:1336,1 -DA:1338,1 -DA:1341,1 -DA:1346,1 -DA:1347,1 -DA:1348,1 -DA:1349,1 -DA:1350,1 -DA:1351,2 -DA:1352,2 -DA:1353,2 -DA:1358,5 -DA:1361,6 -DA:1363,19 -DA:1366,6 -DA:1368,6 -DA:1369,6 -DA:1370,5 -DA:1371,5 -DA:1372,2 -DA:1374,6 -DA:1375,10 -DA:1376,5 -DA:1377,9 -DA:1378,8 -DA:1379,4 -DA:1380,4 -DA:1382,12 -DA:1384,16 -DA:1385,1 -DA:1386,3 -DA:1387,6 -DA:1402,7 -DA:1403,7 -DA:1404,14 -DA:1405,4 -DA:1408,14 -DA:1410,7 -DA:1411,21 -DA:1413,7 -DA:1414,7 -DA:1415,7 -DA:1418,9 -DA:1419,2 -DA:1421,14 -DA:1424,14 -DA:1425,7 -DA:1429,4 -DA:1430,8 -DA:1431,12 -DA:1435,2 -DA:1436,2 -DA:1438,4 -DA:1439,6 -DA:1440,4 -DA:1442,2 -DA:1444,4 -DA:1445,2 -DA:1448,1 -DA:1449,1 -DA:1450,3 -DA:1451,2 -DA:1455,2 -DA:1456,1 -DA:1459,1 -DA:1460,1 -DA:1462,2 -DA:1463,3 -DA:1466,3 -DA:1470,1 -DA:1471,2 -DA:1473,2 -DA:1475,2 -DA:1476,1 -DA:1479,2 -DA:1480,4 -DA:1481,3 -DA:1482,2 -DA:1487,7 -DA:1490,21 -DA:1493,14 -DA:1494,14 -DA:1495,7 -DA:1496,7 -DA:1497,7 -DA:1498,7 -DA:1502,1 -DA:1504,1 -DA:1505,6 -DA:1515,14 -DA:1517,7 -DA:1518,28 -DA:1524,4 -DA:1526,4 -DA:1527,12 -DA:1528,12 -DA:1531,7 -DA:1532,28 -DA:1536,2 -DA:1537,10 -DA:1545,4 -DA:1548,2 -DA:1549,6 -DA:1550,2 -DA:1553,2 -DA:1554,4 -DA:1557,2 -DA:1558,8 -DA:1562,3 -DA:1563,6 -DA:1565,3 -DA:1568,3 -LF:573 -LH:573 -end_of_record diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index 77078b88e1bb..22be39c3acb7 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -577,18 +577,6 @@ class WidgetBuilderArgReference extends Reference { /// The [argumentName] is "scope" and its [parts] are `["result", "text"]`. final String argumentName; - /// Creates a new [WidgetBuilderArgReference] that indexes even deeper than this one. - /// - /// For example, suppose a widget's arguments consisted of a map with one key, - /// "a", whose value was a [WidgetBuilderArgReference] referencing "scope.foo.bar". - /// Now suppose that the widget itself has an [ArgsReference] that references - /// "args.a.baz". The "args.a" part identifies the aforementioned - /// [WidgetBuilderArgReference], and so the resulting reference is actually to - /// "scope.foo.bar.baz". - WidgetBuilderArgReference constructReference(List moreParts) { - return WidgetBuilderArgReference(argumentName, parts + moreParts); - } - @override String toString() => '$argumentName.${parts.join('.')}'; } From 93b6ac13445b1e3054b145df49118c6f45cfdb55 Mon Sep 17 00:00:00 2001 From: Juan Tugores Date: Wed, 6 Mar 2024 12:37:32 -0800 Subject: [PATCH 22/22] Make the analyzer happy and loved --- packages/rfw/test/runtime_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index b368607aceb2..f081df3e8126 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -1099,7 +1099,7 @@ void main() { runtime.update(localLibraryName, LocalWidgetLibrary( { 'Builder': (BuildContext context, DataSource source) { final Widget? builder = source.optionalBuilder(['builder'], {}); - return builder ?? Text('Hello World!', textDirection: TextDirection.ltr); + return builder ?? const Text('Hello World!', textDirection: TextDirection.ltr); }, })); runtime.update(remoteLibraryName, parseLibraryFile(''' @@ -1128,7 +1128,7 @@ void main() { const LibraryName remoteLibraryName = LibraryName(['remote']); final Runtime runtime = Runtime(); final DynamicContent data = DynamicContent(); - const expectedErrorMessage = 'Not a builder at [builder] (got core:Text {} {text: Not a builder :/}) for local:Builder.'; + const String expectedErrorMessage = 'Not a builder at [builder] (got core:Text {} {text: Not a builder :/}) for local:Builder.'; runtime.update(coreLibraryName, createCoreWidgets()); runtime.update(localLibraryName, LocalWidgetLibrary( {