diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md index 1630957ffa5..3380850fa0e 100644 --- a/packages/animations/CHANGELOG.md +++ b/packages/animations/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 2.1.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. ## 2.0.11 diff --git a/packages/animations/example/android/app/build.gradle b/packages/animations/example/android/app/build.gradle index 5d331fa1132..e9083f04998 100644 --- a/packages/animations/example/android/app/build.gradle +++ b/packages/animations/example/android/app/build.gradle @@ -11,12 +11,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/animations/example/lib/container_transition.dart b/packages/animations/example/lib/container_transition.dart index 2c8caf09341..4f188eae2b2 100644 --- a/packages/animations/example/lib/container_transition.dart +++ b/packages/animations/example/lib/container_transition.dart @@ -84,10 +84,9 @@ class _OpenContainerTransformDemoState onPressed: (int index) { setModalState(() { setState(() { - _transitionType = - index == 0 - ? ContainerTransitionType.fade - : ContainerTransitionType.fadeThrough; + _transitionType = index == 0 + ? ContainerTransitionType.fade + : ContainerTransitionType.fadeThrough; }); }); }, diff --git a/packages/animations/example/lib/fade_scale_transition.dart b/packages/animations/example/lib/fade_scale_transition.dart index 815de52f85f..176363a47ab 100644 --- a/packages/animations/example/lib/fade_scale_transition.dart +++ b/packages/animations/example/lib/fade_scale_transition.dart @@ -21,18 +21,19 @@ class _FadeScaleTransitionDemoState extends State @override void initState() { - _controller = AnimationController( - value: 0.0, - duration: const Duration(milliseconds: 150), - reverseDuration: const Duration(milliseconds: 75), - vsync: this, - )..addStatusListener((AnimationStatus status) { - setState(() { - // setState needs to be called to trigger a rebuild because - // the 'HIDE FAB'/'SHOW FAB' button needs to be updated based - // the latest value of [_controller.status]. - }); - }); + _controller = + AnimationController( + value: 0.0, + duration: const Duration(milliseconds: 150), + reverseDuration: const Duration(milliseconds: 75), + vsync: this, + )..addStatusListener((AnimationStatus status) { + setState(() { + // setState needs to be called to trigger a rebuild because + // the 'HIDE FAB'/'SHOW FAB' button needs to be updated based + // the latest value of [_controller.status]. + }); + }); super.initState(); } @@ -99,10 +100,9 @@ class _FadeScaleTransitionDemoState extends State _controller.forward(); } }, - child: - _isAnimationRunningForwardsOrComplete - ? const Text('HIDE FAB') - : const Text('SHOW FAB'), + child: _isAnimationRunningForwardsOrComplete + ? const Text('HIDE FAB') + : const Text('SHOW FAB'), ), ], ), diff --git a/packages/animations/example/lib/fade_through_transition.dart b/packages/animations/example/lib/fade_through_transition.dart index 2bd0cbbf35d..249c9439436 100644 --- a/packages/animations/example/lib/fade_through_transition.dart +++ b/packages/animations/example/lib/fade_through_transition.dart @@ -25,17 +25,18 @@ class _FadeThroughTransitionDemoState extends State { return Scaffold( appBar: AppBar(title: const Text('Fade through')), body: PageTransitionSwitcher( - transitionBuilder: ( - Widget child, - Animation animation, - Animation secondaryAnimation, - ) { - return FadeThroughTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - }, + transitionBuilder: + ( + Widget child, + Animation animation, + Animation secondaryAnimation, + ) { + return FadeThroughTransition( + animation: animation, + secondaryAnimation: secondaryAnimation, + child: child, + ); + }, child: pageList[pageIndex], ), bottomNavigationBar: BottomNavigationBar( diff --git a/packages/animations/example/lib/shared_axis_transition.dart b/packages/animations/example/lib/shared_axis_transition.dart index 2c5633d17a1..e7d7e85b5a3 100644 --- a/packages/animations/example/lib/shared_axis_transition.dart +++ b/packages/animations/example/lib/shared_axis_transition.dart @@ -44,18 +44,19 @@ class _SharedAxisTransitionDemoState extends State { Expanded( child: PageTransitionSwitcher( reverse: !_isLoggedIn, - transitionBuilder: ( - Widget child, - Animation animation, - Animation secondaryAnimation, - ) { - return SharedAxisTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - transitionType: _transitionType!, - child: child, - ); - }, + transitionBuilder: + ( + Widget child, + Animation animation, + Animation secondaryAnimation, + ) { + return SharedAxisTransition( + animation: animation, + secondaryAnimation: secondaryAnimation, + transitionType: _transitionType!, + child: child, + ); + }, child: _isLoggedIn ? _CoursePage() : _SignInPage(), ), ), diff --git a/packages/animations/example/pubspec.yaml b/packages/animations/example/pubspec.yaml index 75e7e2118e4..3a5b1b207c9 100644 --- a/packages/animations/example/pubspec.yaml +++ b/packages/animations/example/pubspec.yaml @@ -6,8 +6,8 @@ publish_to: none version: 0.0.1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: animations: diff --git a/packages/animations/lib/src/fade_scale_transition.dart b/packages/animations/lib/src/fade_scale_transition.dart index b118c8e2b44..9c525ea7f6c 100644 --- a/packages/animations/lib/src/fade_scale_transition.dart +++ b/packages/animations/lib/src/fade_scale_transition.dart @@ -137,29 +137,23 @@ class FadeScaleTransition extends StatelessWidget { Widget build(BuildContext context) { return DualTransitionBuilder( animation: animation, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: _fadeInTransition.animate(animation), - child: ScaleTransition( - scale: _scaleInTransition.animate(animation), - child: child, - ), - ); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: _fadeOutTransition.animate(animation), - child: child, - ); - }, + forwardBuilder: + (BuildContext context, Animation animation, Widget? child) { + return FadeTransition( + opacity: _fadeInTransition.animate(animation), + child: ScaleTransition( + scale: _scaleInTransition.animate(animation), + child: child, + ), + ); + }, + reverseBuilder: + (BuildContext context, Animation animation, Widget? child) { + return FadeTransition( + opacity: _fadeOutTransition.animate(animation), + child: child, + ); + }, child: child, ); } diff --git a/packages/animations/lib/src/fade_through_transition.dart b/packages/animations/lib/src/fade_through_transition.dart index 9acc9fe722f..61a8cb59fa7 100644 --- a/packages/animations/lib/src/fade_through_transition.dart +++ b/packages/animations/lib/src/fade_through_transition.dart @@ -222,20 +222,14 @@ class _ZoomedFadeInFadeOut extends StatelessWidget { Widget build(BuildContext context) { return DualTransitionBuilder( animation: animation, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _ZoomedFadeIn(animation: animation, child: child); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _FadeOut(animation: animation, child: child); - }, + forwardBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _ZoomedFadeIn(animation: animation, child: child); + }, + reverseBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _FadeOut(animation: animation, child: child); + }, child: child, ); } diff --git a/packages/animations/lib/src/open_container.dart b/packages/animations/lib/src/open_container.dart index 33aff2435c1..31d92276508 100644 --- a/packages/animations/lib/src/open_container.dart +++ b/packages/animations/lib/src/open_container.dart @@ -279,28 +279,29 @@ class _OpenContainerState extends State> { Future openContainer() async { final Color middleColor = widget.middleColor ?? Theme.of(context).canvasColor; - final T? data = await Navigator.of( - context, - rootNavigator: widget.useRootNavigator, - ).push( - _OpenContainerRoute( - closedColor: widget.closedColor, - openColor: widget.openColor, - middleColor: middleColor, - closedElevation: widget.closedElevation, - openElevation: widget.openElevation, - closedShape: widget.closedShape, - openShape: widget.openShape, - closedBuilder: widget.closedBuilder, - openBuilder: widget.openBuilder, - hideableKey: _hideableKey, - closedBuilderKey: _closedBuilderKey, - transitionDuration: widget.transitionDuration, - transitionType: widget.transitionType, - useRootNavigator: widget.useRootNavigator, - routeSettings: widget.routeSettings, - ), - ); + final T? data = + await Navigator.of( + context, + rootNavigator: widget.useRootNavigator, + ).push( + _OpenContainerRoute( + closedColor: widget.closedColor, + openColor: widget.openColor, + middleColor: middleColor, + closedElevation: widget.closedElevation, + openElevation: widget.openElevation, + closedShape: widget.closedShape, + openShape: widget.openShape, + closedBuilder: widget.closedBuilder, + openBuilder: widget.openBuilder, + hideableKey: _hideableKey, + closedBuilderKey: _closedBuilderKey, + transitionDuration: widget.transitionDuration, + transitionType: widget.transitionType, + useRootNavigator: widget.useRootNavigator, + routeSettings: widget.routeSettings, + ), + ); if (widget.onClosed != null) { widget.onClosed!(data); } @@ -738,8 +739,9 @@ class _OpenContainerRoute extends ModalRoute { final Animation curvedAnimation = CurvedAnimation( parent: animation, curve: Curves.fastOutSlowIn, - reverseCurve: - _transitionWasInterrupted ? null : Curves.fastOutSlowIn.flipped, + reverseCurve: _transitionWasInterrupted + ? null + : Curves.fastOutSlowIn.flipped, ); TweenSequence? colorTween; TweenSequence? closedOpacityTween, openOpacityTween; @@ -800,23 +802,20 @@ class _OpenContainerRoute extends ModalRoute { height: _rectTween.begin!.height, child: (hideableKey.currentState?.isInTree ?? false) - ? null - : FadeTransition( - opacity: closedOpacityTween!.animate( - animation, - ), - child: Builder( - key: closedBuilderKey, - builder: (BuildContext context) { - // Use dummy "open container" callback - // since we are in the process of opening. - return closedBuilder( - context, - () {}, - ); - }, - ), + ? null + : FadeTransition( + opacity: closedOpacityTween!.animate( + animation, + ), + child: Builder( + key: closedBuilderKey, + builder: (BuildContext context) { + // Use dummy "open container" callback + // since we are in the process of opening. + return closedBuilder(context, () {}); + }, ), + ), ), ), diff --git a/packages/animations/lib/src/shared_axis_transition.dart b/packages/animations/lib/src/shared_axis_transition.dart index a199a3c457b..f361f79cd14 100644 --- a/packages/animations/lib/src/shared_axis_transition.dart +++ b/packages/animations/lib/src/shared_axis_transition.dart @@ -233,56 +233,44 @@ class SharedAxisTransition extends StatelessWidget { final Color color = fillColor ?? Theme.of(context).canvasColor; return DualTransitionBuilder( animation: animation, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _EnterTransition( - animation: animation, - transitionType: transitionType, - child: child, - ); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _ExitTransition( - animation: animation, - transitionType: transitionType, - reverse: true, - fillColor: color, - child: child, - ); - }, + forwardBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _EnterTransition( + animation: animation, + transitionType: transitionType, + child: child, + ); + }, + reverseBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _ExitTransition( + animation: animation, + transitionType: transitionType, + reverse: true, + fillColor: color, + child: child, + ); + }, child: DualTransitionBuilder( animation: ReverseAnimation(secondaryAnimation), - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _EnterTransition( - animation: animation, - transitionType: transitionType, - reverse: true, - child: child, - ); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return _ExitTransition( - animation: animation, - transitionType: transitionType, - fillColor: color, - child: child, - ); - }, + forwardBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _EnterTransition( + animation: animation, + transitionType: transitionType, + reverse: true, + child: child, + ); + }, + reverseBuilder: + (BuildContext context, Animation animation, Widget? child) { + return _ExitTransition( + animation: animation, + transitionType: transitionType, + fillColor: color, + child: child, + ); + }, child: child, ), ); diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml index 96a682100af..00bbe44a805 100644 --- a/packages/animations/pubspec.yaml +++ b/packages/animations/pubspec.yaml @@ -2,11 +2,11 @@ name: animations description: Fancy pre-built animations that can easily be integrated into any Flutter application. repository: https://github.com/flutter/packages/tree/main/packages/animations issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+animations%22 -version: 2.0.11 +version: 2.1.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/animations/test/dual_transition_builder_test.dart b/packages/animations/test/dual_transition_builder_test.dart index 93e7d8d4135..c8fd4cea946 100644 --- a/packages/animations/test/dual_transition_builder_test.dart +++ b/packages/animations/test/dual_transition_builder_test.dart @@ -16,23 +16,28 @@ void main() { Center( child: DualTransitionBuilder( animation: controller, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return ScaleTransition(scale: animation, child: child); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: Tween(begin: 1.0, end: 0.0).animate(animation), - child: child, - ); - }, + forwardBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return ScaleTransition(scale: animation, child: child); + }, + reverseBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return FadeTransition( + opacity: Tween( + begin: 1.0, + end: 0.0, + ).animate(animation), + child: child, + ); + }, child: Container(color: Colors.green, height: 100, width: 100), ), ), @@ -81,23 +86,28 @@ void main() { child: Center( child: DualTransitionBuilder( animation: controller, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return ScaleTransition(scale: animation, child: child); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: Tween(begin: 1.0, end: 0.0).animate(animation), - child: child, - ); - }, + forwardBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return ScaleTransition(scale: animation, child: child); + }, + reverseBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return FadeTransition( + opacity: Tween( + begin: 1.0, + end: 0.0, + ).animate(animation), + child: child, + ); + }, child: const _StatefulTestWidget(name: 'Foo'), ), ), @@ -144,23 +154,28 @@ void main() { Center( child: DualTransitionBuilder( animation: controller, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return ScaleTransition(scale: animation, child: child); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: Tween(begin: 1.0, end: 0.0).animate(animation), - child: child, - ); - }, + forwardBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return ScaleTransition(scale: animation, child: child); + }, + reverseBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return FadeTransition( + opacity: Tween( + begin: 1.0, + end: 0.0, + ).animate(animation), + child: child, + ); + }, child: Container(color: Colors.green, height: 100, width: 100), ), ), @@ -206,23 +221,28 @@ void main() { Center( child: DualTransitionBuilder( animation: controller, - forwardBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return ScaleTransition(scale: animation, child: child); - }, - reverseBuilder: ( - BuildContext context, - Animation animation, - Widget? child, - ) { - return FadeTransition( - opacity: Tween(begin: 1.0, end: 0.0).animate(animation), - child: child, - ); - }, + forwardBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return ScaleTransition(scale: animation, child: child); + }, + reverseBuilder: + ( + BuildContext context, + Animation animation, + Widget? child, + ) { + return FadeTransition( + opacity: Tween( + begin: 1.0, + end: 0.0, + ).animate(animation), + child: child, + ); + }, child: Container(color: Colors.green, height: 100, width: 100), ), ), diff --git a/packages/animations/test/fade_through_transition_test.dart b/packages/animations/test/fade_through_transition_test.dart index f84e5abb13f..82d26b6e552 100644 --- a/packages/animations/test/fade_through_transition_test.dart +++ b/packages/animations/test/fade_through_transition_test.dart @@ -472,9 +472,9 @@ class _TestWidget extends StatelessWidget { return contentBuilder != null ? contentBuilder!(settings) : Center( - key: ValueKey(settings.name), - child: Text(settings.name!), - ); + key: ValueKey(settings.name), + child: Text(settings.name!), + ); }, ); }, diff --git a/packages/animations/test/modal_test.dart b/packages/animations/test/modal_test.dart index e89b663fee1..2f3bbe90182 100644 --- a/packages/animations/test/modal_test.dart +++ b/packages/animations/test/modal_test.dart @@ -464,8 +464,9 @@ void main() { // Expect the last route pushed to the navigator to contain RouteSettings // equal to the RouteSettings passed to showModal - final ModalRoute modalRoute = - ModalRoute.of(tester.element(find.byType(_FlutterLogoModal)))!; + final ModalRoute modalRoute = ModalRoute.of( + tester.element(find.byType(_FlutterLogoModal)), + )!; expect(modalRoute.settings, routeSettings); }); diff --git a/packages/animations/test/open_container_test.dart b/packages/animations/test/open_container_test.dart index fb674952d5c..2897c806f81 100644 --- a/packages/animations/test/open_container_test.dart +++ b/packages/animations/test/open_container_test.dart @@ -1508,15 +1508,13 @@ void main() { closedBuilder: (BuildContext context, VoidCallback action) { return GestureDetector(onTap: action, child: const Text('Closed')); }, - openBuilder: ( - BuildContext context, - CloseContainerActionCallback action, - ) { - return GestureDetector( - onTap: () => action(returnValue: true), - child: const Text('Open'), - ); - }, + openBuilder: + (BuildContext context, CloseContainerActionCallback action) { + return GestureDetector( + onTap: () => action(returnValue: true), + child: const Text('Open'), + ); + }, ); await tester.pumpWidget(_boilerplate(child: openContainer)); @@ -1548,23 +1546,20 @@ void main() { closedBuilder: (BuildContext context, VoidCallback action) { return Text('Close', key: closedBuilderKey); }, - openBuilder: ( - BuildContext context, - CloseContainerActionCallback action, - ) { - return const Text('Open'); - }, + openBuilder: + (BuildContext context, CloseContainerActionCallback action) { + return const Text('Open'); + }, ); await tester.pumpWidget(_boilerplate(child: openContainer)); - final Finder closedBuilderMaterial = - find - .ancestor( - of: find.byKey(closedBuilderKey), - matching: find.byType(Material), - ) - .first; + final Finder closedBuilderMaterial = find + .ancestor( + of: find.byKey(closedBuilderKey), + matching: find.byType(Material), + ) + .first; final Material material = tester.widget(closedBuilderMaterial); expect(material.clipBehavior, Clip.antiAlias); @@ -1576,24 +1571,21 @@ void main() { closedBuilder: (BuildContext context, VoidCallback action) { return Text('Close', key: closedBuilderKey); }, - openBuilder: ( - BuildContext context, - CloseContainerActionCallback action, - ) { - return const Text('Open'); - }, + openBuilder: + (BuildContext context, CloseContainerActionCallback action) { + return const Text('Open'); + }, clipBehavior: Clip.none, ); await tester.pumpWidget(_boilerplate(child: openContainer)); - final Finder closedBuilderMaterial = - find - .ancestor( - of: find.byKey(closedBuilderKey), - matching: find.byType(Material), - ) - .first; + final Finder closedBuilderMaterial = find + .ancestor( + of: find.byKey(closedBuilderKey), + matching: find.byType(Material), + ) + .first; final Material material = tester.widget(closedBuilderMaterial); expect(material.clipBehavior, Clip.none); @@ -1777,8 +1769,9 @@ void main() { // Expect the last route pushed to the navigator to contain RouteSettings // equal to the RouteSettings passed to the OpenContainer - final ModalRoute modalRoute = - ModalRoute.of(tester.element(find.text('Open')))!; + final ModalRoute modalRoute = ModalRoute.of( + tester.element(find.text('Open')), + )!; expect(modalRoute.settings, routeSettings); }); } @@ -1891,35 +1884,34 @@ class __RemoveOpenContainerExampleState return removeOpenContainerWidget ? const Text('Container has been removed') : OpenContainer( - closedBuilder: - (BuildContext context, VoidCallback action) => Column( - children: [ - const Text('Closed'), - ElevatedButton( - onPressed: action, - child: const Text('Open the container'), - ), - ], - ), - openBuilder: - (BuildContext context, VoidCallback action) => Column( - children: [ - const Text('Open'), - ElevatedButton( - onPressed: action, - child: const Text('Close the container'), - ), - ElevatedButton( - onPressed: () { - setState(() { - removeOpenContainerWidget = true; - }); - }, - child: const Text('Remove the container'), - ), - ], - ), - ); + closedBuilder: (BuildContext context, VoidCallback action) => + Column( + children: [ + const Text('Closed'), + ElevatedButton( + onPressed: action, + child: const Text('Open the container'), + ), + ], + ), + openBuilder: (BuildContext context, VoidCallback action) => Column( + children: [ + const Text('Open'), + ElevatedButton( + onPressed: action, + child: const Text('Close the container'), + ), + ElevatedButton( + onPressed: () { + setState(() { + removeOpenContainerWidget = true; + }); + }, + child: const Text('Remove the container'), + ), + ], + ), + ); } } diff --git a/packages/animations/test/shared_axis_transition_test.dart b/packages/animations/test/shared_axis_transition_test.dart index f251e21002a..db861390a6f 100644 --- a/packages/animations/test/shared_axis_transition_test.dart +++ b/packages/animations/test/shared_axis_transition_test.dart @@ -517,13 +517,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -534,13 +533,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -562,13 +560,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -579,13 +576,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1171,13 +1167,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1188,13 +1183,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1216,13 +1210,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1233,13 +1226,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1715,13 +1707,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1732,13 +1723,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1760,13 +1750,12 @@ void main() { ); expect(find.text(bottomRoute), findsOneWidget); - Finder fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/')), - ) - .last; + Finder fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1777,13 +1766,12 @@ void main() { await tester.pump(); await tester.pumpAndSettle(); - fillContainerFinder = - find - .ancestor( - matching: find.byType(ColoredBox), - of: find.byKey(const ValueKey('/a')), - ) - .last; + fillContainerFinder = find + .ancestor( + matching: find.byType(ColoredBox), + of: find.byKey(const ValueKey('/a')), + ) + .last; expect(fillContainerFinder, findsOneWidget); expect( tester.widget(fillContainerFinder).color, @@ -1956,9 +1944,9 @@ class _TestWidget extends StatelessWidget { return contentBuilder != null ? contentBuilder!(settings) : Center( - key: ValueKey(settings.name), - child: Text(settings.name!), - ); + key: ValueKey(settings.name), + child: Text(settings.name!), + ); }, ); }, diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md index 737a601ac7c..265fce5e59f 100644 --- a/packages/camera/camera_android/CHANGELOG.md +++ b/packages/camera/camera_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.11 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 0.10.10+8 * Restores compileSdk version to flutter.compileSdkVersion. diff --git a/packages/camera/camera_android/android/build.gradle b/packages/camera/camera_android/android/build.gradle index fc5cef29083..3f521d2c800 100644 --- a/packages/camera/camera_android/android/build.gradle +++ b/packages/camera/camera_android/android/build.gradle @@ -43,8 +43,8 @@ buildFeatures { disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions { diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index c9dc7d3ee8c..4b62d4aa71d 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.10+8 +version: 0.10.11 environment: sdk: ^3.9.0 diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index dc1f168e948..73f271aefc3 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.6.24 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 0.6.23 * Converts NV21-compatible streamed images to NV21 when requested. In doing so, diff --git a/packages/camera/camera_android_camerax/android/build.gradle b/packages/camera/camera_android_camerax/android/build.gradle index 2194285e5c9..9cf212db7e6 100644 --- a/packages/camera/camera_android_camerax/android/build.gradle +++ b/packages/camera/camera_android_camerax/android/build.gradle @@ -30,13 +30,13 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { // This must match the Java version provided in compileOptions. - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } defaultConfig { diff --git a/packages/camera/camera_android_camerax/example/android/app/build.gradle b/packages/camera/camera_android_camerax/example/android/app/build.gradle index cf978c3685e..c622ae4f9de 100644 --- a/packages/camera/camera_android_camerax/example/android/app/build.gradle +++ b/packages/camera/camera_android_camerax/example/android/app/build.gradle @@ -28,13 +28,13 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { // This must match the Java version provided in compileOptions. - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } defaultConfig { diff --git a/packages/camera/camera_android_camerax/example/integration_test/integration_test.dart b/packages/camera/camera_android_camerax/example/integration_test/integration_test.dart index 904e7491e38..93de4ea42f9 100644 --- a/packages/camera/camera_android_camerax/example/integration_test/integration_test.dart +++ b/packages/camera/camera_android_camerax/example/integration_test/integration_test.dart @@ -48,8 +48,9 @@ void main() { testWidgets('availableCameras only supports valid back or front cameras', ( WidgetTester tester, ) async { - final List availableCameras = - await CameraPlatform.instance.availableCameras(); + final List availableCameras = await CameraPlatform + .instance + .availableCameras(); for (final CameraDescription cameraDescription in availableCameras) { expect( @@ -63,8 +64,8 @@ void main() { testWidgets('Preview takes expected resolution from preset', ( WidgetTester tester, ) async { - final List cameras = - await CameraPlatform.instance.availableCameras(); + final List cameras = await CameraPlatform.instance + .availableCameras(); if (cameras.isEmpty) { return; } @@ -104,8 +105,8 @@ void main() { testWidgets('Images from streaming have expected resolution from preset', ( WidgetTester tester, ) async { - final List cameras = - await CameraPlatform.instance.availableCameras(); + final List cameras = await CameraPlatform.instance + .availableCameras(); if (cameras.isEmpty) { return; } diff --git a/packages/camera/camera_android_camerax/example/lib/camera_controller.dart b/packages/camera/camera_android_camerax/example/lib/camera_controller.dart index d66f321538e..2974dbe64ee 100644 --- a/packages/camera/camera_android_camerax/example/lib/camera_controller.dart +++ b/packages/camera/camera_android_camerax/example/lib/camera_controller.dart @@ -187,20 +187,17 @@ class CameraValue { exposurePointSupported ?? this.exposurePointSupported, focusPointSupported: focusPointSupported ?? this.focusPointSupported, deviceOrientation: deviceOrientation ?? this.deviceOrientation, - lockedCaptureOrientation: - lockedCaptureOrientation == null - ? this.lockedCaptureOrientation - : lockedCaptureOrientation.orNull, - recordingOrientation: - recordingOrientation == null - ? this.recordingOrientation - : recordingOrientation.orNull, + lockedCaptureOrientation: lockedCaptureOrientation == null + ? this.lockedCaptureOrientation + : lockedCaptureOrientation.orNull, + recordingOrientation: recordingOrientation == null + ? this.recordingOrientation + : recordingOrientation.orNull, isPreviewPaused: isPreviewPaused ?? this.isPreviewPaused, description: description ?? this.description, - previewPauseOrientation: - previewPauseOrientation == null - ? this.previewPauseOrientation - : previewPauseOrientation.orNull, + previewPauseOrientation: previewPauseOrientation == null + ? this.previewPauseOrientation + : previewPauseOrientation.orNull, ); } diff --git a/packages/camera/camera_android_camerax/example/lib/camera_preview.dart b/packages/camera/camera_android_camerax/example/lib/camera_preview.dart index b24c38e0bf5..54d5b43a240 100644 --- a/packages/camera/camera_android_camerax/example/lib/camera_preview.dart +++ b/packages/camera/camera_android_camerax/example/lib/camera_preview.dart @@ -23,24 +23,23 @@ class CameraPreview extends StatelessWidget { Widget build(BuildContext context) { return controller.value.isInitialized ? ValueListenableBuilder( - valueListenable: controller, - builder: (BuildContext context, Object? value, Widget? child) { - return AspectRatio( - aspectRatio: - _isLandscape() - ? controller.value.aspectRatio - : (1 / controller.value.aspectRatio), - child: Stack( - fit: StackFit.expand, - children: [ - _wrapInRotatedBox(child: controller.buildPreview()), - child ?? Container(), - ], - ), - ); - }, - child: child, - ) + valueListenable: controller, + builder: (BuildContext context, Object? value, Widget? child) { + return AspectRatio( + aspectRatio: _isLandscape() + ? controller.value.aspectRatio + : (1 / controller.value.aspectRatio), + child: Stack( + fit: StackFit.expand, + children: [ + _wrapInRotatedBox(child: controller.buildPreview()), + child ?? Container(), + ], + ), + ); + }, + child: child, + ) : Container(); } @@ -73,7 +72,7 @@ class CameraPreview extends StatelessWidget { return controller.value.isRecordingVideo ? controller.value.recordingOrientation! : (controller.value.previewPauseOrientation ?? - controller.value.lockedCaptureOrientation ?? - controller.value.deviceOrientation); + controller.value.lockedCaptureOrientation ?? + controller.value.deviceOrientation); } } diff --git a/packages/camera/camera_android_camerax/example/lib/main.dart b/packages/camera/camera_android_camerax/example/lib/main.dart index 55a689cdeaf..d67f4412ec0 100644 --- a/packages/camera/camera_android_camerax/example/lib/main.dart +++ b/packages/camera/camera_android_camerax/example/lib/main.dart @@ -141,8 +141,8 @@ class _CameraExampleHomeState extends State border: Border.all( color: controller != null && controller!.value.isRecordingVideo - ? Colors.redAccent - : Colors.grey, + ? Colors.redAccent + : Colors.grey, width: 3.0, ), ), @@ -190,9 +190,8 @@ class _CameraExampleHomeState extends State behavior: HitTestBehavior.opaque, onScaleStart: _handleScaleStart, onScaleUpdate: _handleScaleUpdate, - onTapDown: - (TapDownDetails details) => - onViewFinderTap(details, constraints), + onTapDown: (TapDownDetails details) => + onViewFinderTap(details, constraints), ); }, ), @@ -235,28 +234,26 @@ class _CameraExampleHomeState extends State SizedBox( width: 64.0, height: 64.0, - child: - (localVideoController == null) - ? ( - // The captured image on the web contains a network-accessible URL - // pointing to a location within the browser. It may be displayed - // either with Image.network or Image.memory after loading the image - // bytes to memory. - kIsWeb - ? Image.network(imageFile!.path) - : Image.file(File(imageFile!.path))) - : Container( - decoration: BoxDecoration( - border: Border.all(color: Colors.pink), - ), - child: Center( - child: AspectRatio( - aspectRatio: - localVideoController.value.aspectRatio, - child: VideoPlayer(localVideoController), - ), + child: (localVideoController == null) + ? ( + // The captured image on the web contains a network-accessible URL + // pointing to a location within the browser. It may be displayed + // either with Image.network or Image.memory after loading the image + // bytes to memory. + kIsWeb + ? Image.network(imageFile!.path) + : Image.file(File(imageFile!.path))) + : Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.pink), + ), + child: Center( + child: AspectRatio( + aspectRatio: localVideoController.value.aspectRatio, + child: VideoPlayer(localVideoController), ), ), + ), ), ], ), @@ -279,19 +276,21 @@ class _CameraExampleHomeState extends State // The exposure and focus mode are currently not supported on the web. ...!kIsWeb ? [ - IconButton( - icon: const Icon(Icons.exposure), - color: Colors.blue, - onPressed: - controller != null ? onExposureModeButtonPressed : null, - ), - IconButton( - icon: const Icon(Icons.filter_center_focus), - color: Colors.blue, - onPressed: - controller != null ? onFocusModeButtonPressed : null, - ), - ] + IconButton( + icon: const Icon(Icons.exposure), + color: Colors.blue, + onPressed: controller != null + ? onExposureModeButtonPressed + : null, + ), + IconButton( + icon: const Icon(Icons.filter_center_focus), + color: Colors.blue, + onPressed: controller != null + ? onFocusModeButtonPressed + : null, + ), + ] : [], IconButton( icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute), @@ -305,10 +304,9 @@ class _CameraExampleHomeState extends State : Icons.screen_rotation, ), color: Colors.blue, - onPressed: - controller != null - ? onCaptureOrientationLockButtonPressed - : null, + onPressed: controller != null + ? onCaptureOrientationLockButtonPressed + : null, ), ], ), @@ -328,47 +326,39 @@ class _CameraExampleHomeState extends State children: [ IconButton( icon: const Icon(Icons.flash_off), - color: - controller?.value.flashMode == FlashMode.off - ? Colors.orange - : Colors.blue, - onPressed: - controller != null - ? () => onSetFlashModeButtonPressed(FlashMode.off) - : null, + color: controller?.value.flashMode == FlashMode.off + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.off) + : null, ), IconButton( icon: const Icon(Icons.flash_auto), - color: - controller?.value.flashMode == FlashMode.auto - ? Colors.orange - : Colors.blue, - onPressed: - controller != null - ? () => onSetFlashModeButtonPressed(FlashMode.auto) - : null, + color: controller?.value.flashMode == FlashMode.auto + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.auto) + : null, ), IconButton( icon: const Icon(Icons.flash_on), - color: - controller?.value.flashMode == FlashMode.always - ? Colors.orange - : Colors.blue, - onPressed: - controller != null - ? () => onSetFlashModeButtonPressed(FlashMode.always) - : null, + color: controller?.value.flashMode == FlashMode.always + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.always) + : null, ), IconButton( icon: const Icon(Icons.highlight), - color: - controller?.value.flashMode == FlashMode.torch - ? Colors.orange - : Colors.blue, - onPressed: - controller != null - ? () => onSetFlashModeButtonPressed(FlashMode.torch) - : null, + color: controller?.value.flashMode == FlashMode.torch + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.torch) + : null, ), ], ), @@ -378,16 +368,14 @@ class _CameraExampleHomeState extends State Widget _exposureModeControlRowWidget() { final ButtonStyle styleAuto = TextButton.styleFrom( - foregroundColor: - controller?.value.exposureMode == ExposureMode.auto - ? Colors.orange - : Colors.blue, + foregroundColor: controller?.value.exposureMode == ExposureMode.auto + ? Colors.orange + : Colors.blue, ); final ButtonStyle styleLocked = TextButton.styleFrom( - foregroundColor: - controller?.value.exposureMode == ExposureMode.locked - ? Colors.orange - : Colors.blue, + foregroundColor: controller?.value.exposureMode == ExposureMode.locked + ? Colors.orange + : Colors.blue, ); return SizeTransition( @@ -403,12 +391,10 @@ class _CameraExampleHomeState extends State children: [ TextButton( style: styleAuto, - onPressed: - controller != null - ? () => onSetExposureModeButtonPressed( - ExposureMode.auto, - ) - : null, + onPressed: controller != null + ? () => + onSetExposureModeButtonPressed(ExposureMode.auto) + : null, onLongPress: () { if (controller != null) { CameraPlatform.instance.setExposurePoint( @@ -422,20 +408,18 @@ class _CameraExampleHomeState extends State ), TextButton( style: styleLocked, - onPressed: - controller != null - ? () => onSetExposureModeButtonPressed( - ExposureMode.locked, - ) - : null, + onPressed: controller != null + ? () => onSetExposureModeButtonPressed( + ExposureMode.locked, + ) + : null, child: const Text('LOCKED'), ), TextButton( style: styleLocked, - onPressed: - controller != null - ? () => controller!.setExposureOffset(0.0) - : null, + onPressed: controller != null + ? () => controller!.setExposureOffset(0.0) + : null, child: const Text('RESET OFFSET'), ), ], @@ -453,9 +437,9 @@ class _CameraExampleHomeState extends State onChanged: (_) {}, onChangeEnd: _minAvailableExposureOffset == - _maxAvailableExposureOffset - ? null - : setExposureOffset, + _maxAvailableExposureOffset + ? null + : setExposureOffset, ), Text(_maxAvailableExposureOffset.toString()), ], @@ -469,16 +453,14 @@ class _CameraExampleHomeState extends State Widget _focusModeControlRowWidget() { final ButtonStyle styleAuto = TextButton.styleFrom( - foregroundColor: - controller?.value.focusMode == FocusMode.auto - ? Colors.orange - : Colors.blue, + foregroundColor: controller?.value.focusMode == FocusMode.auto + ? Colors.orange + : Colors.blue, ); final ButtonStyle styleLocked = TextButton.styleFrom( - foregroundColor: - controller?.value.focusMode == FocusMode.locked - ? Colors.orange - : Colors.blue, + foregroundColor: controller?.value.focusMode == FocusMode.locked + ? Colors.orange + : Colors.blue, ); return SizeTransition( @@ -494,10 +476,9 @@ class _CameraExampleHomeState extends State children: [ TextButton( style: styleAuto, - onPressed: - controller != null - ? () => onSetFocusModeButtonPressed(FocusMode.auto) - : null, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.auto) + : null, onLongPress: () { if (controller != null) { CameraPlatform.instance.setFocusPoint( @@ -511,11 +492,9 @@ class _CameraExampleHomeState extends State ), TextButton( style: styleLocked, - onPressed: - controller != null - ? () => - onSetFocusModeButtonPressed(FocusMode.locked) - : null, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.locked) + : null, child: const Text('LOCKED'), ), ], @@ -539,23 +518,24 @@ class _CameraExampleHomeState extends State color: Colors.blue, onPressed: cameraController != null && - cameraController.value.isInitialized && - !cameraController.value.isRecordingVideo - ? onTakePictureButtonPressed - : null, + cameraController.value.isInitialized && + !cameraController.value.isRecordingVideo + ? onTakePictureButtonPressed + : null, ), IconButton( icon: const Icon(Icons.videocam), color: Colors.blue, - onPressed: - cameraController == null ? null : onVideoRecordButtonPressed, + onPressed: cameraController == null + ? null + : onVideoRecordButtonPressed, ), IconButton( icon: cameraController != null && - cameraController.value.isRecordingPaused - ? const Icon(Icons.play_arrow) - : const Icon(Icons.pause), + cameraController.value.isRecordingPaused + ? const Icon(Icons.play_arrow) + : const Icon(Icons.pause), color: Colors.blue, onPressed: () { if (cameraController == null) { @@ -576,10 +556,11 @@ class _CameraExampleHomeState extends State icon: const Icon(Icons.pause_presentation), color: cameraController != null && cameraController.value.isPreviewPaused - ? Colors.red - : Colors.blue, - onPressed: - cameraController == null ? null : onPausePreviewButtonPressed, + ? Colors.red + : Colors.blue, + onPressed: cameraController == null + ? null + : onPausePreviewButtonPressed, ), ], ); @@ -687,13 +668,13 @@ class _CameraExampleHomeState extends State // The exposure mode is currently not supported on the web. ...!kIsWeb ? >[ - cameraController.getMinExposureOffset().then( - (double value) => _minAvailableExposureOffset = value, - ), - cameraController.getMaxExposureOffset().then( - (double value) => _maxAvailableExposureOffset = value, - ), - ] + cameraController.getMinExposureOffset().then( + (double value) => _minAvailableExposureOffset = value, + ), + cameraController.getMaxExposureOffset().then( + (double value) => _maxAvailableExposureOffset = value, + ), + ] : >[], cameraController.getMaxZoomLevel().then( (double value) => _maxAvailableZoom = value, @@ -1012,10 +993,9 @@ class _CameraExampleHomeState extends State return; } - final VideoPlayerController vController = - kIsWeb - ? VideoPlayerController.networkUrl(Uri.parse(videoFile!.path)) - : VideoPlayerController.file(File(videoFile!.path)); + final VideoPlayerController vController = kIsWeb + ? VideoPlayerController.networkUrl(Uri.parse(videoFile!.path)) + : VideoPlayerController.file(File(videoFile!.path)); videoPlayerListener = () { if (videoController != null) { diff --git a/packages/camera/camera_android_camerax/example/pubspec.yaml b/packages/camera/camera_android_camerax/example/pubspec.yaml index f5238212492..81a4e079b2a 100644 --- a/packages/camera/camera_android_camerax/example/pubspec.yaml +++ b/packages/camera/camera_android_camerax/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the camera_android_camerax plugin. publish_to: 'none' environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: camera_android_camerax: diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index 311df6f2e43..12d68972dc6 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,11 +2,11 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.6.23 +version: 0.6.24 environment: - sdk: ^3.8.1 - flutter: ">=3.32.8" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md b/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md index 13720c1e0c9..28761f2dcc5 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md +++ b/packages/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 3.1.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. ## 3.0.0 diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle b/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle index 15c442e5542..74f99b1b546 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle @@ -27,8 +27,8 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { diff --git a/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index 8a297916798..7c27ce7810a 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin and googleapis. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: extension_google_sign_in_as_googleapis_auth: diff --git a/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml b/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml index c36b2a630e2..754c7b963c0 100644 --- a/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml +++ b/packages/extension_google_sign_in_as_googleapis_auth/pubspec.yaml @@ -8,11 +8,11 @@ name: extension_google_sign_in_as_googleapis_auth description: A bridge package between google_sign_in and googleapis_auth, to create Authenticated Clients from google_sign_in user credentials. repository: https://github.com/flutter/packages/tree/main/packages/extension_google_sign_in_as_googleapis_auth issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+extension_google_sign_in_as_googleapis_auth%22 -version: 3.0.0 +version: 3.1.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index 16122ff93c0..fa45c12ab43 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 1.0.4 * Updates the example app and README examples to work on iOS. diff --git a/packages/file_selector/file_selector/example/android/app/build.gradle b/packages/file_selector/file_selector/example/android/app/build.gradle index eea010a3dfe..272243c1d34 100644 --- a/packages/file_selector/file_selector/example/android/app/build.gradle +++ b/packages/file_selector/file_selector/example/android/app/build.gradle @@ -33,7 +33,7 @@ android { } kotlinOptions { - jvmTarget = '17' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/file_selector/file_selector/example/lib/home_page.dart b/packages/file_selector/file_selector/example/lib/home_page.dart index b059580ad85..76801d5fa58 100644 --- a/packages/file_selector/file_selector/example/lib/home_page.dart +++ b/packages/file_selector/file_selector/example/lib/home_page.dart @@ -64,8 +64,8 @@ class HomePage extends StatelessWidget { ElevatedButton( style: style, child: const Text('Open a get multi directories dialog'), - onPressed: - () => Navigator.pushNamed(context, '/multi-directories'), + onPressed: () => + Navigator.pushNamed(context, '/multi-directories'), ), ], ], diff --git a/packages/file_selector/file_selector/example/lib/main.dart b/packages/file_selector/file_selector/example/lib/main.dart index a2810d08c42..da38163967d 100644 --- a/packages/file_selector/file_selector/example/lib/main.dart +++ b/packages/file_selector/file_selector/example/lib/main.dart @@ -32,13 +32,13 @@ class MyApp extends StatelessWidget { home: const HomePage(), routes: { '/open/image': (BuildContext context) => const OpenImagePage(), - '/open/images': - (BuildContext context) => const OpenMultipleImagesPage(), + '/open/images': (BuildContext context) => + const OpenMultipleImagesPage(), '/open/text': (BuildContext context) => const OpenTextPage(), '/save/text': (BuildContext context) => SaveTextPage(), '/directory': (BuildContext context) => GetDirectoryPage(), - '/multi-directories': - (BuildContext context) => const GetMultipleDirectoriesPage(), + '/multi-directories': (BuildContext context) => + const GetMultipleDirectoriesPage(), }, ); } diff --git a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart index a1fd347cc1e..9f74c92f5af 100644 --- a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart @@ -83,10 +83,9 @@ class MultipleImagesDisplay extends StatelessWidget { children: [ ...files.map( (XFile file) => Flexible( - child: - kIsWeb - ? Image.network(file.path) - : Image.file(File(file.path)), + child: kIsWeb + ? Image.network(file.path) + : Image.file(File(file.path)), ), ), ], diff --git a/packages/file_selector/file_selector/example/lib/open_text_page.dart b/packages/file_selector/file_selector/example/lib/open_text_page.dart index de751fe1196..55ea3ff7d69 100644 --- a/packages/file_selector/file_selector/example/lib/open_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_text_page.dart @@ -21,8 +21,9 @@ class OpenTextPage extends StatelessWidget { // This demonstrates using an initial directory for the prompt, which should // only be done in cases where the application can likely predict where the // file would be. In most cases, this parameter should not be provided. - final String? initialDirectory = - kIsWeb ? null : (await getApplicationDocumentsDirectory()).path; + final String? initialDirectory = kIsWeb + ? null + : (await getApplicationDocumentsDirectory()).path; final XFile? file = await openFile( acceptedTypeGroups: [typeGroup], initialDirectory: initialDirectory, diff --git a/packages/file_selector/file_selector/example/lib/save_text_page.dart b/packages/file_selector/file_selector/example/lib/save_text_page.dart index 0c8d825048b..d5dcd117458 100644 --- a/packages/file_selector/file_selector/example/lib/save_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/save_text_page.dart @@ -23,10 +23,9 @@ class SaveTextPage extends StatelessWidget { // only be done in cases where the application can likely predict where the // file will be saved. In most cases, this parameter should not be provided, // and in the web, path_provider shouldn't even be called. - final String? initialDirectory = - kIsWeb - ? null - : (await path_provider.getApplicationDocumentsDirectory()).path; + final String? initialDirectory = kIsWeb + ? null + : (await path_provider.getApplicationDocumentsDirectory()).path; final FileSaveLocation? result = await getSaveLocation( initialDirectory: initialDirectory, suggestedName: fileName, diff --git a/packages/file_selector/file_selector/example/pubspec.yaml b/packages/file_selector/file_selector/example/pubspec.yaml index bd8a1c0881b..3f132c9ce8b 100644 --- a/packages/file_selector/file_selector/example/pubspec.yaml +++ b/packages/file_selector/file_selector/example/pubspec.yaml @@ -5,8 +5,8 @@ publish_to: none version: 1.0.0+1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: file_selector: diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index b3db183febe..2cbb8ca2678 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for opening and saving files, or selecting directories, using native file selection UI. repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 -version: 1.0.4 +version: 1.1.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/file_selector/file_selector/test/file_selector_test.dart b/packages/file_selector/file_selector/test/file_selector_test.dart index 6cadab026bf..9320ceb0db2 100644 --- a/packages/file_selector/file_selector/test/file_selector_test.dart +++ b/packages/file_selector/file_selector/test/file_selector_test.dart @@ -424,12 +424,11 @@ class FakeFileSelector extends Fake return path == null ? null : FileSaveLocation( - path, - activeFilter: - activeFilterIndex == null - ? null - : acceptedTypeGroups?[activeFilterIndex], - ); + path, + activeFilter: activeFilterIndex == null + ? null + : acceptedTypeGroups?[activeFilterIndex], + ); } @override diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md index f025abdf18e..53e99d8d0fa 100644 --- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md +++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.1.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.0.30 * Bumps com.android.tools.build:gradle to 8.12.1. diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle index 4aba6aa739f..753301bc516 100644 --- a/packages/flutter_plugin_android_lifecycle/android/build.gradle +++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle @@ -32,8 +32,8 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } lintOptions { diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml index bf925f75018..bfeb272f2a7 100644 --- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the flutter_plugin_android_lifecycle plugin publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index 18e7c96de49..8cf50912568 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -2,11 +2,11 @@ name: flutter_plugin_android_lifecycle description: Flutter plugin for accessing an Android Lifecycle within other plugins. repository: https://github.com/flutter/packages/tree/main/packages/flutter_plugin_android_lifecycle issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_plugin_android_lifecycle%22 -version: 2.0.30 +version: 2.1.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 5abdfcd2f0d..630ef97856f 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,8 @@ +## 16.3.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 16.2.4 - Fix Android Cold Start deep link with empty path losing scheme and authority. diff --git a/packages/go_router/doc/configuration.md b/packages/go_router/doc/configuration.md index 81be3be03d7..6f56b5959e2 100644 --- a/packages/go_router/doc/configuration.md +++ b/packages/go_router/doc/configuration.md @@ -178,18 +178,16 @@ branches: [ // The screen to display as the root in the first tab of the // bottom navigation bar. path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const RootScreen(label: 'A', detailsPath: '/a/details'), + builder: (BuildContext context, GoRouterState state) => + const RootScreen(label: 'A', detailsPath: '/a/details'), routes: [ // The details screen to display stacked on navigator of the // first tab. This will cover screen A but not the application // shell (bottom navigation bar). GoRoute( path: 'details', - builder: - (BuildContext context, GoRouterState state) => - const DetailsScreen(label: 'A'), + builder: (BuildContext context, GoRouterState state) => + const DetailsScreen(label: 'A'), ), ], ), @@ -207,17 +205,18 @@ which is passed as the last argument to the builder function. Example: ```dart StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - // Return the widget that implements the custom shell (in this case - // using a BottomNavigationBar). The StatefulNavigationShell is passed - // to be able access the state of the shell and to navigate to other - // branches in a stateful way. - return ScaffoldWithNavBar(navigationShell: navigationShell); - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + // Return the widget that implements the custom shell (in this case + // using a BottomNavigationBar). The StatefulNavigationShell is passed + // to be able access the state of the shell and to navigate to other + // branches in a stateful way. + return ScaffoldWithNavBar(navigationShell: navigationShell); + }, ``` Within the custom shell widget, the StatefulNavigationShell is first and diff --git a/packages/go_router/example/android/app/build.gradle b/packages/go_router/example/android/app/build.gradle index d9e5fd655fe..b5b67f6af7b 100644 --- a/packages/go_router/example/android/app/build.gradle +++ b/packages/go_router/example/android/app/build.gradle @@ -26,12 +26,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/go_router/example/lib/async_redirection.dart b/packages/go_router/example/lib/async_redirection.dart index 6fdc6100323..ddba52ac036 100644 --- a/packages/go_router/example/lib/async_redirection.dart +++ b/packages/go_router/example/lib/async_redirection.dart @@ -39,13 +39,13 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], @@ -89,12 +89,11 @@ class _LoginScreenState extends State @override void initState() { super.initState(); - controller = AnimationController( - vsync: this, - duration: const Duration(seconds: 1), - )..addListener(() { - setState(() {}); - }); + controller = + AnimationController(vsync: this, duration: const Duration(seconds: 1)) + ..addListener(() { + setState(() {}); + }); controller.repeat(); } diff --git a/packages/go_router/example/lib/books/main.dart b/packages/go_router/example/lib/books/main.dart index 2cba6e7bec2..8652f0dbd0e 100644 --- a/packages/go_router/example/lib/books/main.dart +++ b/packages/go_router/example/lib/books/main.dart @@ -40,8 +40,8 @@ class Bookstore extends StatelessWidget { GoRoute(path: '/', redirect: (_, __) => '/books'), GoRoute( path: '/signin', - pageBuilder: - (BuildContext context, GoRouterState state) => FadeTransitionPage( + pageBuilder: (BuildContext context, GoRouterState state) => + FadeTransitionPage( key: state.pageKey, child: SignInScreen( onSignIn: (Credentials credentials) { @@ -55,14 +55,13 @@ class Bookstore extends StatelessWidget { GoRoute(path: '/books', redirect: (_, __) => '/books/popular'), GoRoute( path: '/book/:bookId', - redirect: - (BuildContext context, GoRouterState state) => - '/books/all/${state.pathParameters['bookId']}', + redirect: (BuildContext context, GoRouterState state) => + '/books/all/${state.pathParameters['bookId']}', ), GoRoute( path: '/books/:kind(new|all|popular)', - pageBuilder: - (BuildContext context, GoRouterState state) => FadeTransitionPage( + pageBuilder: (BuildContext context, GoRouterState state) => + FadeTransitionPage( key: _scaffoldKey, child: BookstoreScaffold( selectedTab: ScaffoldTab.books, @@ -84,14 +83,13 @@ class Bookstore extends StatelessWidget { ), GoRoute( path: '/author/:authorId', - redirect: - (BuildContext context, GoRouterState state) => - '/authors/${state.pathParameters['authorId']}', + redirect: (BuildContext context, GoRouterState state) => + '/authors/${state.pathParameters['authorId']}', ), GoRoute( path: '/authors', - pageBuilder: - (BuildContext context, GoRouterState state) => FadeTransitionPage( + pageBuilder: (BuildContext context, GoRouterState state) => + FadeTransitionPage( key: _scaffoldKey, child: const BookstoreScaffold( selectedTab: ScaffoldTab.authors, @@ -113,8 +111,8 @@ class Bookstore extends StatelessWidget { ), GoRoute( path: '/settings', - pageBuilder: - (BuildContext context, GoRouterState state) => FadeTransitionPage( + pageBuilder: (BuildContext context, GoRouterState state) => + FadeTransitionPage( key: _scaffoldKey, child: const BookstoreScaffold( selectedTab: ScaffoldTab.settings, diff --git a/packages/go_router/example/lib/books/src/auth.dart b/packages/go_router/example/lib/books/src/auth.dart index dbe94cee4bb..65a9a470d98 100644 --- a/packages/go_router/example/lib/books/src/auth.dart +++ b/packages/go_router/example/lib/books/src/auth.dart @@ -40,8 +40,7 @@ class BookstoreAuthScope extends InheritedNotifier { }); /// Gets the [BookstoreAuth] above the context. - static BookstoreAuth of(BuildContext context) => - context - .dependOnInheritedWidgetOfExactType()! - .notifier!; + static BookstoreAuth of(BuildContext context) => context + .dependOnInheritedWidgetOfExactType()! + .notifier!; } diff --git a/packages/go_router/example/lib/books/src/data/library.dart b/packages/go_router/example/lib/books/src/data/library.dart index 70f2b5244aa..a211026ff5f 100644 --- a/packages/go_router/example/lib/books/src/data/library.dart +++ b/packages/go_router/example/lib/books/src/data/library.dart @@ -6,32 +6,31 @@ import 'author.dart'; import 'book.dart'; /// Library data mock. -final Library libraryInstance = - Library() - ..addBook( - title: 'Left Hand of Darkness', - authorName: 'Ursula K. Le Guin', - isPopular: true, - isNew: true, - ) - ..addBook( - title: 'Too Like the Lightning', - authorName: 'Ada Palmer', - isPopular: false, - isNew: true, - ) - ..addBook( - title: 'Kindred', - authorName: 'Octavia E. Butler', - isPopular: true, - isNew: false, - ) - ..addBook( - title: 'The Lathe of Heaven', - authorName: 'Ursula K. Le Guin', - isPopular: false, - isNew: false, - ); +final Library libraryInstance = Library() + ..addBook( + title: 'Left Hand of Darkness', + authorName: 'Ursula K. Le Guin', + isPopular: true, + isNew: true, + ) + ..addBook( + title: 'Too Like the Lightning', + authorName: 'Ada Palmer', + isPopular: false, + isNew: true, + ) + ..addBook( + title: 'Kindred', + authorName: 'Octavia E. Butler', + isPopular: true, + isNew: false, + ) + ..addBook( + title: 'The Lathe of Heaven', + authorName: 'Ursula K. Le Guin', + isPopular: false, + isNew: false, + ); /// A library that contains books and authors. class Library { diff --git a/packages/go_router/example/lib/books/src/screens/book_details.dart b/packages/go_router/example/lib/books/src/screens/book_details.dart index 72414d96ad4..83626824f2f 100644 --- a/packages/go_router/example/lib/books/src/screens/book_details.dart +++ b/packages/go_router/example/lib/books/src/screens/book_details.dart @@ -39,9 +39,8 @@ class BookDetailsScreen extends StatelessWidget { onPressed: () { Navigator.of(context).push( MaterialPageRoute( - builder: - (BuildContext context) => - AuthorDetailsScreen(author: book!.author), + builder: (BuildContext context) => + AuthorDetailsScreen(author: book!.author), ), ); }, @@ -49,8 +48,8 @@ class BookDetailsScreen extends StatelessWidget { ), Link( uri: Uri.parse('/author/${book!.author.id}'), - builder: - (BuildContext context, FollowLink? followLink) => TextButton( + builder: (BuildContext context, FollowLink? followLink) => + TextButton( onPressed: followLink, child: const Text('View author (Link)'), ), diff --git a/packages/go_router/example/lib/books/src/screens/settings.dart b/packages/go_router/example/lib/books/src/screens/settings.dart index 2d5dc28ee9e..4b0a386f243 100644 --- a/packages/go_router/example/lib/books/src/screens/settings.dart +++ b/packages/go_router/example/lib/books/src/screens/settings.dart @@ -57,11 +57,10 @@ class SettingsContent extends StatelessWidget { ), Link( uri: Uri.parse('/book/0'), - builder: - (BuildContext context, FollowLink? followLink) => TextButton( - onPressed: followLink, - child: const Text('Go directly to /book/0 (Link)'), - ), + builder: (BuildContext context, FollowLink? followLink) => TextButton( + onPressed: followLink, + child: const Text('Go directly to /book/0 (Link)'), + ), ), TextButton( onPressed: () { @@ -73,25 +72,23 @@ class SettingsContent extends StatelessWidget { (Widget w) => Padding(padding: const EdgeInsets.all(8), child: w), ), TextButton( - onPressed: - () => showDialog( - context: context, - builder: - (BuildContext context) => AlertDialog( - title: const Text('Alert!'), - content: const Text('The alert description goes here.'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, 'Cancel'), - child: const Text('Cancel'), - ), - TextButton( - onPressed: () => Navigator.pop(context, 'OK'), - child: const Text('OK'), - ), - ], - ), - ), + onPressed: () => showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Alert!'), + content: const Text('The alert description goes here.'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'Cancel'), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + ), + ), child: const Text('Show Dialog'), ), ], diff --git a/packages/go_router/example/lib/books/src/widgets/author_list.dart b/packages/go_router/example/lib/books/src/widgets/author_list.dart index 855cd5f1b37..1cfb22014e9 100644 --- a/packages/go_router/example/lib/books/src/widgets/author_list.dart +++ b/packages/go_router/example/lib/books/src/widgets/author_list.dart @@ -20,11 +20,10 @@ class AuthorList extends StatelessWidget { @override Widget build(BuildContext context) => ListView.builder( itemCount: authors.length, - itemBuilder: - (BuildContext context, int index) => ListTile( - title: Text(authors[index].name), - subtitle: Text('${authors[index].books.length} books'), - onTap: onTap != null ? () => onTap!(authors[index]) : null, - ), + itemBuilder: (BuildContext context, int index) => ListTile( + title: Text(authors[index].name), + subtitle: Text('${authors[index].books.length} books'), + onTap: onTap != null ? () => onTap!(authors[index]) : null, + ), ); } diff --git a/packages/go_router/example/lib/books/src/widgets/book_list.dart b/packages/go_router/example/lib/books/src/widgets/book_list.dart index 330e4b2e983..3c78b665591 100644 --- a/packages/go_router/example/lib/books/src/widgets/book_list.dart +++ b/packages/go_router/example/lib/books/src/widgets/book_list.dart @@ -20,11 +20,10 @@ class BookList extends StatelessWidget { @override Widget build(BuildContext context) => ListView.builder( itemCount: books.length, - itemBuilder: - (BuildContext context, int index) => ListTile( - title: Text(books[index].title), - subtitle: Text(books[index].author.name), - onTap: onTap != null ? () => onTap!(books[index]) : null, - ), + itemBuilder: (BuildContext context, int index) => ListTile( + title: Text(books[index].title), + subtitle: Text(books[index].author.name), + onTap: onTap != null ? () => onTap!(books[index]) : null, + ), ); } diff --git a/packages/go_router/example/lib/extra_codec.dart b/packages/go_router/example/lib/extra_codec.dart index 5684b83f135..5667986dd01 100644 --- a/packages/go_router/example/lib/extra_codec.dart +++ b/packages/go_router/example/lib/extra_codec.dart @@ -15,8 +15,8 @@ final GoRouter _router = GoRouter( routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), ], extraCodec: const MyExtraCodec(), diff --git a/packages/go_router/example/lib/named_routes.dart b/packages/go_router/example/lib/named_routes.dart index 41d461b47a0..4223486f019 100644 --- a/packages/go_router/example/lib/named_routes.dart +++ b/packages/go_router/example/lib/named_routes.dart @@ -77,15 +77,14 @@ class App extends StatelessWidget { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(fid: state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(fid: state.pathParameters['fid']!), routes: [ GoRoute( name: 'person', @@ -119,13 +118,12 @@ class HomeScreen extends StatelessWidget { for (final MapEntry entry in _families.entries) ListTile( title: Text(entry.value.name), - onTap: - () => context.go( - context.namedLocation( - 'family', - pathParameters: {'fid': entry.key}, - ), - ), + onTap: () => context.go( + context.namedLocation( + 'family', + pathParameters: {'fid': entry.key}, + ), + ), ), ], ), @@ -151,17 +149,16 @@ class FamilyScreen extends StatelessWidget { for (final MapEntry entry in people.entries) ListTile( title: Text(entry.value.name), - onTap: - () => context.go( - context.namedLocation( - 'person', - pathParameters: { - 'fid': fid, - 'pid': entry.key, - }, - queryParameters: {'qid': 'quid'}, - ), - ), + onTap: () => context.go( + context.namedLocation( + 'person', + pathParameters: { + 'fid': fid, + 'pid': entry.key, + }, + queryParameters: {'qid': 'quid'}, + ), + ), ), ], ), diff --git a/packages/go_router/example/lib/others/custom_stateful_shell_route.dart b/packages/go_router/example/lib/others/custom_stateful_shell_route.dart index 78a84868b9d..0755d2bf330 100644 --- a/packages/go_router/example/lib/others/custom_stateful_shell_route.dart +++ b/packages/go_router/example/lib/others/custom_stateful_shell_route.dart @@ -50,36 +50,38 @@ class NestedTabNavigationExampleApp extends StatelessWidget { initialLocation: '/a', routes: [ StatefulShellRoute( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - // This nested StatefulShellRoute demonstrates the use of a - // custom container for the branch Navigators. In this implementation, - // no customization is done in the builder function (navigationShell - // itself is simply used as the Widget for the route). Instead, the - // navigatorContainerBuilder function below is provided to - // customize the container for the branch Navigators. - return navigationShell; - }, - navigatorContainerBuilder: ( - BuildContext context, - StatefulNavigationShell navigationShell, - List children, - ) { - // Returning a customized container for the branch - // Navigators (i.e. the `List children` argument). - // - // See ScaffoldWithNavBar for more details on how the children - // are managed (using AnimatedBranchContainer). - return ScaffoldWithNavBar( - navigationShell: navigationShell, - children: children, - ); - // NOTE: To use a Cupertino version of ScaffoldWithNavBar, replace - // ScaffoldWithNavBar above with CupertinoScaffoldWithNavBar. - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + // This nested StatefulShellRoute demonstrates the use of a + // custom container for the branch Navigators. In this implementation, + // no customization is done in the builder function (navigationShell + // itself is simply used as the Widget for the route). Instead, the + // navigatorContainerBuilder function below is provided to + // customize the container for the branch Navigators. + return navigationShell; + }, + navigatorContainerBuilder: + ( + BuildContext context, + StatefulNavigationShell navigationShell, + List children, + ) { + // Returning a customized container for the branch + // Navigators (i.e. the `List children` argument). + // + // See ScaffoldWithNavBar for more details on how the children + // are managed (using AnimatedBranchContainer). + return ScaffoldWithNavBar( + navigationShell: navigationShell, + children: children, + ); + // NOTE: To use a Cupertino version of ScaffoldWithNavBar, replace + // ScaffoldWithNavBar above with CupertinoScaffoldWithNavBar. + }, branches: [ // The route branch for the first tab of the bottom navigation bar. StatefulShellBranch( @@ -89,18 +91,16 @@ class NestedTabNavigationExampleApp extends StatelessWidget { // The screen to display as the root in the first tab of the // bottom navigation bar. path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const RootScreenA(), + builder: (BuildContext context, GoRouterState state) => + const RootScreenA(), routes: [ // The details screen to display stacked on navigator of the // first tab. This will cover screen A but not the application // shell (bottom navigation bar). GoRoute( path: 'details', - builder: - (BuildContext context, GoRouterState state) => - const DetailsScreen(label: 'A'), + builder: (BuildContext context, GoRouterState state) => + const DetailsScreen(label: 'A'), ), ], ), @@ -120,33 +120,35 @@ class NestedTabNavigationExampleApp extends StatelessWidget { // defaultLocation: '/b1', routes: [ StatefulShellRoute( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - // Just like with the top level StatefulShellRoute, no - // customization is done in the builder function. - return navigationShell; - }, - navigatorContainerBuilder: ( - BuildContext context, - StatefulNavigationShell navigationShell, - List children, - ) { - // Returning a customized container for the branch - // Navigators (i.e. the `List children` argument). - // - // See TabbedRootScreen for more details on how the children - // are managed (in a TabBarView). - return TabbedRootScreen( - navigationShell: navigationShell, - key: tabbedRootScreenKey, - children: children, - ); - // NOTE: To use a PageView version of TabbedRootScreen, - // replace TabbedRootScreen above with PagedRootScreen. - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + // Just like with the top level StatefulShellRoute, no + // customization is done in the builder function. + return navigationShell; + }, + navigatorContainerBuilder: + ( + BuildContext context, + StatefulNavigationShell navigationShell, + List children, + ) { + // Returning a customized container for the branch + // Navigators (i.e. the `List children` argument). + // + // See TabbedRootScreen for more details on how the children + // are managed (in a TabBarView). + return TabbedRootScreen( + navigationShell: navigationShell, + key: tabbedRootScreenKey, + children: children, + ); + // NOTE: To use a PageView version of TabbedRootScreen, + // replace TabbedRootScreen above with PagedRootScreen. + }, // This bottom tab uses a nested shell, wrapping sub routes in a // top TabBar. branches: [ @@ -155,12 +157,11 @@ class NestedTabNavigationExampleApp extends StatelessWidget { routes: [ GoRoute( path: '/b1', - builder: - (BuildContext context, GoRouterState state) => - const TabScreen( - label: 'B1', - detailsPath: '/b1/details', - ), + builder: (BuildContext context, GoRouterState state) => + const TabScreen( + label: 'B1', + detailsPath: '/b1/details', + ), routes: [ GoRoute( path: 'details', @@ -183,12 +184,11 @@ class NestedTabNavigationExampleApp extends StatelessWidget { routes: [ GoRoute( path: '/b2', - builder: - (BuildContext context, GoRouterState state) => - const TabScreen( - label: 'B2', - detailsPath: '/b2/details', - ), + builder: (BuildContext context, GoRouterState state) => + const TabScreen( + label: 'B2', + detailsPath: '/b2/details', + ), routes: [ GoRoute( path: 'details', @@ -362,18 +362,17 @@ class AnimatedBranchContainer extends StatelessWidget { @override Widget build(BuildContext context) { return Stack( - children: - children.mapIndexed((int index, Widget navigator) { - return AnimatedScale( - scale: index == currentIndex ? 1 : 1.5, - duration: const Duration(milliseconds: 400), - child: AnimatedOpacity( - opacity: index == currentIndex ? 1 : 0, - duration: const Duration(milliseconds: 400), - child: _branchNavigatorWrapper(index, navigator), - ), - ); - }).toList(), + children: children.mapIndexed((int index, Widget navigator) { + return AnimatedScale( + scale: index == currentIndex ? 1 : 1.5, + duration: const Duration(milliseconds: 400), + child: AnimatedOpacity( + opacity: index == currentIndex ? 1 : 0, + duration: const Duration(milliseconds: 400), + child: _branchNavigatorWrapper(index, navigator), + ), + ); + }).toList(), ); } @@ -554,10 +553,9 @@ class TabbedRootScreenState extends State @override Widget build(BuildContext context) { - final List tabs = - widget.children - .mapIndexed((int i, _) => Tab(text: 'Tab ${i + 1}')) - .toList(); + final List tabs = widget.children + .mapIndexed((int i, _) => Tab(text: 'Tab ${i + 1}')) + .toList(); return Scaffold( appBar: AppBar( diff --git a/packages/go_router/example/lib/others/error_screen.dart b/packages/go_router/example/lib/others/error_screen.dart index 885ada3afe0..27b30a956f0 100644 --- a/packages/go_router/example/lib/others/error_screen.dart +++ b/packages/go_router/example/lib/others/error_screen.dart @@ -23,18 +23,17 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), GoRoute( path: '/page2', - builder: - (BuildContext context, GoRouterState state) => const Page2Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page2Screen(), ), ], - errorBuilder: - (BuildContext context, GoRouterState state) => - ErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + ErrorScreen(state.error!), ); } diff --git a/packages/go_router/example/lib/others/extra_param.dart b/packages/go_router/example/lib/others/extra_param.dart index e0b9495b39b..9644aab6708 100644 --- a/packages/go_router/example/lib/others/extra_param.dart +++ b/packages/go_router/example/lib/others/extra_param.dart @@ -62,8 +62,8 @@ class App extends StatelessWidget { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', @@ -94,11 +94,10 @@ class HomeScreen extends StatelessWidget { for (final MapEntry entry in _families.entries) ListTile( title: Text(entry.value.name), - onTap: - () => context.goNamed( - 'family', - extra: {'fid': entry.key}, - ), + onTap: () => context.goNamed( + 'family', + extra: {'fid': entry.key}, + ), ), ], ), diff --git a/packages/go_router/example/lib/others/init_loc.dart b/packages/go_router/example/lib/others/init_loc.dart index 6ba03a259f3..a980b8df619 100644 --- a/packages/go_router/example/lib/others/init_loc.dart +++ b/packages/go_router/example/lib/others/init_loc.dart @@ -24,18 +24,18 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), GoRoute( path: '/page2', - builder: - (BuildContext context, GoRouterState state) => const Page2Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page2Screen(), ), GoRoute( path: '/page3', - builder: - (BuildContext context, GoRouterState state) => const Page3Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page3Screen(), ), ], ); diff --git a/packages/go_router/example/lib/others/nav_observer.dart b/packages/go_router/example/lib/others/nav_observer.dart index 4fd74c0549f..fea069fa3c2 100644 --- a/packages/go_router/example/lib/others/nav_observer.dart +++ b/packages/go_router/example/lib/others/nav_observer.dart @@ -26,22 +26,20 @@ class App extends StatelessWidget { GoRoute( // if there's no name, path will be used as name for observers path: '/', - builder: - (BuildContext context, GoRouterState state) => const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), routes: [ GoRoute( name: 'page2', path: 'page2/:p1', - builder: - (BuildContext context, GoRouterState state) => - const Page2Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page2Screen(), routes: [ GoRoute( name: 'page3', path: 'page3', - builder: - (BuildContext context, GoRouterState state) => - const Page3Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page3Screen(), ), ], ), @@ -107,12 +105,11 @@ class Page1Screen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( - onPressed: - () => context.goNamed( - 'page2', - pathParameters: {'p1': 'pv1'}, - queryParameters: {'q1': 'qv1'}, - ), + onPressed: () => context.goNamed( + 'page2', + pathParameters: {'p1': 'pv1'}, + queryParameters: {'q1': 'qv1'}, + ), child: const Text('Go to page 2'), ), ], @@ -134,11 +131,10 @@ class Page2Screen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( - onPressed: - () => context.goNamed( - 'page3', - pathParameters: {'p1': 'pv2'}, - ), + onPressed: () => context.goNamed( + 'page3', + pathParameters: {'p1': 'pv2'}, + ), child: const Text('Go to page 3'), ), ], diff --git a/packages/go_router/example/lib/others/push.dart b/packages/go_router/example/lib/others/push.dart index 25ae99822e2..f915bae847f 100644 --- a/packages/go_router/example/lib/others/push.dart +++ b/packages/go_router/example/lib/others/push.dart @@ -23,14 +23,13 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const Page1ScreenWithPush(), + builder: (BuildContext context, GoRouterState state) => + const Page1ScreenWithPush(), ), GoRoute( path: '/page2', - builder: - (BuildContext context, GoRouterState state) => Page2ScreenWithPush( + builder: (BuildContext context, GoRouterState state) => + Page2ScreenWithPush( int.parse(state.uri.queryParameters['push-count']!), ), ), @@ -87,8 +86,8 @@ class Page2ScreenWithPush extends StatelessWidget { Padding( padding: const EdgeInsets.all(8), child: ElevatedButton( - onPressed: - () => context.push('/page2?push-count=${pushCount + 1}'), + onPressed: () => + context.push('/page2?push-count=${pushCount + 1}'), child: const Text('Push page 2 (again)'), ), ), diff --git a/packages/go_router/example/lib/others/router_neglect.dart b/packages/go_router/example/lib/others/router_neglect.dart index d529d756c45..3c1e4bcc768 100644 --- a/packages/go_router/example/lib/others/router_neglect.dart +++ b/packages/go_router/example/lib/others/router_neglect.dart @@ -26,13 +26,13 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), GoRoute( path: '/page2', - builder: - (BuildContext context, GoRouterState state) => const Page2Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page2Screen(), ), ], ); @@ -59,8 +59,8 @@ class Page1Screen extends StatelessWidget { // turn off history tracking in the browser for this navigation; // note that this isn't necessary when you've set routerNeglect // but it does illustrate the technique - onPressed: - () => Router.neglect(context, () => context.push('/page2')), + onPressed: () => + Router.neglect(context, () => context.push('/page2')), child: const Text('Push page 2'), ), ], diff --git a/packages/go_router/example/lib/others/transitions.dart b/packages/go_router/example/lib/others/transitions.dart index 02ab8fa899c..d95862b1962 100644 --- a/packages/go_router/example/lib/others/transitions.dart +++ b/packages/go_router/example/lib/others/transitions.dart @@ -24,99 +24,94 @@ class App extends StatelessWidget { GoRoute(path: '/', redirect: (_, __) => '/none'), GoRoute( path: '/fade', - pageBuilder: - (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'fade', - color: Colors.red, - ), - transitionsBuilder: - ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => FadeTransition(opacity: animation, child: child), - ), + pageBuilder: (BuildContext context, GoRouterState state) => + CustomTransitionPage( + key: state.pageKey, + child: const ExampleTransitionsScreen( + kind: 'fade', + color: Colors.red, + ), + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) => FadeTransition(opacity: animation, child: child), + ), ), GoRoute( path: '/scale', - pageBuilder: - (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'scale', - color: Colors.green, - ), - transitionsBuilder: - ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => ScaleTransition(scale: animation, child: child), - ), + pageBuilder: (BuildContext context, GoRouterState state) => + CustomTransitionPage( + key: state.pageKey, + child: const ExampleTransitionsScreen( + kind: 'scale', + color: Colors.green, + ), + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) => ScaleTransition(scale: animation, child: child), + ), ), GoRoute( path: '/slide', - pageBuilder: - (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'slide', - color: Colors.yellow, + pageBuilder: (BuildContext context, GoRouterState state) => + CustomTransitionPage( + key: state.pageKey, + child: const ExampleTransitionsScreen( + kind: 'slide', + color: Colors.yellow, + ), + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) => SlideTransition( + position: animation.drive( + Tween( + begin: const Offset(0.25, 0.25), + end: Offset.zero, + ).chain(CurveTween(curve: Curves.easeIn)), + ), + child: child, ), - transitionsBuilder: - ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => SlideTransition( - position: animation.drive( - Tween( - begin: const Offset(0.25, 0.25), - end: Offset.zero, - ).chain(CurveTween(curve: Curves.easeIn)), - ), - child: child, - ), - ), + ), ), GoRoute( path: '/rotation', - pageBuilder: - (BuildContext context, GoRouterState state) => - CustomTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'rotation', - color: Colors.purple, - ), - transitionsBuilder: - ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => RotationTransition(turns: animation, child: child), - ), + pageBuilder: (BuildContext context, GoRouterState state) => + CustomTransitionPage( + key: state.pageKey, + child: const ExampleTransitionsScreen( + kind: 'rotation', + color: Colors.purple, + ), + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) => RotationTransition(turns: animation, child: child), + ), ), GoRoute( path: '/none', - pageBuilder: - (BuildContext context, GoRouterState state) => - NoTransitionPage( - key: state.pageKey, - child: const ExampleTransitionsScreen( - kind: 'none', - color: Colors.white, - ), - ), + pageBuilder: (BuildContext context, GoRouterState state) => + NoTransitionPage( + key: state.pageKey, + child: const ExampleTransitionsScreen( + kind: 'none', + color: Colors.white, + ), + ), ), ], ); diff --git a/packages/go_router/example/lib/path_and_query_parameters.dart b/packages/go_router/example/lib/path_and_query_parameters.dart index d444b99e021..6cd8a4b77d3 100755 --- a/packages/go_router/example/lib/path_and_query_parameters.dart +++ b/packages/go_router/example/lib/path_and_query_parameters.dart @@ -73,8 +73,8 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', @@ -128,10 +128,9 @@ class FamilyScreen extends StatelessWidget { @override Widget build(BuildContext context) { final Map newQueries; - final List names = - _families[fid]!.people.values - .map((Person p) => p.name) - .toList(); + final List names = _families[fid]!.people.values + .map((Person p) => p.name) + .toList(); names.sort(); if (asc) { newQueries = const {'sort': 'desc'}; @@ -143,12 +142,11 @@ class FamilyScreen extends StatelessWidget { title: Text(_families[fid]!.name), actions: [ IconButton( - onPressed: - () => context.goNamed( - 'family', - pathParameters: {'fid': fid}, - queryParameters: newQueries, - ), + onPressed: () => context.goNamed( + 'family', + pathParameters: {'fid': fid}, + queryParameters: newQueries, + ), tooltip: 'sort ascending or descending', icon: const Icon(Icons.sort), ), diff --git a/packages/go_router/example/lib/push_with_shell_route.dart b/packages/go_router/example/lib/push_with_shell_route.dart index e51f02deb68..95d04c5be0e 100644 --- a/packages/go_router/example/lib/push_with_shell_route.dart +++ b/packages/go_router/example/lib/push_with_shell_route.dart @@ -38,10 +38,9 @@ class PushWithShellRouteExampleApp extends StatelessWidget { ), GoRoute( path: '/shell1', - pageBuilder: - (_, __) => const NoTransitionPage( - child: Center(child: Text('shell1 body')), - ), + pageBuilder: (_, __) => const NoTransitionPage( + child: Center(child: Text('shell1 body')), + ), ), ], ), @@ -88,7 +87,10 @@ class ScaffoldForShell1 extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold(appBar: AppBar(title: const Text('shell1')), body: child); + return Scaffold( + appBar: AppBar(title: const Text('shell1')), + body: child, + ); } } @@ -103,7 +105,10 @@ class ScaffoldForShell2 extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold(appBar: AppBar(title: const Text('shell2')), body: child); + return Scaffold( + appBar: AppBar(title: const Text('shell2')), + body: child, + ); } } diff --git a/packages/go_router/example/lib/redirection.dart b/packages/go_router/example/lib/redirection.dart index b95ecb5d15d..449324b93c3 100644 --- a/packages/go_router/example/lib/redirection.dart +++ b/packages/go_router/example/lib/redirection.dart @@ -61,13 +61,13 @@ class App extends StatelessWidget { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], diff --git a/packages/go_router/example/lib/routing_config.dart b/packages/go_router/example/lib/routing_config.dart index 5a47615ab11..209e1176c34 100644 --- a/packages/go_router/example/lib/routing_config.dart +++ b/packages/go_router/example/lib/routing_config.dart @@ -25,22 +25,21 @@ class _MyAppState extends State { late final GoRouter router = GoRouter.routingConfig( routingConfig: myConfig, - errorBuilder: - (_, GoRouterState state) => Scaffold( - appBar: AppBar(title: const Text('Page not found')), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('${state.uri} does not exist'), - ElevatedButton( - onPressed: () => router.go('/'), - child: const Text('Go to home'), - ), - ], + errorBuilder: (_, GoRouterState state) => Scaffold( + appBar: AppBar(title: const Text('Page not found')), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('${state.uri} does not exist'), + ElevatedButton( + onPressed: () => router.go('/'), + child: const Text('Go to home'), ), - ), + ], ), + ), + ), ); RoutingConfig _generateRoutingConfig() { @@ -56,20 +55,18 @@ class _MyAppState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( - onPressed: - isNewRouteAdded - ? null - : () { - setState(() { - isNewRouteAdded = true; - // Modify the routing config. - myConfig.value = _generateRoutingConfig(); - }); - }, - child: - isNewRouteAdded - ? const Text('A route has been added') - : const Text('Add a new route'), + onPressed: isNewRouteAdded + ? null + : () { + setState(() { + isNewRouteAdded = true; + // Modify the routing config. + myConfig.value = _generateRoutingConfig(); + }); + }, + child: isNewRouteAdded + ? const Text('A route has been added') + : const Text('Add a new route'), ), ElevatedButton( onPressed: () { diff --git a/packages/go_router/example/lib/shell_route_top_route.dart b/packages/go_router/example/lib/shell_route_top_route.dart index a4652edc630..9fa2df1e9ee 100644 --- a/packages/go_router/example/lib/shell_route_top_route.dart +++ b/packages/go_router/example/lib/shell_route_top_route.dart @@ -178,13 +178,13 @@ class ScaffoldWithNavBar extends StatelessWidget { /// The [Scaffold]'s default back button cannot be used because it doesn't /// have the context of the current child. Widget? _buildLeadingButton(BuildContext context) { - final RouteMatchList currentConfiguration = - GoRouter.of(context).routerDelegate.currentConfiguration; + final RouteMatchList currentConfiguration = GoRouter.of( + context, + ).routerDelegate.currentConfiguration; final RouteMatch lastMatch = currentConfiguration.last; - final Uri location = - lastMatch is ImperativeRouteMatch - ? lastMatch.matches.uri - : currentConfiguration.uri; + final Uri location = lastMatch is ImperativeRouteMatch + ? lastMatch.matches.uri + : currentConfiguration.uri; final bool canPop = location.pathSegments.length > 1; return canPop ? BackButton(onPressed: GoRouter.of(context).pop) : null; } diff --git a/packages/go_router/example/lib/state_restoration/shell_route_state_restoration.dart b/packages/go_router/example/lib/state_restoration/shell_route_state_restoration.dart index 5d6b60667ba..e3ee30b9fc2 100644 --- a/packages/go_router/example/lib/state_restoration/shell_route_state_restoration.dart +++ b/packages/go_router/example/lib/state_restoration/shell_route_state_restoration.dart @@ -29,16 +29,13 @@ class _AppState extends State { routes: [ ShellRoute( restorationScopeId: 'onboardingShell', - pageBuilder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return MaterialPage( - restorationId: 'onboardingPage', - child: OnboardingScaffold(child: child), - ); - }, + pageBuilder: + (BuildContext context, GoRouterState state, Widget child) { + return MaterialPage( + restorationId: 'onboardingPage', + child: OnboardingScaffold(child: child), + ); + }, routes: [ GoRoute( path: 'welcome', diff --git a/packages/go_router/example/lib/state_restoration/stateful_shell_route_state_restoration.dart b/packages/go_router/example/lib/state_restoration/stateful_shell_route_state_restoration.dart index 962c60cae86..a81a1031b7c 100644 --- a/packages/go_router/example/lib/state_restoration/stateful_shell_route_state_restoration.dart +++ b/packages/go_router/example/lib/state_restoration/stateful_shell_route_state_restoration.dart @@ -23,16 +23,17 @@ class _AppState extends State { routes: [ StatefulShellRoute.indexedStack( restorationScopeId: 'appShell', - pageBuilder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - return MaterialPage( - restorationId: 'appShellPage', - child: AppShell(navigationShell: navigationShell), - ); - }, + pageBuilder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return MaterialPage( + restorationId: 'appShellPage', + child: AppShell(navigationShell: navigationShell), + ); + }, branches: [ StatefulShellBranch( restorationScopeId: 'homeBranch', diff --git a/packages/go_router/example/lib/stateful_shell_route.dart b/packages/go_router/example/lib/stateful_shell_route.dart index 159f50184a1..39e14ad53c3 100644 --- a/packages/go_router/example/lib/stateful_shell_route.dart +++ b/packages/go_router/example/lib/stateful_shell_route.dart @@ -31,17 +31,18 @@ class NestedTabNavigationExampleApp extends StatelessWidget { routes: [ // #docregion configuration-builder StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - // Return the widget that implements the custom shell (in this case - // using a BottomNavigationBar). The StatefulNavigationShell is passed - // to be able access the state of the shell and to navigate to other - // branches in a stateful way. - return ScaffoldWithNavBar(navigationShell: navigationShell); - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + // Return the widget that implements the custom shell (in this case + // using a BottomNavigationBar). The StatefulNavigationShell is passed + // to be able access the state of the shell and to navigate to other + // branches in a stateful way. + return ScaffoldWithNavBar(navigationShell: navigationShell); + }, // #enddocregion configuration-builder // #docregion configuration-branches branches: [ @@ -53,18 +54,16 @@ class NestedTabNavigationExampleApp extends StatelessWidget { // The screen to display as the root in the first tab of the // bottom navigation bar. path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const RootScreen(label: 'A', detailsPath: '/a/details'), + builder: (BuildContext context, GoRouterState state) => + const RootScreen(label: 'A', detailsPath: '/a/details'), routes: [ // The details screen to display stacked on navigator of the // first tab. This will cover screen A but not the application // shell (bottom navigation bar). GoRoute( path: 'details', - builder: - (BuildContext context, GoRouterState state) => - const DetailsScreen(label: 'A'), + builder: (BuildContext context, GoRouterState state) => + const DetailsScreen(label: 'A'), ), ], ), @@ -83,22 +82,20 @@ class NestedTabNavigationExampleApp extends StatelessWidget { // The screen to display as the root in the second tab of the // bottom navigation bar. path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const RootScreen( - label: 'B', - detailsPath: '/b/details/1', - secondDetailsPath: '/b/details/2', - ), + builder: (BuildContext context, GoRouterState state) => + const RootScreen( + label: 'B', + detailsPath: '/b/details/1', + secondDetailsPath: '/b/details/2', + ), routes: [ GoRoute( path: 'details/:param', - builder: - (BuildContext context, GoRouterState state) => - DetailsScreen( - label: 'B', - param: state.pathParameters['param'], - ), + builder: (BuildContext context, GoRouterState state) => + DetailsScreen( + label: 'B', + param: state.pathParameters['param'], + ), ), ], ), @@ -112,15 +109,13 @@ class NestedTabNavigationExampleApp extends StatelessWidget { // The screen to display as the root in the third tab of the // bottom navigation bar. path: '/c', - builder: - (BuildContext context, GoRouterState state) => - const RootScreen(label: 'C', detailsPath: '/c/details'), + builder: (BuildContext context, GoRouterState state) => + const RootScreen(label: 'C', detailsPath: '/c/details'), routes: [ GoRoute( path: 'details', - builder: - (BuildContext context, GoRouterState state) => - DetailsScreen(label: 'C', extra: state.extra), + builder: (BuildContext context, GoRouterState state) => + DetailsScreen(label: 'C', extra: state.extra), ), ], ), diff --git a/packages/go_router/example/lib/transition_animations.dart b/packages/go_router/example/lib/transition_animations.dart index 32b03f84017..96f93f1d9f8 100644 --- a/packages/go_router/example/lib/transition_animations.dart +++ b/packages/go_router/example/lib/transition_animations.dart @@ -29,21 +29,22 @@ final GoRouter _router = GoRouter( key: state.pageKey, child: const DetailsScreen(), transitionDuration: const Duration(milliseconds: 150), - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - // Change the opacity of the screen using a Curve based on the the animation's - // value - return FadeTransition( - opacity: CurveTween( - curve: Curves.easeInOut, - ).animate(animation), - child: child, - ); - }, + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + // Change the opacity of the screen using a Curve based on the the animation's + // value + return FadeTransition( + opacity: CurveTween( + curve: Curves.easeInOut, + ).animate(animation), + child: child, + ); + }, ); }, ), @@ -72,14 +73,15 @@ final GoRouter _router = GoRouter( opaque: false, transitionDuration: const Duration(milliseconds: 500), reverseTransitionDuration: const Duration(milliseconds: 200), - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return FadeTransition(opacity: animation, child: child); - }, + transitionsBuilder: + ( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + return FadeTransition(opacity: animation, child: child); + }, ); }, ), @@ -123,8 +125,8 @@ class HomeScreen extends StatelessWidget { ), const SizedBox(height: 48), ElevatedButton( - onPressed: - () => context.go('/custom-reverse-transition-duration'), + onPressed: () => + context.go('/custom-reverse-transition-duration'), child: const Text( 'Go to the Custom Reverse Transition Duration Screen', ), diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index 056e9de8271..86900a2469a 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -4,8 +4,8 @@ version: 3.0.1 publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: adaptive_navigation: ^0.0.4 diff --git a/packages/go_router/lib/src/builder.dart b/packages/go_router/lib/src/builder.dart index 5eb0466cef4..dd6f89f10f3 100644 --- a/packages/go_router/lib/src/builder.dart +++ b/packages/go_router/lib/src/builder.dart @@ -286,36 +286,37 @@ class _CustomNavigatorState extends State<_CustomNavigator> { navigatorKey: navigatorKey, match: match, routeMatchList: widget.matchList, - navigatorBuilder: ( - GlobalKey navigatorKey, - ShellRouteMatch match, - RouteMatchList matchList, - List? observers, - String? restorationScopeId, - ) { - return PopScope( - // Prevent ShellRoute from being popped, for example - // by an iOS back gesture, when the route has active sub-routes. - // TODO(LukasMirbt): Remove when minimum flutter version includes - // https://github.com/flutter/flutter/pull/152330. - canPop: match.matches.length == 1, - child: _CustomNavigator( - // The state needs to persist across rebuild. - key: GlobalObjectKey(navigatorKey.hashCode), - navigatorRestorationId: restorationScopeId, - navigatorKey: navigatorKey, - matches: match.matches, - matchList: matchList, - configuration: widget.configuration, - observers: observers ?? const [], - onPopPageWithRouteMatch: widget.onPopPageWithRouteMatch, - // This is used to recursively build pages under this shell route. - errorBuilder: widget.errorBuilder, - errorPageBuilder: widget.errorPageBuilder, - requestFocus: widget.requestFocus, - ), - ); - }, + navigatorBuilder: + ( + GlobalKey navigatorKey, + ShellRouteMatch match, + RouteMatchList matchList, + List? observers, + String? restorationScopeId, + ) { + return PopScope( + // Prevent ShellRoute from being popped, for example + // by an iOS back gesture, when the route has active sub-routes. + // TODO(LukasMirbt): Remove when minimum flutter version includes + // https://github.com/flutter/flutter/pull/152330. + canPop: match.matches.length == 1, + child: _CustomNavigator( + // The state needs to persist across rebuild. + key: GlobalObjectKey(navigatorKey.hashCode), + navigatorRestorationId: restorationScopeId, + navigatorKey: navigatorKey, + matches: match.matches, + matchList: matchList, + configuration: widget.configuration, + observers: observers ?? const [], + onPopPageWithRouteMatch: widget.onPopPageWithRouteMatch, + // This is used to recursively build pages under this shell route. + errorBuilder: widget.errorBuilder, + errorPageBuilder: widget.errorPageBuilder, + requestFocus: widget.requestFocus, + ), + ); + }, ); final Page? page = match.route.buildPage( context, @@ -353,13 +354,13 @@ class _CustomNavigatorState extends State<_CustomNavigator> { if (elem != null && isMaterialApp(elem)) { log('Using MaterialApp configuration'); _pageBuilderForAppType = pageBuilderForMaterialApp; - _errorBuilderForAppType = - (BuildContext c, GoRouterState s) => MaterialErrorScreen(s.error); + _errorBuilderForAppType = (BuildContext c, GoRouterState s) => + MaterialErrorScreen(s.error); } else if (elem != null && isCupertinoApp(elem)) { log('Using CupertinoApp configuration'); _pageBuilderForAppType = pageBuilderForCupertinoApp; - _errorBuilderForAppType = - (BuildContext c, GoRouterState s) => CupertinoErrorScreen(s.error); + _errorBuilderForAppType = (BuildContext c, GoRouterState s) => + CupertinoErrorScreen(s.error); } else { log('Using WidgetsApp configuration'); _pageBuilderForAppType = @@ -376,8 +377,8 @@ class _CustomNavigatorState extends State<_CustomNavigator> { restorationId: restorationId, child: child, ); - _errorBuilderForAppType = - (BuildContext c, GoRouterState s) => ErrorScreen(s.error); + _errorBuilderForAppType = (BuildContext c, GoRouterState s) => + ErrorScreen(s.error); } } @@ -433,12 +434,12 @@ class _CustomNavigatorState extends State<_CustomNavigator> { return widget.errorPageBuilder != null ? widget.errorPageBuilder!(context, state) : _buildPlatformAdapterPage( - context, - state, - errorBuilder != null - ? errorBuilder(context, state) - : _errorBuilderForAppType!(context, state), - ); + context, + state, + errorBuilder != null + ? errorBuilder(context, state) + : _errorBuilderForAppType!(context, state), + ); } bool _handlePopPage(Route route, Object? result) { diff --git a/packages/go_router/lib/src/configuration.dart b/packages/go_router/lib/src/configuration.dart index 178736637c3..c8479b7955b 100644 --- a/packages/go_router/lib/src/configuration.dart +++ b/packages/go_router/lib/src/configuration.dart @@ -142,8 +142,9 @@ class RouteConfiguration { // Recursively search for the first GoRoute descendant. Will // throw assertion error if not found. final GoRoute? route = branch.defaultRoute; - final String? initialLocation = - route != null ? locationForRoute(route) : null; + final String? initialLocation = route != null + ? locationForRoute(route) + : null; assert( initialLocation != null, 'The default location of a StatefulShellBranch must be ' @@ -587,13 +588,16 @@ class RouteConfiguration { index, routes.length, ); - final String decorationString = - decoration.map((_DecorationType e) => e.toString()).join(); + final String decorationString = decoration + .map((_DecorationType e) => e.toString()) + .join(); String path = parentFullpath; if (route is GoRoute) { path = concatenatePaths(parentFullpath, route.path); - final String? screenName = - route.builder?.runtimeType.toString().split('=> ').last; + final String? screenName = route.builder?.runtimeType + .toString() + .split('=> ') + .last; sb.writeln( '$decorationString$path ' '${screenName == null ? '' : '($screenName)'}', diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index ef27d8be90e..229c9865b1a 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -258,8 +258,9 @@ class GoRouterDelegate extends RouterDelegate } if (indexOfFirstDiff < currentGoRouteMatches.length) { - final List exitingMatches = - currentGoRouteMatches.sublist(indexOfFirstDiff).toList(); + final List exitingMatches = currentGoRouteMatches + .sublist(indexOfFirstDiff) + .toList(); return _callOnExitStartsAt( exitingMatches.length - 1, context: navigatorContext, diff --git a/packages/go_router/lib/src/match.dart b/packages/go_router/lib/src/match.dart index 27d843b1e47..b8ddbaac9c2 100644 --- a/packages/go_router/lib/src/match.dart +++ b/packages/go_router/lib/src/match.dart @@ -127,8 +127,9 @@ abstract class RouteMatchBase with Diagnosticable { // Grab the route matches for the scope navigator key and put it into the // matches for `null`. if (result.containsKey(scopedNavigatorKey)) { - final List matchesForScopedNavigator = - result.remove(scopedNavigatorKey)!; + final List matchesForScopedNavigator = result.remove( + scopedNavigatorKey, + )!; assert(matchesForScopedNavigator.isNotEmpty); result .putIfAbsent(null, () => []) @@ -149,8 +150,8 @@ abstract class RouteMatchBase with Diagnosticable { }) { final GlobalKey? parentKey = route.parentNavigatorKey == scopedNavigatorKey - ? null - : route.parentNavigatorKey; + ? null + : route.parentNavigatorKey; Map?, List>? subRouteMatches; late GlobalKey navigatorKeyUsed; for (final RouteBase subRoute in route.routes) { @@ -202,8 +203,8 @@ abstract class RouteMatchBase with Diagnosticable { }) { final GlobalKey? parentKey = route.parentNavigatorKey == scopedNavigatorKey - ? null - : route.parentNavigatorKey; + ? null + : route.parentNavigatorKey; final RegExpMatch? regExpMatch = route.matchPatternAsPrefix( remainingLocation, diff --git a/packages/go_router/lib/src/parser.dart b/packages/go_router/lib/src/parser.dart index eb2e8a5af84..b96dd0dddd7 100644 --- a/packages/go_router/lib/src/parser.dart +++ b/packages/go_router/lib/src/parser.dart @@ -71,17 +71,15 @@ class GoRouteInformationParser extends RouteInformationParser { final RouteMatchList matchList = _routeMatchListCodec.decode( state as Map, ); - return debugParserFuture = _redirect( - context, - matchList, - ).then((RouteMatchList value) { - if (value.isError && onParserException != null) { - // TODO(chunhtai): Figure out what to return if context is invalid. - // ignore: use_build_context_synchronously - return onParserException!(context, value); - } - return value; - }); + return debugParserFuture = _redirect(context, matchList) + .then((RouteMatchList value) { + if (value.isError && onParserException != null) { + // TODO(chunhtai): Figure out what to return if context is invalid. + // ignore: use_build_context_synchronously + return onParserException!(context, value); + } + return value; + }); } Uri uri = routeInformation.uri; @@ -99,32 +97,30 @@ class GoRouteInformationParser extends RouteInformationParser { log('No initial matches: ${routeInformation.uri.path}'); } - return debugParserFuture = _redirect( - context, - initialMatches, - ).then((RouteMatchList matchList) { - if (matchList.isError && onParserException != null) { - // TODO(chunhtai): Figure out what to return if context is invalid. - // ignore: use_build_context_synchronously - return onParserException!(context, matchList); - } - - assert(() { - if (matchList.isNotEmpty) { - assert( - !matchList.last.route.redirectOnly, - 'A redirect-only route must redirect to location different from itself.\n The offending route: ${matchList.last.route}', + return debugParserFuture = _redirect(context, initialMatches) + .then((RouteMatchList matchList) { + if (matchList.isError && onParserException != null) { + // TODO(chunhtai): Figure out what to return if context is invalid. + // ignore: use_build_context_synchronously + return onParserException!(context, matchList); + } + + assert(() { + if (matchList.isNotEmpty) { + assert( + !matchList.last.route.redirectOnly, + 'A redirect-only route must redirect to location different from itself.\n The offending route: ${matchList.last.route}', + ); + } + return true; + }()); + return _updateRouteMatchList( + matchList, + baseRouteMatchList: state.baseRouteMatchList, + completer: state.completer, + type: state.type, ); - } - return true; - }()); - return _updateRouteMatchList( - matchList, - baseRouteMatchList: state.baseRouteMatchList, - completer: state.completer, - type: state.type, - ); - }); + }); } @override diff --git a/packages/go_router/lib/src/path_utils.dart b/packages/go_router/lib/src/path_utils.dart index d9d961c856f..29aec2c475f 100644 --- a/packages/go_router/lib/src/path_utils.dart +++ b/packages/go_router/lib/src/path_utils.dart @@ -36,10 +36,9 @@ RegExp patternToRegExp( } final String name = match[1]!; final String? optionalPattern = match[2]; - final String regex = - optionalPattern != null - ? _escapeGroup(optionalPattern, name) - : '(?<$name>[^/]+)'; + final String regex = optionalPattern != null + ? _escapeGroup(optionalPattern, name) + : '(?<$name>[^/]+)'; buffer.write(regex); parameters.add(name); start = match.end; @@ -150,21 +149,20 @@ String canonicalUri(String loc) { // /login?from=/ => /login?from=/ canon = uri.path.endsWith('/') && - uri.path != '/' && - !uri.hasQuery && - !uri.hasFragment - ? canon.substring(0, canon.length - 1) - : canon; + uri.path != '/' && + !uri.hasQuery && + !uri.hasFragment + ? canon.substring(0, canon.length - 1) + : canon; // replace '/?', except for first occurrence, from path only // /login/?from=/ => /login?from=/ // /?from=/ => /?from=/ - final int pathStartIndex = - uri.host.isNotEmpty - ? uri.toString().indexOf(uri.host) + uri.host.length - : uri.hasScheme - ? uri.toString().indexOf(uri.scheme) + uri.scheme.length - : 0; + final int pathStartIndex = uri.host.isNotEmpty + ? uri.toString().indexOf(uri.host) + uri.host.length + : uri.hasScheme + ? uri.toString().indexOf(uri.scheme) + uri.scheme.length + : 0; if (pathStartIndex < canon.length) { canon = canon.replaceFirst('/?', '?', pathStartIndex + 1); } @@ -179,10 +177,9 @@ String? fullPathForRoute( List routes, ) { for (final RouteBase route in routes) { - final String fullPath = - (route is GoRoute) - ? concatenatePaths(parentFullpath, route.path) - : parentFullpath; + final String fullPath = (route is GoRoute) + ? concatenatePaths(parentFullpath, route.path) + : parentFullpath; if (route == targetRoute) { return fullPath; diff --git a/packages/go_router/lib/src/route.dart b/packages/go_router/lib/src/route.dart index 5f006a4deb0..aea79382c78 100644 --- a/packages/go_router/lib/src/route.dart +++ b/packages/go_router/lib/src/route.dart @@ -1299,8 +1299,8 @@ class StatefulNavigationShell extends StatefulWidget { /// Gets the state for the nearest stateful shell route in the Widget tree. static StatefulNavigationShellState of(BuildContext context) { - final StatefulNavigationShellState? shellState = - context.findAncestorStateOfType(); + final StatefulNavigationShellState? shellState = context + .findAncestorStateOfType(); assert(shellState != null); return shellState!; } @@ -1309,8 +1309,8 @@ class StatefulNavigationShell extends StatefulWidget { /// /// Returns null if no stateful shell route is found. static StatefulNavigationShellState? maybeOf(BuildContext context) { - final StatefulNavigationShellState? shellState = - context.findAncestorStateOfType(); + final StatefulNavigationShellState? shellState = context + .findAncestorStateOfType(); return shellState; } @@ -1492,8 +1492,9 @@ class StatefulNavigationShellState extends State /// the branch (see [StatefulShellBranch.initialLocation]). void goBranch(int index, {bool initialLocation = false}) { assert(index >= 0 && index < route.branches.length); - final RouteMatchList? matchList = - initialLocation ? null : _matchListForBranch(index); + final RouteMatchList? matchList = initialLocation + ? null + : _matchListForBranch(index); if (matchList != null && matchList.isNotEmpty) { _router.restore(matchList); } else { @@ -1528,18 +1529,16 @@ class StatefulNavigationShellState extends State @override Widget build(BuildContext context) { - final List children = - route.branches - .map( - (StatefulShellBranch branch) => _BranchNavigatorProxy( - key: ObjectKey(branch), - branch: branch, - navigatorForBranch: - (StatefulShellBranch branch) => - _branchState[branch]?.navigator, - ), - ) - .toList(); + final List children = route.branches + .map( + (StatefulShellBranch branch) => _BranchNavigatorProxy( + key: ObjectKey(branch), + branch: branch, + navigatorForBranch: (StatefulShellBranch branch) => + _branchState[branch]?.navigator, + ), + ) + .toList(); return widget.containerBuilder(context, widget, children); } @@ -1649,16 +1648,12 @@ class _IndexedStackedRouteBranchContainer extends StatelessWidget { @override Widget build(BuildContext context) { - final List stackItems = - children - .mapIndexed( - (int index, Widget child) => _buildRouteBranchContainer( - context, - currentIndex == index, - child, - ), - ) - .toList(); + final List stackItems = children + .mapIndexed( + (int index, Widget child) => + _buildRouteBranchContainer(context, currentIndex == index, child), + ) + .toList(); return IndexedStack(index: currentIndex, children: stackItems); } diff --git a/packages/go_router/lib/src/route_data.dart b/packages/go_router/lib/src/route_data.dart index dab78cbc476..93184457365 100644 --- a/packages/go_router/lib/src/route_data.dart +++ b/packages/go_router/lib/src/route_data.dart @@ -117,18 +117,14 @@ _GoRouteParameters _createGoRouteParameters({ } return _GoRouteParameters( - builder: - (BuildContext context, GoRouterState state) => - factoryImpl(state).build(context, state), - pageBuilder: - (BuildContext context, GoRouterState state) => - factoryImpl(state).buildPage(context, state), - redirect: - (BuildContext context, GoRouterState state) => - factoryImpl(state).redirect(context, state), - onExit: - (BuildContext context, GoRouterState state) => - factoryImpl(state).onExit(context, state), + builder: (BuildContext context, GoRouterState state) => + factoryImpl(state).build(context, state), + pageBuilder: (BuildContext context, GoRouterState state) => + factoryImpl(state).buildPage(context, state), + redirect: (BuildContext context, GoRouterState state) => + factoryImpl(state).redirect(context, state), + onExit: (BuildContext context, GoRouterState state) => + factoryImpl(state).onExit(context, state), ); } @@ -380,10 +376,9 @@ abstract class StatefulShellRouteData extends RouteData { BuildContext context, GoRouterState state, StatefulNavigationShell navigationShell, - ) => - throw UnimplementedError( - 'One of `builder` or `pageBuilder` must be implemented.', - ); + ) => throw UnimplementedError( + 'One of `builder` or `pageBuilder` must be implemented.', + ); /// A helper function used by generated code. /// diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 370e52d2a28..6964fcf7c54 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -213,18 +213,16 @@ class GoRouter implements RouterConfig { final ParserExceptionHandler? parserExceptionHandler; if (onException != null) { - parserExceptionHandler = ( - BuildContext context, - RouteMatchList routeMatchList, - ) { - onException( - context, - configuration.buildTopLevelGoRouterState(routeMatchList), - this, - ); - // Avoid updating GoRouterDelegate if onException is provided. - return routerDelegate.currentConfiguration; - }; + parserExceptionHandler = + (BuildContext context, RouteMatchList routeMatchList) { + onException( + context, + configuration.buildTopLevelGoRouterState(routeMatchList), + this, + ); + // Avoid updating GoRouterDelegate if onException is provided. + return routerDelegate.currentConfiguration; + }; } else { parserExceptionHandler = null; } @@ -251,9 +249,8 @@ class GoRouter implements RouterConfig { requestFocus: requestFocus, // wrap the returned Navigator to enable GoRouter.of(context).go() et al, // allowing the caller to wrap the navigator themselves - builderWithNav: - (BuildContext context, Widget child) => - InheritedGoRouter(goRouter: this, child: child), + builderWithNav: (BuildContext context, Widget child) => + InheritedGoRouter(goRouter: this, child: child), ); assert(() { @@ -376,16 +373,16 @@ class GoRouter implements RouterConfig { Object? extra, String? fragment, }) => - /// Construct location with optional fragment, using null-safe navigation - go( - namedLocation( - name, - pathParameters: pathParameters, - queryParameters: queryParameters, - fragment: fragment, - ), - extra: extra, - ); + /// Construct location with optional fragment, using null-safe navigation + go( + namedLocation( + name, + pathParameters: pathParameters, + queryParameters: queryParameters, + fragment: fragment, + ), + extra: extra, + ); /// Push a URI location onto the page stack w/ optional query parameters, e.g. /// `/family/f2/person/p1?color=blue`. diff --git a/packages/go_router/lib/src/state.dart b/packages/go_router/lib/src/state.dart index 269eb320223..b9db0e561ae 100644 --- a/packages/go_router/lib/src/state.dart +++ b/packages/go_router/lib/src/state.dart @@ -125,11 +125,8 @@ class GoRouterState { } final RouteSettings settings = route.settings; if (settings is Page) { - scope = - context - .dependOnInheritedWidgetOfExactType< - GoRouterStateRegistryScope - >(); + scope = context + .dependOnInheritedWidgetOfExactType(); if (scope == null) { throw _noGoRouterStateError; } @@ -252,8 +249,9 @@ class GoRouterStateRegistry extends ChangeNotifier { route.completed.then((Object? result) { // Can't use `page` directly because Route.settings may have changed during // the lifetime of this route. - final Page associatedPage = - _routePageAssociation.remove(route)!; + final Page associatedPage = _routePageAssociation.remove( + route, + )!; assert(registry.containsKey(associatedPage)); registry.remove(associatedPage); }); @@ -270,8 +268,8 @@ class GoRouterStateRegistry extends ChangeNotifier { /// Updates this registry with new records. void updateRegistry(Map, GoRouterState> newRegistry) { bool shouldNotify = false; - final Set> pagesWithAssociation = - _routePageAssociation.values.toSet(); + final Set> pagesWithAssociation = _routePageAssociation.values + .toSet(); for (final MapEntry, GoRouterState> entry in newRegistry.entries) { final GoRouterState? existingState = registry[entry.key]; diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 5f5517bb3a5..75618086218 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,13 +1,13 @@ name: go_router description: A declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more -version: 16.2.4 +version: 16.3.0 repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: collection: ^1.15.0 diff --git a/packages/go_router/test/builder_test.dart b/packages/go_router/test/builder_test.dart index 7e496979d9a..66cc2d58920 100644 --- a/packages/go_router/test/builder_test.dart +++ b/packages/go_router/test/builder_test.dart @@ -381,9 +381,8 @@ void main() { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const Scaffold(body: Center(child: Text('Home'))), + builder: (BuildContext context, GoRouterState state) => + const Scaffold(body: Center(child: Text('Home'))), ), ], ); @@ -405,9 +404,8 @@ void main() { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const Scaffold(body: Center(child: Text('Home'))), + builder: (BuildContext context, GoRouterState state) => + const Scaffold(body: Center(child: Text('Home'))), ), ], requestFocus: false, @@ -434,7 +432,10 @@ class _HomeScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( body: Column( - children: [const Text('Home Screen'), Expanded(child: child)], + children: [ + const Text('Home Screen'), + Expanded(child: child), + ], ), ); } diff --git a/packages/go_router/test/custom_transition_page_test.dart b/packages/go_router/test/custom_transition_page_test.dart index 71e11415b68..9f4c765d357 100644 --- a/packages/go_router/test/custom_transition_page_test.dart +++ b/packages/go_router/test/custom_transition_page_test.dart @@ -118,16 +118,18 @@ void main() { final GoRouter router = GoRouter( routes: [ - GoRoute(path: '/', builder: (_, __) => const HomeScreen(key: homeKey)), + GoRoute( + path: '/', + builder: (_, __) => const HomeScreen(key: homeKey), + ), GoRoute( path: '/dismissible-modal', - pageBuilder: - (_, GoRouterState state) => CustomTransitionPage( - key: state.pageKey, - barrierDismissible: true, - transitionsBuilder: (_, __, ___, Widget child) => child, - child: const DismissibleModal(key: dismissibleModalKey), - ), + pageBuilder: (_, GoRouterState state) => CustomTransitionPage( + key: state.pageKey, + barrierDismissible: true, + transitionsBuilder: (_, __, ___, Widget child) => child, + child: const DismissibleModal(key: dismissibleModalKey), + ), ), ], ); @@ -152,19 +154,21 @@ void main() { final GoRouter router = GoRouter( routes: [ - GoRoute(path: '/', builder: (_, __) => const HomeScreen(key: homeKey)), + GoRoute( + path: '/', + builder: (_, __) => const HomeScreen(key: homeKey), + ), GoRoute( path: '/login', - pageBuilder: - (_, GoRouterState state) => CustomTransitionPage( - key: state.pageKey, - transitionDuration: transitionDuration, - reverseTransitionDuration: reverseTransitionDuration, - transitionsBuilder: - (_, Animation animation, ___, Widget child) => - FadeTransition(opacity: animation, child: child), - child: const LoginScreen(key: loginKey), - ), + pageBuilder: (_, GoRouterState state) => CustomTransitionPage( + key: state.pageKey, + transitionDuration: transitionDuration, + reverseTransitionDuration: reverseTransitionDuration, + transitionsBuilder: + (_, Animation animation, ___, Widget child) => + FadeTransition(opacity: animation, child: child), + child: const LoginScreen(key: loginKey), + ), ), ], ); diff --git a/packages/go_router/test/delegate_test.dart b/packages/go_router/test/delegate_test.dart index f523c7d44ea..ae85f7cca1d 100644 --- a/packages/go_router/test/delegate_test.dart +++ b/packages/go_router/test/delegate_test.dart @@ -100,21 +100,19 @@ Future createGoRouterWithStatefulShellRouteAndPopScopes( routes: [ GoRoute( path: '/c', - builder: - (_, __) => PopScope( - onPopInvokedWithResult: onPopBranch, - canPop: canPopBranch, - child: const Text('Home'), - ), + builder: (_, __) => PopScope( + onPopInvokedWithResult: onPopBranch, + canPop: canPopBranch, + child: const Text('Home'), + ), routes: [ GoRoute( path: 'c1', - builder: - (_, __) => PopScope( - onPopInvokedWithResult: onPopBranchSubRoute, - canPop: canPopBranchSubRoute, - child: const Text('SubRoute'), - ), + builder: (_, __) => PopScope( + onPopInvokedWithResult: onPopBranchSubRoute, + canPop: canPopBranchSubRoute, + child: const Text('SubRoute'), + ), ), ], ), @@ -197,14 +195,13 @@ void main() { routes: [ GoRoute( path: '/', - builder: - (_, __) => PopScope( - onPopInvokedWithResult: (bool result, _) { - didPop = true; - }, - canPop: false, - child: const Text('Home'), - ), + builder: (_, __) => PopScope( + onPopInvokedWithResult: (bool result, _) { + didPop = true; + }, + canPop: false, + child: const Text('Home'), + ), ), ], ); diff --git a/packages/go_router/test/exception_handling_test.dart b/packages/go_router/test/exception_handling_test.dart index a3e65aaeddd..47a881df2df 100644 --- a/packages/go_router/test/exception_handling_test.dart +++ b/packages/go_router/test/exception_handling_test.dart @@ -70,14 +70,13 @@ void main() { [ GoRoute( path: '/error', - builder: - (_, GoRouterState state) => Text('redirected ${state.extra}'), + builder: (_, GoRouterState state) => + Text('redirected ${state.extra}'), ), ], tester, - onException: - (_, GoRouterState state, GoRouter router) => - router.go('/error', extra: state.uri.toString()), + onException: (_, GoRouterState state, GoRouter router) => + router.go('/error', extra: state.uri.toString()), ); expect(find.text('redirected /'), findsOneWidget); @@ -95,9 +94,8 @@ void main() { ), ], tester, - onException: - (_, GoRouterState state, GoRouter router) => - router.go('/error', extra: state.extra), + onException: (_, GoRouterState state, GoRouter router) => + router.go('/error', extra: state.extra), ); expect(find.text('extra: null'), findsOneWidget); diff --git a/packages/go_router/test/extension_test.dart b/packages/go_router/test/extension_test.dart index 4d36f5a5ade..9a28d17d4c7 100644 --- a/packages/go_router/test/extension_test.dart +++ b/packages/go_router/test/extension_test.dart @@ -52,12 +52,11 @@ class _MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return ElevatedButton( - onPressed: - () => context.replaceNamed( - 'page-0', - pathParameters: {'tab': 'settings'}, - queryParameters: {'search': 'notification'}, - ), + onPressed: () => context.replaceNamed( + 'page-0', + pathParameters: {'tab': 'settings'}, + queryParameters: {'search': 'notification'}, + ), child: const Text('Settings'), ); } diff --git a/packages/go_router/test/go_route_test.dart b/packages/go_router/test/go_route_test.dart index 785ce4d0b94..4ede231e47f 100644 --- a/packages/go_router/test/go_route_test.dart +++ b/packages/go_router/test/go_route_test.dart @@ -51,20 +51,17 @@ void main() { routes: [ ShellRoute( parentNavigatorKey: rootNavigatorKey, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - body: Column( - children: [ - const Text('Screen D'), - Expanded(child: child), - ], - ), - ); - }, + builder: + (BuildContext context, GoRouterState state, Widget child) { + return Scaffold( + body: Column( + children: [ + const Text('Screen D'), + Expanded(child: child), + ], + ), + ); + }, routes: [ GoRoute( path: 'c', @@ -261,9 +258,8 @@ void main() { routes: [ GoRoute( path: '1', - builder: - (_, __) => - const Text('/route/1'), // Renders "/route/1" text + builder: (_, __) => + const Text('/route/1'), // Renders "/route/1" text ), ], ), diff --git a/packages/go_router/test/go_router_state_test.dart b/packages/go_router/test/go_router_state_test.dart index 5e769e05d52..8d82976c14d 100644 --- a/packages/go_router/test/go_router_state_test.dart +++ b/packages/go_router/test/go_router_state_test.dart @@ -152,12 +152,11 @@ void main() { initialLocation: '/a', ); expect(tester.widget(find.byKey(key)).data, '/a'); - final GoRouterStateRegistry registry = - tester - .widget( - find.byType(GoRouterStateRegistryScope), - ) - .notifier!; + final GoRouterStateRegistry registry = tester + .widget( + find.byType(GoRouterStateRegistryScope), + ) + .notifier!; expect(registry.registry.length, 2); router.go('/'); await tester.pump(); @@ -207,12 +206,11 @@ void main() { navigatorKey: nav, ); expect(tester.widget(find.byKey(key)).data, '/a'); - final GoRouterStateRegistry registry = - tester - .widget( - find.byType(GoRouterStateRegistryScope), - ) - .notifier!; + final GoRouterStateRegistry registry = tester + .widget( + find.byType(GoRouterStateRegistryScope), + ) + .notifier!; expect(registry.registry.length, 2); nav.currentState!.pop(); await tester.pump(); @@ -292,25 +290,27 @@ void main() { routes: [ StatefulShellRoute.indexedStack( parentNavigatorKey: rootNavigatorKey, - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - final String? routeName = - GoRouterState.of(context).topRoute?.name; - final String title = switch (routeName) { - 'a' => 'A', - 'b' => 'B', - _ => 'Unknown', - }; - return Column( - children: [ - Text(title), - Expanded(child: navigationShell), - ], - ); - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + final String? routeName = GoRouterState.of( + context, + ).topRoute?.name; + final String title = switch (routeName) { + 'a' => 'A', + 'b' => 'B', + _ => 'Unknown', + }; + return Column( + children: [ + Text(title), + Expanded(child: navigationShell), + ], + ); + }, branches: [ StatefulShellBranch( routes: [ diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 7a3372b6490..f5a66379462 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -45,8 +45,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), ]; @@ -126,9 +126,8 @@ void main() { final GoRouter router = await createRouter( routes, tester, - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); router.go('/foo'); await tester.pumpAndSettle(); @@ -142,14 +141,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -169,22 +167,20 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'page1', - builder: - (BuildContext context, GoRouterState state) => - const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), ], ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -204,14 +200,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -275,9 +270,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), ]; @@ -298,15 +292,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -376,7 +368,10 @@ void main() { final UniqueKey dialog = UniqueKey(); final GlobalKey navKey = GlobalKey(); final List routes = [ - GoRoute(path: '/', builder: (_, __) => DummyScreen(key: home)), + GoRoute( + path: '/', + builder: (_, __) => DummyScreen(key: home), + ), GoRoute( path: '/settings', builder: (_, __) => DummyScreen(key: settings), @@ -429,13 +424,12 @@ void main() { builder: (_, __) => const Text('home'), routes: [ ShellRoute( - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Column(children: [const Text('shell'), child]); - }, + builder: + (BuildContext context, GoRouterState state, Widget child) { + return Column( + children: [const Text('shell'), child], + ); + }, routes: [ GoRoute( path: 'page', @@ -490,18 +484,18 @@ void main() { final List routes = [ GoRoute( path: '/', - pageBuilder: - (_, __) => const MaterialPage(child: HomeScreen()), + pageBuilder: (_, __) => + const MaterialPage(child: HomeScreen()), ), GoRoute( path: '/page1', - pageBuilder: - (_, __) => const MaterialPage(child: Page1Screen()), + pageBuilder: (_, __) => + const MaterialPage(child: Page1Screen()), ), GoRoute( path: '/page2', - pageBuilder: - (_, __) => const MaterialPage(child: Page2Screen()), + pageBuilder: (_, __) => + const MaterialPage(child: Page2Screen()), ), ]; final GoRouter router = await createRouter( @@ -536,14 +530,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -565,28 +558,25 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( path: 'person/:pid', - builder: - (BuildContext context, GoRouterState state) => - const PersonScreen('dummy', 'dummy'), + builder: (BuildContext context, GoRouterState state) => + const PersonScreen('dummy', 'dummy'), ), ], ), GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -646,32 +636,28 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'foo/bar', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen(''), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen(''), ), GoRoute( path: 'bar', - builder: - (BuildContext context, GoRouterState state) => - const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), GoRoute( path: 'foo', - builder: - (BuildContext context, GoRouterState state) => - const Page2Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page2Screen(), routes: [ GoRoute( path: 'bar', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -794,15 +780,14 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/family/:fid', caseSensitive: false, - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), ), ]; @@ -829,14 +814,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), ), ]; @@ -867,20 +851,18 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/abc', - builder: - (BuildContext context, GoRouterState state) => - const SizedBox(key: Key('abc')), + builder: (BuildContext context, GoRouterState state) => + const SizedBox(key: Key('abc')), ), GoRoute( path: '/ABC', - builder: - (BuildContext context, GoRouterState state) => - const SizedBox(key: Key('ABC')), + builder: (BuildContext context, GoRouterState state) => + const SizedBox(key: Key('ABC')), ), ]; @@ -1150,11 +1132,10 @@ void main() { GoRoute( path: '/', pageBuilder: (BuildContext context, GoRouterState state) { - final String value = - context - .dependOnInheritedWidgetOfExactType()! - .notifier! - .value; + final String value = context + .dependOnInheritedWidgetOfExactType()! + .notifier! + .value; return MaterialPage(key: state.pageKey, child: Text(value)); }, ), @@ -1219,16 +1200,17 @@ void main() { routes: [ ShellRoute( navigatorKey: shellNavigatorKeyB, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - appBar: AppBar(title: const Text('Shell')), - body: child, - ); - }, + builder: + ( + BuildContext context, + GoRouterState state, + Widget child, + ) { + return Scaffold( + appBar: AppBar(title: const Text('Shell')), + body: child, + ); + }, routes: [ GoRoute( path: 'b', @@ -1297,9 +1279,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), routes: [ ShellRoute( builder: @@ -1308,9 +1289,8 @@ void main() { routes: [ GoRoute( path: 'c', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -1547,13 +1527,10 @@ void main() { }, routes: [ ShellRoute( - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold(appBar: AppBar(), body: child); - }, + builder: + (BuildContext context, GoRouterState state, Widget child) { + return Scaffold(appBar: AppBar(), body: child); + }, routes: [ GoRoute( path: 'b', @@ -1619,10 +1596,8 @@ void main() { routes: [ GoRoute( path: 'settings', - builder: - (_, GoRouterState state) => DummyScreen( - key: ValueKey('settings-${state.extra}'), - ), + builder: (_, GoRouterState state) => + DummyScreen(key: ValueKey('settings-${state.extra}')), ), ], ), @@ -1675,7 +1650,10 @@ void main() { final UniqueKey login = UniqueKey(); final List routes = [ GoRoute(path: '/', builder: (_, __) => const DummyScreen()), - GoRoute(path: '/login', builder: (_, __) => DummyScreen(key: login)), + GoRoute( + path: '/login', + builder: (_, __) => DummyScreen(key: login), + ), ]; final Completer completer = Completer(); final GoRouter router = await createRouter( @@ -1716,8 +1694,8 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), ]; @@ -1757,15 +1735,14 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( name: 'login', path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -1778,15 +1755,14 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'login', path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -1801,15 +1777,14 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( name: 'person', @@ -1840,22 +1815,20 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( name: 'person', path: 'person/:pid', - builder: - (BuildContext context, GoRouterState state) => - const PersonScreen('dummy', 'dummy'), + builder: (BuildContext context, GoRouterState state) => + const PersonScreen('dummy', 'dummy'), ), ], ), @@ -1874,15 +1847,14 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'family', path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( name: 'PeRsOn', @@ -1915,9 +1887,8 @@ void main() { GoRoute( name: 'family', path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), ), ]; await expectLater(() async { @@ -1931,9 +1902,8 @@ void main() { GoRoute( name: 'family', path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), ), ]; await expectLater(() async { @@ -1950,15 +1920,14 @@ void main() { GoRoute(path: '/', builder: dummy, redirect: (_, __) => '/family/f2'), GoRoute( path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), routes: [ GoRoute( name: 'person', path: 'person:pid', - builder: - (BuildContext context, GoRouterState state) => PersonScreen( + builder: (BuildContext context, GoRouterState state) => + PersonScreen( state.pathParameters['fid']!, state.pathParameters['pid']!, ), @@ -2037,14 +2006,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2060,14 +2028,13 @@ void main() { final List routes = [ GoRoute( path: '/home', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2087,14 +2054,13 @@ void main() { final List routes = [ GoRoute( path: '/home', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( name: 'person', @@ -2135,14 +2101,13 @@ void main() { final List routes = [ GoRoute( path: '/home', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'family', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( path: 'person', @@ -2180,20 +2145,18 @@ void main() { final List routes = [ GoRoute( path: '/home', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'family/:fid', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( path: 'person/:pid', - builder: - (BuildContext context, GoRouterState state) => - const PersonScreen('dummy', 'dummy'), + builder: (BuildContext context, GoRouterState state) => + const PersonScreen('dummy', 'dummy'), ), ], ), @@ -2205,9 +2168,8 @@ void main() { routes, tester, initialLocation: '/home', - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); router.go('./family/person/$pid'); await tester.pumpAndSettle(); @@ -2222,20 +2184,18 @@ void main() { final List routes = [ GoRoute( path: '/home', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'family', - builder: - (BuildContext context, GoRouterState state) => - const FamilyScreen('dummy'), + builder: (BuildContext context, GoRouterState state) => + const FamilyScreen('dummy'), routes: [ GoRoute( path: 'person', - builder: - (BuildContext context, GoRouterState state) => - const PersonScreen('dummy', 'dummy'), + builder: (BuildContext context, GoRouterState state) => + const PersonScreen('dummy', 'dummy'), ), ], ), @@ -2247,9 +2207,8 @@ void main() { routes, tester, initialLocation: '/home', - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); router.go('person'); @@ -2322,11 +2281,10 @@ void main() { initialLocation: '/home', ); - final String loc = - Uri( - path: 'page1', - queryParameters: {'param1': param1}, - ).toString(); + final String loc = Uri( + path: 'page1', + queryParameters: {'param1': param1}, + ).toString(); router.go('./$loc'); await tester.pumpAndSettle(); @@ -2342,20 +2300,18 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2395,16 +2351,15 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', // Return same location. redirect: (_, GoRouterState state) => state.uri.toString(), - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -2436,22 +2391,20 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'dummy', path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( name: 'login', path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2460,11 +2413,10 @@ void main() { final GoRouter router = await createRouter( routes, tester, - redirect: - (BuildContext context, GoRouterState state) => - state.matchedLocation == '/login' - ? null - : state.namedLocation('login'), + redirect: (BuildContext context, GoRouterState state) => + state.matchedLocation == '/login' + ? null + : state.namedLocation('login'), ); expect( router.routerDelegate.currentConfiguration.uri.toString(), @@ -2476,21 +2428,19 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), redirect: (BuildContext context, GoRouterState state) => '/login', ), GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2511,14 +2461,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), redirect: (BuildContext context, GoRouterState state) { // should never be reached. assert(false); @@ -2527,15 +2476,13 @@ void main() { ), GoRoute( path: 'dummy2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2568,25 +2515,22 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'dummy', path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), - redirect: - (BuildContext context, GoRouterState state) => - state.namedLocation('login'), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), + redirect: (BuildContext context, GoRouterState state) => + state.namedLocation('login'), ), GoRoute( name: 'login', path: 'login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ], ), @@ -2605,20 +2549,18 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy1', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( path: 'dummy2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), redirect: (BuildContext context, GoRouterState state) => '/', ), ], @@ -2628,9 +2570,8 @@ void main() { final GoRouter router = await createRouter( routes, tester, - redirect: - (BuildContext context, GoRouterState state) => - state.matchedLocation == '/dummy1' ? '/dummy2' : null, + redirect: (BuildContext context, GoRouterState state) => + state.matchedLocation == '/dummy1' ? '/dummy2' : null, ); router.go('/dummy1'); await tester.pump(); @@ -2641,16 +2582,14 @@ void main() { final GoRouter router = await createRouter( [], tester, - redirect: - (BuildContext context, GoRouterState state) => - state.matchedLocation == '/' - ? '/login' - : state.matchedLocation == '/login' - ? '/' - : null, - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + redirect: (BuildContext context, GoRouterState state) => + state.matchedLocation == '/' + ? '/login' + : state.matchedLocation == '/login' + ? '/' + : null, + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); final List matches = router.routerDelegate.currentConfiguration.matches; @@ -2677,9 +2616,8 @@ void main() { ), ], tester, - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); final List matches = @@ -2702,12 +2640,10 @@ void main() { ), ], tester, - redirect: - (BuildContext context, GoRouterState state) => - state.matchedLocation == '/' ? '/login' : null, - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + redirect: (BuildContext context, GoRouterState state) => + state.matchedLocation == '/' ? '/login' : null, + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); final List matches = @@ -2726,16 +2662,14 @@ void main() { final GoRouter router = await createRouter( [], tester, - redirect: - (BuildContext context, GoRouterState state) => - state.matchedLocation == '/' - ? '/login?from=${state.uri}' - : state.matchedLocation == '/login' - ? '/' - : null, - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + redirect: (BuildContext context, GoRouterState state) => + state.matchedLocation == '/' + ? '/login?from=${state.uri}' + : state.matchedLocation == '/login' + ? '/' + : null, + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), ); final List matches = @@ -2754,8 +2688,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/dummy', @@ -2776,14 +2710,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/login', - builder: - (BuildContext context, GoRouterState state) => - const LoginScreen(), + builder: (BuildContext context, GoRouterState state) => + const LoginScreen(), ), ]; @@ -2815,15 +2748,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), routes: [ GoRoute( path: ':id', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -2887,9 +2818,8 @@ void main() { routes: [ GoRoute( path: 'family/:fid', - builder: - (BuildContext c, GoRouterState s) => - FamilyScreen(s.pathParameters['fid']!), + builder: (BuildContext c, GoRouterState s) => + FamilyScreen(s.pathParameters['fid']!), routes: [ GoRoute( path: 'person/:pid', @@ -2898,11 +2828,10 @@ void main() { expect(s.pathParameters['pid'], 'p1'); return null; }, - builder: - (BuildContext c, GoRouterState s) => PersonScreen( - s.pathParameters['fid']!, - s.pathParameters['pid']!, - ), + builder: (BuildContext c, GoRouterState s) => PersonScreen( + s.pathParameters['fid']!, + s.pathParameters['pid']!, + ), ), ], ), @@ -2932,11 +2861,10 @@ void main() { final GoRouter router = await createRouter( [], tester, - redirect: - (BuildContext context, GoRouterState state) => '/${state.uri}+', - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + redirect: (BuildContext context, GoRouterState state) => + '/${state.uri}+', + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), redirectLimit: 10, ); @@ -2997,8 +2925,8 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( name: 'login', @@ -3043,21 +2971,19 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), redirect: (BuildContext context, GoRouterState state) => '/other', routes: [ GoRoute( path: 'dummy2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), redirect: (BuildContext context, GoRouterState state) { assert(false); return '/other2'; @@ -3067,15 +2993,13 @@ void main() { ), GoRoute( path: 'other', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( path: 'other2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -3099,29 +3023,25 @@ void main() { final List routes = [ ShellRoute( redirect: (BuildContext context, GoRouterState state) => '/dummy', - builder: - (BuildContext context, GoRouterState state, Widget child) => - Scaffold(appBar: AppBar(), body: child), + builder: (BuildContext context, GoRouterState state, Widget child) => + Scaffold(appBar: AppBar(), body: child), routes: [ GoRoute( path: '/other', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), GoRoute( path: '/other2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), GoRoute( path: '/dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ]; @@ -3143,21 +3063,21 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( redirect: (BuildContext context, GoRouterState state) => '/dummy', - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/other', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -3165,9 +3085,8 @@ void main() { routes: [ GoRoute( path: '/other2', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -3175,9 +3094,8 @@ void main() { ), GoRoute( path: '/dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ]; @@ -3199,14 +3117,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -3227,8 +3144,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', @@ -3257,8 +3174,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/dummy', @@ -3279,22 +3196,21 @@ void main() { 'does not take precedence over platformDispatcher.defaultRouteName', (WidgetTester tester) async { TestWidgetsFlutterBinding - .instance - .platformDispatcher - .defaultRouteNameTestValue = '/dummy'; + .instance + .platformDispatcher + .defaultRouteNameTestValue = + '/dummy'; final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'dummy', - builder: - (BuildContext context, GoRouterState state) => - const DummyScreen(), + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), ), ], ), @@ -3325,8 +3241,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), ]; @@ -3335,9 +3251,10 @@ void main() { 'scheme, authority, no path', (WidgetTester tester) async { TestWidgetsFlutterBinding - .instance - .platformDispatcher - .defaultRouteNameTestValue = 'https://domain.com'; + .instance + .platformDispatcher + .defaultRouteNameTestValue = + 'https://domain.com'; final GoRouter router = await createRouter(routes, tester); expect(router.routeInformationProvider.value.uri.path, '/'); TestWidgetsFlutterBinding.instance.platformDispatcher @@ -3350,9 +3267,10 @@ void main() { 'scheme, authority, no path, but trailing slash', (WidgetTester tester) async { TestWidgetsFlutterBinding - .instance - .platformDispatcher - .defaultRouteNameTestValue = 'https://domain.com/'; + .instance + .platformDispatcher + .defaultRouteNameTestValue = + 'https://domain.com/'; final GoRouter router = await createRouter(routes, tester); expect(router.routeInformationProvider.value.uri.path, '/'); TestWidgetsFlutterBinding.instance.platformDispatcher @@ -3365,9 +3283,10 @@ void main() { 'scheme, authority, no path, and query parameters', (WidgetTester tester) async { TestWidgetsFlutterBinding - .instance - .platformDispatcher - .defaultRouteNameTestValue = 'https://domain.com?param=1'; + .instance + .platformDispatcher + .defaultRouteNameTestValue = + 'https://domain.com?param=1'; final GoRouter router = await createRouter(routes, tester); expect( router.routeInformationProvider.value.uri.toString(), @@ -3384,14 +3303,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), ), ]; @@ -3414,14 +3332,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/family', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.uri.queryParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.uri.queryParameters['fid']!), ), ]; @@ -3502,9 +3419,8 @@ void main() { routes: [ GoRoute(path: '/:id/:blah/:bam/:id/:blah', builder: dummy), ], - errorBuilder: - (BuildContext context, GoRouterState state) => - TestErrorScreen(state.error!), + errorBuilder: (BuildContext context, GoRouterState state) => + TestErrorScreen(state.error!), initialLocation: '/0/1/2/0/1', ); expect(false, true); @@ -3561,17 +3477,15 @@ void main() { GoRoute(path: '/', builder: dummy), GoRoute( path: '/family', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.uri.queryParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.uri.queryParameters['fid']!), ), GoRoute( path: '/person', - builder: - (BuildContext context, GoRouterState state) => PersonScreen( - state.uri.queryParameters['fid']!, - state.uri.queryParameters['pid']!, - ), + builder: (BuildContext context, GoRouterState state) => PersonScreen( + state.uri.queryParameters['fid']!, + state.uri.queryParameters['pid']!, + ), ), ], tester); @@ -3596,17 +3510,15 @@ void main() { GoRoute(path: '/', builder: dummy), GoRoute( path: '/family', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen((state.extra! as Map)['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen((state.extra! as Map)['fid']!), ), GoRoute( path: '/person', - builder: - (BuildContext context, GoRouterState state) => PersonScreen( - (state.extra! as Map)['fid']!, - (state.extra! as Map)['pid']!, - ), + builder: (BuildContext context, GoRouterState state) => PersonScreen( + (state.extra! as Map)['fid']!, + (state.extra! as Map)['pid']!, + ), ), ], tester); @@ -3630,14 +3542,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( path: '/family/:fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), routes: [ GoRoute( path: 'person/:pid', @@ -3676,22 +3587,22 @@ void main() { StatefulNavigationShell? routeState; final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -3699,15 +3610,13 @@ void main() { routes: [ GoRoute( path: '/family', - builder: - (BuildContext context, GoRouterState state) => - const Text('Families'), + builder: (BuildContext context, GoRouterState state) => + const Text('Families'), routes: [ GoRoute( path: ':fid', - builder: - (BuildContext context, GoRouterState state) => - FamilyScreen(state.pathParameters['fid']!), + builder: (BuildContext context, GoRouterState state) => + FamilyScreen(state.pathParameters['fid']!), routes: [ GoRoute( path: 'person/:pid', @@ -3771,22 +3680,22 @@ void main() { Object? latestExtra; final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -3836,8 +3745,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( name: 'page', @@ -3896,8 +3805,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( name: 'page', @@ -3947,8 +3856,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( name: 'page', @@ -3989,15 +3898,14 @@ void main() { GoRoute( path: '/', name: 'home', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: key), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: key), ), GoRoute( path: '/page1', name: 'page1', - builder: - (BuildContext context, GoRouterState state) => const Page1Screen(), + builder: (BuildContext context, GoRouterState state) => + const Page1Screen(), ), ]; @@ -4359,9 +4267,8 @@ void main() { routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -4369,9 +4276,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), ), ], ), @@ -4403,8 +4309,8 @@ void main() { final List routes = [ GoRoute( path: '/root', - builder: - (BuildContext context, GoRouterState state) => const Text('Root'), + builder: (BuildContext context, GoRouterState state) => + const Text('Root'), routes: [ StatefulShellRoute.indexedStack( builder: @@ -4418,9 +4324,8 @@ void main() { routes: [ GoRoute( path: 'a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -4428,9 +4333,8 @@ void main() { routes: [ GoRoute( path: 'b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), ), ], ), @@ -4466,22 +4370,22 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -4489,9 +4393,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), ), ], ), @@ -4499,9 +4402,8 @@ void main() { routes: [ GoRoute( path: '/c', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen C'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen C'), ), ], ), @@ -4509,9 +4411,8 @@ void main() { routes: [ GoRoute( path: '/d', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen D'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen D'), ), ], ), @@ -4571,33 +4472,32 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), routes: [ GoRoute( path: 'detailA', - builder: - (BuildContext context, GoRouterState state) => - Column( - children: [ - const Text('Screen A Detail'), - DummyStatefulWidget(key: statefulWidgetKey), - ], - ), + builder: (BuildContext context, GoRouterState state) => + Column( + children: [ + const Text('Screen A Detail'), + DummyStatefulWidget(key: statefulWidgetKey), + ], + ), ), ], ), @@ -4607,9 +4507,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), ), ], ), @@ -4660,22 +4559,22 @@ void main() { builder: (_, __) => const Placeholder(), routes: [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: 'a', - builder: - (BuildContext context, GoRouterState state) => - Text('a id is ${state.pathParameters['id']}'), + builder: (BuildContext context, GoRouterState state) => + Text('a id is ${state.pathParameters['id']}'), ), ], ), @@ -4683,9 +4582,8 @@ void main() { routes: [ GoRoute( path: 'b', - builder: - (BuildContext context, GoRouterState state) => - Text('b id is ${state.pathParameters['id']}'), + builder: (BuildContext context, GoRouterState state) => + Text('b id is ${state.pathParameters['id']}'), ), ], ), @@ -4716,26 +4614,28 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState1 = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState1 = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState2 = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState2 = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ @@ -4790,9 +4690,8 @@ void main() { routes: [ GoRoute( path: '/d', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen D'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen D'), ), ], ), @@ -4844,29 +4743,28 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( navigatorKey: sectionANavigatorKey, routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), routes: [ GoRoute( path: 'detailA', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A Detail'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A Detail'), ), ], ), @@ -4877,15 +4775,13 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), routes: [ GoRoute( path: 'detailB', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B Detail'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B Detail'), ), ], ), @@ -4942,22 +4838,22 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -4965,9 +4861,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - Text('Screen B - ${state.extra}'), + builder: (BuildContext context, GoRouterState state) => + Text('Screen B - ${state.extra}'), ), ], ), @@ -5010,27 +4905,26 @@ void main() { final List routes = [ GoRoute( path: '/common', - builder: - (BuildContext context, GoRouterState state) => - Text('Common - ${state.extra}'), + builder: (BuildContext context, GoRouterState state) => + Text('Common - ${state.extra}'), ), StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -5038,9 +4932,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), ), ], ), @@ -5102,9 +4995,8 @@ void main() { routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyA), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyA), ), ], ), @@ -5112,9 +5004,8 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyB), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyB), ), ], ), @@ -5128,9 +5019,8 @@ void main() { routes: [ GoRoute( path: '/c', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyC), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyC), ), ], ), @@ -5139,9 +5029,8 @@ void main() { routes: [ GoRoute( path: '/d', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyD), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyD), ), ], ), @@ -5151,15 +5040,13 @@ void main() { routes: [ GoRoute( path: '/e', - builder: - (BuildContext context, GoRouterState state) => - const Text('E'), + builder: (BuildContext context, GoRouterState state) => + const Text('E'), routes: [ GoRoute( path: 'details', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyE), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyE), ), ], ), @@ -5242,9 +5129,8 @@ void main() { routes: [ GoRoute( path: '/c', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyC), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyC), ), ], ), @@ -5252,9 +5138,8 @@ void main() { routes: [ GoRoute( path: '/d', - builder: - (BuildContext context, GoRouterState state) => - DummyStatefulWidget(key: statefulWidgetKeyD), + builder: (BuildContext context, GoRouterState state) => + DummyStatefulWidget(key: statefulWidgetKeyD), ), ], ), @@ -5282,22 +5167,22 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -5305,21 +5190,18 @@ void main() { routes: [ GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B'), routes: [ GoRoute( path: 'details1', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B Detail1'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B Detail1'), ), GoRoute( path: 'details2', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen B Detail2'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen B Detail2'), ), ], ), @@ -5330,15 +5212,13 @@ void main() { GoRoute(path: '/c', redirect: (_, __) => '/c/main2'), GoRoute( path: '/c/main1', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen C1'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen C1'), ), GoRoute( path: '/c/main2', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen C2'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen C2'), ), ], ), @@ -5393,22 +5273,22 @@ void main() { final List routes = [ // First level shell StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Text('Screen A'), + builder: (BuildContext context, GoRouterState state) => + const Text('Screen A'), ), ], ), @@ -5464,9 +5344,8 @@ void main() { GoRoute( path: '/top-modal', parentNavigatorKey: rootNavigatorKey, - builder: - (BuildContext context, GoRouterState state) => - const Text('Top Modal'), + builder: (BuildContext context, GoRouterState state) => + const Text('Top Modal'), ), ]; @@ -5532,9 +5411,8 @@ void main() { routes: [ GoRoute( path: '/$name', - builder: - (BuildContext context, GoRouterState state) => - Text('Screen $name'), + builder: (BuildContext context, GoRouterState state) => + Text('Screen $name'), ), ], ); @@ -5542,14 +5420,15 @@ void main() { List createRoutes(bool includeCRoute) => [ StatefulShellRoute.indexedStack( key: statefulShellKey, - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return navigationShell; + }, branches: [ makeBranch('a'), makeBranch('b'), @@ -5658,16 +5537,13 @@ void main() { routes: [ ShellRoute( navigatorKey: shellNavigatorKey, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - appBar: AppBar(title: const Text('Shell')), - body: child, - ); - }, + builder: + (BuildContext context, GoRouterState state, Widget child) { + return Scaffold( + appBar: AppBar(title: const Text('Shell')), + body: child, + ); + }, routes: [ GoRoute( path: '/a', @@ -5803,22 +5679,19 @@ void main() { routes: [ ShellRoute( navigatorKey: shell, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - body: Center( - child: Column( - children: [ - const Text('Shell'), - Expanded(child: child), - ], - ), - ), - ); - }, + builder: + (BuildContext context, GoRouterState state, Widget child) { + return Scaffold( + body: Center( + child: Column( + children: [ + const Text('Shell'), + Expanded(child: child), + ], + ), + ), + ); + }, routes: [ GoRoute(path: '/', builder: (_, __) => const Text('A Screen')), ], @@ -5865,22 +5738,23 @@ void main() { routes: [ ShellRoute( navigatorKey: shell, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - body: Center( - child: Column( - children: [ - const Text('Shell'), - Expanded(child: child), - ], - ), - ), - ); - }, + builder: + ( + BuildContext context, + GoRouterState state, + Widget child, + ) { + return Scaffold( + body: Center( + child: Column( + children: [ + const Text('Shell'), + Expanded(child: child), + ], + ), + ), + ); + }, routes: [ GoRoute( path: 'a', @@ -5948,22 +5822,23 @@ void main() { routes: [ ShellRoute( navigatorKey: shell, - builder: ( - BuildContext context, - GoRouterState state, - Widget child, - ) { - return Scaffold( - body: Center( - child: Column( - children: [ - const Text('Shell'), - Expanded(child: child), - ], - ), - ), - ); - }, + builder: + ( + BuildContext context, + GoRouterState state, + Widget child, + ) { + return Scaffold( + body: Center( + child: Column( + children: [ + const Text('Shell'), + Expanded(child: child), + ], + ), + ), + ); + }, routes: [ GoRoute( path: 'a', @@ -6061,7 +5936,10 @@ void main() { ) async { const Key key = Key('key'); final List routes = [ - GoRoute(path: '/', builder: (_, __) => const SizedBox(key: key)), + GoRoute( + path: '/', + builder: (_, __) => const SizedBox(key: key), + ), ]; final GoRouter router = await createRouter(routes, tester); @@ -6087,7 +5965,10 @@ void main() { ) async { const Key key = Key('key'); final List routes = [ - GoRoute(path: '/', builder: (_, __) => const SizedBox(key: key)), + GoRoute( + path: '/', + builder: (_, __) => const SizedBox(key: key), + ), ]; final GoRouter router = await createRouter(routes, tester); @@ -6174,17 +6055,18 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( restorationScopeId: 'shell', - pageBuilder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeState = navigationShell; - return MaterialPage( - restorationId: 'shellWidget', - child: navigationShell, - ); - }, + pageBuilder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeState = navigationShell; + return MaterialPage( + restorationId: 'shellWidget', + child: navigationShell, + ); + }, branches: [ StatefulShellBranch( restorationScopeId: 'branchA', @@ -6334,17 +6216,18 @@ void main() { final List routes = [ StatefulShellRoute.indexedStack( restorationScopeId: 'shell', - pageBuilder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeStateRoot = navigationShell; - return MaterialPage( - restorationId: 'shellWidget', - child: navigationShell, - ); - }, + pageBuilder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeStateRoot = navigationShell; + return MaterialPage( + restorationId: 'shellWidget', + child: navigationShell, + ); + }, branches: [ StatefulShellBranch( restorationScopeId: 'branchA', @@ -6380,17 +6263,18 @@ void main() { routes: [ StatefulShellRoute.indexedStack( restorationScopeId: 'branchB-nested-shell', - pageBuilder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - routeStateNested = navigationShell; - return MaterialPage( - restorationId: 'shellWidget-nested', - child: navigationShell, - ); - }, + pageBuilder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + routeStateNested = navigationShell; + return MaterialPage( + restorationId: 'shellWidget-nested', + child: navigationShell, + ); + }, branches: [ StatefulShellBranch( restorationScopeId: 'branchB-nested', @@ -6501,15 +6385,13 @@ void main() { routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), ], ), @@ -6529,15 +6411,13 @@ void main() { final List routes = [ GoRoute( path: '/abc', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), GoRoute( path: '/bcd', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), ]; @@ -6595,34 +6475,30 @@ void main() { GoRoute( name: 'home', path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), ), GoRoute( name: 'books', path: '/books', - builder: - (BuildContext context, GoRouterState state) => - const Text('books'), + builder: (BuildContext context, GoRouterState state) => + const Text('books'), ), GoRoute( name: 'boats', path: '/boats', - builder: - (BuildContext context, GoRouterState state) => - const Text('boats'), + builder: (BuildContext context, GoRouterState state) => + const Text('boats'), ), ShellRoute( - builder: - (BuildContext context, GoRouterState state, Widget child) => - child, + builder: (BuildContext context, GoRouterState state, Widget child) => + child, routes: [ GoRoute( name: 'tulips', path: '/tulips', - builder: - (BuildContext context, GoRouterState state) => - const Text('tulips'), + builder: (BuildContext context, GoRouterState state) => + const Text('tulips'), ), ], ), @@ -6674,26 +6550,23 @@ void main() { final List routes = [ GoRoute( path: '/', // root cannot be empty (existing assert) - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: 'child-route', - builder: - (BuildContext context, GoRouterState state) => - const Text('/child-route'), + builder: (BuildContext context, GoRouterState state) => + const Text('/child-route'), routes: [ GoRoute( path: 'grand-child-route', - builder: - (BuildContext context, GoRouterState state) => - const Text('/grand-child-route'), + builder: (BuildContext context, GoRouterState state) => + const Text('/grand-child-route'), ), GoRoute( path: 'redirected-grand-child-route', - redirect: - (BuildContext context, GoRouterState state) => - '/child-route', + redirect: (BuildContext context, GoRouterState state) => + '/child-route', ), ], ), @@ -6725,26 +6598,23 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => const HomeScreen(), + builder: (BuildContext context, GoRouterState state) => + const HomeScreen(), routes: [ GoRoute( path: '/child-route', - builder: - (BuildContext context, GoRouterState state) => - const Text('/child-route'), + builder: (BuildContext context, GoRouterState state) => + const Text('/child-route'), routes: [ GoRoute( path: '/grand-child-route', - builder: - (BuildContext context, GoRouterState state) => - const Text('/grand-child-route'), + builder: (BuildContext context, GoRouterState state) => + const Text('/grand-child-route'), ), GoRoute( path: '/redirected-grand-child-route', - redirect: - (BuildContext context, GoRouterState state) => - '/child-route', + redirect: (BuildContext context, GoRouterState state) => + '/child-route', ), ], ), diff --git a/packages/go_router/test/imperative_api_test.dart b/packages/go_router/test/imperative_api_test.dart index 4075e3374b0..de3cbda0cf0 100644 --- a/packages/go_router/test/imperative_api_test.dart +++ b/packages/go_router/test/imperative_api_test.dart @@ -22,8 +22,14 @@ void main() { ); }, routes: [ - GoRoute(path: '/a', builder: (_, __) => DummyScreen(key: a)), - GoRoute(path: '/b', builder: (_, __) => DummyScreen(key: b)), + GoRoute( + path: '/a', + builder: (_, __) => DummyScreen(key: a), + ), + GoRoute( + path: '/b', + builder: (_, __) => DummyScreen(key: b), + ), ], ), ]; @@ -48,7 +54,10 @@ void main() { final UniqueKey a = UniqueKey(); final UniqueKey b = UniqueKey(); final List routes = [ - GoRoute(path: '/a', builder: (_, __) => DummyScreen(key: a)), + GoRoute( + path: '/a', + builder: (_, __) => DummyScreen(key: a), + ), ShellRoute( builder: (_, __, Widget child) { return Scaffold( @@ -57,7 +66,10 @@ void main() { ); }, routes: [ - GoRoute(path: '/b', builder: (_, __) => DummyScreen(key: b)), + GoRoute( + path: '/b', + builder: (_, __) => DummyScreen(key: b), + ), ], ), ]; @@ -96,7 +108,10 @@ void main() { path: '/', builder: (_, __) => DummyScreen(key: home), routes: [ - GoRoute(path: 'a', builder: (_, __) => DummyScreen(key: a)), + GoRoute( + path: 'a', + builder: (_, __) => DummyScreen(key: a), + ), ], ), ], @@ -139,7 +154,10 @@ void main() { ); }, routes: [ - GoRoute(path: '/a', builder: (_, __) => DummyScreen(key: a)), + GoRoute( + path: '/a', + builder: (_, __) => DummyScreen(key: a), + ), ], ), ShellRoute( @@ -150,7 +168,10 @@ void main() { ); }, routes: [ - GoRoute(path: '/b', builder: (_, __) => DummyScreen(key: b)), + GoRoute( + path: '/b', + builder: (_, __) => DummyScreen(key: b), + ), ], ), ]; @@ -186,10 +207,16 @@ void main() { ); }, routes: [ - GoRoute(path: '/in', builder: (_, __) => DummyScreen(key: inside)), + GoRoute( + path: '/in', + builder: (_, __) => DummyScreen(key: inside), + ), ], ), - GoRoute(path: '/out', builder: (_, __) => DummyScreen(key: outside)), + GoRoute( + path: '/out', + builder: (_, __) => DummyScreen(key: outside), + ), ]; final GoRouter router = await createRouter( routes, @@ -229,18 +256,30 @@ void main() { ); }, routes: [ - GoRoute(path: '/a', builder: (_, __) => DummyScreen(key: a)), - GoRoute(path: '/c', builder: (_, __) => DummyScreen(key: c)), + GoRoute( + path: '/a', + builder: (_, __) => DummyScreen(key: a), + ), + GoRoute( + path: '/c', + builder: (_, __) => DummyScreen(key: c), + ), ], ), GoRoute( path: '/d', builder: (_, __) => DummyScreen(key: d), routes: [ - GoRoute(path: 'e', builder: (_, __) => DummyScreen(key: e)), + GoRoute( + path: 'e', + builder: (_, __) => DummyScreen(key: e), + ), ], ), - GoRoute(path: '/b', builder: (_, __) => DummyScreen(key: b)), + GoRoute( + path: '/b', + builder: (_, __) => DummyScreen(key: b), + ), ]; final GoRouter router = await createRouter( routes, diff --git a/packages/go_router/test/matching_test.dart b/packages/go_router/test/matching_test.dart index 48cdf5db48c..e195d182d85 100644 --- a/packages/go_router/test/matching_test.dart +++ b/packages/go_router/test/matching_test.dart @@ -18,8 +18,8 @@ void main() { final List routes = [ GoRoute( path: '/page-0', - builder: - (BuildContext context, GoRouterState state) => const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), ]; @@ -36,8 +36,8 @@ void main() { test('RouteMatchList compares', () async { final GoRoute route = GoRoute( path: '/page-0', - builder: - (BuildContext context, GoRouterState state) => const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ); final Map params1 = {}; final List match1 = RouteMatchBase.match( @@ -82,15 +82,13 @@ void main() { routes: [ GoRoute( path: '/a', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), GoRoute( path: '/b', - builder: - (BuildContext context, GoRouterState state) => - const Placeholder(), + builder: (BuildContext context, GoRouterState state) => + const Placeholder(), ), ], redirectLimit: 0, diff --git a/packages/go_router/test/on_exit_test.dart b/packages/go_router/test/on_exit_test.dart index cf996954278..07f5be7e4bf 100644 --- a/packages/go_router/test/on_exit_test.dart +++ b/packages/go_router/test/on_exit_test.dart @@ -18,15 +18,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), routes: [ GoRoute( path: '1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) { return allow; }, @@ -59,15 +57,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), ), GoRoute( path: '/1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) { return allow; }, @@ -98,15 +94,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), routes: [ GoRoute( path: '1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) async { return allow.future; }, @@ -147,15 +141,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), ), GoRoute( path: '/1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) async { return allow.future; }, @@ -195,9 +187,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), onExit: (BuildContext context, GoRouterState state) { return allow; }, @@ -222,9 +213,8 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), onExit: (BuildContext context, GoRouterState state) async { return allow; }, @@ -252,9 +242,8 @@ void main() { routes: [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), onExit: (BuildContext context, GoRouterState state) { return allow; }, @@ -286,15 +275,13 @@ void main() { final List routes = [ GoRoute( path: '/', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: home), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: home), routes: [ GoRoute( path: '1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) { onExitState1 = state; return true; @@ -302,9 +289,8 @@ void main() { routes: [ GoRoute( path: '2', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page2), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page2), onExit: (BuildContext context, GoRouterState state) { onExitState2 = state; return true; @@ -312,9 +298,8 @@ void main() { routes: [ GoRoute( path: '3', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page3), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page3), onExit: (BuildContext context, GoRouterState state) { onExitState3 = state; return true; @@ -365,15 +350,13 @@ void main() { final List routes = [ GoRoute( path: '/route-0/:id0', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page0), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page0), ), GoRoute( path: '/route-1/:id1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) { onExitState1 = state; return true; @@ -381,9 +364,8 @@ void main() { ), GoRoute( path: '/route-2/:id2', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page2), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page2), onExit: (BuildContext context, GoRouterState state) { onExitState2 = state; return true; @@ -449,9 +431,8 @@ void main() { final List routes = [ GoRoute( path: '/route-0/:id0', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page0), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page0), onExit: (BuildContext context, GoRouterState state) { onExitState0 = state; return true; @@ -459,9 +440,8 @@ void main() { ), GoRoute( path: '/route-1/:id1', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page1), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page1), onExit: (BuildContext context, GoRouterState state) { onExitState1 = state; return true; @@ -469,9 +449,8 @@ void main() { ), GoRoute( path: '/route-2/:id2', - builder: - (BuildContext context, GoRouterState state) => - DummyScreen(key: page2), + builder: (BuildContext context, GoRouterState state) => + DummyScreen(key: page2), onExit: (BuildContext context, GoRouterState state) { onExitState2 = state; return true; diff --git a/packages/go_router/test/parser_test.dart b/packages/go_router/test/parser_test.dart index 838e85f2b6c..9520336768d 100644 --- a/packages/go_router/test/parser_test.dart +++ b/packages/go_router/test/parser_test.dart @@ -263,8 +263,9 @@ void main() { expect(matchList.uri.toString(), '/abc'); expect(matchList.matches.length, 3); - final RouteInformation restoredRouteInformation = - router.routeInformationParser.restoreRouteInformation(matchList)!; + final RouteInformation restoredRouteInformation = router + .routeInformationParser + .restoreRouteInformation(matchList)!; expect(restoredRouteInformation.uri.path, '/'); // Can restore back to original RouteMatchList. @@ -597,9 +598,8 @@ void main() { GoRoute( path: '/abc', builder: (_, __) => const Placeholder(), - redirect: - (BuildContext context, GoRouterState state) => - state.uri.toString(), + redirect: (BuildContext context, GoRouterState state) => + state.uri.toString(), ), ]; final GoRouteInformationParser parser = await createParser( diff --git a/packages/go_router/test/path_utils_test.dart b/packages/go_router/test/path_utils_test.dart index df3fd875fd4..32218ffcd47 100644 --- a/packages/go_router/test/path_utils_test.dart +++ b/packages/go_router/test/path_utils_test.dart @@ -111,8 +111,10 @@ void main() { test('concatenateUris', () { void verify(String pathA, String pathB, String expected) { - final String result = - concatenateUris(Uri.parse(pathA), Uri.parse(pathB)).toString(); + final String result = concatenateUris( + Uri.parse(pathA), + Uri.parse(pathB), + ).toString(); expect(result, expected); } diff --git a/packages/go_router/test/route_data_test.dart b/packages/go_router/test/route_data_test.dart index 96144c64c0b..61726de2649 100644 --- a/packages/go_router/test/route_data_test.dart +++ b/packages/go_router/test/route_data_test.dart @@ -193,8 +193,8 @@ class _StatefulShellRouteDataPageBuilder extends StatefulShellRouteData { final StatefulShellRoute _statefulShellRouteDataPageBuilder = StatefulShellRouteData.$route( - factory: - (GoRouterState state) => const _StatefulShellRouteDataPageBuilder(), + factory: (GoRouterState state) => + const _StatefulShellRouteDataPageBuilder(), branches: [ StatefulShellBranchData.$branch( routes: [ @@ -318,8 +318,8 @@ void main() { ) async { final List errors = []; - FlutterError.onError = - (FlutterErrorDetails details) => errors.add(details); + FlutterError.onError = (FlutterErrorDetails details) => + errors.add(details); const String errorText = 'Should be generated'; @@ -329,11 +329,10 @@ void main() { await tester.pumpWidget( MaterialApp( home: Builder( - builder: - (BuildContext context) => GestureDetector( - child: const Text('Tap'), - onTap: () => onTap(context), - ), + builder: (BuildContext context) => GestureDetector( + child: const Text('Tap'), + onTap: () => onTap(context), + ), ), ), ); @@ -403,8 +402,8 @@ void main() { final GoRoute routeWithDefaultCaseSensitivity = RelativeGoRouteData.$route( path: 'path', - factory: - (GoRouterState state) => const _RelativeGoRouteDataBuild(), + factory: (GoRouterState state) => + const _RelativeGoRouteDataBuild(), ); expect(routeWithDefaultCaseSensitivity.caseSensitive, true); @@ -418,8 +417,8 @@ void main() { RelativeGoRouteData.$route( path: 'path', caseSensitive: false, - factory: - (GoRouterState state) => const _RelativeGoRouteDataBuild(), + factory: (GoRouterState state) => + const _RelativeGoRouteDataBuild(), ); expect(routeWithDefaultCaseSensitivity.caseSensitive, false); @@ -431,8 +430,8 @@ void main() { ) async { final List errors = []; - FlutterError.onError = - (FlutterErrorDetails details) => errors.add(details); + FlutterError.onError = (FlutterErrorDetails details) => + errors.add(details); const String errorText = 'Should be generated'; @@ -442,11 +441,10 @@ void main() { await tester.pumpWidget( MaterialApp( home: Builder( - builder: - (BuildContext context) => GestureDetector( - child: const Text('Tap'), - onTap: () => onTap(context), - ), + builder: (BuildContext context) => GestureDetector( + child: const Text('Tap'), + onTap: () => onTap(context), + ), ), ), ); @@ -510,29 +508,25 @@ void main() { initialLocation: '/child/test', routes: [ ShellRouteData.$route( - factory: - (GoRouterState state) => - const _ShellRouteDataWithKey(Key('under-shell')), + factory: (GoRouterState state) => + const _ShellRouteDataWithKey(Key('under-shell')), routes: [ GoRouteData.$route( path: '/child', - factory: - (GoRouterState state) => - const _GoRouteDataBuildWithKey(Key('under')), + factory: (GoRouterState state) => + const _GoRouteDataBuildWithKey(Key('under')), routes: [ ShellRouteData.$route( - factory: - (GoRouterState state) => - const _ShellRouteDataWithKey(Key('above-shell')), + factory: (GoRouterState state) => + const _ShellRouteDataWithKey(Key('above-shell')), navigatorKey: inner, parentNavigatorKey: root, routes: [ GoRouteData.$route( parentNavigatorKey: inner, path: 'test', - factory: - (GoRouterState state) => - const _GoRouteDataBuildWithKey(Key('above')), + factory: (GoRouterState state) => + const _GoRouteDataBuildWithKey(Key('above')), ), ], ), @@ -620,8 +614,8 @@ void main() { final GlobalKey key = GlobalKey(); final StatefulShellRoute route = StatefulShellRouteData.$route( parentNavigatorKey: key, - factory: - (GoRouterState state) => const _StatefulShellRouteDataPageBuilder(), + factory: (GoRouterState state) => + const _StatefulShellRouteDataPageBuilder(), branches: [ StatefulShellBranchData.$branch( routes: [ @@ -673,9 +667,8 @@ void main() { routes: [ _goRouteDataBuildPage, StatefulShellRouteData.$route( - factory: - (GoRouterState state) => - const _StatefulShellRouteDataRedirectPage(), + factory: (GoRouterState state) => + const _StatefulShellRouteDataRedirectPage(), branches: [ StatefulShellBranchData.$branch( routes: [ diff --git a/packages/go_router/test/routing_config_test.dart b/packages/go_router/test/routing_config_test.dart index 6c64aeee057..01eb5330c7d 100644 --- a/packages/go_router/test/routing_config_test.dart +++ b/packages/go_router/test/routing_config_test.dart @@ -129,8 +129,8 @@ void main() { routes: [ GoRoute( path: '/', - builder: - (_, __) => StatefulTest(key: key, child: const Text('home')), + builder: (_, __) => + StatefulTest(key: key, child: const Text('home')), ), ], ), @@ -179,9 +179,8 @@ void main() { routes: [ GoRoute(path: '/', builder: (_, __) => const Text('home')), ], - builder: - (_, __, Widget widget) => - StatefulTest(key: key, child: widget), + builder: (_, __, Widget widget) => + StatefulTest(key: key, child: widget), ), ], ), @@ -204,8 +203,8 @@ void main() { GoRoute(path: '/', builder: (_, __) => const Text('home')), GoRoute(path: '/abc', builder: (_, __) => const Text('/abc')), ], - builder: - (_, __, Widget widget) => StatefulTest(key: key, child: widget), + builder: (_, __, Widget widget) => + StatefulTest(key: key, child: widget), ), ], ); diff --git a/packages/go_router/test/stateful_shell_route_system_back_test.dart b/packages/go_router/test/stateful_shell_route_system_back_test.dart index 4df7d89f70e..834af97b01b 100644 --- a/packages/go_router/test/stateful_shell_route_system_back_test.dart +++ b/packages/go_router/test/stateful_shell_route_system_back_test.dart @@ -117,13 +117,14 @@ class _TestAppState extends State<_TestApp> { }, routes: [ StatefulShellRoute.indexedStack( - builder: ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, - ) { - return navigationShell; - }, + builder: + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return navigationShell; + }, branches: [ StatefulShellBranch( routes: [ diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 261faf16d68..13a4d5564bf 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -194,8 +194,9 @@ Future createRouter( addTearDown(goRouter.dispose); await tester.pumpWidget( MaterialApp.router( - restorationScopeId: - restorationScopeId != null ? '$restorationScopeId-root' : null, + restorationScopeId: restorationScopeId != null + ? '$restorationScopeId-root' + : null, routerConfig: goRouter, ), ); @@ -228,8 +229,9 @@ Future createRouterWithRoutingConfig( addTearDown(goRouter.dispose); await tester.pumpWidget( MaterialApp.router( - restorationScopeId: - restorationScopeId != null ? '$restorationScopeId-root' : null, + restorationScopeId: restorationScopeId != null + ? '$restorationScopeId-root' + : null, routerConfig: goRouter, ), ); @@ -373,13 +375,14 @@ GoRouterPageBuilder createPageBuilder({ (BuildContext context, GoRouterState state) => MaterialPage(restorationId: restorationId, child: child); -StatefulShellRouteBuilder mockStackedShellBuilder = ( - BuildContext context, - GoRouterState state, - StatefulNavigationShell navigationShell, -) { - return navigationShell; -}; +StatefulShellRouteBuilder mockStackedShellBuilder = + ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return navigationShell; + }; /// A routing config that is never going to change. class ConstantRoutingConfig extends ValueListenable { @@ -424,8 +427,8 @@ class SimpleDependencyProvider extends InheritedNotifier { }) : super(notifier: dependency); static SimpleDependency of(BuildContext context) { - final SimpleDependencyProvider result = - context.dependOnInheritedWidgetOfExactType()!; + final SimpleDependencyProvider result = context + .dependOnInheritedWidgetOfExactType()!; return result.notifier!; } } diff --git a/packages/go_router/tool/run_tests.dart b/packages/go_router/tool/run_tests.dart index 7a41e08c840..6fa363072dd 100644 --- a/packages/go_router/tool/run_tests.dart +++ b/packages/go_router/tool/run_tests.dart @@ -19,8 +19,9 @@ import 'package:path/path.dart' as p; // that references `go_router`, and running `dart fix --compare-to-golden` // on the temp directory. Future main(List args) async { - final Directory goRouterPackageRoot = - File.fromUri(Platform.script).parent.parent; + final Directory goRouterPackageRoot = File.fromUri( + Platform.script, + ).parent.parent; final Directory testTempDir = await Directory.systemTemp.createTemp(); @@ -72,7 +73,8 @@ Future _prepareTemplate({ // The pubspec.yaml file to create. final File targetPubspecFile = File(p.join(testTempDir.path, 'pubspec.yaml')); - final String targetYaml = ''' + final String targetYaml = + ''' name: test_fixes publish_to: "none" version: 1.0.0 diff --git a/packages/google_fonts/CHANGELOG.md b/packages/google_fonts/CHANGELOG.md index b49a261fe0d..42e50ba2b86 100644 --- a/packages/google_fonts/CHANGELOG.md +++ b/packages/google_fonts/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.4.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 6.3.2 - Makes a map keyed on FontWeight non-const for compatibility with proposed changes to the engine's implementation of FontWeight. diff --git a/packages/google_fonts/example/android/app/build.gradle b/packages/google_fonts/example/android/app/build.gradle index def30ec1102..d4c0f02efd6 100644 --- a/packages/google_fonts/example/android/app/build.gradle +++ b/packages/google_fonts/example/android/app/build.gradle @@ -11,12 +11,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17 } sourceSets { diff --git a/packages/google_fonts/example/lib/example_font_selection.dart b/packages/google_fonts/example/lib/example_font_selection.dart index f8adaae64ba..5c31dc11439 100644 --- a/packages/google_fonts/example/lib/example_font_selection.dart +++ b/packages/google_fonts/example/lib/example_font_selection.dart @@ -68,13 +68,14 @@ class ExampleFontSelectionState extends State { ); }); }, - dropdownMenuEntries: - GoogleFonts.asMap().keys.map((String font) { - return DropdownMenuEntry( - label: font, - value: font, - ); - }).toList(), + dropdownMenuEntries: GoogleFonts.asMap().keys.map(( + String font, + ) { + return DropdownMenuEntry( + label: font, + value: font, + ); + }).toList(), ), ], ), @@ -82,22 +83,24 @@ class ExampleFontSelectionState extends State { Expanded( child: FutureBuilder>( future: _googleFontsPending, - builder: ( - BuildContext context, - AsyncSnapshot> snapshot, - ) { - if (snapshot.connectionState != ConnectionState.done) { - return const SizedBox(); - } + builder: + ( + BuildContext context, + AsyncSnapshot> snapshot, + ) { + if (snapshot.connectionState != + ConnectionState.done) { + return const SizedBox(); + } - return Text( - _textEditingController.text, - style: GoogleFonts.getFont( - _selectedFont, - fontSize: 50.0, - ), - ); - }, + return Text( + _textEditingController.text, + style: GoogleFonts.getFont( + _selectedFont, + fontSize: 50.0, + ), + ); + }, ), ), ], diff --git a/packages/google_fonts/example/lib/main.dart b/packages/google_fonts/example/lib/main.dart index a89c427c5da..31b2ab85a05 100644 --- a/packages/google_fonts/example/lib/main.dart +++ b/packages/google_fonts/example/lib/main.dart @@ -26,7 +26,10 @@ class MyApp extends StatelessWidget { appBar: AppBar( title: const Text('Google Fonts Demo'), bottom: const TabBar( - tabs: [Tab(text: 'Simple'), Tab(text: 'Select a font')], + tabs: [ + Tab(text: 'Simple'), + Tab(text: 'Select a font'), + ], ), ), body: const TabBarView( diff --git a/packages/google_fonts/example/pubspec.yaml b/packages/google_fonts/example/pubspec.yaml index c2e372294e2..6b706aafd9d 100644 --- a/packages/google_fonts/example/pubspec.yaml +++ b/packages/google_fonts/example/pubspec.yaml @@ -3,7 +3,7 @@ description: A Flutter application showcasing how to use the google_fonts packag publish_to: none environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: cupertino_icons: ^1.0.0 diff --git a/packages/google_fonts/generator/generator.dart b/packages/google_fonts/generator/generator.dart index d7ff08ef51f..e6b7cba183f 100644 --- a/packages/google_fonts/generator/generator.dart +++ b/packages/google_fonts/generator/generator.dart @@ -112,8 +112,9 @@ Future _tryUrl(http.Client client, Uri url, Font font) async { try { final http.Response fileContents = await client.get(url); final int actualFileLength = fileContents.bodyBytes.length; - final String actualFileHash = - sha256.convert(fileContents.bodyBytes).toString(); + final String actualFileHash = sha256 + .convert(fileContents.bodyBytes) + .toString(); if (font.file.fileSize != actualFileLength || _hashToString(font.file.hash) != actualFileHash) { throw Exception('Font from $url did not match length of or checksum.'); @@ -224,8 +225,9 @@ void _generateDartCode(Directory fontDirectory) { for (final Font variant in item.fonts) { 'variantWeight': variant.weight.start, - 'variantStyle': - variant.italic.start.round() == 1 ? 'italic' : 'normal', + 'variantStyle': variant.italic.start.round() == 1 + ? 'italic' + : 'normal', 'hash': _hashToString(variant.file.hash), 'length': variant.file.fileSize, }, diff --git a/packages/google_fonts/lib/src/google_fonts_base.dart b/packages/google_fonts/lib/src/google_fonts_base.dart index 583ff9011ae..14744275195 100755 --- a/packages/google_fonts/lib/src/google_fonts_base.dart +++ b/packages/google_fonts/lib/src/google_fonts_base.dart @@ -129,8 +129,8 @@ TextStyle googleFontsTextStyle({ /// the [fontUrl] and stored on device. In all cases, the returned future /// completes once the font is loaded into the [FontLoader]. Future loadFontIfNecessary(GoogleFontsDescriptor descriptor) async { - final String familyWithVariantString = - descriptor.familyWithVariant.toString(); + final String familyWithVariantString = descriptor.familyWithVariant + .toString(); final String fontName = descriptor.familyWithVariant.toApiFilenamePrefix(); final String fileHash = descriptor.file.expectedFileHash; // If this font has already already loaded or is loading, then there is no diff --git a/packages/google_fonts/lib/src/google_fonts_variant.dart b/packages/google_fonts/lib/src/google_fonts_variant.dart index 347887ff8ad..a5081f3c93d 100644 --- a/packages/google_fonts/lib/src/google_fonts_variant.dart +++ b/packages/google_fonts/lib/src/google_fonts_variant.dart @@ -48,8 +48,9 @@ class GoogleFontsVariant { variantString == _italic ? 3 : (int.parse(variantString.replaceAll(_italic, '')) ~/ 100) - 1], - fontStyle = - variantString.contains(_italic) ? FontStyle.italic : FontStyle.normal; + fontStyle = variantString.contains(_italic) + ? FontStyle.italic + : FontStyle.normal; final FontWeight fontWeight; final FontStyle fontStyle; @@ -133,8 +134,9 @@ class GoogleFontsVariant { /// See [GoogleFontsVariant.toString] for the inverse function. @override String toString() { - final Object fontWeightString = - fontWeight.index == 3 ? '' : (fontWeight.index + 1) * 100; + final Object fontWeightString = fontWeight.index == 3 + ? '' + : (fontWeight.index + 1) * 100; final String fontStyleString = fontStyle .toString() .replaceAll('FontStyle.', '') diff --git a/packages/google_fonts/pubspec.yaml b/packages/google_fonts/pubspec.yaml index 3a81ffc7a7c..ce8f20a9cc9 100644 --- a/packages/google_fonts/pubspec.yaml +++ b/packages/google_fonts/pubspec.yaml @@ -2,11 +2,11 @@ name: google_fonts description: A Flutter package to use fonts from fonts.google.com. Supports HTTP fetching, caching, and asset bundling. repository: https://github.com/flutter/packages/tree/main/packages/google_fonts issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_fonts%22 -version: 6.3.2 +version: 6.4.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: crypto: ^3.0.0 @@ -30,7 +30,7 @@ topics: - fonts screenshots: - - description: 'Google Fonts and Flutter logos.' - path: screenshots/logo_mashup.png - - description: 'Using hot reload to change the font family.' - path: screenshots/hot_reload.gif + - description: "Google Fonts and Flutter logos." + path: screenshots/logo_mashup.png + - description: "Using hot reload to change the font family." + path: screenshots/hot_reload.gif diff --git a/packages/google_fonts/test/google_fonts_text_style_test.dart b/packages/google_fonts/test/google_fonts_text_style_test.dart index ee756e471d8..bc705d8a8f4 100644 --- a/packages/google_fonts/test/google_fonts_text_style_test.dart +++ b/packages/google_fonts/test/google_fonts_text_style_test.dart @@ -46,10 +46,9 @@ final GoogleFontsFile _fakeResponseFile = GoogleFontsFile( final Map fakeFonts = { const GoogleFontsVariant( - fontWeight: FontWeight.w400, - fontStyle: FontStyle.normal, - ): - _fakeResponseFile, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal, + ): _fakeResponseFile, }; void main() { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md index d274d16389f..6e380f9dd32 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.19.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.18.2 * Bumps com.android.tools.build:gradle to 8.12.1. diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle b/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle index 01d22eb02cf..e280be37488 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/build.gradle @@ -49,8 +49,8 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart index 456c0e08c9a..d421bcf9718 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart @@ -667,8 +667,8 @@ void main() { ); await tester.pumpAndSettle(const Duration(seconds: 3)); - final LatLngBounds secondVisibleRegion = - await mapController.getVisibleRegion(); + final LatLngBounds secondVisibleRegion = await mapController + .getVisibleRegion(); expect(secondVisibleRegion, isNot(zeroLatLngBounds)); @@ -1219,16 +1219,14 @@ void main() { final GoogleMapsInspectorPlatform inspector = GoogleMapsInspectorPlatform.instance!; - final TileOverlay tileOverlayInfo1 = - (await inspector.getTileOverlayInfo( - tileOverlay1.mapsId, - mapId: mapId, - ))!; - final TileOverlay tileOverlayInfo2 = - (await inspector.getTileOverlayInfo( - tileOverlay2.mapsId, - mapId: mapId, - ))!; + final TileOverlay tileOverlayInfo1 = (await inspector.getTileOverlayInfo( + tileOverlay1.mapsId, + mapId: mapId, + ))!; + final TileOverlay tileOverlayInfo2 = (await inspector.getTileOverlayInfo( + tileOverlay2.mapsId, + mapId: mapId, + ))!; expect(tileOverlayInfo1.visible, isTrue); expect(tileOverlayInfo1.fadeIn, isTrue); @@ -1306,11 +1304,10 @@ void main() { await tester.pumpAndSettle(const Duration(seconds: 3)); - final TileOverlay tileOverlayInfo1 = - (await inspector.getTileOverlayInfo( - tileOverlay1.mapsId, - mapId: mapId, - ))!; + final TileOverlay tileOverlayInfo1 = (await inspector.getTileOverlayInfo( + tileOverlay1.mapsId, + mapId: mapId, + ))!; final TileOverlay? tileOverlayInfo2 = await inspector.getTileOverlayInfo( tileOverlay2.mapsId, mapId: mapId, @@ -1780,18 +1777,12 @@ void main() { GoogleMapsInspectorPlatform.instance!; if (inspector.supportsGettingGroundOverlayInfo()) { - final GroundOverlay groundOverlayBoundsInfo1 = - (await inspector.getGroundOverlayInfo( - groundOverlayBounds1.mapsId, - mapId: mapId, - ))!; - final GroundOverlay groundOverlayBoundsInfo2 = - (await inspector.getGroundOverlayInfo( - groundOverlayBounds2.mapsId, - mapId: mapId, - ))!; - final GroundOverlay groundOverlayPositionInfo1 = - (await inspector.getGroundOverlayInfo( + final GroundOverlay groundOverlayBoundsInfo1 = (await inspector + .getGroundOverlayInfo(groundOverlayBounds1.mapsId, mapId: mapId))!; + final GroundOverlay groundOverlayBoundsInfo2 = (await inspector + .getGroundOverlayInfo(groundOverlayBounds2.mapsId, mapId: mapId))!; + final GroundOverlay groundOverlayPositionInfo1 = (await inspector + .getGroundOverlayInfo( groundOverlayPosition1.mapsId, mapId: mapId, ))!; @@ -1876,13 +1867,10 @@ void main() { await tester.pumpAndSettle(const Duration(seconds: 3)); if (inspector.supportsGettingGroundOverlayInfo()) { - final GroundOverlay groundOverlayBounds1Info = - (await inspector.getGroundOverlayInfo( - groundOverlayBounds1.mapsId, - mapId: mapId, - ))!; - final GroundOverlay groundOverlayPosition1Info = - (await inspector.getGroundOverlayInfo( + final GroundOverlay groundOverlayBounds1Info = (await inspector + .getGroundOverlayInfo(groundOverlayBounds1.mapsId, mapId: mapId))!; + final GroundOverlay groundOverlayPosition1Info = (await inspector + .getGroundOverlayInfo( groundOverlayPosition1.mapsId, mapId: mapId, ))!; diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/animate_camera.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/animate_camera.dart index 95b132fe9e6..a7c515c3692 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/animate_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/animate_camera.dart @@ -40,10 +40,9 @@ class AnimateCameraState extends State { void _toggleAnimationDuration() { setState(() { - _cameraUpdateAnimationDuration = - _cameraUpdateAnimationDuration != null - ? null - : const Duration(seconds: _durationSeconds); + _cameraUpdateAnimationDuration = _cameraUpdateAnimationDuration != null + ? null + : const Duration(seconds: _durationSeconds); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/clustering.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/clustering.dart index 2a4463c9ca6..ca60d810373 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/clustering.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/clustering.dart @@ -131,10 +131,9 @@ class ClusteringBodyState extends State { final ClusterManager clusterManager = ClusterManager( clusterManagerId: clusterManagerId, - onClusterTap: - (Cluster cluster) => setState(() { - lastCluster = cluster; - }), + onClusterTap: (Cluster cluster) => setState(() { + lastCluster = cluster; + }), ); setState(() { @@ -203,10 +202,9 @@ class ClusteringBodyState extends State { final Marker marker = markers[markerId]!; final double current = marker.alpha; markers[markerId] = marker.copyWith( - alphaParam: - current == _fullyVisibleAlpha - ? _halfVisibleAlpha - : _fullyVisibleAlpha, + alphaParam: current == _fullyVisibleAlpha + ? _halfVisibleAlpha + : _fullyVisibleAlpha, ); } setState(() {}); @@ -231,18 +229,15 @@ class ClusteringBodyState extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( - onPressed: - clusterManagers.length >= _clusterManagerMaxCount - ? null - : () => _addClusterManager(), + onPressed: clusterManagers.length >= _clusterManagerMaxCount + ? null + : () => _addClusterManager(), child: const Text('Add cluster manager'), ), TextButton( - onPressed: - clusterManagers.isEmpty - ? null - : () => - _removeClusterManager(clusterManagers.values.last), + onPressed: clusterManagers.isEmpty + ? null + : () => _removeClusterManager(clusterManagers.values.last), child: const Text('Remove cluster manager'), ), ], @@ -262,15 +257,14 @@ class ClusteringBodyState extends State { alignment: WrapAlignment.spaceEvenly, children: [ TextButton( - onPressed: - selectedId == null - ? null - : () { - _remove(selectedId); - setState(() { - selectedMarker = null; - }); - }, + onPressed: selectedId == null + ? null + : () { + _remove(selectedId); + setState(() { + selectedMarker = null; + }); + }, child: const Text('Remove selected marker'), ), TextButton( diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/ground_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/ground_overlay.dart index 948da41b6ad..33f310de2b2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/ground_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/ground_overlay.dart @@ -137,8 +137,9 @@ class GroundOverlayBodyState extends State { // Adjusts the bearing by 10 degrees, wrapping around at 360 degrees. // 10 is the increment, 350 degrees of the full circle -10. _groundOverlay = _groundOverlay!.copyWith( - bearingParam: - _groundOverlay!.bearing >= 350 ? 0 : _groundOverlay!.bearing + 10, + bearingParam: _groundOverlay!.bearing >= 350 + ? 0 + : _groundOverlay!.bearing + 10, ); }); } @@ -146,8 +147,9 @@ class GroundOverlayBodyState extends State { void _changeTransparency() { assert(_groundOverlay != null); setState(() { - final double transparency = - _groundOverlay!.transparency == 0.0 ? 0.5 : 0.0; + final double transparency = _groundOverlay!.transparency == 0.0 + ? 0.5 + : 0.0; _groundOverlay = _groundOverlay!.copyWith( transparencyParam: transparency, ); @@ -158,10 +160,9 @@ class GroundOverlayBodyState extends State { assert(_groundOverlay != null); assert(_placingType == _GroundOverlayPlacing.position); setState(() { - _dimensions = - _dimensions == const Offset(1000, 1000) - ? const Offset(1500, 500) - : const Offset(1000, 1000); + _dimensions = _dimensions == const Offset(1000, 1000) + ? const Offset(1500, 500) + : const Offset(1000, 1000); }); // Re-add the ground overlay to apply the new position, as the position @@ -173,10 +174,9 @@ class GroundOverlayBodyState extends State { assert(_groundOverlay != null); assert(_placingType == _GroundOverlayPlacing.position); setState(() { - _currentGroundOverlayPos = - _currentGroundOverlayPos == _groundOverlayPos1 - ? _groundOverlayPos2 - : _groundOverlayPos1; + _currentGroundOverlayPos = _currentGroundOverlayPos == _groundOverlayPos1 + ? _groundOverlayPos2 + : _groundOverlayPos1; }); // Re-add the ground overlay to apply the new position, as the position @@ -190,8 +190,8 @@ class GroundOverlayBodyState extends State { setState(() { _currentGroundOverlayBounds = _currentGroundOverlayBounds == _groundOverlayBounds1 - ? _groundOverlayBounds2 - : _groundOverlayBounds1; + ? _groundOverlayBounds2 + : _groundOverlayBounds1; }); // Re-add the ground overlay to apply the new position, as the position @@ -219,10 +219,9 @@ class GroundOverlayBodyState extends State { Future _changeType() async { setState(() { - _placingType = - _placingType == _GroundOverlayPlacing.position - ? _GroundOverlayPlacing.bounds - : _GroundOverlayPlacing.position; + _placingType = _placingType == _GroundOverlayPlacing.position + ? _GroundOverlayPlacing.bounds + : _GroundOverlayPlacing.position; }); // Re-add the ground overlay to apply the new position, as the position @@ -233,10 +232,9 @@ class GroundOverlayBodyState extends State { Future _changeAnchor() async { assert(_groundOverlay != null); setState(() { - _anchor = - _groundOverlay!.anchor == const Offset(0.5, 0.5) - ? const Offset(1.0, 1.0) - : const Offset(0.5, 0.5); + _anchor = _groundOverlay!.anchor == const Offset(0.5, 0.5) + ? const Offset(1.0, 1.0) + : const Offset(0.5, 0.5); }); // Re-add the ground overlay to apply the new anchor, as anchor cannot be @@ -281,8 +279,9 @@ class GroundOverlayBodyState extends State { alignment: WrapAlignment.spaceEvenly, children: [ TextButton( - onPressed: - _groundOverlay == null ? null : () => _changeTransparency(), + onPressed: _groundOverlay == null + ? null + : () => _changeTransparency(), child: const Text('change transparency'), ), TextButton( @@ -312,25 +311,25 @@ class GroundOverlayBodyState extends State { TextButton( onPressed: _placingType != _GroundOverlayPlacing.position || - _groundOverlay == null - ? null - : () => _changePosition(), + _groundOverlay == null + ? null + : () => _changePosition(), child: const Text('change position'), ), TextButton( onPressed: _placingType != _GroundOverlayPlacing.position || - _groundOverlay == null - ? null - : () => _changeDimensions(), + _groundOverlay == null + ? null + : () => _changeDimensions(), child: const Text('change dimensions'), ), TextButton( onPressed: _placingType != _GroundOverlayPlacing.bounds || - _groundOverlay == null - ? null - : () => _changeBounds(), + _groundOverlay == null + ? null + : () => _changeBounds(), child: const Text('change bounds'), ), ], diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/main.dart index 3b7480328c6..b980e1d2a64 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/main.dart @@ -57,9 +57,10 @@ class MapsDemo extends StatelessWidget { void _pushPage(BuildContext context, GoogleMapExampleAppPage page) { Navigator.of(context).push( MaterialPageRoute( - builder: - (_) => - Scaffold(appBar: AppBar(title: Text(page.title)), body: page), + builder: (_) => Scaffold( + appBar: AppBar(title: Text(page.title)), + body: page, + ), ), ); } @@ -70,12 +71,11 @@ class MapsDemo extends StatelessWidget { appBar: AppBar(title: const Text('GoogleMaps examples')), body: ListView.builder( itemCount: _allPages.length, - itemBuilder: - (_, int index) => ListTile( - leading: _allPages[index].leading, - title: Text(_allPages[index].title), - onTap: () => _pushPage(context, _allPages[index]), - ), + itemBuilder: (_, int index) => ListTile( + leading: _allPages[index].leading, + title: Text(_allPages[index].title), + onTap: () => _pushPage(context, _allPages[index]), + ), ), ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart index 140f8b7105f..3cad6f0f84e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart @@ -103,10 +103,9 @@ class MapUiBodyState extends State { ), onPressed: () { setState(() { - _cameraTargetBounds = - _cameraTargetBounds.bounds == null - ? CameraTargetBounds(sydneyBounds) - : CameraTargetBounds.unbounded; + _cameraTargetBounds = _cameraTargetBounds.bounds == null + ? CameraTargetBounds(sydneyBounds) + : CameraTargetBounds.unbounded; }); }, ); @@ -119,10 +118,9 @@ class MapUiBodyState extends State { ), onPressed: () { setState(() { - _minMaxZoomPreference = - _minMaxZoomPreference.minZoom == null - ? const MinMaxZoomPreference(12.0, 16.0) - : MinMaxZoomPreference.unbounded; + _minMaxZoomPreference = _minMaxZoomPreference.minZoom == null + ? const MinMaxZoomPreference(12.0, 16.0) + : MinMaxZoomPreference.unbounded; }); }, ); @@ -255,8 +253,9 @@ class MapUiBodyState extends State { child: Text('${_nightMode ? 'disable' : 'enable'} night mode'), onPressed: () async { _nightMode = !_nightMode; - final String style = - _nightMode ? await _getFileData('assets/night_mode.json') : ''; + final String style = _nightMode + ? await _getFileData('assets/night_mode.json') + : ''; setState(() { _mapStyle = style; }); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/marker_icons.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/marker_icons.dart index ccb58231fa1..40df30c94ac 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/marker_icons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/marker_icons.dart @@ -112,15 +112,14 @@ class MarkerIconsBodyState extends State { }); } }, - items: - _MarkerSizeOption.values.map(( - _MarkerSizeOption option, - ) { - return DropdownMenuItem<_MarkerSizeOption>( - value: option, - child: Text(_getMarkerSizeOptionName(option)), - ); - }).toList(), + items: _MarkerSizeOption.values.map(( + _MarkerSizeOption option, + ) { + return DropdownMenuItem<_MarkerSizeOption>( + value: option, + child: Text(_getMarkerSizeOptionName(option)), + ); + }).toList(), ), ], ), @@ -253,10 +252,12 @@ class MarkerIconsBodyState extends State { Future _updateMarkerAssetImage(BuildContext context) async { // Width and height are used only for custom size. - final (double? width, double? height) = - _scalingEnabled && _customSizeEnabled - ? _getCurrentMarkerSize() - : (null, null); + final ( + double? width, + double? height, + ) = _scalingEnabled && _customSizeEnabled + ? _getCurrentMarkerSize() + : (null, null); AssetMapBitmap assetMapBitmap; if (_mipMapsEnabled) { @@ -268,8 +269,9 @@ class MarkerIconsBodyState extends State { 'assets/red_square.png', width: width, height: height, - bitmapScaling: - _scalingEnabled ? MapBitmapScaling.auto : MapBitmapScaling.none, + bitmapScaling: _scalingEnabled + ? MapBitmapScaling.auto + : MapBitmapScaling.none, ); } else { // Uses hardcoded asset path @@ -279,8 +281,9 @@ class MarkerIconsBodyState extends State { 'assets/red_square.png', width: width, height: height, - bitmapScaling: - _scalingEnabled ? MapBitmapScaling.auto : MapBitmapScaling.none, + bitmapScaling: _scalingEnabled + ? MapBitmapScaling.auto + : MapBitmapScaling.none, ); } @@ -304,18 +307,21 @@ class MarkerIconsBodyState extends State { final ByteData bytes = await createCustomMarkerIconImage(size: canvasSize); // Width and height are used only for custom size. - final (double? width, double? height) = - _scalingEnabled && _customSizeEnabled - ? _getCurrentMarkerSize() - : (null, null); + final ( + double? width, + double? height, + ) = _scalingEnabled && _customSizeEnabled + ? _getCurrentMarkerSize() + : (null, null); final BytesMapBitmap bitmap = BytesMapBitmap( bytes.buffer.asUint8List(), imagePixelRatio: imagePixelRatio, width: width, height: height, - bitmapScaling: - _scalingEnabled ? MapBitmapScaling.auto : MapBitmapScaling.none, + bitmapScaling: _scalingEnabled + ? MapBitmapScaling.auto + : MapBitmapScaling.none, ); _updateBytesBitmap(bitmap); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_circle.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_circle.dart index b3090032be1..d45ec7e5c27 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_circle.dart @@ -171,17 +171,15 @@ class PlaceCircleBodyState extends State { children: [ TextButton(onPressed: _add, child: const Text('add')), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _remove(selectedId), + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), child: const Text('remove'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _toggleVisible(selectedId), + onPressed: (selectedId == null) + ? null + : () => _toggleVisible(selectedId), child: const Text('toggle visible'), ), ], @@ -189,24 +187,21 @@ class PlaceCircleBodyState extends State { Column( children: [ TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeStrokeWidth(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeStrokeWidth(selectedId), child: const Text('change stroke width'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeStrokeColor(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeStrokeColor(selectedId), child: const Text('change stroke color'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeFillColor(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeFillColor(selectedId), child: const Text('change fill color'), ), ], diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_marker.dart index 8617ea8fecc..e32b7b27747 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_marker.dart @@ -287,8 +287,9 @@ class PlaceMarkerBodyState extends State { children: [ TextButton(onPressed: _add, child: const Text('Add')), TextButton( - onPressed: - selectedId == null ? null : () => _remove(selectedId), + onPressed: selectedId == null + ? null + : () => _remove(selectedId), child: const Text('Remove'), ), ], @@ -297,82 +298,73 @@ class PlaceMarkerBodyState extends State { alignment: WrapAlignment.spaceEvenly, children: [ TextButton( - onPressed: - selectedId == null ? null : () => _changeInfo(selectedId), + onPressed: selectedId == null + ? null + : () => _changeInfo(selectedId), child: const Text('change info'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changeInfoAnchor(selectedId), + onPressed: selectedId == null + ? null + : () => _changeInfoAnchor(selectedId), child: const Text('change info anchor'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changeAlpha(selectedId), + onPressed: selectedId == null + ? null + : () => _changeAlpha(selectedId), child: const Text('change alpha'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changeAnchor(selectedId), + onPressed: selectedId == null + ? null + : () => _changeAnchor(selectedId), child: const Text('change anchor'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _toggleDraggable(selectedId), + onPressed: selectedId == null + ? null + : () => _toggleDraggable(selectedId), child: const Text('toggle draggable'), ), TextButton( - onPressed: - selectedId == null ? null : () => _toggleFlat(selectedId), + onPressed: selectedId == null + ? null + : () => _toggleFlat(selectedId), child: const Text('toggle flat'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changePosition(selectedId), + onPressed: selectedId == null + ? null + : () => _changePosition(selectedId), child: const Text('change position'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changeRotation(selectedId), + onPressed: selectedId == null + ? null + : () => _changeRotation(selectedId), child: const Text('change rotation'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _toggleVisible(selectedId), + onPressed: selectedId == null + ? null + : () => _toggleVisible(selectedId), child: const Text('toggle visible'), ), TextButton( - onPressed: - selectedId == null - ? null - : () => _changeZIndex(selectedId), + onPressed: selectedId == null + ? null + : () => _changeZIndex(selectedId), child: const Text('change zIndex'), ), TextButton( - onPressed: - selectedId == null - ? null - : () { - _getMarkerIcon(context).then(( - BitmapDescriptor icon, - ) { - _setMarkerIcon(selectedId, icon); - }); - }, + onPressed: selectedId == null + ? null + : () { + _getMarkerIcon(context).then((BitmapDescriptor icon) { + _setMarkerIcon(selectedId, icon); + }); + }, child: const Text('set marker icon'), ), ], diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polygon.dart index 1fffc4452f2..79475381c15 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polygon.dart @@ -194,24 +194,21 @@ class PlacePolygonBodyState extends State { children: [ TextButton(onPressed: _add, child: const Text('add')), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _remove(selectedId), + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), child: const Text('remove'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _toggleVisible(selectedId), + onPressed: (selectedId == null) + ? null + : () => _toggleVisible(selectedId), child: const Text('toggle visible'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _toggleGeodesic(selectedId), + onPressed: (selectedId == null) + ? null + : () => _toggleGeodesic(selectedId), child: const Text('toggle geodesic'), ), ], @@ -219,42 +216,37 @@ class PlacePolygonBodyState extends State { Column( children: [ TextButton( - onPressed: - (selectedId == null) - ? null - : (polygons[selectedId]!.holes.isNotEmpty - ? null - : () => _addHoles(selectedId)), + onPressed: (selectedId == null) + ? null + : (polygons[selectedId]!.holes.isNotEmpty + ? null + : () => _addHoles(selectedId)), child: const Text('add holes'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : (polygons[selectedId]!.holes.isEmpty - ? null - : () => _removeHoles(selectedId)), + onPressed: (selectedId == null) + ? null + : (polygons[selectedId]!.holes.isEmpty + ? null + : () => _removeHoles(selectedId)), child: const Text('remove holes'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeWidth(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeWidth(selectedId), child: const Text('change stroke width'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeStrokeColor(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeStrokeColor(selectedId), child: const Text('change stroke color'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeFillColor(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeFillColor(selectedId), child: const Text('change fill color'), ), ], diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polyline.dart index 2bfacb9c30e..854046b3053 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/place_polyline.dart @@ -237,24 +237,21 @@ class PlacePolylineBodyState extends State { children: [ TextButton(onPressed: _add, child: const Text('add')), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _remove(selectedId), + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), child: const Text('remove'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _toggleVisible(selectedId), + onPressed: (selectedId == null) + ? null + : () => _toggleVisible(selectedId), child: const Text('toggle visible'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _toggleGeodesic(selectedId), + onPressed: (selectedId == null) + ? null + : () => _toggleGeodesic(selectedId), child: const Text('toggle geodesic'), ), ], @@ -262,45 +259,39 @@ class PlacePolylineBodyState extends State { Column( children: [ TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeWidth(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeWidth(selectedId), child: const Text('change width'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changeColor(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changeColor(selectedId), child: const Text('change color'), ), TextButton( - onPressed: - isIOS || (selectedId == null) - ? null - : () => _changeStartCap(selectedId), + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeStartCap(selectedId), child: const Text('change start cap [Android only]'), ), TextButton( - onPressed: - isIOS || (selectedId == null) - ? null - : () => _changeEndCap(selectedId), + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeEndCap(selectedId), child: const Text('change end cap [Android only]'), ), TextButton( - onPressed: - isIOS || (selectedId == null) - ? null - : () => _changeJointType(selectedId), + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeJointType(selectedId), child: const Text('change joint type [Android only]'), ), TextButton( - onPressed: - (selectedId == null) - ? null - : () => _changePattern(selectedId), + onPressed: (selectedId == null) + ? null + : () => _changePattern(selectedId), child: const Text('change pattern'), ), ], diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/scrolling_map.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/scrolling_map.dart index c1970920175..57d8cd6d9ff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/scrolling_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/scrolling_map.dart @@ -50,7 +50,7 @@ class ScrollingMapBody extends StatelessWidget { zoom: 11.0, ), gestureRecognizers: // - >{ + >{ Factory( () => EagerGestureRecognizer(), ), diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/snapshot.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/snapshot.dart index d003226ac5b..8fa4d67b642 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/snapshot.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/snapshot.dart @@ -57,8 +57,8 @@ class _SnapshotBodyState extends State<_SnapshotBody> { TextButton( child: const Text('Take a snapshot'), onPressed: () async { - final Uint8List? imageBytes = - await _mapController?.takeSnapshot(); + final Uint8List? imageBytes = await _mapController + ?.takeSnapshot(); setState(() { _imageBytes = imageBytes; }); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml index 11f5f9cf7fe..e556fa6acf9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the google_maps_flutter plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: cupertino_icons: ^1.0.5 diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart index 4c89d698245..ef0b0aeb351 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart @@ -53,8 +53,9 @@ class GoogleMapsInspectorAndroid extends GoogleMapsInspectorPlatform { @override Future getMinMaxZoomLevels({required int mapId}) async { - final PlatformZoomRange zoomLevels = - await _inspectorProvider(mapId)!.getZoomRange(); + final PlatformZoomRange zoomLevels = await _inspectorProvider( + mapId, + )!.getZoomRange(); return MinMaxZoomPreference(zoomLevels.min, zoomLevels.max); } @@ -196,8 +197,9 @@ class GoogleMapsInspectorAndroid extends GoogleMapsInspectorPlatform { @override Future getCameraPosition({required int mapId}) async { - final PlatformCameraPosition cameraPosition = - await _inspectorProvider(mapId)!.getCameraPosition(); + final PlatformCameraPosition cameraPosition = await _inspectorProvider( + mapId, + )!.getCameraPosition(); return CameraPosition( target: LatLng( cameraPosition.target.latitude, diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart index 4871b2d3302..34d05ca6f8f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart @@ -329,10 +329,9 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { }) { final Map? currentTileOverlays = _tileOverlays[mapId]; - final Set previousSet = - currentTileOverlays != null - ? currentTileOverlays.values.toSet() - : {}; + final Set previousSet = currentTileOverlays != null + ? currentTileOverlays.values.toSet() + : {}; final _TileOverlayUpdates updates = _TileOverlayUpdates.from( previousSet, newTileOverlays, @@ -572,44 +571,44 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { widgetConfiguration.initialCameraPosition, ), mapConfiguration: mapConfiguration, - initialMarkers: - mapObjects.markers.map(_platformMarkerFromMarker).toList(), - initialPolygons: - mapObjects.polygons.map(_platformPolygonFromPolygon).toList(), - initialPolylines: - mapObjects.polylines.map(_platformPolylineFromPolyline).toList(), - initialCircles: - mapObjects.circles.map(_platformCircleFromCircle).toList(), - initialHeatmaps: - mapObjects.heatmaps.map(_platformHeatmapFromHeatmap).toList(), - initialTileOverlays: - mapObjects.tileOverlays - .map(_platformTileOverlayFromTileOverlay) - .toList(), - initialClusterManagers: - mapObjects.clusterManagers - .map(_platformClusterManagerFromClusterManager) - .toList(), - initialGroundOverlays: - mapObjects.groundOverlays - .map(_platformGroundOverlayFromGroundOverlay) - .toList(), + initialMarkers: mapObjects.markers + .map(_platformMarkerFromMarker) + .toList(), + initialPolygons: mapObjects.polygons + .map(_platformPolygonFromPolygon) + .toList(), + initialPolylines: mapObjects.polylines + .map(_platformPolylineFromPolyline) + .toList(), + initialCircles: mapObjects.circles + .map(_platformCircleFromCircle) + .toList(), + initialHeatmaps: mapObjects.heatmaps + .map(_platformHeatmapFromHeatmap) + .toList(), + initialTileOverlays: mapObjects.tileOverlays + .map(_platformTileOverlayFromTileOverlay) + .toList(), + initialClusterManagers: mapObjects.clusterManagers + .map(_platformClusterManagerFromClusterManager) + .toList(), + initialGroundOverlays: mapObjects.groundOverlays + .map(_platformGroundOverlayFromGroundOverlay) + .toList(), ); const String viewType = 'plugins.flutter.dev/google_maps_android'; if (useAndroidViewSurface) { return PlatformViewLink( viewType: viewType, - surfaceFactory: ( - BuildContext context, - PlatformViewController controller, - ) { - return AndroidViewSurface( - controller: controller as AndroidViewController, - gestureRecognizers: widgetConfiguration.gestureRecognizers, - hitTestBehavior: PlatformViewHitTestBehavior.opaque, - ); - }, + surfaceFactory: + (BuildContext context, PlatformViewController controller) { + return AndroidViewSurface( + controller: controller as AndroidViewController, + gestureRecognizers: widgetConfiguration.gestureRecognizers, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, onCreatePlatformView: (PlatformViewCreationParams params) { final AndroidViewController controller = PlatformViewsService.initExpensiveAndroidView( @@ -834,15 +833,13 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { ) { return PlatformGroundOverlay( groundOverlayId: groundOverlay.groundOverlayId.value, - anchor: - groundOverlay.anchor != null - ? _platformPairFromOffset(groundOverlay.anchor!) - : null, + anchor: groundOverlay.anchor != null + ? _platformPairFromOffset(groundOverlay.anchor!) + : null, image: platformBitmapFromBitmapDescriptor(groundOverlay.image), - position: - groundOverlay.position != null - ? _platformLatLngFromLatLng(groundOverlay.position!) - : null, + position: groundOverlay.position != null + ? _platformLatLngFromLatLng(groundOverlay.position!) + : null, bounds: _platformLatLngBoundsFromLatLngBounds(groundOverlay.bounds), visible: groundOverlay.visible, zIndex: groundOverlay.zIndex, @@ -855,12 +852,14 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { } static PlatformPolygon _platformPolygonFromPolygon(Polygon polygon) { - final List points = - polygon.points.map(_platformLatLngFromLatLng).toList(); - final List> holes = - polygon.holes.map((List hole) { - return hole.map(_platformLatLngFromLatLng).toList(); - }).toList(); + final List points = polygon.points + .map(_platformLatLngFromLatLng) + .toList(); + final List> holes = polygon.holes.map(( + List hole, + ) { + return hole.map(_platformLatLngFromLatLng).toList(); + }).toList(); return PlatformPolygon( polygonId: polygon.polygonId.value, fillColor: polygon.fillColor.value, @@ -876,10 +875,12 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { } static PlatformPolyline _platformPolylineFromPolyline(Polyline polyline) { - final List points = - polyline.points.map(_platformLatLngFromLatLng).toList(); - final List pattern = - polyline.patterns.map(platformPatternItemFromPatternItem).toList(); + final List points = polyline.points + .map(_platformLatLngFromLatLng) + .toList(); + final List pattern = polyline.patterns + .map(platformPatternItemFromPatternItem) + .toList(); return PlatformPolyline( polylineId: polyline.polylineId.value, consumesTapEvents: polyline.consumeTapEvents, @@ -955,10 +956,9 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { return PlatformCameraUpdate( cameraUpdate: PlatformCameraUpdateZoomBy( amount: update.amount, - focus: - update.focus == null - ? null - : _platformPairFromOffset(update.focus!), + focus: update.focus == null + ? null + : _platformPairFromOffset(update.focus!), ), ); case CameraUpdateType.zoomIn: @@ -1019,10 +1019,9 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { return PlatformBitmap( bitmap: PlatformBitmapBytes( byteData: bytes.byteData, - size: - (bytes.size == null) - ? null - : _platformPairFromSize(bytes.size!), + size: (bytes.size == null) + ? null + : _platformPairFromSize(bytes.size!), ), ); case final AssetBitmap asset: @@ -1036,10 +1035,9 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { bitmap: PlatformBitmapAssetImage( name: asset.name, scale: asset.scale, - size: - (asset.size == null) - ? null - : _platformPairFromSize(asset.size!), + size: (asset.size == null) + ? null + : _platformPairFromSize(asset.size!), ), ); case final AssetMapBitmap asset: @@ -1135,10 +1133,9 @@ class HostMapMessageHandler implements MapsCallbackApi { TileOverlayId(tileOverlayId), ); final TileProvider? tileProvider = tileOverlay?.tileProvider; - final Tile tile = - tileProvider == null - ? TileProvider.noTile - : await tileProvider.getTile(location.x, location.y, zoom); + final Tile tile = tileProvider == null + ? TileProvider.noTile + : await tileProvider.getTile(location.x, location.y, zoom); return _platformTileFromTile(tile); } @@ -1302,8 +1299,8 @@ PlatformCameraTargetBounds? _platformCameraTargetBoundsFromCameraTargetBounds( return bounds == null ? null : PlatformCameraTargetBounds( - bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds), - ); + bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds), + ); } PlatformMapType? _platformMapTypeFromMapType(MapType? type) { @@ -1342,11 +1339,11 @@ PlatformEdgeInsets? _platformEdgeInsetsFromEdgeInsets(EdgeInsets? insets) { return insets == null ? null : PlatformEdgeInsets( - top: insets.top, - bottom: insets.bottom, - left: insets.left, - right: insets.right, - ); + top: insets.top, + bottom: insets.bottom, + left: insets.left, + right: insets.right, + ); } PlatformMapConfiguration _platformMapConfigurationFromMapConfiguration( @@ -1387,8 +1384,8 @@ PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( // All of these hard-coded values and structures come from // google_maps_flutter_platform_interface/lib/src/types/utils/map_configuration_serialization.dart // to support this legacy API that relied on cross-package magic strings. - final List? padding = - (options['padding'] as List?)?.cast(); + final List? padding = (options['padding'] as List?) + ?.cast(); final int? mapType = options['mapType'] as int?; return PlatformMapConfiguration( compassEnabled: options['compassEnabled'] as bool?, @@ -1408,15 +1405,14 @@ PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( zoomGesturesEnabled: options['zoomGesturesEnabled'] as bool?, myLocationEnabled: options['myLocationEnabled'] as bool?, myLocationButtonEnabled: options['myLocationButtonEnabled'] as bool?, - padding: - padding == null - ? null - : PlatformEdgeInsets( - top: padding[0], - left: padding[1], - bottom: padding[2], - right: padding[3], - ), + padding: padding == null + ? null + : PlatformEdgeInsets( + top: padding[0], + left: padding[1], + bottom: padding[2], + right: padding[3], + ), indoorViewEnabled: options['indoorEnabled'] as bool?, trafficEnabled: options['trafficEnabled'] as bool?, buildingsEnabled: options['buildingsEnabled'] as bool?, @@ -1490,8 +1486,8 @@ PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreferenceJson( return null; } // See `MinMaxZoomPreference.toJson`. - final List minMaxZoom = - (zoomPrefsJson as List).cast(); + final List minMaxZoom = (zoomPrefsJson as List) + .cast(); return PlatformZoomRange(min: minMaxZoom[0], max: minMaxZoom[1]); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart index 6789c92799e..04d02cb3439 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart @@ -1010,12 +1010,12 @@ class PlatformMapViewCreationParams { initialPolygons: (result[4] as List?)!.cast(), initialPolylines: (result[5] as List?)!.cast(), initialHeatmaps: (result[6] as List?)!.cast(), - initialTileOverlays: - (result[7] as List?)!.cast(), - initialClusterManagers: - (result[8] as List?)!.cast(), - initialGroundOverlays: - (result[9] as List?)!.cast(), + initialTileOverlays: (result[7] as List?)! + .cast(), + initialClusterManagers: (result[8] as List?)! + .cast(), + initialGroundOverlays: (result[9] as List?)! + .cast(), ); } } @@ -1663,8 +1663,9 @@ class MapsApi { /// BinaryMessenger will be used which routes to the host platform. MapsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -2412,8 +2413,9 @@ abstract class MapsCallbackApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -2980,8 +2982,9 @@ class MapsInitializerApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -3063,8 +3066,9 @@ class MapsPlatformViewApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -3105,8 +3109,9 @@ class MapsInspectorApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart index a67ebb16d36..7a9aca87b9a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart @@ -105,11 +105,10 @@ HeatmapGradient? deserializeHeatmapGradient(Object? json) { } assert(json is Map); final Map map = (json as Map).cast(); - final List colors = - (map[_heatmapGradientColorsKey]! as List) - .whereType() - .map((int e) => Color(e)) - .toList(); + final List colors = (map[_heatmapGradientColorsKey]! as List) + .whereType() + .map((int e) => Color(e)) + .toList(); final List startPoints = (map[_heatmapGradientStartPointsKey]! as List) .whereType() diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml index 346bd44e54e..68e235e5d7a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml @@ -2,11 +2,11 @@ name: google_maps_flutter_android description: Android implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.18.2 +version: 2.19.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md index bbabd96e56c..99fa8b96bf9 100644 --- a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 7.3.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 7.2.0 * Adds support for `disconnect`. diff --git a/packages/google_sign_in/google_sign_in_android/android/build.gradle b/packages/google_sign_in/google_sign_in_android/android/build.gradle index 2b29433ce5d..7d7943cdce6 100644 --- a/packages/google_sign_in/google_sign_in_android/android/build.gradle +++ b/packages/google_sign_in/google_sign_in_android/android/build.gradle @@ -34,12 +34,12 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/google_sign_in/google_sign_in_android/example/lib/main.dart b/packages/google_sign_in/google_sign_in_android/example/lib/main.dart index 1abec9b3f9c..8ab6e537868 100644 --- a/packages/google_sign_in/google_sign_in_android/example/lib/main.dart +++ b/packages/google_sign_in/google_sign_in_android/example/lib/main.dart @@ -43,11 +43,11 @@ class SignInDemoState extends State { Future _ensureInitialized() { // The example app uses the parsing of values from google-services.json // to provide the serverClientId, otherwise it would be required here. - return _initialization ??= GoogleSignInPlatform.instance.init( - const InitParameters(), - )..catchError((dynamic _) { - _initialization = null; - }); + return _initialization ??= + GoogleSignInPlatform.instance.init(const InitParameters()) + ..catchError((dynamic _) { + _initialization = null; + }); } void _setUser(GoogleSignInUserData? user) { @@ -70,10 +70,9 @@ class SignInDemoState extends State { _setUser(result?.user); } on GoogleSignInException catch (e) { setState(() { - _errorMessage = - e.code == GoogleSignInExceptionCode.canceled - ? '' - : 'GoogleSignInException ${e.code}: ${e.description}'; + _errorMessage = e.code == GoogleSignInExceptionCode.canceled + ? '' + : 'GoogleSignInException ${e.code}: ${e.description}'; }); } } @@ -178,10 +177,9 @@ class SignInDemoState extends State { _setUser(result.user); } on GoogleSignInException catch (e) { setState(() { - _errorMessage = - e.code == GoogleSignInExceptionCode.canceled - ? '' - : 'GoogleSignInException ${e.code}: ${e.description}'; + _errorMessage = e.code == GoogleSignInExceptionCode.canceled + ? '' + : 'GoogleSignInException ${e.code}: ${e.description}'; }); } } diff --git a/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml b/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml index 65ac709b16d..daa8a3537db 100644 --- a/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Example of Google Sign-In plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart b/packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart index 7d446c37ea7..de66df6f4ba 100644 --- a/packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart +++ b/packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart @@ -252,8 +252,9 @@ class GoogleSignInAndroid extends GoogleSignInPlatform { scopes: request.scopes, accountEmail: email, hostedDomain: _hostedDomain, - serverClientIdForForcedRefreshToken: - requestOfflineAccess ? _serverClientId : null, + serverClientIdForForcedRefreshToken: requestOfflineAccess + ? _serverClientId + : null, ), promptIfUnauthorized: request.promptIfUnauthorized, ); diff --git a/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart b/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart index a9584272f43..7de737a2395 100644 --- a/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart +++ b/packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart @@ -674,8 +674,9 @@ class GoogleSignInApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/google_sign_in/google_sign_in_android/pubspec.yaml b/packages/google_sign_in/google_sign_in_android/pubspec.yaml index c45ec03e428..774ed1e8592 100644 --- a/packages/google_sign_in/google_sign_in_android/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_android/pubspec.yaml @@ -2,11 +2,11 @@ name: google_sign_in_android description: Android implementation of the google_sign_in plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 7.2.0 +version: 7.3.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index fc1981d33fe..b2c76b874aa 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.8.14 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 0.8.13+3 * Bumps androidx.exifinterface:exifinterface from 1.3.7 to 1.4.1. diff --git a/packages/image_picker/image_picker_android/android/build.gradle b/packages/image_picker/image_picker_android/android/build.gradle index d2cfc910ce1..8ee553f3d67 100644 --- a/packages/image_picker/image_picker_android/android/build.gradle +++ b/packages/image_picker/image_picker_android/android/build.gradle @@ -47,8 +47,8 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } testOptions { diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index 839ea7b6a1c..d70e40bfd96 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.13+3 +version: 0.8.14 environment: sdk: ^3.9.0 diff --git a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md index 9624ebbfd99..1832367c05d 100644 --- a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.4.1 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 0.4.0+4 * Bumps com.android.tools.build:gradle to 8.12.1. diff --git a/packages/in_app_purchase/in_app_purchase_android/android/build.gradle b/packages/in_app_purchase/in_app_purchase_android/android/build.gradle index ef2a8e11281..2d5d9de95da 100644 --- a/packages/in_app_purchase/in_app_purchase_android/android/build.gradle +++ b/packages/in_app_purchase/in_app_purchase_android/android/build.gradle @@ -40,8 +40,8 @@ android { disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } diff --git a/packages/in_app_purchase/in_app_purchase_android/example/lib/main.dart b/packages/in_app_purchase/in_app_purchase_android/example/lib/main.dart index 9abe1d6acc6..9986df72f53 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/lib/main.dart +++ b/packages/in_app_purchase/in_app_purchase_android/example/lib/main.dart @@ -208,8 +208,9 @@ class _MyAppState extends State<_MyApp> { final Widget storeHeader = ListTile( leading: Icon( _isAvailable ? Icons.check : Icons.block, - color: - _isAvailable ? Colors.green : ThemeData.light().colorScheme.error, + color: _isAvailable + ? Colors.green + : ThemeData.light().colorScheme.error, ), title: Text( 'The store is ${_isAvailable ? 'available' : 'unavailable'}.', @@ -454,50 +455,48 @@ class _MyAppState extends State<_MyApp> { return ListTile( title: Text(productDetails.title), subtitle: Text(productDetails.description), - trailing: - previousPurchase != null - ? const SizedBox.shrink() - : TextButton( - style: TextButton.styleFrom( - backgroundColor: Colors.green[800], - foregroundColor: Colors.white, - ), - onPressed: () { - // NOTE: If you are making a subscription purchase/upgrade/downgrade, we recommend you to - // verify the latest status of you your subscription by using server side receipt validation - // and update the UI accordingly. The subscription purchase status shown - // inside the app may not be accurate. - final GooglePlayPurchaseDetails? oldSubscription = - _getOldSubscription( - productDetails as GooglePlayProductDetails, - purchases, - ); - final GooglePlayPurchaseParam purchaseParam = - GooglePlayPurchaseParam( - productDetails: productDetails, - changeSubscriptionParam: - oldSubscription != null - ? ChangeSubscriptionParam( - oldPurchaseDetails: oldSubscription, - replacementMode: - ReplacementMode.withTimeProration, - ) - : null, - ); - if (productDetails.id == _kConsumableId) { - _inAppPurchasePlatform.buyConsumable( - purchaseParam: purchaseParam, - // ignore: avoid_redundant_argument_values - autoConsume: _kAutoConsume, + trailing: previousPurchase != null + ? const SizedBox.shrink() + : TextButton( + style: TextButton.styleFrom( + backgroundColor: Colors.green[800], + foregroundColor: Colors.white, + ), + onPressed: () { + // NOTE: If you are making a subscription purchase/upgrade/downgrade, we recommend you to + // verify the latest status of you your subscription by using server side receipt validation + // and update the UI accordingly. The subscription purchase status shown + // inside the app may not be accurate. + final GooglePlayPurchaseDetails? oldSubscription = + _getOldSubscription( + productDetails as GooglePlayProductDetails, + purchases, ); - } else { - _inAppPurchasePlatform.buyNonConsumable( - purchaseParam: purchaseParam, + final GooglePlayPurchaseParam purchaseParam = + GooglePlayPurchaseParam( + productDetails: productDetails, + changeSubscriptionParam: oldSubscription != null + ? ChangeSubscriptionParam( + oldPurchaseDetails: oldSubscription, + replacementMode: + ReplacementMode.withTimeProration, + ) + : null, ); - } - }, - child: Text(productDetails.price), - ), + if (productDetails.id == _kConsumableId) { + _inAppPurchasePlatform.buyConsumable( + purchaseParam: purchaseParam, + // ignore: avoid_redundant_argument_values + autoConsume: _kAutoConsume, + ); + } else { + _inAppPurchasePlatform.buyNonConsumable( + purchaseParam: purchaseParam, + ); + } + }, + child: Text(productDetails.price), + ), ); }), ); @@ -524,16 +523,15 @@ class _MyAppState extends State<_MyApp> { const ListTile consumableHeader = ListTile( title: Text('Purchased consumables'), ); - final List tokens = - _consumables.map((String id) { - return GridTile( - child: IconButton( - icon: const Icon(Icons.stars, size: 42.0, color: Colors.orange), - splashColor: Colors.yellowAccent, - onPressed: () => consume(id), - ), - ); - }).toList(); + final List tokens = _consumables.map((String id) { + return GridTile( + child: IconButton( + icon: const Icon(Icons.stars, size: 42.0, color: Colors.orange), + splashColor: Colors.yellowAccent, + onPressed: () => consume(id), + ), + ); + }).toList(); return Card( child: Column( children: [ diff --git a/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml index 1c803ec27da..fd0013c822a 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the in_app_purchase_android plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart index 1950d711f54..32664d2a34b 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart @@ -37,8 +37,8 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { @visibleForTesting BillingClientManager? manager, }) : billingClientManager = manager ?? BillingClientManager() { // Register [InAppPurchaseAndroidPlatformAddition]. - InAppPurchasePlatformAddition - .instance = InAppPurchaseAndroidPlatformAddition(billingClientManager); + InAppPurchasePlatformAddition.instance = + InAppPurchaseAndroidPlatformAddition(billingClientManager); billingClientManager.purchasesUpdatedStream .asyncMap(_getPurchaseDetailsFromResult) @@ -87,28 +87,26 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { await Future.wait(>[ billingClientManager.runWithClient( (BillingClient client) => client.queryProductDetails( - productList: - identifiers - .map( - (String productId) => ProductWrapper( - productId: productId, - productType: ProductType.inapp, - ), - ) - .toList(), + productList: identifiers + .map( + (String productId) => ProductWrapper( + productId: productId, + productType: ProductType.inapp, + ), + ) + .toList(), ), ), billingClientManager.runWithClient( (BillingClient client) => client.queryProductDetails( - productList: - identifiers - .map( - (String productId) => ProductWrapper( - productId: productId, - productType: ProductType.subs, - ), - ) - .toList(), + productList: identifiers + .map( + (String productId) => ProductWrapper( + productId: productId, + productType: ProductType.subs, + ), + ) + .toList(), ), ), ]); @@ -131,36 +129,34 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { ), ]; } - final List productDetailsList = - productResponses - .expand((ProductDetailsResponseWrapper response) { - return response.productDetailsList; - }) - .expand((ProductDetailsWrapper productDetailWrapper) { - return GooglePlayProductDetails.fromProductDetails( - productDetailWrapper, - ); - }) - .toList(); - - final Set successIDS = - productDetailsList - .map((ProductDetails productDetails) => productDetails.id) - .toSet(); - final List notFoundIDS = - identifiers.difference(successIDS).toList(); + final List productDetailsList = productResponses + .expand((ProductDetailsResponseWrapper response) { + return response.productDetailsList; + }) + .expand((ProductDetailsWrapper productDetailWrapper) { + return GooglePlayProductDetails.fromProductDetails( + productDetailWrapper, + ); + }) + .toList(); + + final Set successIDS = productDetailsList + .map((ProductDetails productDetails) => productDetails.id) + .toSet(); + final List notFoundIDS = identifiers + .difference(successIDS) + .toList(); return ProductDetailsResponse( productDetails: productDetailsList, notFoundIDs: notFoundIDS, - error: - exception == null - ? null - : IAPError( - source: kIAPSource, - code: exception.code, - message: exception.message ?? '', - details: exception.details, - ), + error: exception == null + ? null + : IAPError( + source: kIAPSource, + code: exception.code, + message: exception.message ?? '', + details: exception.details, + ), ); } @@ -187,11 +183,10 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { offerToken: offerToken, accountId: purchaseParam.applicationUserName, oldProduct: changeSubscriptionParam?.oldPurchaseDetails.productID, - purchaseToken: - changeSubscriptionParam - ?.oldPurchaseDetails - .verificationData - .serverVerificationData, + purchaseToken: changeSubscriptionParam + ?.oldPurchaseDetails + .verificationData + .serverVerificationData, replacementMode: changeSubscriptionParam?.replacementMode, ), ); @@ -245,33 +240,31 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { ), ]); - final Set errorCodeSet = - responses - .where( - (PurchasesResultWrapper response) => - response.responseCode != BillingResponse.ok, - ) - .map( - (PurchasesResultWrapper response) => - response.responseCode.toString(), - ) - .toSet(); - - final String errorMessage = - errorCodeSet.isNotEmpty ? errorCodeSet.join(', ') : ''; - - final List pastPurchases = - responses - .expand((PurchasesResultWrapper response) => response.purchasesList) - .expand( - (PurchaseWrapper purchaseWrapper) => - GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper), - ) - .map( - (GooglePlayPurchaseDetails details) => - details..status = PurchaseStatus.restored, - ) - .toList(); + final Set errorCodeSet = responses + .where( + (PurchasesResultWrapper response) => + response.responseCode != BillingResponse.ok, + ) + .map( + (PurchasesResultWrapper response) => response.responseCode.toString(), + ) + .toSet(); + + final String errorMessage = errorCodeSet.isNotEmpty + ? errorCodeSet.join(', ') + : ''; + + final List pastPurchases = responses + .expand((PurchasesResultWrapper response) => response.purchasesList) + .expand( + (PurchaseWrapper purchaseWrapper) => + GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper), + ) + .map( + (GooglePlayPurchaseDetails details) => + details..status = PurchaseStatus.restored, + ) + .toList(); if (errorMessage.isNotEmpty) { throw InAppPurchaseException( @@ -323,20 +316,19 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { details: resultWrapper.billingResult.debugMessage, ); } - final List> purchases = - resultWrapper.purchasesList - .expand( - (PurchaseWrapper purchase) => - GooglePlayPurchaseDetails.fromPurchase(purchase), - ) - .map((GooglePlayPurchaseDetails purchaseDetails) { - purchaseDetails.error = error; - if (resultWrapper.responseCode == BillingResponse.userCanceled) { - purchaseDetails.status = PurchaseStatus.canceled; - } - return _maybeAutoConsumePurchase(purchaseDetails); - }) - .toList(); + final List> purchases = resultWrapper.purchasesList + .expand( + (PurchaseWrapper purchase) => + GooglePlayPurchaseDetails.fromPurchase(purchase), + ) + .map((GooglePlayPurchaseDetails purchaseDetails) { + purchaseDetails.error = error; + if (resultWrapper.responseCode == BillingResponse.userCanceled) { + purchaseDetails.status = PurchaseStatus.canceled; + } + return _maybeAutoConsumePurchase(purchaseDetails); + }) + .toList(); if (purchases.isNotEmpty) { return Future.wait(purchases); } else { diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform_addition.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform_addition.dart index aa9886337cc..e4d27cdb99b 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform_addition.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform_addition.dart @@ -96,29 +96,27 @@ class InAppPurchaseAndroidPlatformAddition ]; } - final Set errorCodeSet = - responses - .where( - (PurchasesResultWrapper response) => - response.responseCode != BillingResponse.ok, - ) - .map( - (PurchasesResultWrapper response) => - response.responseCode.toString(), - ) - .toSet(); - - final String errorMessage = - errorCodeSet.isNotEmpty ? errorCodeSet.join(', ') : ''; - - final List pastPurchases = - responses - .expand((PurchasesResultWrapper response) => response.purchasesList) - .expand( - (PurchaseWrapper purchaseWrapper) => - GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper), - ) - .toList(); + final Set errorCodeSet = responses + .where( + (PurchasesResultWrapper response) => + response.responseCode != BillingResponse.ok, + ) + .map( + (PurchasesResultWrapper response) => response.responseCode.toString(), + ) + .toSet(); + + final String errorMessage = errorCodeSet.isNotEmpty + ? errorCodeSet.join(', ') + : ''; + + final List pastPurchases = responses + .expand((PurchasesResultWrapper response) => response.purchasesList) + .expand( + (PurchaseWrapper purchaseWrapper) => + GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper), + ) + .toList(); IAPError? error; if (exception != null) { diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart index 9b4c32ca068..053e1f3c8f0 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/messages.g.dart @@ -237,9 +237,8 @@ class PlatformProductDetails { title: result[4]! as String, oneTimePurchaseOfferDetails: result[5] as PlatformOneTimePurchaseOfferDetails?, - subscriptionOfferDetails: - (result[6] as List?) - ?.cast(), + subscriptionOfferDetails: (result[6] as List?) + ?.cast(), ); } } @@ -264,8 +263,8 @@ class PlatformProductDetailsResponse { result as List; return PlatformProductDetailsResponse( billingResult: result[0]! as PlatformBillingResult, - productDetails: - (result[1] as List?)!.cast(), + productDetails: (result[1] as List?)! + .cast(), ); } } @@ -611,8 +610,8 @@ class PlatformPurchaseHistoryResponse { result as List; return PlatformPurchaseHistoryResponse( billingResult: result[0]! as PlatformBillingResult, - purchases: - (result[1] as List?)!.cast(), + purchases: (result[1] as List?)! + .cast(), ); } } @@ -683,8 +682,8 @@ class PlatformSubscriptionOfferDetails { offerId: result[1] as String?, offerToken: result[2]! as String, offerTags: (result[3] as List?)!.cast(), - pricingPhases: - (result[4] as List?)!.cast(), + pricingPhases: (result[4] as List?)! + .cast(), installmentPlanDetails: result[5] as PlatformInstallmentPlanDetails?, ); } @@ -717,8 +716,8 @@ class PlatformUserChoiceDetails { return PlatformUserChoiceDetails( originalExternalTransactionId: result[0] as String?, externalTransactionToken: result[1]! as String, - products: - (result[2] as List?)!.cast(), + products: (result[2] as List?)! + .cast(), ); } } @@ -973,8 +972,9 @@ class InAppPurchaseApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -1438,8 +1438,9 @@ abstract class InAppPurchaseCallbackApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart index f3a455b7f87..c3586df9c6a 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/pigeon_converters.dart @@ -35,8 +35,9 @@ ProductDetailsResponseWrapper productDetailsResponseWrapperFromPlatform( ) { return ProductDetailsResponseWrapper( billingResult: resultWrapperFromPlatform(response.billingResult), - productDetailsList: - response.productDetails.map(productDetailsWrapperFromPlatform).toList(), + productDetailsList: response.productDetails + .map(productDetailsWrapperFromPlatform) + .toList(), ); } @@ -53,10 +54,9 @@ ProductDetailsWrapper productDetailsWrapperFromPlatform( oneTimePurchaseOfferDetails: oneTimePurchaseOfferDetailsWrapperFromPlatform( product.oneTimePurchaseOfferDetails, ), - subscriptionOfferDetails: - product.subscriptionOfferDetails - ?.map(subscriptionOfferDetailsWrapperFromPlatform) - .toList(), + subscriptionOfferDetails: product.subscriptionOfferDetails + ?.map(subscriptionOfferDetailsWrapperFromPlatform) + .toList(), ); } @@ -81,10 +81,9 @@ PurchasesHistoryResult purchaseHistoryResultFromPlatform( ) { return PurchasesHistoryResult( billingResult: resultWrapperFromPlatform(response.billingResult), - purchaseHistoryRecordList: - response.purchases - .map(purchaseHistoryRecordWrapperFromPlatform) - .toList(), + purchaseHistoryRecordList: response.purchases + .map(purchaseHistoryRecordWrapperFromPlatform) + .toList(), ); } @@ -110,10 +109,9 @@ PurchasesResultWrapper purchasesResultWrapperFromPlatform( return PurchasesResultWrapper( billingResult: resultWrapperFromPlatform(response.billingResult), purchasesList: response.purchases.map(purchaseWrapperFromPlatform).toList(), - responseCode: - forceOkResponseCode - ? BillingResponse.ok - : billingResponseFromPlatform(response.billingResult.responseCode), + responseCode: forceOkResponseCode + ? BillingResponse.ok + : billingResponseFromPlatform(response.billingResult.responseCode), ); } @@ -258,8 +256,9 @@ SubscriptionOfferDetailsWrapper subscriptionOfferDetailsWrapperFromPlatform( offerId: offer.offerId, offerTags: offer.offerTags, offerIdToken: offer.offerToken, - pricingPhases: - offer.pricingPhases.map(pricingPhaseWrapperFromPlatform).toList(), + pricingPhases: offer.pricingPhases + .map(pricingPhaseWrapperFromPlatform) + .toList(), installmentPlanDetails: installmentPlanDetailsFromPlatform( offer.installmentPlanDetails, ), @@ -273,8 +272,9 @@ UserChoiceDetailsWrapper userChoiceDetailsFromPlatform( return UserChoiceDetailsWrapper( originalExternalTransactionId: details.originalExternalTransactionId ?? '', externalTransactionToken: details.externalTransactionToken, - products: - details.products.map(userChoiceDetailsProductFromPlatform).toList(), + products: details.products + .map(userChoiceDetailsProductFromPlatform) + .toList(), ); } diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_product_details.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_product_details.dart index 460659902b8..21d022e0f13 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_product_details.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_product_details.dart @@ -160,9 +160,9 @@ class GooglePlayProductDetails extends ProductDetails { /// object was contructed for, or `null` if it was not a subscription. String? get offerToken => subscriptionIndex != null && - productDetails.subscriptionOfferDetails != null - ? productDetails - .subscriptionOfferDetails![subscriptionIndex!] - .offerIdToken - : null; + productDetails.subscriptionOfferDetails != null + ? productDetails + .subscriptionOfferDetails![subscriptionIndex!] + .offerIdToken + : null; } diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/translator.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/translator.dart index 51dd8808c0a..d2579ea69c6 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/translator.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/translator.dart @@ -19,13 +19,12 @@ class Translator { originalExternalTransactionId: detailsWrapper.originalExternalTransactionId, externalTransactionToken: detailsWrapper.externalTransactionToken, - products: - detailsWrapper.products - .map( - (UserChoiceDetailsProductWrapper e) => - convertToUserChoiceDetailsProduct(e), - ) - .toList(), + products: detailsWrapper.products + .map( + (UserChoiceDetailsProductWrapper e) => + convertToUserChoiceDetailsProduct(e), + ) + .toList(), ); } diff --git a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml index f8dc43e5e7c..99f4fb3ae96 100644 --- a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml @@ -3,11 +3,11 @@ description: An implementation for the Android platform of the Flutter `in_app_p repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 0.4.0+4 +version: 0.4.1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_manager_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_manager_test.dart index 3f88ac8aaf3..1f21f04868d 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_manager_test.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_manager_test.dart @@ -154,10 +154,9 @@ void main() { ) async { timesCalled++; return BillingResultWrapper( - responseCode: - timesCalled == 1 - ? BillingResponse.serviceDisconnected - : BillingResponse.ok, + responseCode: timesCalled == 1 + ? BillingResponse.serviceDisconnected + : BillingResponse.ok, ); }); verify(mockApi.startConnection(any, any, any)).called(1); diff --git a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.dart index 7598f417f89..b87fe0a6742 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -489,13 +489,11 @@ void main() { responseCode: PlatformBillingResponse.ok, debugMessage: debugMessage, ), - purchases: - expectedList - .map( - (PurchaseWrapper purchase) => - convertToPigeonPurchase(purchase), - ) - .toList(), + purchases: expectedList + .map( + (PurchaseWrapper purchase) => convertToPigeonPurchase(purchase), + ) + .toList(), ), ); @@ -633,8 +631,8 @@ void main() { when( mockApi.getBillingConfigAsync(), ).thenAnswer((_) async => platformBillingConfigFromWrapper(expected)); - final BillingConfigWrapper result = - await billingClient.getBillingConfig(); + final BillingConfigWrapper result = await billingClient + .getBillingConfig(); expect(result.countryCode, 'US'); expect(result, expected); }); @@ -652,8 +650,8 @@ void main() { debugMessage: expected.debugMessage!, ), ); - final BillingResultWrapper result = - await billingClient.isAlternativeBillingOnlyAvailable(); + final BillingResultWrapper result = await billingClient + .isAlternativeBillingOnlyAvailable(); expect(result, expected); }); }); @@ -690,8 +688,8 @@ void main() { debugMessage: expected.debugMessage!, ), ); - final BillingResultWrapper result = - await billingClient.showAlternativeBillingOnlyInformationDialog(); + final BillingResultWrapper result = await billingClient + .showAlternativeBillingOnlyInformationDialog(); expect(result, expected); }); }); diff --git a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart index 80a0fa790fa..e8d4c2c38e6 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.mocks.dart @@ -362,28 +362,30 @@ class MockInAppPurchaseApi extends _i1.Mock implements _i2.InAppPurchaseApi { #createAlternativeBillingOnlyReportingDetailsAsync, [], ), - returnValue: _i4.Future< - _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse - >.value( - _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( - this, - Invocation.method( - #createAlternativeBillingOnlyReportingDetailsAsync, - [], + returnValue: + _i4.Future< + _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse + >.value( + _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( + this, + Invocation.method( + #createAlternativeBillingOnlyReportingDetailsAsync, + [], + ), + ), ), - ), - ), - returnValueForMissingStub: _i4.Future< - _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse - >.value( - _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( - this, - Invocation.method( - #createAlternativeBillingOnlyReportingDetailsAsync, - [], + returnValueForMissingStub: + _i4.Future< + _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse + >.value( + _FakePlatformAlternativeBillingOnlyReportingDetailsResponse_5( + this, + Invocation.method( + #createAlternativeBillingOnlyReportingDetailsAsync, + [], + ), + ), ), - ), - ), ) as _i4.Future< _i2.PlatformAlternativeBillingOnlyReportingDetailsResponse diff --git a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_addition_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_addition_test.dart index d7edc418f0f..93fec10b283 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_addition_test.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_addition_test.dart @@ -76,8 +76,8 @@ void main() { when( mockApi.getBillingConfigAsync(), ).thenAnswer((_) async => platformBillingConfigFromWrapper(expected)); - final String countryCode = - await iapAndroidPlatformAddition.getCountryCode(); + final String countryCode = await iapAndroidPlatformAddition + .getCountryCode(); expect(countryCode, equals(expectedCountryCode)); }); @@ -133,8 +133,8 @@ void main() { ), ); - final BillingResultWrapper result = - await iapAndroidPlatformAddition.isAlternativeBillingOnlyAvailable(); + final BillingResultWrapper result = await iapAndroidPlatformAddition + .isAlternativeBillingOnlyAvailable(); expect(result, equals(expected)); }); @@ -153,8 +153,8 @@ void main() { when( mockApi.showAlternativeBillingOnlyInformationDialog(), ).thenAnswer((_) async => convertToPigeonResult(expected)); - final BillingResultWrapper result = - await iapAndroidPlatformAddition.isAlternativeBillingOnlyAvailable(); + final BillingResultWrapper result = await iapAndroidPlatformAddition + .isAlternativeBillingOnlyAvailable(); expect(result, equals(expected)); }); diff --git a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart index 5c72fd7b190..908e89542aa 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart @@ -114,10 +114,9 @@ void main() { debugMessage: '', ); }); - final PurchaseDetails purchase = - GooglePlayPurchaseDetails.fromPurchase( - dummyUnacknowledgedPurchase, - ).first; + final PurchaseDetails purchase = GooglePlayPurchaseDetails.fromPurchase( + dummyUnacknowledgedPurchase, + ).first; final BillingResultWrapper result = await iapAndroidPlatform .completePurchase(purchase); verify(mockApi.acknowledgePurchase(any)).called(2); @@ -379,8 +378,9 @@ void main() { final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( offerToken: productDetails.subscriptionOfferDetails?.first.offerIdToken, - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); final bool launchResult = await iapAndroidPlatform.buyNonConsumable( @@ -443,8 +443,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); final bool launchResult = await iapAndroidPlatform.buyNonConsumable( @@ -491,8 +492,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); await iapAndroidPlatform.buyNonConsumable(purchaseParam: purchaseParam); @@ -572,8 +574,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); final bool launchResult = await iapAndroidPlatform.buyConsumable( @@ -609,10 +612,9 @@ void main() { final bool result = await iapAndroidPlatform.buyNonConsumable( purchaseParam: GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails( - dummyOneTimeProductDetails, - ).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + dummyOneTimeProductDetails, + ).first, ), ); @@ -636,10 +638,9 @@ void main() { final bool result = await iapAndroidPlatform.buyConsumable( purchaseParam: GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails( - dummyOneTimeProductDetails, - ).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + dummyOneTimeProductDetails, + ).first, ), ); @@ -710,8 +711,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam); @@ -793,8 +795,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); await iapAndroidPlatform.buyConsumable( @@ -872,8 +875,9 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, ); await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam); @@ -921,14 +925,14 @@ void main() { subscription.cancel(); }, onDone: () {}); final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( - productDetails: - GooglePlayProductDetails.fromProductDetails(productDetails).first, + productDetails: GooglePlayProductDetails.fromProductDetails( + productDetails, + ).first, applicationUserName: accountId, changeSubscriptionParam: ChangeSubscriptionParam( - oldPurchaseDetails: - GooglePlayPurchaseDetails.fromPurchase( - dummyUnacknowledgedPurchase, - ).first, + oldPurchaseDetails: GooglePlayPurchaseDetails.fromPurchase( + dummyUnacknowledgedPurchase, + ).first, replacementMode: ReplacementMode.deferred, ), ); diff --git a/packages/in_app_purchase/in_app_purchase_android/test/test_conversion_utils.dart b/packages/in_app_purchase/in_app_purchase_android/test/test_conversion_utils.dart index 55b93993539..b80ab357458 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/test_conversion_utils.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/test_conversion_utils.dart @@ -36,12 +36,12 @@ PlatformPurchase convertToPigeonPurchase(PurchaseWrapper purchase) { quantity: 99, accountIdentifiers: purchase.obfuscatedAccountId != null || - purchase.obfuscatedProfileId != null - ? PlatformAccountIdentifiers( - obfuscatedAccountId: purchase.obfuscatedAccountId, - obfuscatedProfileId: purchase.obfuscatedProfileId, - ) - : null, + purchase.obfuscatedProfileId != null + ? PlatformAccountIdentifiers( + obfuscatedAccountId: purchase.obfuscatedAccountId, + obfuscatedProfileId: purchase.obfuscatedProfileId, + ) + : null, ); } @@ -58,10 +58,9 @@ PlatformProductDetails convertToPigeonProductDetails( oneTimePurchaseOfferDetails: _convertToPigeonOneTimePurchaseOfferDetails( details.oneTimePurchaseOfferDetails, ), - subscriptionOfferDetails: - details.subscriptionOfferDetails - ?.map(convertToPigeonSubscriptionOfferDetails) - .toList(), + subscriptionOfferDetails: details.subscriptionOfferDetails + ?.map(convertToPigeonSubscriptionOfferDetails) + .toList(), ); } @@ -73,8 +72,9 @@ PlatformSubscriptionOfferDetails convertToPigeonSubscriptionOfferDetails( offerId: details.offerId, offerToken: details.offerIdToken, offerTags: details.offerTags, - pricingPhases: - details.pricingPhases.map(convertToPigeonPricingPhase).toList(), + pricingPhases: details.pricingPhases + .map(convertToPigeonPricingPhase) + .toList(), ); } diff --git a/packages/interactive_media_ads/CHANGELOG.md b/packages/interactive_media_ads/CHANGELOG.md index 456b0b506d4..f9634b62175 100644 --- a/packages/interactive_media_ads/CHANGELOG.md +++ b/packages/interactive_media_ads/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.8 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 0.2.7 * Adds support to retrieve content time offsets at which ad breaks are scheduled. See diff --git a/packages/interactive_media_ads/README.md b/packages/interactive_media_ads/README.md index ffdae020187..1796ad3d2f1 100644 --- a/packages/interactive_media_ads/README.md +++ b/packages/interactive_media_ads/README.md @@ -67,8 +67,8 @@ android { // ··· compileOptions { coreLibraryDesugaringEnabled true - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } // ··· } @@ -236,41 +236,40 @@ Widget build(BuildContext context) { body: Center( child: SizedBox( width: 300, - child: - !_contentVideoController.value.isInitialized - ? Container() - : AspectRatio( - aspectRatio: _contentVideoController.value.aspectRatio, - child: Stack( - children: [ - // The display container must be on screen before any Ads can be - // loaded and can't be removed between ads. This handles clicks for - // ads. - _adDisplayContainer, - if (_shouldShowContentVideo) - VideoPlayer(_contentVideoController), - ], - ), + child: !_contentVideoController.value.isInitialized + ? Container() + : AspectRatio( + aspectRatio: _contentVideoController.value.aspectRatio, + child: Stack( + children: [ + // The display container must be on screen before any Ads can be + // loaded and can't be removed between ads. This handles clicks for + // ads. + _adDisplayContainer, + if (_shouldShowContentVideo) + VideoPlayer(_contentVideoController), + ], ), + ), ), ), floatingActionButton: _contentVideoController.value.isInitialized && _shouldShowContentVideo - ? FloatingActionButton( - onPressed: () { - setState(() { - _contentVideoController.value.isPlaying - ? _contentVideoController.pause() - : _contentVideoController.play(); - }); - }, - child: Icon( + ? FloatingActionButton( + onPressed: () { + setState(() { _contentVideoController.value.isPlaying - ? Icons.pause - : Icons.play_arrow, - ), - ) - : null, + ? _contentVideoController.pause() + : _contentVideoController.play(); + }); + }, + child: Icon( + _contentVideoController.value.isPlaying + ? Icons.pause + : Icons.play_arrow, + ), + ) + : null, ); } diff --git a/packages/interactive_media_ads/android/build.gradle b/packages/interactive_media_ads/android/build.gradle index 80304caa837..241c52957d1 100644 --- a/packages/interactive_media_ads/android/build.gradle +++ b/packages/interactive_media_ads/android/build.gradle @@ -30,12 +30,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17 } sourceSets { diff --git a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt index fb74ed55930..2853cdf5d19 100644 --- a/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt +++ b/packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt @@ -21,7 +21,7 @@ class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) : * * This must match the version in pubspec.yaml. */ - const val pluginVersion = "0.2.7" + const val pluginVersion = "0.2.8" } override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) { diff --git a/packages/interactive_media_ads/example/android/app/build.gradle b/packages/interactive_media_ads/example/android/app/build.gradle index a16412fe39f..bacc8f8e075 100644 --- a/packages/interactive_media_ads/example/android/app/build.gradle +++ b/packages/interactive_media_ads/example/android/app/build.gradle @@ -32,13 +32,13 @@ android { // #docregion android_desugaring compileOptions { coreLibraryDesugaringEnabled true - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } // #enddocregion android_desugaring kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/interactive_media_ads/example/lib/main.dart b/packages/interactive_media_ads/example/lib/main.dart index 4205c992fe7..ab6c3b86649 100644 --- a/packages/interactive_media_ads/example/lib/main.dart +++ b/packages/interactive_media_ads/example/lib/main.dart @@ -53,8 +53,8 @@ class _HomeScreenState extends State { }) { Navigator.of(context).push( MaterialPageRoute( - builder: - (_) => VideoAdExampleScreen(adType: adType, adTagUrl: adTagUrl), + builder: (_) => + VideoAdExampleScreen(adType: adType, adTagUrl: adTagUrl), ), ); } @@ -74,11 +74,10 @@ class _HomeScreenState extends State { itemBuilder: (_, int index) { final (String adType, String adTagUrl) = _testAdTagUrls[index]; return ElevatedButton( - onPressed: - () => _pushVideoAdExampleWithAdTagUrl( - adType: adType, - adTagUrl: adTagUrl, - ), + onPressed: () => _pushVideoAdExampleWithAdTagUrl( + adType: adType, + adTagUrl: adTagUrl, + ), child: Text(adType), ); }, diff --git a/packages/interactive_media_ads/example/lib/readme_example.dart b/packages/interactive_media_ads/example/lib/readme_example.dart index 3d8dedb02a1..0165be8a58e 100644 --- a/packages/interactive_media_ads/example/lib/readme_example.dart +++ b/packages/interactive_media_ads/example/lib/readme_example.dart @@ -221,41 +221,40 @@ class _AdExampleWidgetState extends State body: Center( child: SizedBox( width: 300, - child: - !_contentVideoController.value.isInitialized - ? Container() - : AspectRatio( - aspectRatio: _contentVideoController.value.aspectRatio, - child: Stack( - children: [ - // The display container must be on screen before any Ads can be - // loaded and can't be removed between ads. This handles clicks for - // ads. - _adDisplayContainer, - if (_shouldShowContentVideo) - VideoPlayer(_contentVideoController), - ], - ), + child: !_contentVideoController.value.isInitialized + ? Container() + : AspectRatio( + aspectRatio: _contentVideoController.value.aspectRatio, + child: Stack( + children: [ + // The display container must be on screen before any Ads can be + // loaded and can't be removed between ads. This handles clicks for + // ads. + _adDisplayContainer, + if (_shouldShowContentVideo) + VideoPlayer(_contentVideoController), + ], ), + ), ), ), floatingActionButton: _contentVideoController.value.isInitialized && _shouldShowContentVideo - ? FloatingActionButton( - onPressed: () { - setState(() { - _contentVideoController.value.isPlaying - ? _contentVideoController.pause() - : _contentVideoController.play(); - }); - }, - child: Icon( + ? FloatingActionButton( + onPressed: () { + setState(() { _contentVideoController.value.isPlaying - ? Icons.pause - : Icons.play_arrow, - ), - ) - : null, + ? _contentVideoController.pause() + : _contentVideoController.play(); + }); + }, + child: Icon( + _contentVideoController.value.isPlaying + ? Icons.pause + : Icons.play_arrow, + ), + ) + : null, ); // #docregion example_widget } diff --git a/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart b/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart index a248a27d4c0..7684cfbaf3b 100644 --- a/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart +++ b/packages/interactive_media_ads/example/lib/video_ad_example_screen.dart @@ -239,22 +239,21 @@ class _VideoAdExampleScreenState extends State ), SizedBox( width: 300, - child: - !_contentVideoController.value.isInitialized - ? Container() - : AspectRatio( - aspectRatio: _contentVideoController.value.aspectRatio, - child: Stack( - children: [ - // The display container must be on screen before any Ads can be - // loaded and can't be removed between ads. This handles clicks for - // ads. - _adDisplayContainer, - if (_shouldShowContentVideo) - VideoPlayer(_contentVideoController), - ], - ), + child: !_contentVideoController.value.isInitialized + ? Container() + : AspectRatio( + aspectRatio: _contentVideoController.value.aspectRatio, + child: Stack( + children: [ + // The display container must be on screen before any Ads can be + // loaded and can't be removed between ads. This handles clicks for + // ads. + _adDisplayContainer, + if (_shouldShowContentVideo) + VideoPlayer(_contentVideoController), + ], ), + ), ), ColoredBox( color: Colors.green, @@ -269,21 +268,21 @@ class _VideoAdExampleScreenState extends State ), floatingActionButton: _contentVideoController.value.isInitialized && _shouldShowContentVideo - ? FloatingActionButton( - onPressed: () { - setState(() { - _contentVideoController.value.isPlaying - ? _contentVideoController.pause() - : _contentVideoController.play(); - }); - }, - child: Icon( + ? FloatingActionButton( + onPressed: () { + setState(() { _contentVideoController.value.isPlaying - ? Icons.pause - : Icons.play_arrow, - ), - ) - : null, + ? _contentVideoController.pause() + : _contentVideoController.play(); + }); + }, + child: Icon( + _contentVideoController.value.isPlaying + ? Icons.pause + : Icons.play_arrow, + ), + ) + : null, ); } } diff --git a/packages/interactive_media_ads/example/pubspec.yaml b/packages/interactive_media_ads/example/pubspec.yaml index f47472464a1..dbfea384957 100644 --- a/packages/interactive_media_ads/example/pubspec.yaml +++ b/packages/interactive_media_ads/example/pubspec.yaml @@ -3,8 +3,8 @@ description: "Demonstrates how to use the interactive_media_ads plugin." publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift index 6ac61aa981e..ea5e0d43096 100644 --- a/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift +++ b/packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift @@ -13,7 +13,7 @@ class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest { /// The current version of the `interactive_media_ads` plugin. /// /// This must match the version in pubspec.yaml. - static let pluginVersion = "0.2.7" + static let pluginVersion = "0.2.8" func pigeonDefaultConstructor( pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer, diff --git a/packages/interactive_media_ads/lib/src/ads_request.dart b/packages/interactive_media_ads/lib/src/ads_request.dart index a68e1dff526..e4a74533ff6 100644 --- a/packages/interactive_media_ads/lib/src/ads_request.dart +++ b/packages/interactive_media_ads/lib/src/ads_request.dart @@ -87,10 +87,8 @@ class AdsRequest { /// based on content progress (cue points). ContentProgressProvider? get contentProgressProvider => platform.contentProgressProvider != null - ? ContentProgressProvider.fromPlatform( - platform.contentProgressProvider!, - ) - : null; + ? ContentProgressProvider.fromPlatform(platform.contentProgressProvider!) + : null; /// Notifies the SDK whether the player intends to start the content and ad in /// response to a user action or whether it will be automatically played. diff --git a/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart index a8968d522d6..2a55badc033 100644 --- a/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart +++ b/packages/interactive_media_ads/lib/src/android/android_ad_display_container.dart @@ -80,8 +80,8 @@ base class AndroidAdDisplayContainer extends PlatformAdDisplayContainer { // The `ViewGroup` used to create the native `ima.AdDisplayContainer`. The // `View` that handles playing an ad is added as a child to this `ViewGroup`. - late final ima.FrameLayout _frameLayout = - _androidParams._imaProxy.newFrameLayout(); + late final ima.FrameLayout _frameLayout = _androidParams._imaProxy + .newFrameLayout(); // Handles loading and displaying an ad. late ima.VideoView _videoView; @@ -132,10 +132,10 @@ base class AndroidAdDisplayContainer extends PlatformAdDisplayContainer { late final AndroidAdDisplayContainerCreationParams _androidParams = params is AndroidAdDisplayContainerCreationParams - ? params as AndroidAdDisplayContainerCreationParams - : AndroidAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( - params, - ); + ? params as AndroidAdDisplayContainerCreationParams + : AndroidAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( + params, + ); @override Widget build(BuildContext context) { @@ -306,8 +306,8 @@ base class AndroidAdDisplayContainer extends PlatformAdDisplayContainer { // app is returned to the foreground. container._startPlayerWhenVideoIsPrepared = false; await player.pause(); - container._savedAdPosition = - await container._videoView.getCurrentPosition(); + container._savedAdPosition = await container._videoView + .getCurrentPosition(); container._stopAdProgressTracking(); await Future.wait(>[ for (final ima.VideoAdPlayerCallback callback diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart b/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart index 953489d7d4f..c48bfd94a5f 100644 --- a/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart +++ b/packages/interactive_media_ads/lib/src/android/android_ads_loader.dart @@ -60,16 +60,16 @@ base class AndroidAdsLoader extends PlatformAdsLoader { _adsLoaderFuture = _createAdsLoader(); } - late final ima.ImaSdkFactory _sdkFactory = - _androidParams._proxy.instanceImaSdkFactory(); + late final ima.ImaSdkFactory _sdkFactory = _androidParams._proxy + .instanceImaSdkFactory(); late Future _adsLoaderFuture; late final AndroidAdsLoaderCreationParams _androidParams = params is AndroidAdsLoaderCreationParams - ? params as AndroidAdsLoaderCreationParams - : AndroidAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( - params, - ); + ? params as AndroidAdsLoaderCreationParams + : AndroidAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( + params, + ); @override Future contentComplete() async { diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart index c0a61fbec6c..63a07cf186b 100644 --- a/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart +++ b/packages/interactive_media_ads/lib/src/android/android_ads_manager.dart @@ -43,12 +43,9 @@ class AndroidAdsManager extends PlatformAdsManager { Future init({PlatformAdsRenderingSettings? settings}) async { ima.AdsRenderingSettings? nativeSettings; if (settings != null) { - nativeSettings = - settings is AndroidAdsRenderingSettings - ? await settings.nativeSettings - : await AndroidAdsRenderingSettings( - settings.params, - ).nativeSettings; + nativeSettings = settings is AndroidAdsRenderingSettings + ? await settings.nativeSettings + : await AndroidAdsRenderingSettings(settings.params).nativeSettings; } await _manager.init(nativeSettings); diff --git a/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart index 82e85028008..3a1ac4f271a 100644 --- a/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart +++ b/packages/interactive_media_ads/lib/src/android/android_ads_rendering_settings.dart @@ -105,8 +105,8 @@ base class AndroidAdsRenderingSettings extends PlatformAdsRenderingSettings { late final AndroidAdsRenderingSettingsCreationParams _androidParams = params is AndroidAdsRenderingSettingsCreationParams - ? params as AndroidAdsRenderingSettingsCreationParams - : AndroidAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( - params, - ); + ? params as AndroidAdsRenderingSettingsCreationParams + : AndroidAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( + params, + ); } diff --git a/packages/interactive_media_ads/lib/src/android/android_companion_ad_slot.dart b/packages/interactive_media_ads/lib/src/android/android_companion_ad_slot.dart index 5293732816b..a0c2560eb70 100644 --- a/packages/interactive_media_ads/lib/src/android/android_companion_ad_slot.dart +++ b/packages/interactive_media_ads/lib/src/android/android_companion_ad_slot.dart @@ -55,8 +55,8 @@ base class AndroidCompanionAdSlot extends PlatformCompanionAdSlot { _initAndroidParams(params); // ViewGroup used to display the Ad. - late final ima.ViewGroup _frameLayout = - _androidParams._proxy.newFrameLayout(); + late final ima.ViewGroup _frameLayout = _androidParams._proxy + .newFrameLayout(); late final Future _adSlotFuture = _initCompanionAdSlot(); @@ -87,10 +87,9 @@ base class AndroidCompanionAdSlot extends PlatformCompanionAdSlot { } Future _initCompanionAdSlot() async { - final ima.CompanionAdSlot adSlot = - await _androidParams._proxy - .instanceImaSdkFactory() - .createCompanionAdSlot(); + final ima.CompanionAdSlot adSlot = await _androidParams._proxy + .instanceImaSdkFactory() + .createCompanionAdSlot(); await Future.wait(>[ adSlot.setContainer(_frameLayout), diff --git a/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart b/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart index e99dcf1f8d4..c70c63e91f7 100644 --- a/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart +++ b/packages/interactive_media_ads/lib/src/android/android_content_progress_provider.dart @@ -44,15 +44,16 @@ base class AndroidContentProgressProvider /// /// This allows the SDK to track progress of the content video. @internal - late final ima.ContentProgressProvider progressProvider = - _androidParams._proxy.newContentProgressProvider(); + late final ima.ContentProgressProvider progressProvider = _androidParams + ._proxy + .newContentProgressProvider(); late final AndroidContentProgressProviderCreationParams _androidParams = params is AndroidContentProgressProviderCreationParams - ? params as AndroidContentProgressProviderCreationParams - : AndroidContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( - params, - ); + ? params as AndroidContentProgressProviderCreationParams + : AndroidContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( + params, + ); @override Future setProgress({ diff --git a/packages/interactive_media_ads/lib/src/android/android_ima_settings.dart b/packages/interactive_media_ads/lib/src/android/android_ima_settings.dart index 407ed42e348..7a42e512059 100644 --- a/packages/interactive_media_ads/lib/src/android/android_ima_settings.dart +++ b/packages/interactive_media_ads/lib/src/android/android_ima_settings.dart @@ -69,8 +69,8 @@ final class AndroidImaSettings extends PlatformImaSettings { } Future _createSettings() async { - final ImaSdkSettings settings = - await ImaSdkFactory.instance.createImaSdkSettings(); + final ImaSdkSettings settings = await ImaSdkFactory.instance + .createImaSdkSettings(); if (params.language case final String language) { await settings.setLanguage(language); } diff --git a/packages/interactive_media_ads/lib/src/android/android_view_widget.dart b/packages/interactive_media_ads/lib/src/android/android_view_widget.dart index fde39439323..f4f904bc27a 100644 --- a/packages/interactive_media_ads/lib/src/android/android_view_widget.dart +++ b/packages/interactive_media_ads/lib/src/android/android_view_widget.dart @@ -61,16 +61,15 @@ class AndroidViewWidget extends StatelessWidget { Widget build(BuildContext context) { return PlatformViewLink( viewType: _viewType, - surfaceFactory: ( - BuildContext context, - PlatformViewController controller, - ) { - return AndroidViewSurface( - controller: controller as AndroidViewController, - hitTestBehavior: PlatformViewHitTestBehavior.opaque, - gestureRecognizers: const >{}, - ); - }, + surfaceFactory: + (BuildContext context, PlatformViewController controller) { + return AndroidViewSurface( + controller: controller as AndroidViewController, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + gestureRecognizers: + const >{}, + ); + }, onCreatePlatformView: (PlatformViewCreationParams params) { return _initAndroidView(params) ..addOnPlatformViewCreatedListener((int id) { diff --git a/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart index dfb02c675b2..91efff52577 100644 --- a/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart +++ b/packages/interactive_media_ads/lib/src/android/interactive_media_ads.g.dart @@ -461,8 +461,8 @@ class PigeonInstanceManager { final PigeonInternalProxyApiBaseClass? strongInstance = _strongInstances[identifier]; if (strongInstance != null) { - final PigeonInternalProxyApiBaseClass copy = - strongInstance.pigeon_copy(); + final PigeonInternalProxyApiBaseClass copy = strongInstance + .pigeon_copy(); _identifiers[copy] = identifier; _weakInstances[identifier] = WeakReference(copy); @@ -2293,8 +2293,8 @@ class AdsManager extends BaseManager { arg_pigeon_instanceIdentifier != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null, expected non-null int.', ); - final List? arg_adCuePoints = - (args[1] as List?)?.cast(); + final List? arg_adCuePoints = (args[1] as List?) + ?.cast(); assert( arg_adCuePoints != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.AdsManager.pigeon_newInstance was null, expected non-null List.', @@ -7944,14 +7944,14 @@ class Ad extends PigeonInternalProxyApiBaseClass { arg_adWrapperCreativeIds != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.', ); - final List? arg_adWrapperIds = - (args[5] as List?)?.cast(); + final List? arg_adWrapperIds = (args[5] as List?) + ?.cast(); assert( arg_adWrapperIds != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.', ); - final List? arg_adWrapperSystems = - (args[6] as List?)?.cast(); + final List? arg_adWrapperSystems = (args[6] as List?) + ?.cast(); assert( arg_adWrapperSystems != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.', @@ -8006,8 +8006,8 @@ class Ad extends PigeonInternalProxyApiBaseClass { arg_traffickingParameters != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null String.', ); - final List? arg_uiElements = - (args[20] as List?)?.cast(); + final List? arg_uiElements = (args[20] as List?) + ?.cast(); assert( arg_uiElements != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.Ad.pigeon_newInstance was null, expected non-null List.', diff --git a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart index 053defe1e56..bb5c9dad327 100644 --- a/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart +++ b/packages/interactive_media_ads/lib/src/ios/interactive_media_ads.g.dart @@ -454,8 +454,8 @@ class PigeonInstanceManager { final PigeonInternalProxyApiBaseClass? strongInstance = _strongInstances[identifier]; if (strongInstance != null) { - final PigeonInternalProxyApiBaseClass copy = - strongInstance.pigeon_copy(); + final PigeonInternalProxyApiBaseClass copy = strongInstance + .pigeon_copy(); _identifiers[copy] = identifier; _weakInstances[identifier] = WeakReference(copy); @@ -3899,8 +3899,8 @@ class IMAAdsManager extends NSObject { arg_pigeon_instanceIdentifier != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null, expected non-null int.', ); - final List? arg_adCuePoints = - (args[1] as List?)?.cast(); + final List? arg_adCuePoints = (args[1] as List?) + ?.cast(); assert( arg_adCuePoints != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAdsManager.pigeon_newInstance was null, expected non-null List.', @@ -6671,8 +6671,8 @@ class IMAAd extends NSObject { arg_dealID != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAd.pigeon_newInstance was null, expected non-null String.', ); - final List? arg_wrapperAdIDs = - (args[25] as List?)?.cast(); + final List? arg_wrapperAdIDs = (args[25] as List?) + ?.cast(); assert( arg_wrapperAdIDs != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAd.pigeon_newInstance was null, expected non-null List.', @@ -6683,8 +6683,8 @@ class IMAAd extends NSObject { arg_wrapperCreativeIDs != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAd.pigeon_newInstance was null, expected non-null List.', ); - final List? arg_wrapperSystems = - (args[27] as List?)?.cast(); + final List? arg_wrapperSystems = (args[27] as List?) + ?.cast(); assert( arg_wrapperSystems != null, 'Argument for dev.flutter.pigeon.interactive_media_ads.IMAAd.pigeon_newInstance was null, expected non-null List.', diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart b/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart index 27f2cce470e..a090fe03ec5 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_ad_display_container.dart @@ -62,10 +62,10 @@ base class IOSAdDisplayContainer extends PlatformAdDisplayContainer { late final IOSAdDisplayContainerCreationParams _iosParams = params is IOSAdDisplayContainerCreationParams - ? params as IOSAdDisplayContainerCreationParams - : IOSAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( - params, - ); + ? params as IOSAdDisplayContainerCreationParams + : IOSAdDisplayContainerCreationParams.fromPlatformAdDisplayContainerCreationParams( + params, + ); @override Widget build(BuildContext context) { @@ -76,11 +76,10 @@ base class IOSAdDisplayContainer extends PlatformAdDisplayContainer { adDisplayContainer = _iosParams._imaProxy.newIMAAdDisplayContainer( adContainer: _controller.view, adContainerViewController: _controller, - companionSlots: - _iosParams.companionSlots - .cast() - .map((IOSCompanionAdSlot slot) => slot.nativeCompanionAdSlot) - .toList(), + companionSlots: _iosParams.companionSlots + .cast() + .map((IOSCompanionAdSlot slot) => slot.nativeCompanionAdSlot) + .toList(), ); await _viewDidAppearCompleter.future; params.onContainerAdded(this); diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart index 62ff961a209..27687dcd72f 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_loader.dart @@ -63,10 +63,8 @@ base class IOSAdsLoader extends PlatformAdsLoader { late final IOSAdsLoaderCreationParams _iosParams = params is IOSAdsLoaderCreationParams - ? params as IOSAdsLoaderCreationParams - : IOSAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams( - params, - ); + ? params as IOSAdsLoaderCreationParams + : IOSAdsLoaderCreationParams.fromPlatformAdsLoaderCreationParams(params); @override Future contentComplete() { @@ -79,9 +77,9 @@ base class IOSAdsLoader extends PlatformAdsLoader { (_iosParams.container as IOSAdDisplayContainer).adDisplayContainer!; final IMAContentPlayhead? contentProgressProvider = request.contentProgressProvider != null - ? (request.contentProgressProvider! as IOSContentProgressProvider) - .contentPlayhead - : null; + ? (request.contentProgressProvider! as IOSContentProgressProvider) + .contentPlayhead + : null; final IMAAdsRequest adsRequest = switch (request) { final PlatformAdsRequestWithAdTagUrl request => IMAAdsRequest( diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart index f8a8c01671e..45f00c0f24c 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager.dart @@ -45,10 +45,9 @@ class IOSAdsManager extends PlatformAdsManager { Future init({PlatformAdsRenderingSettings? settings}) { IMAAdsRenderingSettings? nativeSettings; if (settings != null) { - nativeSettings = - settings is IOSAdsRenderingSettings - ? settings.nativeSettings - : IOSAdsRenderingSettings(settings.params).nativeSettings; + nativeSettings = settings is IOSAdsRenderingSettings + ? settings.nativeSettings + : IOSAdsRenderingSettings(settings.params).nativeSettings; } return _manager.initialize(nativeSettings); @@ -58,8 +57,8 @@ class IOSAdsManager extends PlatformAdsManager { Future setAdsManagerDelegate(PlatformAdsManagerDelegate delegate) { final IOSAdsManagerDelegate platformDelegate = delegate is IOSAdsManagerDelegate - ? delegate - : IOSAdsManagerDelegate(delegate.params); + ? delegate + : IOSAdsManagerDelegate(delegate.params); _delegate = platformDelegate; return _manager.setDelegate(platformDelegate.delegate); } diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart index 6eec2a21c19..e6735e94761 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_manager_delegate.dart @@ -52,10 +52,10 @@ final class IOSAdsManagerDelegate extends PlatformAdsManagerDelegate { late final IOSAdsManagerDelegateCreationParams _iosParams = params is IOSAdsManagerDelegateCreationParams - ? params as IOSAdsManagerDelegateCreationParams - : IOSAdsManagerDelegateCreationParams.fromPlatformAdsManagerDelegateCreationParams( - params, - ); + ? params as IOSAdsManagerDelegateCreationParams + : IOSAdsManagerDelegateCreationParams.fromPlatformAdsManagerDelegateCreationParams( + params, + ); // This value is created in a static method because the callback methods for // any wrapped classes must not reference the encapsulating object. This is to diff --git a/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart b/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart index a65dc6c4113..15b577297ff 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_ads_rendering_settings.dart @@ -78,13 +78,13 @@ base class IOSAdsRenderingSettings extends PlatformAdsRenderingSettings { /// The native iOS IMAAdsRenderingSettings. @internal - late final IMAAdsRenderingSettings nativeSettings = - _iosParams._proxy.newIMAAdsRenderingSettings(); + late final IMAAdsRenderingSettings nativeSettings = _iosParams._proxy + .newIMAAdsRenderingSettings(); late final IOSAdsRenderingSettingsCreationParams _iosParams = params is IOSAdsRenderingSettingsCreationParams - ? params as IOSAdsRenderingSettingsCreationParams - : IOSAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( - params, - ); + ? params as IOSAdsRenderingSettingsCreationParams + : IOSAdsRenderingSettingsCreationParams.fromPlatformAdsRenderingSettingsCreationParams( + params, + ); } diff --git a/packages/interactive_media_ads/lib/src/ios/ios_companion_ad_slot.dart b/packages/interactive_media_ads/lib/src/ios/ios_companion_ad_slot.dart index a7c829ec226..fbd003eee33 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_companion_ad_slot.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_companion_ad_slot.dart @@ -84,12 +84,12 @@ base class IOSCompanionAdSlot extends PlatformCompanionAdSlot { IMACompanionAdSlot _initCompanionAdSlot() { final IMACompanionAdSlot adSlot = switch (params.size) { - final CompanionAdSlotSizeFixed size => _iosParams._proxy - .sizeIMACompanionAdSlot( - view: _view, - width: size.width, - height: size.height, - ), + final CompanionAdSlotSizeFixed size => + _iosParams._proxy.sizeIMACompanionAdSlot( + view: _view, + width: size.width, + height: size.height, + ), CompanionAdSlotSizeFluid() => _iosParams._proxy.newIMACompanionAdSlot( view: _view, ), diff --git a/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart b/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart index 98b2b88359c..c8bc7a8a0a7 100644 --- a/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart +++ b/packages/interactive_media_ads/lib/src/ios/ios_content_progress_provider.dart @@ -43,15 +43,15 @@ base class IOSContentProgressProvider extends PlatformContentProgressProvider { /// /// This allows the SDK to track progress of the content video. @internal - late final ima.IMAContentPlayhead contentPlayhead = - _iosParams._proxy.newIMAContentPlayhead(); + late final ima.IMAContentPlayhead contentPlayhead = _iosParams._proxy + .newIMAContentPlayhead(); late final IOSContentProgressProviderCreationParams _iosParams = params is IOSContentProgressProviderCreationParams - ? params as IOSContentProgressProviderCreationParams - : IOSContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( - params, - ); + ? params as IOSContentProgressProviderCreationParams + : IOSContentProgressProviderCreationParams.fromPlatformContentProgressProviderCreationParams( + params, + ); @override Future setProgress({ diff --git a/packages/interactive_media_ads/pubspec.yaml b/packages/interactive_media_ads/pubspec.yaml index 385101a9c01..24dff31c0eb 100644 --- a/packages/interactive_media_ads/pubspec.yaml +++ b/packages/interactive_media_ads/pubspec.yaml @@ -2,13 +2,13 @@ name: interactive_media_ads description: A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS. repository: https://github.com/flutter/packages/tree/main/packages/interactive_media_ads issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+interactive_media_ads%22 -version: 0.2.7 # This must match the version in +version: 0.2.8 # This must match the version in # `android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt` and # `ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift` environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/interactive_media_ads/test/ad_display_container_test.dart b/packages/interactive_media_ads/test/ad_display_container_test.dart index 1261cbf3236..c20a19ff89e 100644 --- a/packages/interactive_media_ads/test/ad_display_container_test.dart +++ b/packages/interactive_media_ads/test/ad_display_container_test.dart @@ -31,22 +31,20 @@ void main() { 'constructor parameters are correctly passed to creation params', (WidgetTester tester) async { InteractiveMediaAdsPlatform.instance = TestInteractiveMediaAdsPlatform( - onCreatePlatformAdDisplayContainer: ( - PlatformAdDisplayContainerCreationParams params, - ) { - return TestPlatformAdDisplayContainer( - params, - onBuild: (_) => Container(), - ); - }, + onCreatePlatformAdDisplayContainer: + (PlatformAdDisplayContainerCreationParams params) { + return TestPlatformAdDisplayContainer( + params, + onBuild: (_) => Container(), + ); + }, onCreatePlatformAdsLoader: (PlatformAdsLoaderCreationParams params) { throw UnimplementedError(); }, - onCreatePlatformAdsManagerDelegate: ( - PlatformAdsManagerDelegateCreationParams params, - ) { - throw UnimplementedError(); - }, + onCreatePlatformAdsManagerDelegate: + (PlatformAdsManagerDelegateCreationParams params) { + throw UnimplementedError(); + }, onCreatePlatformContentProgressProvider: (_) { throw UnimplementedError(); }, diff --git a/packages/interactive_media_ads/test/ads_manager_delegate_test.dart b/packages/interactive_media_ads/test/ads_manager_delegate_test.dart index a6f6a9cf510..2780d9db4c6 100644 --- a/packages/interactive_media_ads/test/ads_manager_delegate_test.dart +++ b/packages/interactive_media_ads/test/ads_manager_delegate_test.dart @@ -11,21 +11,19 @@ import 'test_stubs.dart'; void main() { test('passes params to platform instance', () async { InteractiveMediaAdsPlatform.instance = TestInteractiveMediaAdsPlatform( - onCreatePlatformAdsManagerDelegate: ( - PlatformAdsManagerDelegateCreationParams params, - ) { - return TestPlatformAdsManagerDelegate(params); - }, + onCreatePlatformAdsManagerDelegate: + (PlatformAdsManagerDelegateCreationParams params) { + return TestPlatformAdsManagerDelegate(params); + }, onCreatePlatformAdsLoader: (PlatformAdsLoaderCreationParams params) { throw UnimplementedError(); }, - onCreatePlatformAdDisplayContainer: ( - PlatformAdDisplayContainerCreationParams params, - ) { - throw UnimplementedError(); - }, - onCreatePlatformContentProgressProvider: - (_) => throw UnimplementedError(), + onCreatePlatformAdDisplayContainer: + (PlatformAdDisplayContainerCreationParams params) { + throw UnimplementedError(); + }, + onCreatePlatformContentProgressProvider: (_) => + throw UnimplementedError(), ); void onAdEvent(AdEvent event) {} diff --git a/packages/interactive_media_ads/test/ads_manager_test.dart b/packages/interactive_media_ads/test/ads_manager_test.dart index 836b5cb77f7..bc74489c0fc 100644 --- a/packages/interactive_media_ads/test/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/ads_manager_test.dart @@ -122,16 +122,14 @@ AdsManager createAdsManager(PlatformAdsManager platformManager) { onRequestAds: (PlatformAdsRequest request) async {}, ); }, - onCreatePlatformAdsManagerDelegate: ( - PlatformAdsManagerDelegateCreationParams params, - ) { - throw UnimplementedError(); - }, - onCreatePlatformAdDisplayContainer: ( - PlatformAdDisplayContainerCreationParams params, - ) { - throw UnimplementedError(); - }, + onCreatePlatformAdsManagerDelegate: + (PlatformAdsManagerDelegateCreationParams params) { + throw UnimplementedError(); + }, + onCreatePlatformAdDisplayContainer: + (PlatformAdDisplayContainerCreationParams params) { + throw UnimplementedError(); + }, onCreatePlatformContentProgressProvider: (_) => throw UnimplementedError(), ); diff --git a/packages/interactive_media_ads/test/android/ad_display_container_test.dart b/packages/interactive_media_ads/test/android/ad_display_container_test.dart index 2342d455789..854b8048f44 100644 --- a/packages/interactive_media_ads/test/android/ad_display_container_test.dart +++ b/packages/interactive_media_ads/test/android/ad_display_container_test.dart @@ -139,36 +139,41 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - required dynamic onError, - dynamic onPrepared, - void Function(ima.VideoView, ima.MediaPlayer)? onCompletion, - }) { - onCompletionCallback = onCompletion!; - return MockVideoView(); - }, + newVideoView: + ({ + required dynamic onError, + dynamic onPrepared, + void Function(ima.VideoView, ima.MediaPlayer)? onCompletion, + }) { + onCompletionCallback = onCompletion!; + return MockVideoView(); + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) - addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - addCallbackCallback = addCallback; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) + addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( @@ -206,37 +211,42 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - required void Function(ima.VideoView, ima.MediaPlayer, int, int) - onError, - dynamic onPrepared, - dynamic onCompletion, - }) { - onErrorCallback = onError; - return MockVideoView(); - }, + newVideoView: + ({ + required void Function(ima.VideoView, ima.MediaPlayer, int, int) + onError, + dynamic onPrepared, + dynamic onCompletion, + }) { + onErrorCallback = onError; + return MockVideoView(); + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) - addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - addCallbackCallback = addCallback; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) + addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( @@ -280,49 +290,52 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - Future Function(ima.VideoView, ima.MediaPlayer)? onPrepared, - dynamic onCompletion, - }) { - onPreparedCallback = onPrepared!; - final MockVideoView mockVideoView = MockVideoView(); - when( - mockVideoView.getCurrentPosition(), - ).thenAnswer((_) async => adProgress); - return mockVideoView; - }, + newVideoView: + ({ + dynamic onError, + Future Function(ima.VideoView, ima.MediaPlayer)? onPrepared, + dynamic onCompletion, + }) { + onPreparedCallback = onPrepared!; + final MockVideoView mockVideoView = MockVideoView(); + when( + mockVideoView.getCurrentPosition(), + ).thenAnswer((_) async => adProgress); + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) - addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - addCallbackCallback = addCallback; - playAdCallback = playAd; - return MockVideoAdPlayer(); - }, - newVideoProgressUpdate: ({ - required int currentTimeMs, - required int durationMs, - }) { - expect(currentTimeMs, adProgress); - expect(durationMs, adDuration); - return MockVideoProgressUpdate(); - }, + newVideoAdPlayer: + ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) + addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + addCallbackCallback = addCallback; + playAdCallback = playAd; + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: + ({required int currentTimeMs, required int durationMs}) { + expect(currentTimeMs, adProgress); + expect(durationMs, adDuration); + return MockVideoProgressUpdate(); + }, ); AndroidAdDisplayContainer( @@ -369,51 +382,56 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, - dynamic onCompletion, - }) { - // VideoView.onPrepared returns void, but the implementation uses an - // async callback method. - onPreparedCallback = - onPrepared! - as Future Function(ima.VideoView, ima.MediaPlayer); - final MockVideoView mockVideoView = MockVideoView(); - when(mockVideoView.getCurrentPosition()).thenAnswer((_) async => 10); - return mockVideoView; - }, + newVideoView: + ({ + dynamic onError, + void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = + onPrepared! + as Future Function(ima.VideoView, ima.MediaPlayer); + final MockVideoView mockVideoView = MockVideoView(); + when( + mockVideoView.getCurrentPosition(), + ).thenAnswer((_) async => 10); + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - // VideoAdPlayer.pauseAd returns void, but the implementation uses an - // async callback method. - pauseAdCallback = - pauseAd - as Future Function(ima.VideoAdPlayer, ima.AdMediaInfo); - return MockVideoAdPlayer(); - }, - newVideoProgressUpdate: ({ - required int currentTimeMs, - required int durationMs, - }) { - return MockVideoProgressUpdate(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + // VideoAdPlayer.pauseAd returns void, but the implementation uses an + // async callback method. + pauseAdCallback = + pauseAd + as Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ); + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: + ({required int currentTimeMs, required int durationMs}) { + return MockVideoProgressUpdate(); + }, ); AndroidAdDisplayContainer( @@ -454,52 +472,57 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, - dynamic onCompletion, - }) { - // VideoView.onPrepared returns void, but the implementation uses an - // async callback method. - onPreparedCallback = - onPrepared! - as Future Function(ima.VideoView, ima.MediaPlayer); - final MockVideoView mockVideoView = MockVideoView(); - when(mockVideoView.getCurrentPosition()).thenAnswer((_) async => 10); - return mockVideoView; - }, + newVideoView: + ({ + dynamic onError, + void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = + onPrepared! + as Future Function(ima.VideoView, ima.MediaPlayer); + final MockVideoView mockVideoView = MockVideoView(); + when( + mockVideoView.getCurrentPosition(), + ).thenAnswer((_) async => 10); + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - // VideoAdPlayer.pauseAd returns void, but the implementation uses an - // async callback method. - pauseAdCallback = - pauseAd - as Future Function(ima.VideoAdPlayer, ima.AdMediaInfo); - releaseCallback = release as void Function(ima.VideoAdPlayer); - return MockVideoAdPlayer(); - }, - newVideoProgressUpdate: ({ - required int currentTimeMs, - required int durationMs, - }) { - return MockVideoProgressUpdate(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + // VideoAdPlayer.pauseAd returns void, but the implementation uses an + // async callback method. + pauseAdCallback = + pauseAd + as Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ); + releaseCallback = release as void Function(ima.VideoAdPlayer); + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: + ({required int currentTimeMs, required int durationMs}) { + return MockVideoProgressUpdate(); + }, ); AndroidAdDisplayContainer( @@ -541,52 +564,57 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, - dynamic onCompletion, - }) { - // VideoView.onPrepared returns void, but the implementation uses an - // async callback method. - onPreparedCallback = - onPrepared! - as Future Function(ima.VideoView, ima.MediaPlayer); - final MockVideoView mockVideoView = MockVideoView(); - when(mockVideoView.getCurrentPosition()).thenAnswer((_) async => 10); - return mockVideoView; - }, + newVideoView: + ({ + dynamic onError, + void Function(ima.VideoView, ima.MediaPlayer)? onPrepared, + dynamic onCompletion, + }) { + // VideoView.onPrepared returns void, but the implementation uses an + // async callback method. + onPreparedCallback = + onPrepared! + as Future Function(ima.VideoView, ima.MediaPlayer); + final MockVideoView mockVideoView = MockVideoView(); + when( + mockVideoView.getCurrentPosition(), + ).thenAnswer((_) async => 10); + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - // VideoAdPlayer.pauseAd returns void, but the implementation uses an - // async callback method. - pauseAdCallback = - pauseAd - as Future Function(ima.VideoAdPlayer, ima.AdMediaInfo); - playAdCallback = playAd; - return MockVideoAdPlayer(); - }, - newVideoProgressUpdate: ({ - required int currentTimeMs, - required int durationMs, - }) { - return MockVideoProgressUpdate(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + // VideoAdPlayer.pauseAd returns void, but the implementation uses an + // async callback method. + pauseAdCallback = + pauseAd + as Future Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ); + playAdCallback = playAd; + return MockVideoAdPlayer(); + }, + newVideoProgressUpdate: + ({required int currentTimeMs, required int durationMs}) { + return MockVideoProgressUpdate(); + }, ); AndroidAdDisplayContainer( @@ -633,34 +661,32 @@ void main() { final MockVideoView mockVideoView = MockVideoView(); final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - dynamic onPrepared, - dynamic onCompletion, - }) { - return mockVideoView; - }, + newVideoView: + ({dynamic onError, dynamic onPrepared, dynamic onCompletion}) { + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAdCallback = loadAd; - playAdCallback = playAd; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAdCallback = loadAd; + playAdCallback = playAd; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( @@ -689,43 +715,41 @@ void main() { int newViewVideoCallCount = 0; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => mockFrameLayout, - newVideoView: ({ - dynamic onError, - dynamic onPrepared, - dynamic onCompletion, - }) { - switch (newViewVideoCallCount) { - case 0: - newViewVideoCallCount++; - return mockVideoView; - case 1: - newViewVideoCallCount++; - return mockVideoView2; - default: - fail('newVideoView was called too many times'); - } - }, + newVideoView: + ({dynamic onError, dynamic onPrepared, dynamic onCompletion}) { + switch (newViewVideoCallCount) { + case 0: + newViewVideoCallCount++; + return mockVideoView; + case 1: + newViewVideoCallCount++; + return mockVideoView2; + default: + fail('newVideoView was called too many times'); + } + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd, - }) { - loadAd(MockVideoAdPlayer(), MockAdMediaInfo(), MockAdPodInfo()); - stopAdCallback = stopAd; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd, + }) { + loadAd(MockVideoAdPlayer(), MockAdMediaInfo(), MockAdPodInfo()); + stopAdCallback = stopAd; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( @@ -750,43 +774,41 @@ void main() { int newViewVideoCallCount = 0; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => mockFrameLayout, - newVideoView: ({ - dynamic onError, - dynamic onPrepared, - dynamic onCompletion, - }) { - switch (newViewVideoCallCount) { - case 0: - newViewVideoCallCount++; - return mockVideoView; - case 1: - newViewVideoCallCount++; - return mockVideoView2; - default: - fail('newVideoView was called too many times'); - } - }, + newVideoView: + ({dynamic onError, dynamic onPrepared, dynamic onCompletion}) { + switch (newViewVideoCallCount) { + case 0: + newViewVideoCallCount++; + return mockVideoView; + case 1: + newViewVideoCallCount++; + return mockVideoView2; + default: + fail('newVideoView was called too many times'); + } + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required dynamic addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required void Function(ima.VideoAdPlayer) release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - loadAd(MockVideoAdPlayer(), MockAdMediaInfo(), MockAdPodInfo()); - releaseCallback = release; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required dynamic addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required void Function(ima.VideoAdPlayer) release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + loadAd(MockVideoAdPlayer(), MockAdMediaInfo(), MockAdPodInfo()); + releaseCallback = release; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( @@ -918,37 +940,42 @@ void main() { final MockVideoView mockVideoView = MockVideoView(); final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newFrameLayout: () => MockFrameLayout(), - newVideoView: ({ - dynamic onError, - dynamic onPrepared, - void Function(ima.VideoView, ima.MediaPlayer)? onCompletion, - }) { - onCompletionCallback = onCompletion!; - return mockVideoView; - }, + newVideoView: + ({ + dynamic onError, + dynamic onPrepared, + void Function(ima.VideoView, ima.MediaPlayer)? onCompletion, + }) { + onCompletionCallback = onCompletion!; + return mockVideoView; + }, createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) - addCallback, - required void Function( - ima.VideoAdPlayer, - ima.AdMediaInfo, - ima.AdPodInfo, - ) - loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd, - }) { - addCallbackCallback = addCallback; - loadAdCallback = loadAd; - stopAdCallback = stopAd; - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required void Function( + ima.VideoAdPlayer, + ima.VideoAdPlayerCallback, + ) + addCallback, + required void Function( + ima.VideoAdPlayer, + ima.AdMediaInfo, + ima.AdPodInfo, + ) + loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd, + }) { + addCallbackCallback = addCallback; + loadAdCallback = loadAd; + stopAdCallback = stopAd; + return MockVideoAdPlayer(); + }, ); AndroidAdDisplayContainer( diff --git a/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart b/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart index 0ffd6327893..0c4e9543ada 100644 --- a/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart +++ b/packages/interactive_media_ads/test/android/ad_display_container_test.mocks.dart @@ -1173,12 +1173,10 @@ class MockSurfaceAndroidViewController extends _i1.Mock _i4.PointTransformer get pointTransformer => (super.noSuchMethod( Invocation.getter(#pointTransformer), - returnValue: - (_i3.Offset position) => - _FakeOffset_17(this, Invocation.getter(#pointTransformer)), - returnValueForMissingStub: - (_i3.Offset position) => - _FakeOffset_17(this, Invocation.getter(#pointTransformer)), + returnValue: (_i3.Offset position) => + _FakeOffset_17(this, Invocation.getter(#pointTransformer)), + returnValueForMissingStub: (_i3.Offset position) => + _FakeOffset_17(this, Invocation.getter(#pointTransformer)), ) as _i4.PointTransformer); diff --git a/packages/interactive_media_ads/test/android/ads_loader_test.dart b/packages/interactive_media_ads/test/android/ads_loader_test.dart index dd8c89107db..e07d8fa6f17 100644 --- a/packages/interactive_media_ads/test/android/ads_loader_test.dart +++ b/packages/interactive_media_ads/test/android/ads_loader_test.dart @@ -116,8 +116,8 @@ void main() { ); final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( - newContentProgressProvider: - () => ima.ContentProgressProvider.pigeon_detached(), + newContentProgressProvider: () => + ima.ContentProgressProvider.pigeon_detached(), ); final AndroidAdsLoader adsLoader = AndroidAdsLoader( @@ -182,8 +182,8 @@ void main() { ); final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( - newContentProgressProvider: - () => ima.ContentProgressProvider.pigeon_detached(), + newContentProgressProvider: () => + ima.ContentProgressProvider.pigeon_detached(), ); final AndroidAdsLoader adsLoader = AndroidAdsLoader( @@ -251,16 +251,17 @@ void main() { onAdsManagerLoadedCallback; final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( - newAdsLoadedListener: ({ - required void Function( - ima.AdsLoadedListener, - ima.AdsManagerLoadedEvent, - ) - onAdsManagerLoaded, - }) { - onAdsManagerLoadedCallback = onAdsManagerLoaded; - return MockAdsLoadedListener(); - }, + newAdsLoadedListener: + ({ + required void Function( + ima.AdsLoadedListener, + ima.AdsManagerLoadedEvent, + ) + onAdsManagerLoaded, + }) { + onAdsManagerLoadedCallback = onAdsManagerLoaded; + return MockAdsLoadedListener(); + }, newAdErrorListener: ({required dynamic onAdError}) { return MockAdErrorListener(); }, @@ -306,13 +307,14 @@ void main() { newAdsLoadedListener: ({required dynamic onAdsManagerLoaded}) { return MockAdsLoadedListener(); }, - newAdErrorListener: ({ - required void Function(ima.AdErrorListener, ima.AdErrorEvent) - onAdError, - }) { - onAdErrorCallback = onAdError; - return MockAdErrorListener(); - }, + newAdErrorListener: + ({ + required void Function(ima.AdErrorListener, ima.AdErrorEvent) + onAdError, + }) { + onAdErrorCallback = onAdError; + return MockAdErrorListener(); + }, ); AndroidAdsLoader( @@ -377,21 +379,22 @@ Future _pumpAdDisplayContainer( createAdDisplayContainerImaSdkFactory: (_, __) async { return MockAdDisplayContainer(); }, - newVideoAdPlayer: ({ - required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) - addCallback, - required dynamic loadAd, - required dynamic pauseAd, - required dynamic playAd, - required dynamic release, - required dynamic removeCallback, - required dynamic stopAd, - }) { - if (mockAdPlayerCallback != null) { - addCallback(MockVideoAdPlayer(), mockAdPlayerCallback); - } - return MockVideoAdPlayer(); - }, + newVideoAdPlayer: + ({ + required void Function(ima.VideoAdPlayer, ima.VideoAdPlayerCallback) + addCallback, + required dynamic loadAd, + required dynamic pauseAd, + required dynamic playAd, + required dynamic release, + required dynamic removeCallback, + required dynamic stopAd, + }) { + if (mockAdPlayerCallback != null) { + addCallback(MockVideoAdPlayer(), mockAdPlayerCallback); + } + return MockVideoAdPlayer(); + }, ); final MockPlatformViewsServiceProxy mockPlatformViewsProxy = diff --git a/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart index da94b7f609a..47e60b975b9 100644 --- a/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart +++ b/packages/interactive_media_ads/test/android/ads_loader_test.mocks.dart @@ -1567,12 +1567,10 @@ class MockSurfaceAndroidViewController extends _i1.Mock _i4.PointTransformer get pointTransformer => (super.noSuchMethod( Invocation.getter(#pointTransformer), - returnValue: - (_i3.Offset position) => - _FakeOffset_18(this, Invocation.getter(#pointTransformer)), - returnValueForMissingStub: - (_i3.Offset position) => - _FakeOffset_18(this, Invocation.getter(#pointTransformer)), + returnValue: (_i3.Offset position) => + _FakeOffset_18(this, Invocation.getter(#pointTransformer)), + returnValueForMissingStub: (_i3.Offset position) => + _FakeOffset_18(this, Invocation.getter(#pointTransformer)), ) as _i4.PointTransformer); diff --git a/packages/interactive_media_ads/test/android/ads_manager_test.dart b/packages/interactive_media_ads/test/android/ads_manager_test.dart index 56aba174591..5eb484f76ad 100644 --- a/packages/interactive_media_ads/test/android/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/android/ads_manager_test.dart @@ -124,12 +124,14 @@ void main() { onAdEventCallback; final InteractiveMediaAdsProxy proxy = InteractiveMediaAdsProxy( - newAdEventListener: ({ - required void Function(ima.AdEventListener, ima.AdEvent) onAdEvent, - }) { - onAdEventCallback = onAdEvent; - return MockAdEventListener(); - }, + newAdEventListener: + ({ + required void Function(ima.AdEventListener, ima.AdEvent) + onAdEvent, + }) { + onAdEventCallback = onAdEvent; + return MockAdEventListener(); + }, newAdErrorListener: ({required dynamic onAdError}) { return MockAdErrorListener(); }, @@ -166,13 +168,14 @@ void main() { newAdEventListener: ({required dynamic onAdEvent}) { return MockAdEventListener(); }, - newAdErrorListener: ({ - required void Function(ima.AdErrorListener, ima.AdErrorEvent) - onAdError, - }) { - onAdErrorCallback = onAdError; - return MockAdErrorListener(); - }, + newAdErrorListener: + ({ + required void Function(ima.AdErrorListener, ima.AdErrorEvent) + onAdError, + }) { + onAdErrorCallback = onAdError; + return MockAdErrorListener(); + }, ); final AndroidAdsManager adsManager = AndroidAdsManager( diff --git a/packages/interactive_media_ads/test/android/companion_ad_slot_test.dart b/packages/interactive_media_ads/test/android/companion_ad_slot_test.dart index 2817b5d6302..ffde3f4d2c1 100644 --- a/packages/interactive_media_ads/test/android/companion_ad_slot_test.dart +++ b/packages/interactive_media_ads/test/android/companion_ad_slot_test.dart @@ -68,15 +68,16 @@ void main() { ).thenAnswer((_) async => mockCompanionAdSlot); return mockFactory; }, - newCompanionAdSlotClickListener: ({ - required void Function(ima.CompanionAdSlotClickListener) - onCompanionAdClick, - }) { - return ima.CompanionAdSlotClickListener.pigeon_detached( - onCompanionAdClick: onCompanionAdClick, - pigeon_instanceManager: _TestInstanceManager(), - ); - }, + newCompanionAdSlotClickListener: + ({ + required void Function(ima.CompanionAdSlotClickListener) + onCompanionAdClick, + }) { + return ima.CompanionAdSlotClickListener.pigeon_detached( + onCompanionAdClick: onCompanionAdClick, + pigeon_instanceManager: _TestInstanceManager(), + ); + }, ), ); diff --git a/packages/interactive_media_ads/test/android/content_progress_provider_test.dart b/packages/interactive_media_ads/test/android/content_progress_provider_test.dart index 8539623555d..19d161485d5 100644 --- a/packages/interactive_media_ads/test/android/content_progress_provider_test.dart +++ b/packages/interactive_media_ads/test/android/content_progress_provider_test.dart @@ -24,18 +24,16 @@ void main() { AndroidContentProgressProviderCreationParams( proxy: InteractiveMediaAdsProxy( newContentProgressProvider: () => mockContentProgressProvider, - newVideoProgressUpdate: ({ - required int currentTimeMs, - required int durationMs, - }) { - expect(currentTimeMs, 1000); - expect(durationMs, 10000); - return ima.VideoProgressUpdate.pigeon_detached( - pigeon_instanceManager: ima.PigeonInstanceManager( - onWeakReferenceRemoved: (_) {}, - ), - ); - }, + newVideoProgressUpdate: + ({required int currentTimeMs, required int durationMs}) { + expect(currentTimeMs, 1000); + expect(durationMs, 10000); + return ima.VideoProgressUpdate.pigeon_detached( + pigeon_instanceManager: ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ), + ); + }, ), ), ); diff --git a/packages/interactive_media_ads/test/content_progress_provider_test.dart b/packages/interactive_media_ads/test/content_progress_provider_test.dart index dc18773c6f5..b35b29656de 100644 --- a/packages/interactive_media_ads/test/content_progress_provider_test.dart +++ b/packages/interactive_media_ads/test/content_progress_provider_test.dart @@ -16,13 +16,11 @@ void main() { final TestContentProgressProvider platformProvider = TestContentProgressProvider( const PlatformContentProgressProviderCreationParams(), - onSetProgress: ({ - required Duration progress, - required Duration duration, - }) async { - callbackProgress = progress; - callbackDuration = duration; - }, + onSetProgress: + ({required Duration progress, required Duration duration}) async { + callbackProgress = progress; + callbackDuration = duration; + }, ); final ContentProgressProvider provider = diff --git a/packages/interactive_media_ads/test/ios/ad_display_container_test.dart b/packages/interactive_media_ads/test/ios/ad_display_container_test.dart index f2aef20825d..bb343feaae8 100644 --- a/packages/interactive_media_ads/test/ios/ad_display_container_test.dart +++ b/packages/interactive_media_ads/test/ios/ad_display_container_test.dart @@ -45,23 +45,22 @@ void main() { testWidgets('onContainerAdded is called', (WidgetTester tester) async { late final void Function(UIViewController, bool) viewDidAppearCallback; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newUIViewController: ({ - void Function(UIViewController, bool)? viewDidAppear, - }) { - viewDidAppearCallback = viewDidAppear!; - - final PigeonInstanceManager instanceManager = PigeonInstanceManager( - onWeakReferenceRemoved: (_) {}, - ); - final UIView view = UIView.pigeon_detached( - pigeon_instanceManager: instanceManager, - ); - instanceManager.addDartCreatedInstance(view); - - final MockUIViewController mockController = MockUIViewController(); - when(mockController.view).thenReturn(view); - return mockController; - }, + newUIViewController: + ({void Function(UIViewController, bool)? viewDidAppear}) { + viewDidAppearCallback = viewDidAppear!; + + final PigeonInstanceManager instanceManager = + PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + final UIView view = UIView.pigeon_detached( + pigeon_instanceManager: instanceManager, + ); + instanceManager.addDartCreatedInstance(view); + + final MockUIViewController mockController = + MockUIViewController(); + when(mockController.view).thenReturn(view); + return mockController; + }, newIMAAdDisplayContainer: ({ required UIView adContainer, @@ -109,37 +108,35 @@ void main() { final Completer?> addedAdSlotsCompleter = Completer?>(); final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newUIViewController: ({ - void Function(UIViewController, bool)? viewDidAppear, - }) { - viewDidAppearCallback = viewDidAppear!; - - final UIView view = UIView.pigeon_detached( - pigeon_instanceManager: instanceManager, - ); - instanceManager.addDartCreatedInstance(view); - - final MockUIViewController mockController = MockUIViewController(); - when(mockController.view).thenReturn(view); - return mockController; - }, - newIMAAdDisplayContainer: ({ - required UIView adContainer, - UIViewController? adContainerViewController, - List? companionSlots, - }) { - addedAdSlotsCompleter.complete(companionSlots); - return MockIMAAdDisplayContainer(); - }, - sizeIMACompanionAdSlot: ({ - required int width, - required int height, - required UIView view, - }) { - expect(width, 300); - expect(height, 400); - return mockCompanionAdSlot; - }, + newUIViewController: + ({void Function(UIViewController, bool)? viewDidAppear}) { + viewDidAppearCallback = viewDidAppear!; + + final UIView view = UIView.pigeon_detached( + pigeon_instanceManager: instanceManager, + ); + instanceManager.addDartCreatedInstance(view); + + final MockUIViewController mockController = + MockUIViewController(); + when(mockController.view).thenReturn(view); + return mockController; + }, + newIMAAdDisplayContainer: + ({ + required UIView adContainer, + UIViewController? adContainerViewController, + List? companionSlots, + }) { + addedAdSlotsCompleter.complete(companionSlots); + return MockIMAAdDisplayContainer(); + }, + sizeIMACompanionAdSlot: + ({required int width, required int height, required UIView view}) { + expect(width, 300); + expect(height, 400); + return mockCompanionAdSlot; + }, newUIView: () { return UIView.pigeon_detached( pigeon_instanceManager: instanceManager, diff --git a/packages/interactive_media_ads/test/ios/ads_loader_test.dart b/packages/interactive_media_ads/test/ios/ads_loader_test.dart index 9dd7074283f..171ea2c1411 100644 --- a/packages/interactive_media_ads/test/ios/ads_loader_test.dart +++ b/packages/interactive_media_ads/test/ios/ads_loader_test.dart @@ -92,16 +92,17 @@ void main() { newIMAContentPlayhead: () => contentPlayheadInstance, ); - ima.PigeonOverrides.iMAAdsRequest_new = ({ - required String adTagUrl, - required ima.IMAAdDisplayContainer adDisplayContainer, - ima.IMAContentPlayhead? contentPlayhead, - }) { - expect(adTagUrl, adTag); - expect(adDisplayContainer, container.adDisplayContainer); - expect(contentPlayhead, contentPlayheadInstance); - return mockRequest; - }; + ima.PigeonOverrides.iMAAdsRequest_new = + ({ + required String adTagUrl, + required ima.IMAAdDisplayContainer adDisplayContainer, + ima.IMAContentPlayhead? contentPlayhead, + }) { + expect(adTagUrl, adTag); + expect(adDisplayContainer, container.adDisplayContainer); + expect(contentPlayhead, contentPlayheadInstance); + return mockRequest; + }; final IOSAdsLoader loader = IOSAdsLoader( IOSAdsLoaderCreationParams( @@ -160,18 +161,19 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newIMAAdsLoader: ({ima.IMASettings? settings}) => MockIMAAdsLoader(), - newIMAAdsLoaderDelegate: ({ - required void Function( - ima.IMAAdsLoaderDelegate, - ima.IMAAdsLoader, - ima.IMAAdsLoadedData, - ) - adLoaderLoadedWith, - required dynamic adsLoaderFailedWithErrorData, - }) { - adLoaderLoadedWithCallback = adLoaderLoadedWith; - return MockIMAAdsLoaderDelegate(); - }, + newIMAAdsLoaderDelegate: + ({ + required void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdsLoadedData, + ) + adLoaderLoadedWith, + required dynamic adsLoaderFailedWithErrorData, + }) { + adLoaderLoadedWithCallback = adLoaderLoadedWith; + return MockIMAAdsLoaderDelegate(); + }, ); final IOSAdsLoader adsLoader = IOSAdsLoader( @@ -214,18 +216,20 @@ void main() { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( newIMAAdsLoader: ({ima.IMASettings? settings}) => MockIMAAdsLoader(), - newIMAAdsLoaderDelegate: ({ - required dynamic adLoaderLoadedWith, - required void Function( - ima.IMAAdsLoaderDelegate, - ima.IMAAdsLoader, - ima.IMAAdLoadingErrorData, - ) - adsLoaderFailedWithErrorData, - }) { - adsLoaderFailedWithErrorDataCallback = adsLoaderFailedWithErrorData; - return MockIMAAdsLoaderDelegate(); - }, + newIMAAdsLoaderDelegate: + ({ + required dynamic adLoaderLoadedWith, + required void Function( + ima.IMAAdsLoaderDelegate, + ima.IMAAdsLoader, + ima.IMAAdLoadingErrorData, + ) + adsLoaderFailedWithErrorData, + }) { + adsLoaderFailedWithErrorDataCallback = + adsLoaderFailedWithErrorData; + return MockIMAAdsLoaderDelegate(); + }, ); final IOSAdsLoader adsLoader = IOSAdsLoader( @@ -266,21 +270,20 @@ Future _pumpAdDisplayContainer( WidgetTester tester, ) async { final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newUIViewController: ({ - void Function(ima.UIViewController, bool)? viewDidAppear, - }) { - final ima.PigeonInstanceManager instanceManager = - ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); - final ima.UIView view = ima.UIView.pigeon_detached( - pigeon_instanceManager: instanceManager, - ); - instanceManager.addDartCreatedInstance(view); + newUIViewController: + ({void Function(ima.UIViewController, bool)? viewDidAppear}) { + final ima.PigeonInstanceManager instanceManager = + ima.PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + final ima.UIView view = ima.UIView.pigeon_detached( + pigeon_instanceManager: instanceManager, + ); + instanceManager.addDartCreatedInstance(view); - final MockUIViewController mockController = MockUIViewController(); - viewDidAppear!.call(mockController, true); - when(mockController.view).thenReturn(view); - return mockController; - }, + final MockUIViewController mockController = MockUIViewController(); + viewDidAppear!.call(mockController, true); + when(mockController.view).thenReturn(view); + return mockController; + }, newIMAAdDisplayContainer: ({ required ima.UIView adContainer, diff --git a/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart index ddf9d08b40b..74c3d30be18 100644 --- a/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart +++ b/packages/interactive_media_ads/test/ios/ads_manager_delegate_tests.dart @@ -24,34 +24,41 @@ void main() { late final ima.IMAAdsManagerDelegate delegate; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newIMAAdsManagerDelegate: ({ - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdEvent, - ) - didReceiveAdEvent, - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdError, - ) - didReceiveAdError, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentPause, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentResume, - }) { - didReceiveAdEventCallback = didReceiveAdEvent; - delegate = ima.IMAAdsManagerDelegate.pigeon_detached( - didReceiveAdEvent: didReceiveAdEvent, - didReceiveAdError: didReceiveAdError, - didRequestContentPause: didRequestContentPause, - didRequestContentResume: didRequestContentResume, - pigeon_instanceManager: instanceManager, - ); - return delegate; - }, + newIMAAdsManagerDelegate: + ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) + didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) + didReceiveAdError, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentPause, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentResume, + }) { + didReceiveAdEventCallback = didReceiveAdEvent; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, ); final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( @@ -92,34 +99,41 @@ void main() { late final ima.IMAAdsManagerDelegate delegate; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newIMAAdsManagerDelegate: ({ - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdEvent, - ) - didReceiveAdEvent, - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdError, - ) - didReceiveAdError, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentPause, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentResume, - }) { - didRequestContentPauseCallback = didRequestContentPause; - delegate = ima.IMAAdsManagerDelegate.pigeon_detached( - didReceiveAdEvent: didReceiveAdEvent, - didReceiveAdError: didReceiveAdError, - didRequestContentPause: didRequestContentPause, - didRequestContentResume: didRequestContentResume, - pigeon_instanceManager: instanceManager, - ); - return delegate; - }, + newIMAAdsManagerDelegate: + ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) + didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) + didReceiveAdError, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentPause, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentResume, + }) { + didRequestContentPauseCallback = didRequestContentPause; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, ); final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( @@ -153,34 +167,41 @@ void main() { late final ima.IMAAdsManagerDelegate delegate; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newIMAAdsManagerDelegate: ({ - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdEvent, - ) - didReceiveAdEvent, - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdError, - ) - didReceiveAdError, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentPause, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentResume, - }) { - didRequestContentResumeCallback = didRequestContentResume; - delegate = ima.IMAAdsManagerDelegate.pigeon_detached( - didReceiveAdEvent: didReceiveAdEvent, - didReceiveAdError: didReceiveAdError, - didRequestContentPause: didRequestContentPause, - didRequestContentResume: didRequestContentResume, - pigeon_instanceManager: instanceManager, - ); - return delegate; - }, + newIMAAdsManagerDelegate: + ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) + didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) + didReceiveAdError, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentPause, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentResume, + }) { + didRequestContentResumeCallback = didRequestContentResume; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, ); final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( @@ -218,34 +239,41 @@ void main() { late final ima.IMAAdsManagerDelegate delegate; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newIMAAdsManagerDelegate: ({ - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdEvent, - ) - didReceiveAdEvent, - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdError, - ) - didReceiveAdError, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentPause, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentResume, - }) { - didReceiveAdErrorCallback = didReceiveAdError; - delegate = ima.IMAAdsManagerDelegate.pigeon_detached( - didReceiveAdEvent: didReceiveAdEvent, - didReceiveAdError: didReceiveAdError, - didRequestContentPause: didRequestContentPause, - didRequestContentResume: didRequestContentResume, - pigeon_instanceManager: instanceManager, - ); - return delegate; - }, + newIMAAdsManagerDelegate: + ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) + didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) + didReceiveAdError, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentPause, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentResume, + }) { + didReceiveAdErrorCallback = didReceiveAdError; + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: instanceManager, + ); + return delegate; + }, ); final IOSAdsManagerDelegate adsManagerDelegate = IOSAdsManagerDelegate( diff --git a/packages/interactive_media_ads/test/ios/ads_manager_test.dart b/packages/interactive_media_ads/test/ios/ads_manager_test.dart index 2f8fdab632b..e042f78777d 100644 --- a/packages/interactive_media_ads/test/ios/ads_manager_test.dart +++ b/packages/interactive_media_ads/test/ios/ads_manager_test.dart @@ -111,35 +111,42 @@ void main() { late final ima.IMAAdsManagerDelegate delegate; final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy( - newIMAAdsManagerDelegate: ({ - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdEvent, - ) - didReceiveAdEvent, - required void Function( - ima.IMAAdsManagerDelegate, - ima.IMAAdsManager, - ima.IMAAdError, - ) - didReceiveAdError, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentPause, - required void Function(ima.IMAAdsManagerDelegate, ima.IMAAdsManager) - didRequestContentResume, - }) { - delegate = ima.IMAAdsManagerDelegate.pigeon_detached( - didReceiveAdEvent: didReceiveAdEvent, - didReceiveAdError: didReceiveAdError, - didRequestContentPause: didRequestContentPause, - didRequestContentResume: didRequestContentResume, - pigeon_instanceManager: ima.PigeonInstanceManager( - onWeakReferenceRemoved: (_) {}, - ), - ); - return delegate; - }, + newIMAAdsManagerDelegate: + ({ + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdEvent, + ) + didReceiveAdEvent, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ima.IMAAdError, + ) + didReceiveAdError, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentPause, + required void Function( + ima.IMAAdsManagerDelegate, + ima.IMAAdsManager, + ) + didRequestContentResume, + }) { + delegate = ima.IMAAdsManagerDelegate.pigeon_detached( + didReceiveAdEvent: didReceiveAdEvent, + didReceiveAdError: didReceiveAdError, + didRequestContentPause: didRequestContentPause, + didRequestContentResume: didRequestContentResume, + pigeon_instanceManager: ima.PigeonInstanceManager( + onWeakReferenceRemoved: (_) {}, + ), + ); + return delegate; + }, ); adsManager.setAdsManagerDelegate( diff --git a/packages/interactive_media_ads/test/ios/companion_ad_slot_test.dart b/packages/interactive_media_ads/test/ios/companion_ad_slot_test.dart index 138a8d2ebbb..451e7e2f0fc 100644 --- a/packages/interactive_media_ads/test/ios/companion_ad_slot_test.dart +++ b/packages/interactive_media_ads/test/ios/companion_ad_slot_test.dart @@ -22,15 +22,16 @@ void main() { IOSCompanionAdSlotCreationParams( size: CompanionAdSlotSize.fixed(width: 300, height: 400), proxy: InteractiveMediaAdsProxy( - sizeIMACompanionAdSlot: ({ - required int width, - required int height, - required UIView view, - }) { - expect(width, 300); - expect(height, 400); - return mockCompanionAdSlot; - }, + sizeIMACompanionAdSlot: + ({ + required int width, + required int height, + required UIView view, + }) { + expect(width, 300); + expect(height, 400); + return mockCompanionAdSlot; + }, newUIView: () { return UIView.pigeon_detached( pigeon_instanceManager: _TestInstanceManager(), @@ -51,30 +52,36 @@ void main() { size: CompanionAdSlotSize.fixed(width: 300, height: 400), onClicked: expectAsync0(() {}), proxy: InteractiveMediaAdsProxy( - sizeIMACompanionAdSlot: ({ - required int width, - required int height, - required UIView view, - }) { - return mockCompanionAdSlot; - }, + sizeIMACompanionAdSlot: + ({ + required int width, + required int height, + required UIView view, + }) { + return mockCompanionAdSlot; + }, newUIView: () { return UIView.pigeon_detached( pigeon_instanceManager: _TestInstanceManager(), ); }, - newIMACompanionDelegate: ({ - void Function(IMACompanionDelegate, IMACompanionAdSlot, bool)? - companionAdSlotFilled, - void Function(IMACompanionDelegate, IMACompanionAdSlot)? - companionSlotWasClicked, - }) { - return IMACompanionDelegate.pigeon_detached( - companionAdSlotFilled: companionAdSlotFilled, - companionSlotWasClicked: companionSlotWasClicked, - pigeon_instanceManager: _TestInstanceManager(), - ); - }, + newIMACompanionDelegate: + ({ + void Function( + IMACompanionDelegate, + IMACompanionAdSlot, + bool, + )? + companionAdSlotFilled, + void Function(IMACompanionDelegate, IMACompanionAdSlot)? + companionSlotWasClicked, + }) { + return IMACompanionDelegate.pigeon_detached( + companionAdSlotFilled: companionAdSlotFilled, + companionSlotWasClicked: companionSlotWasClicked, + pigeon_instanceManager: _TestInstanceManager(), + ); + }, ), ); diff --git a/packages/interactive_media_ads/test/version_test.dart b/packages/interactive_media_ads/test/version_test.dart index 7f7afd6b23c..6f3c3d3bb8c 100644 --- a/packages/interactive_media_ads/test/version_test.dart +++ b/packages/interactive_media_ads/test/version_test.dart @@ -12,8 +12,9 @@ void main() { final String adsRequestProxyApiPath = '${Directory.current.path}/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt'; - final String apiFileAsString = - File(adsRequestProxyApiPath).readAsStringSync(); + final String apiFileAsString = File( + adsRequestProxyApiPath, + ).readAsStringSync(); expect( apiFileAsString, @@ -26,8 +27,9 @@ void main() { final String adsRequestProxyApiDelegatePath = '${Directory.current.path}/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift'; - final String apiFileAsString = - File(adsRequestProxyApiDelegatePath).readAsStringSync(); + final String apiFileAsString = File( + adsRequestProxyApiDelegatePath, + ).readAsStringSync(); expect( apiFileAsString, diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md index 5178a9e3b22..a168b1b84c7 100644 --- a/packages/local_auth/local_auth_android/CHANGELOG.md +++ b/packages/local_auth/local_auth_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 1.0.53 * Removes obsolete code related to supporting SDK <24. diff --git a/packages/local_auth/local_auth_android/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle index 70c9cb1260e..0128224443d 100644 --- a/packages/local_auth/local_auth_android/android/build.gradle +++ b/packages/local_auth/local_auth_android/android/build.gradle @@ -31,8 +31,8 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } lintOptions { diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index cccf3f166c2..d848a3a06cc 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth_android description: Android implementation of the local_auth plugin. repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 1.0.53 +version: 1.1.0 environment: sdk: ^3.9.0 diff --git a/packages/path_provider/path_provider_android/CHANGELOG.md b/packages/path_provider/path_provider_android/CHANGELOG.md index b4d298869ac..878e96a4ef3 100644 --- a/packages/path_provider/path_provider_android/CHANGELOG.md +++ b/packages/path_provider/path_provider_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.3.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.2.18 * Bumps com.android.tools.build:gradle to 8.12.1. diff --git a/packages/path_provider/path_provider_android/android/build.gradle b/packages/path_provider/path_provider_android/android/build.gradle index 738db7eaa68..b8d75d65f3c 100644 --- a/packages/path_provider/path_provider_android/android/build.gradle +++ b/packages/path_provider/path_provider_android/android/build.gradle @@ -35,8 +35,8 @@ android { disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } diff --git a/packages/path_provider/path_provider_android/example/pubspec.yaml b/packages/path_provider/path_provider_android/example/pubspec.yaml index 686559935fc..f35ec6388dd 100644 --- a/packages/path_provider/path_provider_android/example/pubspec.yaml +++ b/packages/path_provider/path_provider_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_android/lib/messages.g.dart b/packages/path_provider/path_provider_android/lib/messages.g.dart index 088f959cd24..bd7104e83bb 100644 --- a/packages/path_provider/path_provider_android/lib/messages.g.dart +++ b/packages/path_provider/path_provider_android/lib/messages.g.dart @@ -81,8 +81,9 @@ class PathProviderApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/path_provider/path_provider_android/pubspec.yaml b/packages/path_provider/path_provider_android/pubspec.yaml index bb0b4fc1b61..39f02452d6f 100644 --- a/packages/path_provider/path_provider_android/pubspec.yaml +++ b/packages/path_provider/path_provider_android/pubspec.yaml @@ -2,11 +2,11 @@ name: path_provider_android description: Android implementation of the path_provider plugin. repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.2.18 +version: 2.3.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/path_provider/path_provider_android/test/messages_test.g.dart b/packages/path_provider/path_provider_android/test/messages_test.g.dart index d5fd46f85ca..bb8404324e9 100644 --- a/packages/path_provider/path_provider_android/test/messages_test.g.dart +++ b/packages/path_provider/path_provider_android/test/messages_test.g.dart @@ -64,8 +64,9 @@ abstract class TestPathProviderApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index d36975e5b0f..3eb592068c6 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 26.1.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. ## 26.0.1 diff --git a/packages/pigeon/example/app/android/app/build.gradle b/packages/pigeon/example/app/android/app/build.gradle index caeefa8e5a0..f1eadc2f3cf 100644 --- a/packages/pigeon/example/app/android/app/build.gradle +++ b/packages/pigeon/example/app/android/app/build.gradle @@ -28,12 +28,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/pigeon/example/app/lib/main.dart b/packages/pigeon/example/app/lib/main.dart index 9e66ba3c818..fe1dfe9bf9d 100644 --- a/packages/pigeon/example/app/lib/main.dart +++ b/packages/pigeon/example/app/lib/main.dart @@ -137,16 +137,14 @@ class _MyHomePageState extends State { if (Platform.isAndroid || Platform.isIOS) StreamBuilder( stream: getEventStream(), - builder: ( - BuildContext context, - AsyncSnapshot snapshot, - ) { - if (snapshot.hasData) { - return Text(snapshot.data ?? ''); - } else { - return const CircularProgressIndicator(); - } - }, + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasData) { + return Text(snapshot.data ?? ''); + } else { + return const CircularProgressIndicator(); + } + }, ) else const Text('event channels are not supported on this platform'), diff --git a/packages/pigeon/example/app/lib/src/messages.g.dart b/packages/pigeon/example/app/lib/src/messages.g.dart index 9ac9995e1b0..a1707968cf7 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -143,8 +143,9 @@ class ExampleHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -256,8 +257,9 @@ abstract class MessageFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/example/app/pubspec.yaml b/packages/pigeon/example/app/pubspec.yaml index 8fbb73e09e3..8e2043aaf35 100644 --- a/packages/pigeon/example/app/pubspec.yaml +++ b/packages/pigeon/example/app/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: flutter: diff --git a/packages/pigeon/lib/src/ast.dart b/packages/pigeon/lib/src/ast.dart index 48400707410..669d3bdca61 100644 --- a/packages/pigeon/lib/src/ast.dart +++ b/packages/pigeon/lib/src/ast.dart @@ -91,10 +91,12 @@ class Method extends Node { @override String toString() { - final String objcSelectorStr = - objcSelector.isEmpty ? '' : ' objcSelector:$objcSelector'; - final String swiftFunctionStr = - swiftFunction.isEmpty ? '' : ' swiftFunction:$swiftFunction'; + final String objcSelectorStr = objcSelector.isEmpty + ? '' + : ' objcSelector:$objcSelector'; + final String swiftFunctionStr = swiftFunction.isEmpty + ? '' + : ' swiftFunction:$swiftFunction'; return '(Method name:$name returnType:$returnType parameters:$parameters isAsynchronous:$isAsynchronous$objcSelectorStr$swiftFunctionStr documentationComments:$documentationComments)'; } } @@ -254,8 +256,9 @@ class AstProxyApi extends Api { yield* proxyApi.flutterMethods.map((Method method) => (method, proxyApi)); } if (superClass != null) { - final Set interfaceApisFromSuperClasses = - superClass!.associatedProxyApi!._recursiveFindAllInterfaceApis(); + final Set interfaceApisFromSuperClasses = superClass! + .associatedProxyApi! + ._recursiveFindAllInterfaceApis(); for (final AstProxyApi proxyApi in interfaceApisFromSuperClasses) { yield* proxyApi.methods.map((Method method) => (method, proxyApi)); } @@ -394,8 +397,9 @@ class Constructor extends Method { @override String toString() { - final String swiftFunctionStr = - swiftFunction.isEmpty ? '' : ' swiftFunction:$swiftFunction'; + final String swiftFunctionStr = swiftFunction.isEmpty + ? '' + : ' swiftFunction:$swiftFunction'; return '(Constructor name:$name parameters:$parameters $swiftFunctionStr documentationComments:$documentationComments)'; } } @@ -595,8 +599,9 @@ class TypeDeclaration { @override String toString() { - final String typeArgumentsStr = - typeArguments.isEmpty ? '' : ' typeArguments:$typeArguments'; + final String typeArgumentsStr = typeArguments.isEmpty + ? '' + : ' typeArguments:$typeArguments'; return '(TypeDeclaration baseName:$baseName isNullable:$isNullable$typeArgumentsStr isEnum:$isEnum isClass:$isClass isProxyApi:$isProxyApi)'; } } diff --git a/packages/pigeon/lib/src/cpp/cpp_generator.dart b/packages/pigeon/lib/src/cpp/cpp_generator.dart index 2ae403cfcd6..78f6eb263ee 100644 --- a/packages/pigeon/lib/src/cpp/cpp_generator.dart +++ b/packages/pigeon/lib/src/cpp/cpp_generator.dart @@ -465,10 +465,9 @@ class CppHeaderGenerator extends StructuredGenerator { _writeFunctionDeclaration( indent, 'FromEncodableList', - returnType: - isOverflowClass - ? 'flutter::EncodableValue' - : classDefinition.name, + returnType: isOverflowClass + ? 'flutter::EncodableValue' + : classDefinition.name, parameters: ['const flutter::EncodableList& list'], isStatic: true, ); @@ -814,14 +813,13 @@ class CppHeaderGenerator extends StructuredGenerator { Iterable params, String docComment, ) { - final List paramStrings = - params.map((NamedType param) { - final HostDatatype hostDatatype = getFieldHostDatatype( - param, - _baseCppTypeForBuiltinDartType, - ); - return '${_hostApiArgumentType(hostDatatype)} ${_makeVariableName(param)}'; - }).toList(); + final List paramStrings = params.map((NamedType param) { + final HostDatatype hostDatatype = getFieldHostDatatype( + param, + _baseCppTypeForBuiltinDartType, + ); + return '${_hostApiArgumentType(hostDatatype)} ${_makeVariableName(param)}'; + }).toList(); indent.writeln('$_commentPrefix $docComment'); _writeFunctionDeclaration( indent, @@ -1270,8 +1268,10 @@ EncodableValue $_overflowClassName::FromEncodableList( Indent indent, { required String dartPackageName, }) { - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); indent.newln(); if (root.requiresOverflowClass) { _writeCodecOverflowUtilities( @@ -1342,16 +1342,16 @@ EncodableValue $_overflowClassName::FromEncodableList( for (final EnumeratedType customType in enumeratedTypes) { final String encodeString = customType.type == CustomTypes.customClass - ? 'std::any_cast<${customType.name}>(*custom_value).ToEncodableList()' - : 'static_cast(std::any_cast<${customType.name}>(*custom_value))'; + ? 'std::any_cast<${customType.name}>(*custom_value).ToEncodableList()' + : 'static_cast(std::any_cast<${customType.name}>(*custom_value))'; final String valueString = customType.enumeration < maximumCodecFieldKey - ? encodeString - : 'wrap.ToEncodableList()'; + ? encodeString + : 'wrap.ToEncodableList()'; final int enumeration = customType.enumeration < maximumCodecFieldKey - ? customType.enumeration - : maximumCodecFieldKey; + ? customType.enumeration + : maximumCodecFieldKey; indent.write( 'if (custom_value->type() == typeid(${customType.name})) ', ); @@ -1643,8 +1643,8 @@ EncodableValue $_overflowClassName::FromEncodableList( ); final String unwrapEnum = arg.type.isEnum && arg.type.isNullable - ? ' ? &(*$argName) : nullptr' - : ''; + ? ' ? &(*$argName) : nullptr' + : ''; methodArgument.add('$argName$unwrapEnum'); }); } @@ -1740,20 +1740,18 @@ return EncodableValue(EncodableList{ ); }); - final List paramStrings = - hostParams - .map( - (_HostNamedType param) => - '${_hostApiArgumentType(param.hostType)} ${param.name}', - ) - .toList(); - final List initializerStrings = - hostParams - .map( - (_HostNamedType param) => - '${param.name}_(${_fieldValueExpression(param.hostType, param.name)})', - ) - .toList(); + final List paramStrings = hostParams + .map( + (_HostNamedType param) => + '${_hostApiArgumentType(param.hostType)} ${param.name}', + ) + .toList(); + final List initializerStrings = hostParams + .map( + (_HostNamedType param) => + '${param.name}_(${_fieldValueExpression(param.hostType, param.name)})', + ) + .toList(); _writeFunctionDefinition( indent, classDefinition.name, @@ -1769,15 +1767,14 @@ return EncodableValue(EncodableList{ Class classDefinition, Iterable fields, ) { - final List initializerStrings = - fields.map((NamedType param) { - final String fieldName = _makeInstanceVariableName(param); - final HostDatatype hostType = getFieldHostDatatype( - param, - _shortBaseCppTypeForBuiltinDartType, - ); - return '$fieldName(${_fieldValueExpression(hostType, 'other.$fieldName', sourceIsField: true)})'; - }).toList(); + final List initializerStrings = fields.map((NamedType param) { + final String fieldName = _makeInstanceVariableName(param); + final HostDatatype hostType = getFieldHostDatatype( + param, + _shortBaseCppTypeForBuiltinDartType, + ); + return '$fieldName(${_fieldValueExpression(hostType, 'other.$fieldName', sourceIsField: true)})'; + }).toList(); _writeFunctionDefinition( indent, classDefinition.name, @@ -1812,10 +1809,9 @@ return EncodableValue(EncodableList{ if (_isPointerField(hostDatatype)) { final String constructor = 'std::make_unique<${hostDatatype.datatype}>(*$otherIvar)'; - valueExpression = - hostDatatype.isNullable - ? '$otherIvar ? $constructor : nullptr' - : constructor; + valueExpression = hostDatatype.isNullable + ? '$otherIvar ? $constructor : nullptr' + : constructor; } else { valueExpression = otherIvar; } @@ -1842,10 +1838,9 @@ return EncodableValue(EncodableList{ final String returnExpression; if (_isPointerField(hostDatatype)) { // Convert std::unique_ptr to either T* or const T&. - returnExpression = - hostDatatype.isNullable - ? '$instanceVariableName.get()' - : '*$instanceVariableName'; + returnExpression = hostDatatype.isNullable + ? '$instanceVariableName.get()' + : '*$instanceVariableName'; } else if (hostDatatype.isNullable) { // Convert std::optional to T*. returnExpression = @@ -1940,12 +1935,14 @@ return EncodableValue(EncodableList{ ); const String extractedValue = 'std::move(output).TakeValue()'; - final String wrapperType = - hostType.isBuiltin ? 'EncodableValue' : 'CustomEncodableValue'; + final String wrapperType = hostType.isBuiltin + ? 'EncodableValue' + : 'CustomEncodableValue'; if (returnType.isNullable) { // The value is a std::optional, so needs an extra layer of // handling. - nonErrorPath = ''' + nonErrorPath = + ''' ${prefix}auto output_optional = $extractedValue; ${prefix}if (output_optional) { $prefix\twrapped.push_back($wrapperType(std::move(output_optional).value())); @@ -1998,8 +1995,8 @@ ${prefix}reply(EncodableValue(std::move(wrapped)));'''; if (!hostType.isBuiltin) { final String nonNullValue = hostType.isNullable || (!hostType.isEnum && isNestedClass) - ? '*$variableName' - : variableName; + ? '*$variableName' + : variableName; encodableValue = 'CustomEncodableValue($nonNullValue)'; } else if (dartType.baseName == 'Object') { final String operator = hostType.isNullable ? '*' : ''; diff --git a/packages/pigeon/lib/src/dart/dart_generator.dart b/packages/pigeon/lib/src/dart/dart_generator.dart index 231f38384fa..a429c9e4cc3 100644 --- a/packages/pigeon/lib/src/dart/dart_generator.dart +++ b/packages/pigeon/lib/src/dart/dart_generator.dart @@ -212,10 +212,9 @@ class DartGenerator extends StructuredGenerator { docCommentSpec, ); final String sealed = classDefinition.isSealed ? 'sealed ' : ''; - final String implements = - classDefinition.superClassName != null - ? 'extends ${classDefinition.superClassName} ' - : ''; + final String implements = classDefinition.superClassName != null + ? 'extends ${classDefinition.superClassName} ' + : ''; indent.write('${sealed}class ${classDefinition.name} $implements'); indent.addScoped('{', '}', () { @@ -273,10 +272,11 @@ class DartGenerator extends StructuredGenerator { )) { final String required = !field.type.isNullable && field.defaultValue == null - ? 'required ' - : ''; - final String defaultValueString = - field.defaultValue == null ? '' : ' = ${field.defaultValue}'; + ? 'required ' + : ''; + final String defaultValueString = field.defaultValue == null + ? '' + : ' = ${field.defaultValue}'; indent.writeln('${required}this.${field.name}$defaultValueString,'); } }); @@ -326,10 +326,9 @@ class DartGenerator extends StructuredGenerator { indent.add('($resultAt as $genericType?)$castCallPrefix$castCall'); } else { final String castCallForcePrefix = field.type.isNullable ? '' : '!'; - final String castString = - field.type.baseName == 'Object' - ? '' - : ' as $genericType$nullableTag'; + final String castString = field.type.baseName == 'Object' + ? '' + : ' as $genericType$nullableTag'; indent.add('$resultAt$castCallForcePrefix$castString'); } @@ -404,10 +403,9 @@ class DartGenerator extends StructuredGenerator { indent.writeln('writeValue(buffer, value.index);'); } } else { - final String encodeString = - customType.type == CustomTypes.customClass - ? '.encode()' - : '.index'; + final String encodeString = customType.type == CustomTypes.customClass + ? '.encode()' + : '.index'; indent.writeln( 'final $_overflowClassName wrap = $_overflowClassName(type: ${customType.offset(nonSerializedClassCount) - maximumCodecFieldKey}, wrapped: value$encodeString);', ); @@ -451,8 +449,10 @@ class DartGenerator extends StructuredGenerator { ); indent.newln(); - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); if (root.requiresOverflowClass) { _writeCodecOverflowUtilities(indent, enumeratedTypes); } @@ -556,10 +556,9 @@ class DartGenerator extends StructuredGenerator { ); final bool isAsync = func.isAsynchronous; - final String returnType = - isAsync - ? 'Future<${addGenericTypesNullable(func.returnType)}>' - : addGenericTypesNullable(func.returnType); + final String returnType = isAsync + ? 'Future<${addGenericTypesNullable(func.returnType)}>' + : addGenericTypesNullable(func.returnType); final String argSignature = _getMethodParameterSignature( func.parameters, ); @@ -581,10 +580,9 @@ class DartGenerator extends StructuredGenerator { parameters: func.parameters, returnType: func.returnType, addSuffixVariable: true, - channelName: - channelNameFunc == null - ? makeChannelName(api, func, dartPackageName) - : channelNameFunc(func), + channelName: channelNameFunc == null + ? makeChannelName(api, func, dartPackageName) + : channelNameFunc(func), isMockHandler: isMockHandler, isAsynchronous: func.isAsynchronous, ); @@ -710,178 +708,173 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; required String dartPackageName, }) { final cb.Parameter binaryMessengerParameter = cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = 'binaryMessenger' - ..type = cb.refer('BinaryMessenger?') - ..named = true, + (cb.ParameterBuilder builder) => builder + ..name = 'binaryMessenger' + ..type = cb.refer('BinaryMessenger?') + ..named = true, ); final cb.Field binaryMessengerField = cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = '${varNamePrefix}binaryMessenger' - ..type = cb.refer('BinaryMessenger?') - ..modifier = cb.FieldModifier.final$, + (cb.FieldBuilder builder) => builder + ..name = '${varNamePrefix}binaryMessenger' + ..type = cb.refer('BinaryMessenger?') + ..modifier = cb.FieldModifier.final$, ); final cb.Class instanceManagerApi = cb.Class( - (cb.ClassBuilder builder) => - builder - ..name = dartInstanceManagerApiClassName - ..docs.add( - '/// Generated API for managing the Dart and native `$dartInstanceManagerClassName`s.', - ) - ..constructors.add( - cb.Constructor((cb.ConstructorBuilder builder) { - builder - ..docs.add( - '/// Constructor for [$dartInstanceManagerApiClassName].', - ) - ..optionalParameters.add(binaryMessengerParameter) - ..initializers.add( - cb.Code( - '${binaryMessengerField.name} = ${binaryMessengerParameter.name}', - ), - ); - }), - ) - ..fields.addAll([ - binaryMessengerField, - cb.Field((cb.FieldBuilder builder) { - builder - ..name = pigeonChannelCodec - ..type = cb.refer('MessageCodec') - ..static = true - ..modifier = cb.FieldModifier.constant - ..assignment = const cb.Code('$_pigeonMessageCodec()'); - }), - ]) - ..methods.add( - cb.Method((cb.MethodBuilder builder) { - builder - ..name = 'setUpMessageHandlers' - ..static = true - ..returns = cb.refer('void') - ..optionalParameters.addAll([ - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}clearHandlers' - ..type = cb.refer('bool') - ..named = true - ..defaultTo = const cb.Code('false'), - ), - binaryMessengerParameter, - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = 'instanceManager' - ..named = true - ..type = cb.refer('$dartInstanceManagerClassName?'), - ), - ]) - ..body = cb.Block.of( - cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageHandlerSink = StringBuffer(); - writeFlutterMethodMessageHandler( - Indent(messageHandlerSink), - name: 'removeStrongReferenceName', - parameters: [ - Parameter( - name: 'identifier', - type: const TypeDeclaration( - baseName: 'int', - isNullable: false, - ), - ), - ], - returnType: const TypeDeclaration.voidDeclaration(), - channelName: makeRemoveStrongReferenceChannelName( - dartPackageName, + (cb.ClassBuilder builder) => builder + ..name = dartInstanceManagerApiClassName + ..docs.add( + '/// Generated API for managing the Dart and native `$dartInstanceManagerClassName`s.', + ) + ..constructors.add( + cb.Constructor((cb.ConstructorBuilder builder) { + builder + ..docs.add( + '/// Constructor for [$dartInstanceManagerApiClassName].', + ) + ..optionalParameters.add(binaryMessengerParameter) + ..initializers.add( + cb.Code( + '${binaryMessengerField.name} = ${binaryMessengerParameter.name}', + ), + ); + }), + ) + ..fields.addAll([ + binaryMessengerField, + cb.Field((cb.FieldBuilder builder) { + builder + ..name = pigeonChannelCodec + ..type = cb.refer('MessageCodec') + ..static = true + ..modifier = cb.FieldModifier.constant + ..assignment = const cb.Code('$_pigeonMessageCodec()'); + }), + ]) + ..methods.add( + cb.Method((cb.MethodBuilder builder) { + builder + ..name = 'setUpMessageHandlers' + ..static = true + ..returns = cb.refer('void') + ..optionalParameters.addAll([ + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}clearHandlers' + ..type = cb.refer('bool') + ..named = true + ..defaultTo = const cb.Code('false'), + ), + binaryMessengerParameter, + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = 'instanceManager' + ..named = true + ..type = cb.refer('$dartInstanceManagerClassName?'), + ), + ]) + ..body = cb.Block.of( + cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageHandlerSink = StringBuffer(); + writeFlutterMethodMessageHandler( + Indent(messageHandlerSink), + name: 'removeStrongReferenceName', + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, ), - isMockHandler: false, - isAsynchronous: false, - nullHandlerExpression: - '${classMemberNamePrefix}clearHandlers', - onCreateApiCall: ( + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: makeRemoveStrongReferenceChannelName( + dartPackageName, + ), + isMockHandler: false, + isAsynchronous: false, + nullHandlerExpression: + '${classMemberNamePrefix}clearHandlers', + onCreateApiCall: + ( String methodName, Iterable parameters, Iterable safeArgumentNames, ) { return '(instanceManager ?? $dartInstanceManagerClassName.instance).remove(${safeArgumentNames.single})'; }, - ); - builder.statements.add( - cb.Code(messageHandlerSink.toString()), - ); - }).statements, ); - }), - ) - ..methods.addAll([ - cb.Method((cb.MethodBuilder builder) { - builder - ..name = 'removeStrongReference' - ..returns = cb.refer('Future') - ..modifier = cb.MethodModifier.async - ..requiredParameters.add( - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = 'identifier' - ..type = cb.refer('int'), - ), - ) - ..body = cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageCallSink = StringBuffer(); - writeHostMethodMessageCall( - Indent(messageCallSink), - addSuffixVariable: false, - channelName: makeRemoveStrongReferenceChannelName( - dartPackageName, + builder.statements.add( + cb.Code(messageHandlerSink.toString()), + ); + }).statements, + ); + }), + ) + ..methods.addAll([ + cb.Method((cb.MethodBuilder builder) { + builder + ..name = 'removeStrongReference' + ..returns = cb.refer('Future') + ..modifier = cb.MethodModifier.async + ..requiredParameters.add( + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = 'identifier' + ..type = cb.refer('int'), + ), + ) + ..body = cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + writeHostMethodMessageCall( + Indent(messageCallSink), + addSuffixVariable: false, + channelName: makeRemoveStrongReferenceChannelName( + dartPackageName, + ), + parameters: [ + Parameter( + name: 'identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, ), - parameters: [ - Parameter( - name: 'identifier', - type: const TypeDeclaration( - baseName: 'int', - isNullable: false, - ), - ), - ], - returnType: const TypeDeclaration.voidDeclaration(), - ); - builder.statements.addAll([ - cb.Code(messageCallSink.toString()), - ]); - }); - }), - cb.Method((cb.MethodBuilder builder) { - builder - ..name = 'clear' - ..returns = cb.refer('Future') - ..modifier = cb.MethodModifier.async - ..docs.addAll([ - '/// Clear the native `$dartInstanceManagerClassName`.', - '///', - '/// This is typically called after a hot restart.', - ]) - ..body = cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageCallSink = StringBuffer(); - writeHostMethodMessageCall( - Indent(messageCallSink), - addSuffixVariable: false, - channelName: makeClearChannelName(dartPackageName), - parameters: [], - returnType: const TypeDeclaration.voidDeclaration(), - ); - builder.statements.addAll([ - cb.Code(messageCallSink.toString()), - ]); - }); - }), - ]), + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ); + builder.statements.addAll([ + cb.Code(messageCallSink.toString()), + ]); + }); + }), + cb.Method((cb.MethodBuilder builder) { + builder + ..name = 'clear' + ..returns = cb.refer('Future') + ..modifier = cb.MethodModifier.async + ..docs.addAll([ + '/// Clear the native `$dartInstanceManagerClassName`.', + '///', + '/// This is typically called after a hot restart.', + ]) + ..body = cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + writeHostMethodMessageCall( + Indent(messageCallSink), + addSuffixVariable: false, + channelName: makeClearChannelName(dartPackageName), + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + ); + builder.statements.addAll([ + cb.Code(messageCallSink.toString()), + ]); + }); + }), + ]), ); final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); @@ -917,119 +910,110 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; // AST class used by code_builder to generate the code. final cb.Class proxyApi = cb.Class( - (cb.ClassBuilder builder) => - builder - ..name = api.name - ..extend = - api.superClass != null - ? cb.refer(api.superClass!.baseName) - : cb.refer(proxyApiBaseClassName) - ..implements.addAll( - api.interfaces.map( - (TypeDeclaration type) => cb.refer(type.baseName), - ), - ) - ..docs.addAll( - asDocumentationComments( - api.documentationComments, - docCommentSpec, - ), - ) - ..constructors.addAll( - proxy_api_helper.constructors( - api.constructors, - apiName: api.name, - dartPackageName: dartPackageName, - codecName: codecName, - codecInstanceName: codecInstanceName, - superClassApi: api.superClass?.associatedProxyApi, - unattachedFields: api.unattachedFields, - flutterMethodsFromSuperClasses: - api.flutterMethodsFromSuperClassesWithApis(), - flutterMethodsFromInterfaces: - api.flutterMethodsFromInterfacesWithApis(), - declaredFlutterMethods: api.flutterMethods, - ), - ) - ..constructors.add( - proxy_api_helper.detachedConstructor( - apiName: api.name, - superClassApi: api.superClass?.associatedProxyApi, - unattachedFields: api.unattachedFields, - flutterMethodsFromSuperClasses: - api.flutterMethodsFromSuperClassesWithApis(), - flutterMethodsFromInterfaces: - api.flutterMethodsFromInterfacesWithApis(), - declaredFlutterMethods: api.flutterMethods, - ), - ) - ..fields.addAll([ - if (api.constructors.isNotEmpty || - api.attachedFields.any((ApiField field) => !field.isStatic) || - api.hostMethods.isNotEmpty) - proxy_api_helper.codecInstanceField( - codecInstanceName: codecInstanceName, - codecName: codecName, - ), - ]) - ..fields.addAll( - proxy_api_helper.unattachedFields(api.unattachedFields), - ) - ..fields.addAll( - proxy_api_helper.flutterMethodFields( - api.flutterMethods, - apiName: api.name, - ), - ) - ..fields.addAll( - proxy_api_helper.interfaceApiFields(api.apisOfInterfaces()), - ) - ..fields.addAll(proxy_api_helper.attachedFields(api.attachedFields)) - ..methods.addAll( - proxy_api_helper.staticAttachedFieldsGetters( - api.attachedFields.where((ApiField field) => field.isStatic), - apiName: api.name, - ), - ) - ..methods.add( - proxy_api_helper.setUpMessageHandlerMethod( - flutterMethods: api.flutterMethods, - apiName: api.name, - dartPackageName: dartPackageName, - codecName: codecName, - unattachedFields: api.unattachedFields, - hasCallbackConstructor: api.hasCallbackConstructor(), - ), - ) - ..methods.addAll( - proxy_api_helper.attachedFieldMethods( - api.attachedFields, - apiName: api.name, - dartPackageName: dartPackageName, - codecInstanceName: codecInstanceName, - codecName: codecName, - ), - ) - ..methods.addAll( - proxy_api_helper.hostMethods( - api.hostMethods, - apiName: api.name, - dartPackageName: dartPackageName, - codecInstanceName: codecInstanceName, - codecName: codecName, - ), - ) - ..methods.add( - proxy_api_helper.copyMethod( - apiName: api.name, - unattachedFields: api.unattachedFields, - flutterMethodsFromSuperClasses: - api.flutterMethodsFromSuperClassesWithApis(), - flutterMethodsFromInterfaces: - api.flutterMethodsFromInterfacesWithApis(), - declaredFlutterMethods: api.flutterMethods, - ), + (cb.ClassBuilder builder) => builder + ..name = api.name + ..extend = api.superClass != null + ? cb.refer(api.superClass!.baseName) + : cb.refer(proxyApiBaseClassName) + ..implements.addAll( + api.interfaces.map((TypeDeclaration type) => cb.refer(type.baseName)), + ) + ..docs.addAll( + asDocumentationComments(api.documentationComments, docCommentSpec), + ) + ..constructors.addAll( + proxy_api_helper.constructors( + api.constructors, + apiName: api.name, + dartPackageName: dartPackageName, + codecName: codecName, + codecInstanceName: codecInstanceName, + superClassApi: api.superClass?.associatedProxyApi, + unattachedFields: api.unattachedFields, + flutterMethodsFromSuperClasses: api + .flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: api + .flutterMethodsFromInterfacesWithApis(), + declaredFlutterMethods: api.flutterMethods, + ), + ) + ..constructors.add( + proxy_api_helper.detachedConstructor( + apiName: api.name, + superClassApi: api.superClass?.associatedProxyApi, + unattachedFields: api.unattachedFields, + flutterMethodsFromSuperClasses: api + .flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: api + .flutterMethodsFromInterfacesWithApis(), + declaredFlutterMethods: api.flutterMethods, + ), + ) + ..fields.addAll([ + if (api.constructors.isNotEmpty || + api.attachedFields.any((ApiField field) => !field.isStatic) || + api.hostMethods.isNotEmpty) + proxy_api_helper.codecInstanceField( + codecInstanceName: codecInstanceName, + codecName: codecName, ), + ]) + ..fields.addAll(proxy_api_helper.unattachedFields(api.unattachedFields)) + ..fields.addAll( + proxy_api_helper.flutterMethodFields( + api.flutterMethods, + apiName: api.name, + ), + ) + ..fields.addAll( + proxy_api_helper.interfaceApiFields(api.apisOfInterfaces()), + ) + ..fields.addAll(proxy_api_helper.attachedFields(api.attachedFields)) + ..methods.addAll( + proxy_api_helper.staticAttachedFieldsGetters( + api.attachedFields.where((ApiField field) => field.isStatic), + apiName: api.name, + ), + ) + ..methods.add( + proxy_api_helper.setUpMessageHandlerMethod( + flutterMethods: api.flutterMethods, + apiName: api.name, + dartPackageName: dartPackageName, + codecName: codecName, + unattachedFields: api.unattachedFields, + hasCallbackConstructor: api.hasCallbackConstructor(), + ), + ) + ..methods.addAll( + proxy_api_helper.attachedFieldMethods( + api.attachedFields, + apiName: api.name, + dartPackageName: dartPackageName, + codecInstanceName: codecInstanceName, + codecName: codecName, + ), + ) + ..methods.addAll( + proxy_api_helper.hostMethods( + api.hostMethods, + apiName: api.name, + dartPackageName: dartPackageName, + codecInstanceName: codecInstanceName, + codecName: codecName, + ), + ) + ..methods.add( + proxy_api_helper.copyMethod( + apiName: api.name, + unattachedFields: api.unattachedFields, + flutterMethodsFromSuperClasses: api + .flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: api + .flutterMethodsFromInterfacesWithApis(), + declaredFlutterMethods: api.flutterMethods, + ), + ), ); final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); @@ -1052,12 +1036,11 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; final String testOutPath = generatorOptions.testOut ?? ''; _writeTestPrologue(generatorOptions, root, indent); _writeTestImports(generatorOptions, root, indent); - final String relativeDartPath = path.Context( - style: path.Style.posix, - ).relative( - _posixify(sourceOutPath), - from: _posixify(path.dirname(testOutPath)), - ); + final String relativeDartPath = path.Context(style: path.Style.posix) + .relative( + _posixify(sourceOutPath), + from: _posixify(path.dirname(testOutPath)), + ); if (!relativeDartPath.contains('/lib/')) { // If we can't figure out the package name or the relative path doesn't // include a 'lib' directory, try relative path import which only works in @@ -1091,8 +1074,8 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; root, indent, mockApi, - channelNameFunc: - (Method func) => makeChannelName(api, func, dartPackageName), + channelNameFunc: (Method func) => + makeChannelName(api, func, dartPackageName), isMockHandler: true, dartPackageName: dartPackageName, ); @@ -1321,12 +1304,12 @@ if (wrapped == null) { final String genericCastCall = _makeGenericCastCall(returnType); const String accessor = '${varNamePrefix}replyList[0]'; // Avoid warnings from pointlessly casting to `Object?`. - final String nullablyTypedAccessor = - returnTypeName == 'Object' - ? accessor - : '($accessor as $returnTypeName?)'; - final String nullHandler = - returnType.isNullable ? (genericCastCall.isEmpty ? '' : '?') : '!'; + final String nullablyTypedAccessor = returnTypeName == 'Object' + ? accessor + : '($accessor as $returnTypeName?)'; + final String nullHandler = returnType.isNullable + ? (genericCastCall.isEmpty ? '' : '?') + : '!'; String returnStatement = 'return'; if (!returnType.isVoid) { returnStatement = @@ -1404,15 +1387,15 @@ if (${varNamePrefix}replyList == null) { 'final BasicMessageChannel ${varNamePrefix}channel = BasicMessageChannel(', ); indent.nest(2, () { - final String channelSuffix = - addSuffixVariable ? r'$messageChannelSuffix' : ''; + final String channelSuffix = addSuffixVariable + ? r'$messageChannelSuffix' + : ''; indent.writeln("'$channelName$channelSuffix', $pigeonChannelCodec,"); indent.writeln('binaryMessenger: binaryMessenger);'); }); - final String messageHandlerSetterWithOpeningParentheses = - isMockHandler - ? '_testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(${varNamePrefix}channel, ' - : '${varNamePrefix}channel.setMessageHandler('; + final String messageHandlerSetterWithOpeningParentheses = isMockHandler + ? '_testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(${varNamePrefix}channel, ' + : '${varNamePrefix}channel.setMessageHandler('; indent.write('if ($nullHandlerExpression) '); indent.addScoped('{', '}', () { indent.writeln('${messageHandlerSetterWithOpeningParentheses}null);'); @@ -1483,10 +1466,9 @@ if (${varNamePrefix}replyList == null) { } const String returnExpression = 'output'; - final String returnStatement = - isMockHandler - ? 'return [$returnExpression];' - : 'return wrapResponse(result: $returnExpression);'; + final String returnStatement = isMockHandler + ? 'return [$returnExpression];' + : 'return wrapResponse(result: $returnExpression);'; indent.writeln(returnStatement); } }, addTrailingNewline: false); @@ -1560,24 +1542,24 @@ String _getMethodParameterSignature( return signature; } - final List requiredPositionalParams = - parameters - .where((Parameter p) => p.isPositional && !p.isOptional) - .toList(); - final List optionalPositionalParams = - parameters - .where((Parameter p) => p.isPositional && p.isOptional) - .toList(); - final List namedParams = - parameters.where((Parameter p) => !p.isPositional).toList(); + final List requiredPositionalParams = parameters + .where((Parameter p) => p.isPositional && !p.isOptional) + .toList(); + final List optionalPositionalParams = parameters + .where((Parameter p) => p.isPositional && p.isOptional) + .toList(); + final List namedParams = parameters + .where((Parameter p) => !p.isPositional) + .toList(); String getParameterString(Parameter p) { final String required = p.isRequired && !p.isPositional ? 'required ' : ''; final String type = addGenericTypesNullable(p.type); - final String defaultValue = - p.defaultValue == null ? '' : ' = ${p.defaultValue}'; + final String defaultValue = p.defaultValue == null + ? '' + : ' = ${p.defaultValue}'; return '$required$type ${p.name}$defaultValue'; } @@ -1597,21 +1579,22 @@ String _getMethodParameterSignature( } final String trailingComma = optionalPositionalParams.isNotEmpty || namedParams.isNotEmpty ? ',' : ''; - final String baseParams = - signature.isNotEmpty ? '$signature$trailingComma ' : ''; + final String baseParams = signature.isNotEmpty + ? '$signature$trailingComma ' + : ''; if (optionalPositionalParams.isNotEmpty) { final String trailingComma = requiredPositionalParams.length + optionalPositionalParams.length > 2 - ? ',' - : ''; + ? ',' + : ''; return '$baseParams[$optionalParameterString$trailingComma]'; } if (namedParams.isNotEmpty) { final String trailingComma = addTrailingComma || - requiredPositionalParams.length + namedParams.length > 2 - ? ', ' - : ''; + requiredPositionalParams.length + namedParams.length > 2 + ? ', ' + : ''; return '$baseParams{$namedParameterString$trailingComma}'; } return signature; @@ -1622,10 +1605,9 @@ String _getMethodParameterSignature( String _flattenTypeArguments(List args) { return args .map( - (TypeDeclaration arg) => - arg.typeArguments.isEmpty - ? '${arg.baseName}${arg.isNullable ? '?' : ''}' - : '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments)}>${arg.isNullable ? '?' : ''}', + (TypeDeclaration arg) => arg.typeArguments.isEmpty + ? '${arg.baseName}${arg.isNullable ? '?' : ''}' + : '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments)}>${arg.isNullable ? '?' : ''}', ) .join(', '); } diff --git a/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart b/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart index f06d94d9b02..369a7913321 100644 --- a/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart +++ b/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart @@ -26,95 +26,83 @@ Iterable asConstructorParameters({ }) sync* { if (includeBinaryMessengerAndInstanceManager) { yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}binaryMessenger' - ..named = true - ..type = defineType ? cb.refer('BinaryMessenger?') : null - ..toSuper = !defineType - ..required = false, + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..named = true + ..type = defineType ? cb.refer('BinaryMessenger?') : null + ..toSuper = !defineType + ..required = false, ); yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = instanceManagerVarName - ..named = true - ..type = - defineType ? cb.refer('$dartInstanceManagerClassName?') : null - ..toSuper = !defineType - ..required = false, + (cb.ParameterBuilder builder) => builder + ..name = instanceManagerVarName + ..named = true + ..type = defineType ? cb.refer('$dartInstanceManagerClassName?') : null + ..toSuper = !defineType + ..required = false, ); } for (final ApiField field in unattachedFields) { yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = field.name - ..named = true - ..type = - defineType - ? cb.refer(addGenericTypesNullable(field.type)) - : null - ..toThis = !defineType - ..required = !field.type.isNullable, + (cb.ParameterBuilder builder) => builder + ..name = field.name + ..named = true + ..type = defineType + ? cb.refer(addGenericTypesNullable(field.type)) + : null + ..toThis = !defineType + ..required = !field.type.isNullable, ); } for (final (Method method, AstProxyApi api) in flutterMethodsFromSuperClasses) { yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = method.name - ..named = true - ..type = - defineType - ? methodAsFunctionType(method, apiName: api.name) - : null - ..toSuper = !defineType - ..required = method.isRequired, + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = defineType + ? methodAsFunctionType(method, apiName: api.name) + : null + ..toSuper = !defineType + ..required = method.isRequired, ); } for (final (Method method, AstProxyApi api) in flutterMethodsFromInterfaces) { yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = method.name - ..named = true - ..type = - defineType - ? methodAsFunctionType(method, apiName: api.name) - : null - ..toThis = !defineType - ..required = method.isRequired, + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = defineType + ? methodAsFunctionType(method, apiName: api.name) + : null + ..toThis = !defineType + ..required = method.isRequired, ); } for (final Method method in declaredFlutterMethods) { yield cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = method.name - ..named = true - ..type = - defineType - ? methodAsFunctionType(method, apiName: apiName) - : null - ..toThis = !defineType - ..required = method.isRequired, + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = defineType + ? methodAsFunctionType(method, apiName: apiName) + : null + ..toThis = !defineType + ..required = method.isRequired, ); } yield* parameters.mapIndexed( (int index, NamedType parameter) => cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = getParameterName(index, parameter) - ..type = refer(parameter.type) - ..named = true - ..required = !parameter.type.isNullable, + (cb.ParameterBuilder builder) => builder + ..name = getParameterName(index, parameter) + ..type = refer(parameter.type) + ..named = true + ..required = !parameter.type.isNullable, ), ); } @@ -130,43 +118,42 @@ Iterable overridesClassConstructors( for (final Constructor constructor in api.constructors) { yield cb.Field((cb.FieldBuilder builder) { - final String constructorName = - constructor.name.isEmpty ? 'new' : constructor.name; + final String constructorName = constructor.name.isEmpty + ? 'new' + : constructor.name; final Iterable parameters = asConstructorParameters( apiName: api.name, parameters: constructor.parameters, unattachedFields: api.unattachedFields, - flutterMethodsFromSuperClasses: - api.flutterMethodsFromSuperClassesWithApis(), - flutterMethodsFromInterfaces: - api.flutterMethodsFromInterfacesWithApis(), + flutterMethodsFromSuperClasses: api + .flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: api + .flutterMethodsFromInterfacesWithApis(), declaredFlutterMethods: api.flutterMethods, includeBinaryMessengerAndInstanceManager: false, ); builder - ..name = - constructor.name.isEmpty - ? '${lowerCamelCaseApiName}_new' - : '${lowerCamelCaseApiName}_${constructor.name}' + ..name = constructor.name.isEmpty + ? '${lowerCamelCaseApiName}_new' + : '${lowerCamelCaseApiName}_${constructor.name}' ..static = true ..docs.add('/// Overrides [${api.name}.$constructorName].') ..type = cb.FunctionType( - (cb.FunctionTypeBuilder builder) => - builder - ..returnType = cb.refer(api.name) - ..isNullable = true - ..namedRequiredParameters.addAll({ - for (final cb.Parameter parameter in parameters.where( - (cb.Parameter parameter) => parameter.required, - )) - parameter.name: parameter.type!, - }) - ..namedParameters.addAll({ - for (final cb.Parameter parameter in parameters.where( - (cb.Parameter parameter) => !parameter.required, - )) - parameter.name: parameter.type!, - }), + (cb.FunctionTypeBuilder builder) => builder + ..returnType = cb.refer(api.name) + ..isNullable = true + ..namedRequiredParameters.addAll({ + for (final cb.Parameter parameter in parameters.where( + (cb.Parameter parameter) => parameter.required, + )) + parameter.name: parameter.type!, + }) + ..namedParameters.addAll({ + for (final cb.Parameter parameter in parameters.where( + (cb.Parameter parameter) => !parameter.required, + )) + parameter.name: parameter.type!, + }), ); }); } @@ -264,22 +251,18 @@ cb.Method overridesClassResetMethod(Iterable proxyApis) { /// positional arguments. cb.FunctionType methodAsFunctionType(Method method, {required String apiName}) { return cb.FunctionType( - (cb.FunctionTypeBuilder builder) => - builder - ..returnType = refer( - method.returnType, - asFuture: method.isAsynchronous, - ) - ..isNullable = !method.isRequired - ..requiredParameters.addAll([ - if (method.location == ApiLocation.flutter) - cb.refer('$apiName ${classMemberNamePrefix}instance'), - ...method.parameters.mapIndexed((int index, NamedType parameter) { - return cb.refer( - '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', - ); - }), - ]), + (cb.FunctionTypeBuilder builder) => builder + ..returnType = refer(method.returnType, asFuture: method.isAsynchronous) + ..isNullable = !method.isRequired + ..requiredParameters.addAll([ + if (method.location == ApiLocation.flutter) + cb.refer('$apiName ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed((int index, NamedType parameter) { + return cb.refer( + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', + ); + }), + ]), ); } @@ -300,22 +283,18 @@ Iterable staticAttachedFieldsGetters( }) sync* { for (final ApiField field in fields) { yield cb.Method( - (cb.MethodBuilder builder) => - builder - ..name = field.name - ..type = cb.MethodType.getter - ..static = true - ..returns = cb.refer(addGenericTypesNullable(field.type)) - ..docs.addAll( - asDocumentationComments( - field.documentationComments, - docCommentSpec, - ), - ) - ..lambda = true - ..body = cb.Code( - '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${field.name} ?? _${field.name}', - ), + (cb.MethodBuilder builder) => builder + ..name = field.name + ..type = cb.MethodType.getter + ..static = true + ..returns = cb.refer(addGenericTypesNullable(field.type)) + ..docs.addAll( + asDocumentationComments(field.documentationComments, docCommentSpec), + ) + ..lambda = true + ..body = cb.Code( + '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${field.name} ?? _${field.name}', + ), ); } } @@ -328,23 +307,22 @@ void writeProxyApiPigeonOverrides( required Iterable proxyApis, }) { final cb.Class proxyApiOverrides = cb.Class( - (cb.ClassBuilder builder) => - builder - ..name = proxyApiOverridesClassName - ..annotations.add(cb.refer('visibleForTesting')) - ..docs.addAll([ - '/// Provides overrides for the constructors and static members of each', - '/// Dart proxy class.', - '///', - '/// This is only intended to be used with unit tests to prevent errors from', - '/// making message calls in a unit test.', - '///', - '/// See [$proxyApiOverridesClassName.${classMemberNamePrefix}reset] to set all overrides back to null.', - ]) - ..fields.addAll(overridesClassConstructors(proxyApis)) - ..fields.addAll(overridesClassStaticFields(proxyApis)) - ..fields.addAll(overridesClassStaticMethods(proxyApis)) - ..methods.add(overridesClassResetMethod(proxyApis)), + (cb.ClassBuilder builder) => builder + ..name = proxyApiOverridesClassName + ..annotations.add(cb.refer('visibleForTesting')) + ..docs.addAll([ + '/// Provides overrides for the constructors and static members of each', + '/// Dart proxy class.', + '///', + '/// This is only intended to be used with unit tests to prevent errors from', + '/// making message calls in a unit test.', + '///', + '/// See [$proxyApiOverridesClassName.${classMemberNamePrefix}reset] to set all overrides back to null.', + ]) + ..fields.addAll(overridesClassConstructors(proxyApis)) + ..fields.addAll(overridesClassStaticFields(proxyApis)) + ..fields.addAll(overridesClassStaticMethods(proxyApis)) + ..methods.add(overridesClassResetMethod(proxyApis)), ); final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); @@ -368,22 +346,21 @@ Iterable constructors( required Iterable declaredFlutterMethods, }) sync* { final cb.Parameter binaryMessengerParameter = cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}binaryMessenger' - ..named = true - ..toSuper = true, + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..named = true + ..toSuper = true, ); for (final Constructor constructor in constructors) { - final String? factoryConstructorName = - constructor.name.isNotEmpty ? constructor.name : null; + final String? factoryConstructorName = constructor.name.isNotEmpty + ? constructor.name + : null; final String constructorName = '$classMemberNamePrefix${constructor.name.isNotEmpty ? constructor.name : 'new'}'; - final String overridesConstructorName = - constructor.name.isNotEmpty - ? '${toLowerCamelCase(apiName)}_${constructor.name}' - : '${toLowerCamelCase(apiName)}_new'; + final String overridesConstructorName = constructor.name.isNotEmpty + ? '${toLowerCamelCase(apiName)}_${constructor.name}' + : '${toLowerCamelCase(apiName)}_new'; // Factory constructor that forwards the parameters to the overrides class // or to the constructor yielded below this one. @@ -455,10 +432,9 @@ Iterable constructors( yield cb.Constructor((cb.ConstructorBuilder builder) { final String channelName = makeChannelNameWithStrings( apiName: apiName, - methodName: - constructor.name.isNotEmpty - ? constructor.name - : '${classMemberNamePrefix}defaultConstructor', + methodName: constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor', dartPackageName: dartPackageName, ); builder @@ -540,31 +516,30 @@ cb.Constructor detachedConstructor({ required Iterable declaredFlutterMethods, }) { return cb.Constructor( - (cb.ConstructorBuilder builder) => - builder - ..name = '${classMemberNamePrefix}detached' - ..docs.addAll([ - '/// Constructs [$apiName] without creating the associated native object.', - '///', - '/// This should only be used by subclasses created by this library or to', - '/// create copies for an [$dartInstanceManagerClassName].', - ]) - ..annotations.add(cb.refer('protected')) - ..optionalParameters.addAll( - asConstructorParameters( - apiName: apiName, - parameters: [], - unattachedFields: unattachedFields, - flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, - flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, - declaredFlutterMethods: declaredFlutterMethods, - defineType: false, - ), - ) - ..initializers.addAll([ - if (superClassApi != null) - const cb.Code('super.${classMemberNamePrefix}detached()'), - ]), + (cb.ConstructorBuilder builder) => builder + ..name = '${classMemberNamePrefix}detached' + ..docs.addAll([ + '/// Constructs [$apiName] without creating the associated native object.', + '///', + '/// This should only be used by subclasses created by this library or to', + '/// create copies for an [$dartInstanceManagerClassName].', + ]) + ..annotations.add(cb.refer('protected')) + ..optionalParameters.addAll( + asConstructorParameters( + apiName: apiName, + parameters: [], + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + defineType: false, + ), + ) + ..initializers.addAll([ + if (superClassApi != null) + const cb.Code('super.${classMemberNamePrefix}detached()'), + ]), ); } @@ -574,13 +549,12 @@ cb.Field codecInstanceField({ required String codecName, }) { return cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = codecInstanceName - ..type = cb.refer(codecName) - ..late = true - ..modifier = cb.FieldModifier.final$ - ..assignment = cb.Code('$codecName($instanceManagerVarName)'), + (cb.FieldBuilder builder) => builder + ..name = codecInstanceName + ..type = cb.refer(codecName) + ..late = true + ..modifier = cb.FieldModifier.final$ + ..assignment = cb.Code('$codecName($instanceManagerVarName)'), ); } @@ -589,17 +563,13 @@ cb.Field codecInstanceField({ Iterable unattachedFields(Iterable fields) sync* { for (final ApiField field in fields) { yield cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = field.name - ..type = cb.refer(addGenericTypesNullable(field.type)) - ..modifier = cb.FieldModifier.final$ - ..docs.addAll( - asDocumentationComments( - field.documentationComments, - docCommentSpec, - ), - ), + (cb.FieldBuilder builder) => builder + ..name = field.name + ..type = cb.refer(addGenericTypesNullable(field.type)) + ..modifier = cb.FieldModifier.final$ + ..docs.addAll( + asDocumentationComments(field.documentationComments, docCommentSpec), + ), ); } } @@ -615,37 +585,36 @@ Iterable flutterMethodFields( }) sync* { for (final Method method in methods) { yield cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = method.name - ..modifier = cb.FieldModifier.final$ - ..docs.addAll( - asDocumentationComments([ - ...method.documentationComments, - ...[ - if (method.documentationComments.isEmpty) 'Callback method.', - '', - 'For the associated Native object to be automatically garbage collected,', - "it is required that the implementation of this `Function` doesn't have a", - 'strong reference to the encapsulating class instance. When this `Function`', - 'references a non-local variable, it is strongly recommended to access it', - 'with a `WeakReference`:', - '', - '```dart', - 'final WeakReference weakMyVariable = WeakReference(myVariable);', - 'final $apiName instance = $apiName(', - ' ${method.name}: ($apiName ${classMemberNamePrefix}instance, ...) {', - ' print(weakMyVariable?.target);', - ' },', - ');', - '```', - '', - 'Alternatively, [$dartInstanceManagerClassName.removeWeakReference] can be used to', - 'release the associated Native object manually.', - ], - ], docCommentSpec), - ) - ..type = methodAsFunctionType(method, apiName: apiName), + (cb.FieldBuilder builder) => builder + ..name = method.name + ..modifier = cb.FieldModifier.final$ + ..docs.addAll( + asDocumentationComments([ + ...method.documentationComments, + ...[ + if (method.documentationComments.isEmpty) 'Callback method.', + '', + 'For the associated Native object to be automatically garbage collected,', + "it is required that the implementation of this `Function` doesn't have a", + 'strong reference to the encapsulating class instance. When this `Function`', + 'references a non-local variable, it is strongly recommended to access it', + 'with a `WeakReference`:', + '', + '```dart', + 'final WeakReference weakMyVariable = WeakReference(myVariable);', + 'final $apiName instance = $apiName(', + ' ${method.name}: ($apiName ${classMemberNamePrefix}instance, ...) {', + ' print(weakMyVariable?.target);', + ' },', + ');', + '```', + '', + 'Alternatively, [$dartInstanceManagerClassName.removeWeakReference] can be used to', + 'release the associated Native object manually.', + ], + ], docCommentSpec), + ) + ..type = methodAsFunctionType(method, apiName: apiName), ); } } @@ -666,39 +635,35 @@ Iterable interfaceApiFields( for (final AstProxyApi proxyApi in apisOfInterfaces) { for (final Method method in proxyApi.methods) { yield cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = method.name - ..modifier = cb.FieldModifier.final$ - ..annotations.add(cb.refer('override')) - ..docs.addAll( - asDocumentationComments( - method.documentationComments, - docCommentSpec, - ), + (cb.FieldBuilder builder) => builder + ..name = method.name + ..modifier = cb.FieldModifier.final$ + ..annotations.add(cb.refer('override')) + ..docs.addAll( + asDocumentationComments( + method.documentationComments, + docCommentSpec, + ), + ) + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = refer( + method.returnType, + asFuture: method.isAsynchronous, ) - ..type = cb.FunctionType( - (cb.FunctionTypeBuilder builder) => - builder - ..returnType = refer( - method.returnType, - asFuture: method.isAsynchronous, - ) - ..isNullable = !method.isRequired - ..requiredParameters.addAll([ - cb.refer( - '${proxyApi.name} ${classMemberNamePrefix}instance', - ), - ...method.parameters.mapIndexed(( - int index, - NamedType parameter, - ) { - return cb.refer( - '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', - ); - }), - ]), - ), + ..isNullable = !method.isRequired + ..requiredParameters.addAll([ + cb.refer('${proxyApi.name} ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed(( + int index, + NamedType parameter, + ) { + return cb.refer( + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', + ); + }), + ]), + ), ); } } @@ -717,20 +682,16 @@ Iterable interfaceApiFields( Iterable attachedFields(Iterable fields) sync* { for (final ApiField field in fields) { yield cb.Field( - (cb.FieldBuilder builder) => - builder - ..name = '${field.isStatic ? '_' : ''}${field.name}' - ..type = cb.refer(addGenericTypesNullable(field.type)) - ..modifier = cb.FieldModifier.final$ - ..static = field.isStatic - ..late = !field.isStatic - ..docs.addAll( - asDocumentationComments( - field.documentationComments, - docCommentSpec, - ), - ) - ..assignment = cb.Code('$varNamePrefix${field.name}()'), + (cb.FieldBuilder builder) => builder + ..name = '${field.isStatic ? '_' : ''}${field.name}' + ..type = cb.refer(addGenericTypesNullable(field.type)) + ..modifier = cb.FieldModifier.final$ + ..static = field.isStatic + ..late = !field.isStatic + ..docs.addAll( + asDocumentationComments(field.documentationComments, docCommentSpec), + ) + ..assignment = cb.Code('$varNamePrefix${field.name}()'), ); } } @@ -754,136 +715,123 @@ cb.Method setUpMessageHandlerMethod({ final bool hasAnyMessageHandlers = hasCallbackConstructor || flutterMethods.isNotEmpty; return cb.Method.returnsVoid( - (cb.MethodBuilder builder) => - builder - ..name = '${classMemberNamePrefix}setUpMessageHandlers' - ..returns = cb.refer('void') - ..static = true - ..optionalParameters.addAll([ - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}clearHandlers' - ..type = cb.refer('bool') - ..named = true - ..defaultTo = const cb.Code('false'), - ), - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}binaryMessenger' - ..named = true - ..type = cb.refer('BinaryMessenger?'), - ), - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = instanceManagerVarName - ..named = true - ..type = cb.refer('$dartInstanceManagerClassName?'), - ), - if (hasCallbackConstructor) - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}newInstance' - ..named = true - ..type = cb.FunctionType( - (cb.FunctionTypeBuilder builder) => - builder - ..returnType = cb.refer(apiName) - ..isNullable = true - ..requiredParameters.addAll( - unattachedFields.mapIndexed(( - int index, - ApiField field, - ) { - return cb.refer( - '${addGenericTypesNullable(field.type)} ${getParameterName(index, field)}', - ); - }), - ), - ), - ), - for (final Method method in flutterMethods) - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = method.name - ..type = cb.FunctionType( - (cb.FunctionTypeBuilder builder) => - builder - ..returnType = refer( - method.returnType, - asFuture: method.isAsynchronous, - ) - ..isNullable = true - ..requiredParameters.addAll([ - cb.refer( - '$apiName ${classMemberNamePrefix}instance', - ), - ...method.parameters.mapIndexed(( - int index, - NamedType parameter, - ) { - return cb.refer( - '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', - ); - }), - ]), - ), - ), - ]) - ..body = cb.Block.of([ - if (hasAnyMessageHandlers) ...[ - cb.Code( - 'final $codecName $pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', - ), - const cb.Code( - 'final BinaryMessenger? binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + (cb.MethodBuilder builder) => builder + ..name = '${classMemberNamePrefix}setUpMessageHandlers' + ..returns = cb.refer('void') + ..static = true + ..optionalParameters.addAll([ + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}clearHandlers' + ..type = cb.refer('bool') + ..named = true + ..defaultTo = const cb.Code('false'), + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..named = true + ..type = cb.refer('BinaryMessenger?'), + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = instanceManagerVarName + ..named = true + ..type = cb.refer('$dartInstanceManagerClassName?'), + ), + if (hasCallbackConstructor) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}newInstance' + ..named = true + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = cb.refer(apiName) + ..isNullable = true + ..requiredParameters.addAll( + unattachedFields.mapIndexed((int index, ApiField field) { + return cb.refer( + '${addGenericTypesNullable(field.type)} ${getParameterName(index, field)}', + ); + }), + ), ), - ], - if (hasCallbackConstructor) - ...cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageHandlerSink = StringBuffer(); - const String methodName = '${classMemberNamePrefix}newInstance'; - DartGenerator.writeFlutterMethodMessageHandler( - Indent(messageHandlerSink), - name: methodName, - parameters: [ - Parameter( - name: '${classMemberNamePrefix}instanceIdentifier', - type: const TypeDeclaration( - baseName: 'int', - isNullable: false, - ), - ), - ...unattachedFields.map((ApiField field) { - return Parameter(name: field.name, type: field.type); + ), + for (final Method method in flutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = refer( + method.returnType, + asFuture: method.isAsynchronous, + ) + ..isNullable = true + ..requiredParameters.addAll([ + cb.refer('$apiName ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed(( + int index, + NamedType parameter, + ) { + return cb.refer( + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', + ); }), - ], - returnType: const TypeDeclaration.voidDeclaration(), - channelName: makeChannelNameWithStrings( - apiName: apiName, - methodName: methodName, - dartPackageName: dartPackageName, + ]), + ), + ), + ]) + ..body = cb.Block.of([ + if (hasAnyMessageHandlers) ...[ + cb.Code( + 'final $codecName $pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', + ), + const cb.Code( + 'final BinaryMessenger? binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + ), + ], + if (hasCallbackConstructor) + ...cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageHandlerSink = StringBuffer(); + const String methodName = '${classMemberNamePrefix}newInstance'; + DartGenerator.writeFlutterMethodMessageHandler( + Indent(messageHandlerSink), + name: methodName, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instanceIdentifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, ), - isMockHandler: false, - isAsynchronous: false, - nullHandlerExpression: - '${classMemberNamePrefix}clearHandlers', - onCreateApiCall: ( + ), + ...unattachedFields.map((ApiField field) { + return Parameter(name: field.name, type: field.type); + }), + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: methodName, + dartPackageName: dartPackageName, + ), + isMockHandler: false, + isAsynchronous: false, + nullHandlerExpression: '${classMemberNamePrefix}clearHandlers', + onCreateApiCall: + ( String methodName, Iterable parameters, Iterable safeArgumentNames, ) { - final String argsAsNamedParams = - map2(parameters, safeArgumentNames, ( - Parameter parameter, - String safeArgName, - ) { - return '${parameter.name}: $safeArgName,\n'; - }).skip(1).join(); + final String argsAsNamedParams = map2( + parameters, + safeArgumentNames, + (Parameter parameter, String safeArgName) { + return '${parameter.name}: $safeArgName,\n'; + }, + ).skip(1).join(); return '($instanceManagerVarName ?? $dartInstanceManagerClassName.instance)\n' ' .addHostCreatedInstance(\n' @@ -896,44 +844,40 @@ cb.Method setUpMessageHandlerMethod({ ' ${safeArgumentNames.first},\n' ')'; }, - ); - builder.statements.add(cb.Code(messageHandlerSink.toString())); - }).statements, - for (final Method method in flutterMethods) - ...cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageHandlerSink = StringBuffer(); - DartGenerator.writeFlutterMethodMessageHandler( - Indent(messageHandlerSink), - name: method.name, - parameters: [ - Parameter( - name: '${classMemberNamePrefix}instance', - type: TypeDeclaration( - baseName: apiName, - isNullable: false, - ), - ), - ...method.parameters, - ], - returnType: TypeDeclaration( - baseName: method.returnType.baseName, - isNullable: - !method.isRequired || method.returnType.isNullable, - typeArguments: method.returnType.typeArguments, - associatedEnum: method.returnType.associatedEnum, - associatedClass: method.returnType.associatedClass, - associatedProxyApi: method.returnType.associatedProxyApi, - ), - channelName: makeChannelNameWithStrings( - apiName: apiName, - methodName: method.name, - dartPackageName: dartPackageName, - ), - isMockHandler: false, - isAsynchronous: method.isAsynchronous, - nullHandlerExpression: - '${classMemberNamePrefix}clearHandlers', - onCreateApiCall: ( + ); + builder.statements.add(cb.Code(messageHandlerSink.toString())); + }).statements, + for (final Method method in flutterMethods) + ...cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageHandlerSink = StringBuffer(); + DartGenerator.writeFlutterMethodMessageHandler( + Indent(messageHandlerSink), + name: method.name, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instance', + type: TypeDeclaration(baseName: apiName, isNullable: false), + ), + ...method.parameters, + ], + returnType: TypeDeclaration( + baseName: method.returnType.baseName, + isNullable: !method.isRequired || method.returnType.isNullable, + typeArguments: method.returnType.typeArguments, + associatedEnum: method.returnType.associatedEnum, + associatedClass: method.returnType.associatedClass, + associatedProxyApi: method.returnType.associatedProxyApi, + ), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: method.name, + dartPackageName: dartPackageName, + ), + isMockHandler: false, + isAsynchronous: method.isAsynchronous, + nullHandlerExpression: '${classMemberNamePrefix}clearHandlers', + onCreateApiCall: + ( String methodName, Iterable parameters, Iterable safeArgumentNames, @@ -941,10 +885,10 @@ cb.Method setUpMessageHandlerMethod({ final String nullability = method.isRequired ? '' : '?'; return '($methodName ?? ${safeArgumentNames.first}.$methodName)$nullability.call(${safeArgumentNames.join(',')})'; }, - ); - builder.statements.add(cb.Code(messageHandlerSink.toString())); - }).statements, - ]), + ); + builder.statements.add(cb.Code(messageHandlerSink.toString())); + }).statements, + ]), ); } @@ -1050,100 +994,90 @@ Iterable hostMethods( assert(method.location == ApiLocation.host); final Iterable parameters = method.parameters.mapIndexed( (int index, NamedType parameter) => cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = getParameterName(index, parameter) - ..type = cb.refer(addGenericTypesNullable(parameter.type)), + (cb.ParameterBuilder builder) => builder + ..name = getParameterName(index, parameter) + ..type = cb.refer(addGenericTypesNullable(parameter.type)), ), ); yield cb.Method( - (cb.MethodBuilder builder) => - builder - ..name = method.name - ..static = method.isStatic - ..modifier = cb.MethodModifier.async - ..docs.addAll( - asDocumentationComments( - method.documentationComments, - docCommentSpec, - ), - ) - ..returns = refer(method.returnType, asFuture: true) - ..requiredParameters.addAll(parameters) - ..optionalParameters.addAll([ - if (method.isStatic) ...[ - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = '${classMemberNamePrefix}binaryMessenger' - ..type = cb.refer('BinaryMessenger?') - ..named = true, - ), - cb.Parameter( - (cb.ParameterBuilder builder) => - builder - ..name = instanceManagerVarName - ..type = cb.refer('$dartInstanceManagerClassName?'), - ), - ], - ]) - ..body = cb.Block((cb.BlockBuilder builder) { - final StringBuffer messageCallSink = StringBuffer(); - DartGenerator.writeHostMethodMessageCall( - Indent(messageCallSink), - addSuffixVariable: false, - channelName: makeChannelNameWithStrings( - apiName: apiName, - methodName: method.name, - dartPackageName: dartPackageName, + (cb.MethodBuilder builder) => builder + ..name = method.name + ..static = method.isStatic + ..modifier = cb.MethodModifier.async + ..docs.addAll( + asDocumentationComments(method.documentationComments, docCommentSpec), + ) + ..returns = refer(method.returnType, asFuture: true) + ..requiredParameters.addAll(parameters) + ..optionalParameters.addAll([ + if (method.isStatic) ...[ + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..type = cb.refer('BinaryMessenger?') + ..named = true, + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = instanceManagerVarName + ..type = cb.refer('$dartInstanceManagerClassName?'), + ), + ], + ]) + ..body = cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + DartGenerator.writeHostMethodMessageCall( + Indent(messageCallSink), + addSuffixVariable: false, + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: method.name, + dartPackageName: dartPackageName, + ), + parameters: [ + if (!method.isStatic) + Parameter( + name: 'this', + type: TypeDeclaration(baseName: apiName, isNullable: false), ), - parameters: [ - if (!method.isStatic) - Parameter( - name: 'this', - type: TypeDeclaration( - baseName: apiName, - isNullable: false, - ), + ...method.parameters, + ], + returnType: method.returnType, + ); + builder.statements.addAll([ + if (method.isStatic) ...[ + cb.Code( + 'if ($proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name} != null) {', + ), + cb.CodeExpression( + cb.Code( + '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name}!', ), - ...method.parameters, - ], - returnType: method.returnType, - ); - builder.statements.addAll([ - if (method.isStatic) ...[ - cb.Code( - 'if ($proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name} != null) {', - ), - cb.CodeExpression( - cb.Code( - '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name}!', - ), - ) - .call( - parameters.map( - (cb.Parameter parameter) => cb.refer(parameter.name), - ), - ) - .returned - .statement, - const cb.Code('}'), - ], - if (!method.isStatic) - cb.Code( - 'final $codecName $pigeonChannelCodec =\n' - ' $codecInstanceName;', ) - else - cb.Code( - 'final $codecName $pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', - ), - const cb.Code( - 'final BinaryMessenger? ${varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', - ), - cb.Code(messageCallSink.toString()), - ]); - }), + .call( + parameters.map( + (cb.Parameter parameter) => cb.refer(parameter.name), + ), + ) + .returned + .statement, + const cb.Code('}'), + ], + if (!method.isStatic) + cb.Code( + 'final $codecName $pigeonChannelCodec =\n' + ' $codecInstanceName;', + ) + else + cb.Code( + 'final $codecName $pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', + ), + const cb.Code( + 'final BinaryMessenger? ${varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + ), + cb.Code(messageCallSink.toString()), + ]); + }), ); } } @@ -1169,20 +1103,19 @@ cb.Method copyMethod({ declaredFlutterMethods: declaredFlutterMethods, ); return cb.Method( - (cb.MethodBuilder builder) => - builder - ..name = '${classMemberNamePrefix}copy' - ..returns = cb.refer(apiName) - ..annotations.add(cb.refer('override')) - ..body = cb.Block.of([ - cb - .refer('$apiName.${classMemberNamePrefix}detached') - .call([], { - for (final cb.Parameter parameter in parameters) - parameter.name: cb.refer(parameter.name), - }) - .returned - .statement, - ]), + (cb.MethodBuilder builder) => builder + ..name = '${classMemberNamePrefix}copy' + ..returns = cb.refer(apiName) + ..annotations.add(cb.refer('override')) + ..body = cb.Block.of([ + cb + .refer('$apiName.${classMemberNamePrefix}detached') + .call([], { + for (final cb.Parameter parameter in parameters) + parameter.name: cb.refer(parameter.name), + }) + .returned + .statement, + ]), ); } diff --git a/packages/pigeon/lib/src/dart/templates.dart b/packages/pigeon/lib/src/dart/templates.dart index 4efbc2c56c4..9fb01a90b52 100644 --- a/packages/pigeon/lib/src/dart/templates.dart +++ b/packages/pigeon/lib/src/dart/templates.dart @@ -235,7 +235,8 @@ class $dartInstanceManagerClassName { /// The base class for all Dart proxy classes. /// /// All Dart proxy classes generated as a part of a ProxyApi extends this one. -const String proxyApiBaseClass = ''' +const String proxyApiBaseClass = + ''' /// An immutable object that serves as the base class for all Dart proxy classes /// and can provide functional copies of itself. /// @@ -277,7 +278,8 @@ abstract class $proxyApiBaseClassName { /// All generated Dart proxy classes should use this codec or extend it. This /// codec adds support to convert instances to their corresponding identifier /// from an `InstanceManager` and vice versa. -const String proxyApiBaseCodec = ''' +const String proxyApiBaseCodec = + ''' class $_proxyApiCodecName extends _PigeonCodec { const $_proxyApiCodecName(this.instanceManager); final $dartInstanceManagerClassName instanceManager; diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index 464750e928a..73ced7b3134 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -15,7 +15,7 @@ import 'generator.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '26.0.1'; +const String pigeonVersion = '26.1.0'; /// Read all the content from [stdin] to a String. String readStdin() { @@ -83,19 +83,17 @@ class Indent { }) { final List lines = input.split('\n'); - final int indentationToRemove = - !trimIndentation - ? 0 - : lines - .where((String line) => line.trim().isNotEmpty) - .map((String line) => line.length - line.trimLeft().length) - .reduce(min); + final int indentationToRemove = !trimIndentation + ? 0 + : lines + .where((String line) => line.trim().isNotEmpty) + .map((String line) => line.length - line.trimLeft().length) + .reduce(min); for (int i = 0; i < lines.length; ++i) { - final String line = - lines[i].length >= indentationToRemove - ? lines[i].substring(indentationToRemove) - : lines[i]; + final String line = lines[i].length >= indentationToRemove + ? lines[i].substring(indentationToRemove) + : lines[i]; if (i == 0 && !leadingSpace) { add(line.replaceAll('\t', tab)); @@ -279,10 +277,9 @@ HostDatatype _getHostDatatype( final String? datatype = builtinResolver(type); if (datatype == null) { if (type.isClass) { - final String customName = - customResolver != null - ? customResolver(type.baseName) - : type.baseName; + final String customName = customResolver != null + ? customResolver(type.baseName) + : type.baseName; return HostDatatype( datatype: customName, isBuiltin: false, @@ -290,10 +287,9 @@ HostDatatype _getHostDatatype( isEnum: false, ); } else if (type.isEnum) { - final String customName = - customResolver != null - ? customResolver(type.baseName) - : type.baseName; + final String customName = customResolver != null + ? customResolver(type.baseName) + : type.baseName; return HostDatatype( datatype: customName, isBuiltin: false, @@ -328,8 +324,9 @@ const String generatedCodeWarning = /// Warning printed at the top of all generated code. String getGeneratedCodeWarning() { - final String versionString = - includeVersionInGeneratedWarning ? ' (v$pigeonVersion)' : ''; + final String versionString = includeVersionInGeneratedWarning + ? ' (v$pigeonVersion)' + : ''; return 'Autogenerated from Pigeon$versionString, do not edit directly.'; } @@ -567,8 +564,9 @@ Map> getReferencedTypes( } } - final Set referencedTypeNames = - references.map.keys.map((TypeDeclaration e) => e.baseName).toSet(); + final Set referencedTypeNames = references.map.keys + .map((TypeDeclaration e) => e.baseName) + .toSet(); final List classesToCheck = List.from(referencedTypeNames); while (classesToCheck.isNotEmpty) { final String next = classesToCheck.removeLast(); diff --git a/packages/pigeon/lib/src/gobject/gobject_generator.dart b/packages/pigeon/lib/src/gobject/gobject_generator.dart index c9db9fb809e..103a2b0f905 100644 --- a/packages/pigeon/lib/src/gobject/gobject_generator.dart +++ b/packages/pigeon/lib/src/gobject/gobject_generator.dart @@ -561,10 +561,9 @@ class GObjectHeaderGenerator else 'Returns: a return value.', ], _docCommentSpec); - final String returnType = - _isNullablePrimitiveType(method.returnType) - ? '$primitiveType*' - : primitiveType; + final String returnType = _isNullablePrimitiveType(method.returnType) + ? '$primitiveType*' + : primitiveType; indent.writeln( '$returnType ${responseMethodPrefix}_get_return_value($responseClassName* response${_isNumericListType(method.returnType) ? ', size_t* return_value_length' : ''});', ); @@ -715,8 +714,9 @@ class GObjectHeaderGenerator '${className}ResponseHandle* response_handle', 'gpointer user_data', ]); - final String returnType = - method.isAsynchronous ? 'void' : '$responseClassName*'; + final String returnType = method.isAsynchronous + ? 'void' + : '$responseClassName*'; indent.writeln("$returnType (*$methodName)(${methodArgs.join(', ')});"); } }); @@ -1089,10 +1089,9 @@ class GObjectSourceGenerator final String customTypeId = _getCustomTypeId(module, customType); indent.newln(); - final String valueType = - customType.type == CustomTypes.customClass - ? '$customTypeName*' - : 'FlValue*'; + final String valueType = customType.type == CustomTypes.customClass + ? '$customTypeName*' + : 'FlValue*'; indent.writeScoped( 'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName($_standardCodecName* codec, GByteArray* buffer, $valueType value, GError** error) {', '}', @@ -1457,10 +1456,9 @@ class GObjectSourceGenerator ); indent.newln(); - final String returnType = - _isNullablePrimitiveType(method.returnType) - ? '$primitiveType*' - : primitiveType; + final String returnType = _isNullablePrimitiveType(method.returnType) + ? '$primitiveType*' + : primitiveType; indent.writeScoped( '$returnType ${responseMethodPrefix}_get_return_value($responseClassName* self${_isNumericListType(method.returnType) ? ', size_t* return_value_length' : ''}) {', '}', @@ -2442,20 +2440,17 @@ String _makeFlValue( } else if (type.baseName == 'void') { value = 'fl_value_new_null()'; } else if (type.baseName == 'bool') { - value = - type.isNullable - ? 'fl_value_new_bool(*$variableName)' - : 'fl_value_new_bool($variableName)'; + value = type.isNullable + ? 'fl_value_new_bool(*$variableName)' + : 'fl_value_new_bool($variableName)'; } else if (type.baseName == 'int') { - value = - type.isNullable - ? 'fl_value_new_int(*$variableName)' - : 'fl_value_new_int($variableName)'; + value = type.isNullable + ? 'fl_value_new_int(*$variableName)' + : 'fl_value_new_int($variableName)'; } else if (type.baseName == 'double') { - value = - type.isNullable - ? 'fl_value_new_float(*$variableName)' - : 'fl_value_new_float($variableName)'; + value = type.isNullable + ? 'fl_value_new_float(*$variableName)' + : 'fl_value_new_float($variableName)'; } else if (type.baseName == 'String') { value = 'fl_value_new_string($variableName)'; } else if (type.baseName == 'Uint8List') { diff --git a/packages/pigeon/lib/src/java/java_generator.dart b/packages/pigeon/lib/src/java/java_generator.dart index addbf487267..de675d73458 100644 --- a/packages/pigeon/lib/src/java/java_generator.dart +++ b/packages/pigeon/lib/src/java/java_generator.dart @@ -313,8 +313,9 @@ class JavaGenerator extends StructuredGenerator { field, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x), ); - final String nullability = - field.type.isNullable ? '@Nullable ' : '@NonNull '; + final String nullability = field.type.isNullable + ? '@Nullable ' + : '@NonNull '; addDocumentationComments( indent, field.documentationComments, @@ -405,10 +406,9 @@ class JavaGenerator extends StructuredGenerator { final Iterable nonArrayFieldNames = classDefinition.fields .where((NamedType field) => !_javaTypeIsArray(field.type)) .map((NamedType field) => field.name); - final String nonArrayHashValue = - nonArrayFieldNames.isNotEmpty - ? 'Objects.hash(${nonArrayFieldNames.join(', ')})' - : '0'; + final String nonArrayHashValue = nonArrayFieldNames.isNotEmpty + ? 'Objects.hash(${nonArrayFieldNames.join(', ')})' + : '0'; if (arrayFieldNames.isEmpty) { // Return directly if there are no array variables, to avoid redundant @@ -444,8 +444,9 @@ class JavaGenerator extends StructuredGenerator { field, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x), ); - final String nullability = - field.type.isNullable ? '@Nullable' : '@NonNull'; + final String nullability = field.type.isNullable + ? '@Nullable' + : '@NonNull'; indent.newln(); indent.writeln( 'private @Nullable ${hostDatatype.datatype} ${field.name};', @@ -543,24 +544,24 @@ class JavaGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); void writeEncodeLogic(EnumeratedType customType) { - final String encodeString = - customType.type == CustomTypes.customClass ? 'toList()' : 'index'; - final String nullCheck = - customType.type == CustomTypes.customEnum - ? 'value == null ? null : ' - : ''; - final String valueString = - customType.enumeration < maximumCodecFieldKey - ? '$nullCheck((${customType.name}) value).$encodeString' - : 'wrap.toList()'; - final int enumeration = - customType.enumeration < maximumCodecFieldKey - ? customType.enumeration - : maximumCodecFieldKey; + final String encodeString = customType.type == CustomTypes.customClass + ? 'toList()' + : 'index'; + final String nullCheck = customType.type == CustomTypes.customEnum + ? 'value == null ? null : ' + : ''; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? '$nullCheck((${customType.name}) value).$encodeString' + : 'wrap.toList()'; + final int enumeration = customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; indent.add('if (value instanceof ${customType.name}) '); indent.addScoped('{', '} else ', () { @@ -800,10 +801,9 @@ if (wrapped == null) { for (final Method func in api.methods) { final String resultType = _getResultType(func.returnType); - final String returnType = - func.returnType.isVoid - ? 'Void' - : _javaTypeForDartType(func.returnType); + final String returnType = func.returnType.isVoid + ? 'Void' + : _javaTypeForDartType(func.returnType); String sendArgument; addDocumentationComments( indent, @@ -1008,8 +1008,8 @@ if (wrapped == null) { dartPackageName: dartPackageName, serialBackgroundQueue: method.taskQueueType == TaskQueueType.serialBackgroundThread - ? serialBackgroundQueue - : null, + ? serialBackgroundQueue + : null, ); } }); @@ -1027,14 +1027,12 @@ if (wrapped == null) { final Method method, ) { final String resultType = _getResultType(method.returnType); - final String nullableType = - method.isAsynchronous - ? '' - : _nullabilityAnnotationFromType(method.returnType); - final String returnType = - method.isAsynchronous - ? 'void' - : _javaTypeForDartType(method.returnType); + final String nullableType = method.isAsynchronous + ? '' + : _nullabilityAnnotationFromType(method.returnType); + final String returnType = method.isAsynchronous + ? 'void' + : _javaTypeForDartType(method.returnType); final List argSignature = []; if (method.parameters.isNotEmpty) { final Iterable argTypes = method.parameters.map( @@ -1100,10 +1098,9 @@ if (wrapped == null) { indent.nest(2, () { indent.write('(message, reply) -> '); indent.addScoped('{', '});', () { - final String returnType = - method.returnType.isVoid - ? 'Void' - : _javaTypeForDartType(method.returnType); + final String returnType = method.returnType.isVoid + ? 'Void' + : _javaTypeForDartType(method.returnType); indent.writeln('ArrayList wrapped = new ArrayList<>();'); final List methodArgument = []; if (method.parameters.isNotEmpty) { @@ -1123,13 +1120,16 @@ if (wrapped == null) { }); } if (method.isAsynchronous) { - final String resultValue = - method.returnType.isVoid ? 'null' : 'result'; + final String resultValue = method.returnType.isVoid + ? 'null' + : 'result'; final String resultType = _getResultType(method.returnType); - final String resultParam = - method.returnType.isVoid ? '' : '$returnType result'; - final String addResultArg = - method.returnType.isVoid ? 'null' : resultValue; + final String resultParam = method.returnType.isVoid + ? '' + : '$returnType result'; + final String addResultArg = method.returnType.isVoid + ? 'null' + : resultValue; const String resultName = 'resultCallback'; indent.format(''' $resultType $resultName = diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 79801c4239e..40fc5ee5880 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -342,10 +342,9 @@ class KotlinGenerator extends StructuredGenerator { }) { final String privateString = private ? 'private ' : ''; final String classType = classDefinition.isSealed ? 'sealed' : 'data'; - final String inheritance = - classDefinition.superClass != null - ? ' : ${classDefinition.superClassName}()' - : ''; + final String inheritance = classDefinition.superClass != null + ? ' : ${classDefinition.superClassName}()' + : ''; indent.write('$privateString$classType class ${classDefinition.name} '); if (classDefinition.isSealed) { return; @@ -419,8 +418,8 @@ class KotlinGenerator extends StructuredGenerator { )) { final String comma = getFieldsInSerializationOrder(classDefinition).last == field - ? '' - : ', '; + ? '' + : ', '; indent.add('${field.name}$comma'); } indent.addln(')'); @@ -470,20 +469,21 @@ class KotlinGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); void writeEncodeLogic(EnumeratedType customType) { - final String encodeString = - customType.type == CustomTypes.customClass ? 'toList()' : 'raw'; - final String valueString = - customType.enumeration < maximumCodecFieldKey - ? 'value.$encodeString' - : 'wrap.toList()'; - final int enumeration = - customType.enumeration < maximumCodecFieldKey - ? customType.enumeration - : maximumCodecFieldKey; + final String encodeString = customType.type == CustomTypes.customClass + ? 'toList()' + : 'raw'; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? 'value.$encodeString' + : 'wrap.toList()'; + final int enumeration = customType.enumeration < maximumCodecFieldKey + ? customType.enumeration + : maximumCodecFieldKey; indent.writeScoped('is ${customType.name} -> {', '}', () { if (customType.enumeration >= maximumCodecFieldKey) { indent.writeln( @@ -701,26 +701,27 @@ if (wrapped == null) { channelName: makeChannelName(api, method, dartPackageName), documentationComments: method.documentationComments, dartPackageName: dartPackageName, - onWriteBody: ( - Indent indent, { - required InternalKotlinOptions generatorOptions, - required List parameters, - required TypeDeclaration returnType, - required String channelName, - required String errorClassName, - }) { - indent.writeln( - r'val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""', - ); - _writeFlutterMethodMessageCall( - indent, - generatorOptions: generatorOptions, - parameters: parameters, - returnType: returnType, - channelName: '$channelName\$separatedMessageChannelSuffix', - errorClassName: errorClassName, - ); - }, + onWriteBody: + ( + Indent indent, { + required InternalKotlinOptions generatorOptions, + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeln( + r'val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""', + ); + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + parameters: parameters, + returnType: returnType, + channelName: '$channelName\$separatedMessageChannelSuffix', + errorClassName: errorClassName, + ); + }, ); } }); @@ -812,8 +813,8 @@ if (wrapped == null) { isAsynchronous: method.isAsynchronous, serialBackgroundQueue: method.taskQueueType == TaskQueueType.serialBackgroundThread - ? serialBackgroundQueue - : null, + ? serialBackgroundQueue + : null, ); } }); @@ -888,12 +889,10 @@ if (wrapped == null) { ], returnType: const TypeDeclaration.voidDeclaration(), setHandlerCondition: setHandlerCondition, - onCreateCall: ( - List safeArgNames, { - required String apiVarName, - }) { - return 'instanceManager.remove(${safeArgNames.single})'; - }, + onCreateCall: + (List safeArgNames, {required String apiVarName}) { + return 'instanceManager.remove(${safeArgNames.single})'; + }, ); _writeHostMethodMessageHandler( indent, @@ -904,12 +903,10 @@ if (wrapped == null) { parameters: [], returnType: const TypeDeclaration.voidDeclaration(), setHandlerCondition: setHandlerCondition, - onCreateCall: ( - List safeArgNames, { - required String apiVarName, - }) { - return 'instanceManager.clear()'; - }, + onCreateCall: + (List safeArgNames, {required String apiVarName}) { + return 'instanceManager.clear()'; + }, ); }, ); @@ -940,8 +937,8 @@ if (wrapped == null) { Root root, Indent indent, ) { - final Iterable allProxyApis = - root.apis.whereType(); + final Iterable allProxyApis = root.apis + .whereType(); _writeProxyApiRegistrar( indent, @@ -1036,10 +1033,9 @@ if (wrapped == null) { api.kotlinOptions?.fullClassName ?? api.name; final int? minApi = api.kotlinOptions?.minAndroidApi; - final String versionCheck = - minApi != null - ? 'android.os.Build.VERSION.SDK_INT >= $minApi && ' - : ''; + final String versionCheck = minApi != null + ? 'android.os.Build.VERSION.SDK_INT >= $minApi && ' + : ''; indent.format(''' ${index > 0 ? ' else ' : ''}if (${versionCheck}value is $className) { @@ -1079,8 +1075,9 @@ if (wrapped == null) { ); indent.writeln('@Suppress("UNCHECKED_CAST")'); // The API only needs to be abstract if there are methods to override. - final String classModifier = - api.hasMethodsRequiringImplementation() ? 'abstract' : 'open'; + final String classModifier = api.hasMethodsRequiringImplementation() + ? 'abstract' + : 'open'; indent.writeScoped( '$classModifier class $kotlinApiName(open val pigeonRegistrar: ${proxyApiRegistrarName(generatorOptions)}) {', '}', @@ -1392,8 +1389,9 @@ fun deepEquals(a: Any?, b: Any?): Boolean { ); } - final String returnTypeString = - returnType.isVoid ? '' : _nullSafeKotlinTypeForDartType(returnType); + final String returnTypeString = returnType.isVoid + ? '' + : _nullSafeKotlinTypeForDartType(returnType); final String resultType = returnType.isVoid ? 'Unit' : returnTypeString; addDocumentationComments(indent, documentationComments, _docCommentSpec); @@ -1467,16 +1465,14 @@ fun deepEquals(a: Any?, b: Any?): Boolean { methodArguments.add(argName); }); } - final String call = - onCreateCall != null - ? onCreateCall(methodArguments, apiVarName: 'api') - : 'api.$name(${methodArguments.join(', ')})'; + final String call = onCreateCall != null + ? onCreateCall(methodArguments, apiVarName: 'api') + : 'api.$name(${methodArguments.join(', ')})'; if (isAsynchronous) { - final String resultType = - returnType.isVoid - ? 'Unit' - : _nullSafeKotlinTypeForDartType(returnType); + final String resultType = returnType.isVoid + ? 'Unit' + : _nullSafeKotlinTypeForDartType(returnType); indent.write(methodArguments.isNotEmpty ? '$call ' : 'api.$name'); indent.addScoped('{ result: Result<$resultType> ->', '}', () { indent.writeln('val error = result.exceptionOrNull()'); @@ -1751,19 +1747,17 @@ fun deepEquals(a: Any?, b: Any?): Boolean { for (final Constructor constructor in api.constructors) { _writeMethodDeclaration( indent, - name: - constructor.name.isNotEmpty - ? constructor.name - : '${classMemberNamePrefix}defaultConstructor', + name: constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor', returnType: apiAsTypeDeclaration, documentationComments: constructor.documentationComments, - minApiRequirement: - _findAndroidHighestApiRequirement([ - apiAsTypeDeclaration, - ...constructor.parameters.map( - (Parameter parameter) => parameter.type, - ), - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + ...constructor.parameters.map( + (Parameter parameter) => parameter.type, + ), + ])?.version, isAbstract: true, parameters: [ ...api.unattachedFields.map((ApiField field) { @@ -1789,11 +1783,10 @@ fun deepEquals(a: Any?, b: Any?): Boolean { documentationComments: field.documentationComments, returnType: field.type, isAbstract: true, - minApiRequirement: - _findAndroidHighestApiRequirement([ - apiAsTypeDeclaration, - field.type, - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + field.type, + ])?.version, parameters: [ if (!field.isStatic) Parameter( @@ -1819,11 +1812,10 @@ fun deepEquals(a: Any?, b: Any?): Boolean { documentationComments: field.documentationComments, returnType: field.type, isAbstract: true, - minApiRequirement: - _findAndroidHighestApiRequirement([ - apiAsTypeDeclaration, - field.type, - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + field.type, + ])?.version, parameters: [ Parameter( name: '${classMemberNamePrefix}instance', @@ -1850,12 +1842,11 @@ fun deepEquals(a: Any?, b: Any?): Boolean { documentationComments: method.documentationComments, isAsynchronous: method.isAsynchronous, isAbstract: true, - minApiRequirement: - _findAndroidHighestApiRequirement([ - if (!method.isStatic) apiAsTypeDeclaration, - method.returnType, - ...method.parameters.map((Parameter p) => p.type), - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + if (!method.isStatic) apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter p) => p.type), + ])?.version, parameters: [ if (!method.isStatic) Parameter( @@ -1933,10 +1924,9 @@ fun deepEquals(a: Any?, b: Any?): Boolean { } for (final Constructor constructor in api.constructors) { - final String name = - constructor.name.isNotEmpty - ? constructor.name - : '${classMemberNamePrefix}defaultConstructor'; + final String name = constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor'; final String channelName = makeChannelNameWithStrings( apiName: api.name, methodName: name, @@ -1957,13 +1947,14 @@ fun deepEquals(a: Any?, b: Any?): Boolean { channelName: channelName, taskQueueType: TaskQueueType.serial, returnType: const TypeDeclaration.voidDeclaration(), - onCreateCall: ( - List methodParameters, { - required String apiVarName, - }) { - return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' - '$apiVarName.$name(${methodParameters.skip(1).join(',')}), ${methodParameters.first})'; - }, + onCreateCall: + ( + List methodParameters, { + required String apiVarName, + }) { + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + '$apiVarName.$name(${methodParameters.skip(1).join(',')}), ${methodParameters.first})'; + }, parameters: [ Parameter( name: '${classMemberNamePrefix}identifier', @@ -1999,15 +1990,17 @@ fun deepEquals(a: Any?, b: Any?): Boolean { channelName: channelName, taskQueueType: TaskQueueType.serial, returnType: const TypeDeclaration.voidDeclaration(), - onCreateCall: ( - List methodParameters, { - required String apiVarName, - }) { - final String param = - methodParameters.length > 1 ? methodParameters.first : ''; - return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' - '$apiVarName.${field.name}($param), ${methodParameters.last})'; - }, + onCreateCall: + ( + List methodParameters, { + required String apiVarName, + }) { + final String param = methodParameters.length > 1 + ? methodParameters.first + : ''; + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + '$apiVarName.${field.name}($param), ${methodParameters.last})'; + }, parameters: [ if (!field.isStatic) Parameter( @@ -2092,11 +2085,10 @@ fun deepEquals(a: Any?, b: Any?): Boolean { methodName: newInstanceMethodName, dartPackageName: dartPackageName, ), - minApiRequirement: - _findAndroidHighestApiRequirement([ - apiAsTypeDeclaration, - ...api.unattachedFields.map((ApiField field) => field.type), - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + ...api.unattachedFields.map((ApiField field) => field.type), + ])?.version, dartPackageName: dartPackageName, parameters: [ Parameter( @@ -2108,75 +2100,81 @@ fun deepEquals(a: Any?, b: Any?): Boolean { ), ), ], - onWriteBody: ( - Indent indent, { - required InternalKotlinOptions generatorOptions, - required List parameters, - required TypeDeclaration returnType, - required String channelName, - required String errorClassName, - }) { - indent.writeScoped('if (pigeonRegistrar.ignoreCallsToDart) {', '}', () { - indent.format( - ''' + onWriteBody: + ( + Indent indent, { + required InternalKotlinOptions generatorOptions, + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeScoped( + 'if (pigeonRegistrar.ignoreCallsToDart) {', + '}', + () { + indent.format( + ''' callback( Result.failure( $errorClassName("ignore-calls-error", "Calls to Dart are being ignored.", "")))''', - ); - }, addTrailingNewline: false); - indent.writeScoped( - ' else if (pigeonRegistrar.instanceManager.containsInstance(${classMemberNamePrefix}instanceArg)) {', - '}', - () { - indent.writeln('callback(Result.success(Unit))'); - }, - addTrailingNewline: false, - ); - indent.writeScoped(' else {', '}', () { - if (api.hasCallbackConstructor()) { - indent.writeln( - 'val ${classMemberNamePrefix}identifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(${classMemberNamePrefix}instanceArg)', - ); - enumerate(api.unattachedFields, (int index, ApiField field) { - final String argName = _getSafeArgumentName(index, field); - indent.writeln( - 'val $argName = ${field.name}(${classMemberNamePrefix}instanceArg)', - ); - }); - - indent.writeln( - 'val binaryMessenger = pigeonRegistrar.binaryMessenger', + ); + }, + addTrailingNewline: false, ); - indent.writeln('val codec = pigeonRegistrar.codec'); - _writeFlutterMethodMessageCall( - indent, - generatorOptions: generatorOptions, - returnType: returnType, - channelName: channelName, - errorClassName: errorClassName, - parameters: [ - Parameter( - name: '${classMemberNamePrefix}identifier', - type: const TypeDeclaration( - baseName: 'int', - isNullable: false, - ), - ), - ...api.unattachedFields.map((ApiField field) { - return Parameter(name: field.name, type: field.type); - }), - ], + indent.writeScoped( + ' else if (pigeonRegistrar.instanceManager.containsInstance(${classMemberNamePrefix}instanceArg)) {', + '}', + () { + indent.writeln('callback(Result.success(Unit))'); + }, + addTrailingNewline: false, ); - } else { - indent.format( - ''' + indent.writeScoped(' else {', '}', () { + if (api.hasCallbackConstructor()) { + indent.writeln( + 'val ${classMemberNamePrefix}identifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(${classMemberNamePrefix}instanceArg)', + ); + enumerate(api.unattachedFields, (int index, ApiField field) { + final String argName = _getSafeArgumentName(index, field); + indent.writeln( + 'val $argName = ${field.name}(${classMemberNamePrefix}instanceArg)', + ); + }); + + indent.writeln( + 'val binaryMessenger = pigeonRegistrar.binaryMessenger', + ); + indent.writeln('val codec = pigeonRegistrar.codec'); + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + returnType: returnType, + channelName: channelName, + errorClassName: errorClassName, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}identifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...api.unattachedFields.map((ApiField field) { + return Parameter(name: field.name, type: field.type); + }), + ], + ); + } else { + indent.format( + ''' callback( Result.failure( $errorClassName("new-instance-error", "Attempting to create a new Dart instance of ${api.name}, but the class has a nonnull callback method.", "")))''', - ); - } - }); - }, + ); + } + }); + }, ); indent.newln(); } @@ -2198,12 +2196,11 @@ fun deepEquals(a: Any?, b: Any?): Boolean { channelName: makeChannelName(api, method, dartPackageName), dartPackageName: dartPackageName, documentationComments: method.documentationComments, - minApiRequirement: - _findAndroidHighestApiRequirement([ - apiAsTypeDeclaration, - method.returnType, - ...method.parameters.map((Parameter parameter) => parameter.type), - ])?.version, + minApiRequirement: _findAndroidHighestApiRequirement([ + apiAsTypeDeclaration, + method.returnType, + ...method.parameters.map((Parameter parameter) => parameter.type), + ])?.version, parameters: [ Parameter( name: '${classMemberNamePrefix}instance', @@ -2215,38 +2212,39 @@ fun deepEquals(a: Any?, b: Any?): Boolean { ), ...method.parameters, ], - onWriteBody: ( - Indent indent, { - required InternalKotlinOptions generatorOptions, - required List parameters, - required TypeDeclaration returnType, - required String channelName, - required String errorClassName, - }) { - indent.writeScoped( - 'if (pigeonRegistrar.ignoreCallsToDart) {', - '}', - () { - indent.format(''' + onWriteBody: + ( + Indent indent, { + required InternalKotlinOptions generatorOptions, + required List parameters, + required TypeDeclaration returnType, + required String channelName, + required String errorClassName, + }) { + indent.writeScoped( + 'if (pigeonRegistrar.ignoreCallsToDart) {', + '}', + () { + indent.format(''' callback( Result.failure( $errorClassName("ignore-calls-error", "Calls to Dart are being ignored.", ""))) return'''); + }, + ); + indent.writeln( + 'val binaryMessenger = pigeonRegistrar.binaryMessenger', + ); + indent.writeln('val codec = pigeonRegistrar.codec'); + _writeFlutterMethodMessageCall( + indent, + generatorOptions: generatorOptions, + returnType: returnType, + channelName: channelName, + errorClassName: errorClassName, + parameters: parameters, + ); }, - ); - indent.writeln( - 'val binaryMessenger = pigeonRegistrar.binaryMessenger', - ); - indent.writeln('val codec = pigeonRegistrar.codec'); - _writeFlutterMethodMessageCall( - indent, - generatorOptions: generatorOptions, - returnType: returnType, - channelName: channelName, - errorClassName: errorClassName, - parameters: parameters, - ); - }, ); indent.newln(); } diff --git a/packages/pigeon/lib/src/objc/objc_generator.dart b/packages/pigeon/lib/src/objc/objc_generator.dart index 8af4ed31742..57ca9840e3f 100644 --- a/packages/pigeon/lib/src/objc/objc_generator.dart +++ b/packages/pigeon/lib/src/objc/objc_generator.dart @@ -810,8 +810,10 @@ if (self.wrapped == nil) { required String dartPackageName, }) { const String codecName = 'PigeonCodec'; - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); final String readerWriterName = '${generatorOptions.prefix}${toUpperCamelCase(generatorOptions.fileSpecificClassNameComponent ?? '')}${codecName}ReaderWriter'; final String readerName = @@ -868,22 +870,19 @@ if (self.wrapped == nil) { indent.addScoped('{', '}', () { indent.write(''); for (final EnumeratedType customType in enumeratedTypes) { - final String encodeString = - customType.type == CustomTypes.customClass - ? '[value toList]' - : '(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])'; - final String valueString = - customType.enumeration < maximumCodecFieldKey - ? encodeString - : '[wrap toList]'; - final String className = - customType.type == CustomTypes.customClass - ? _className(generatorOptions.prefix, customType.name) - : _enumName( - customType.name, - prefix: generatorOptions.prefix, - box: true, - ); + final String encodeString = customType.type == CustomTypes.customClass + ? '[value toList]' + : '(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])'; + final String valueString = customType.enumeration < maximumCodecFieldKey + ? encodeString + : '[wrap toList]'; + final String className = customType.type == CustomTypes.customClass + ? _className(generatorOptions.prefix, customType.name) + : _enumName( + customType.name, + prefix: generatorOptions.prefix, + box: true, + ); indent.addScoped( 'if ([value isKindOfClass:[$className class]]) {', '} else ', @@ -893,8 +892,8 @@ if (self.wrapped == nil) { } final int enumeration = customType.enumeration < maximumCodecFieldKey - ? customType.enumeration - : maximumCodecFieldKey; + ? customType.enumeration + : maximumCodecFieldKey; if (customType.enumeration >= maximumCodecFieldKey) { indent.writeln( '${_className(generatorOptions.prefix, _overflowClassName)} *wrap = [${_className(generatorOptions.prefix, _overflowClassName)} makeWithType:${customType.enumeration - maximumCodecFieldKey} wrapped:$encodeString];', @@ -1234,8 +1233,9 @@ static FlutterError *createConnectionError(NSString *channelName) { } // TODO(gaaclarke): Incorporate this into _getSelectorComponents. - final String lastSelectorComponent = - func.isAsynchronous ? 'completion' : 'error'; + final String lastSelectorComponent = func.isAsynchronous + ? 'completion' + : 'error'; final String selector = _getSelector(func, lastSelectorComponent); indent.writeln( 'NSCAssert([api respondsToSelector:@selector($selector)], @"$apiName api (%@) doesn\'t respond to @selector($selector)", api);', @@ -1271,10 +1271,9 @@ static FlutterError *createConnectionError(NSString *channelName) { if (func.isAsynchronous) { writeAsyncBindings(selectorComponents, callSignature, returnType); } else { - final String syncCall = - func.parameters.isEmpty - ? '[api ${selectorComponents.first}:&error]' - : '[api $callSignature error:&error]'; + final String syncCall = func.parameters.isEmpty + ? '[api ${selectorComponents.first}:&error]' + : '[api $callSignature error:&error]'; writeSyncBindings(syncCall, returnType); } }); @@ -1504,25 +1503,22 @@ void _writeObjcSourceClassInitializerDeclaration( classDefinition, )) { final String label = isFirst ? _capitalize(field.name) : field.name; - final void Function(String) printer = - isFirst - ? indent.add - : (String x) { - indent.newln(); - indent.write(x); - }; + final void Function(String) printer = isFirst + ? indent.add + : (String x) { + indent.newln(); + indent.write(x); + }; isFirst = false; final HostDatatype hostDatatype = getFieldHostDatatype( field, (TypeDeclaration x) => _objcTypeStringForPrimitiveDartType(prefix, x, beforeString: true), - customResolver: - field.type.isEnum - ? (String x) => - field.type.isNullable - ? _enumName(x, suffix: ' *', prefix: prefix, box: true) - : _enumName(x, prefix: prefix) - : (String x) => '${_className(prefix, x)} *', + customResolver: field.type.isEnum + ? (String x) => field.type.isNullable + ? _enumName(x, suffix: ' *', prefix: prefix, box: true) + : _enumName(x, prefix: prefix) + : (String x) => '${_className(prefix, x)} *', ); final String nullable = field.type.isNullable ? 'nullable ' : ''; printer('$label:($nullable${hostDatatype.datatype})${field.name}'); @@ -1692,15 +1688,13 @@ String? _objcTypeStringForPrimitiveDartType( }) { final _ObjcType? objcType; if (forceBox || type.isNullable) { - objcType = - _objcTypeForNullableDartTypeMap.containsKey(type.baseName) - ? _objcTypeForDartType(classPrefix, type) - : null; + objcType = _objcTypeForNullableDartTypeMap.containsKey(type.baseName) + ? _objcTypeForDartType(classPrefix, type) + : null; } else { - objcType = - _objcTypeForNonNullableDartTypeMap.containsKey(type.baseName) - ? _objcTypeForDartType(classPrefix, type) - : null; + objcType = _objcTypeForNonNullableDartTypeMap.containsKey(type.baseName) + ? _objcTypeForDartType(classPrefix, type) + : null; } return beforeString ? objcType?.beforeString : objcType?.toString(); } @@ -1718,16 +1712,16 @@ _ObjcType _objcTypeForDartType( ); return primitiveType == null ? _ObjcType( - baseName: _className(classPrefix, field.baseName), - // Non-nullable enums are non-pointer types. - isPointer: !field.isEnum || (field.isNullable || forceBox), - ) + baseName: _className(classPrefix, field.baseName), + // Non-nullable enums are non-pointer types. + isPointer: !field.isEnum || (field.isNullable || forceBox), + ) : field.typeArguments.isEmpty ? primitiveType : _ObjcType( - baseName: - '${primitiveType.baseName}<${_flattenTypeArguments(classPrefix, field.typeArguments)}>', - ); + baseName: + '${primitiveType.baseName}<${_flattenTypeArguments(classPrefix, field.typeArguments)}>', + ); } /// Maps a type to a properties memory semantics (ie strong, copy). @@ -1775,8 +1769,8 @@ Iterable _getSelectorComponents( final bool hasArguments = it.moveNext(); final String namePostfix = (lastSelectorComponent.isNotEmpty && func.parameters.isEmpty) - ? 'With${_capitalize(lastSelectorComponent)}' - : ''; + ? 'With${_capitalize(lastSelectorComponent)}' + : ''; yield '${func.name}${hasArguments ? _capitalize(func.parameters[0].name) : namePostfix}'; while (it.moveNext()) { yield it.current.name; @@ -1991,10 +1985,9 @@ void _writeDataClassDeclaration( field, (TypeDeclaration x) => _objcTypeStringForPrimitiveDartType(prefix, x, beforeString: true), - customResolver: - field.type.isEnum - ? (String x) => _enumName(x, prefix: prefix) - : (String x) => '${_className(prefix, x)} *', + customResolver: field.type.isEnum + ? (String x) => _enumName(x, prefix: prefix) + : (String x) => '${_className(prefix, x)} *', ); late final String propertyType; addDocumentationComments( @@ -2008,15 +2001,14 @@ void _writeDataClassDeclaration( isEnum: field.type.isEnum, ); final String nullability = field.type.isNullable ? ', nullable' : ''; - final String fieldType = - field.type.isEnum && field.type.isNullable - ? _enumName( - field.type.baseName, - suffix: ' *', - prefix: generatorOptions.prefix, - box: field.type.isNullable, - ) - : hostDatatype.datatype; + final String fieldType = field.type.isEnum && field.type.isNullable + ? _enumName( + field.type.baseName, + suffix: ' *', + prefix: generatorOptions.prefix, + box: field.type.isNullable, + ) + : hostDatatype.datatype; indent.writeln( '@property(nonatomic, $propertyType$nullability) $fieldType ${field.name};', ); diff --git a/packages/pigeon/lib/src/pigeon_lib.dart b/packages/pigeon/lib/src/pigeon_lib.dart index 48b6047ff03..cf6ba310190 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -343,47 +343,36 @@ class PigeonOptions { dartTestOut: map['dartTestOut'] as String?, objcHeaderOut: map['objcHeaderOut'] as String?, objcSourceOut: map['objcSourceOut'] as String?, - objcOptions: - map.containsKey('objcOptions') - ? ObjcOptions.fromMap(map['objcOptions']! as Map) - : null, + objcOptions: map.containsKey('objcOptions') + ? ObjcOptions.fromMap(map['objcOptions']! as Map) + : null, javaOut: map['javaOut'] as String?, - javaOptions: - map.containsKey('javaOptions') - ? JavaOptions.fromMap(map['javaOptions']! as Map) - : null, + javaOptions: map.containsKey('javaOptions') + ? JavaOptions.fromMap(map['javaOptions']! as Map) + : null, swiftOut: map['swiftOut'] as String?, - swiftOptions: - map.containsKey('swiftOptions') - ? SwiftOptions.fromList( - map['swiftOptions']! as Map, - ) - : null, + swiftOptions: map.containsKey('swiftOptions') + ? SwiftOptions.fromList(map['swiftOptions']! as Map) + : null, kotlinOut: map['kotlinOut'] as String?, - kotlinOptions: - map.containsKey('kotlinOptions') - ? KotlinOptions.fromMap( - map['kotlinOptions']! as Map, - ) - : null, + kotlinOptions: map.containsKey('kotlinOptions') + ? KotlinOptions.fromMap(map['kotlinOptions']! as Map) + : null, cppHeaderOut: map['cppHeaderOut'] as String?, cppSourceOut: map['cppSourceOut'] as String?, - cppOptions: - map.containsKey('cppOptions') - ? CppOptions.fromMap(map['cppOptions']! as Map) - : null, + cppOptions: map.containsKey('cppOptions') + ? CppOptions.fromMap(map['cppOptions']! as Map) + : null, gobjectHeaderOut: map['gobjectHeaderOut'] as String?, gobjectSourceOut: map['gobjectSourceOut'] as String?, - gobjectOptions: - map.containsKey('gobjectOptions') - ? GObjectOptions.fromMap( - map['gobjectOptions']! as Map, - ) - : null, - dartOptions: - map.containsKey('dartOptions') - ? DartOptions.fromMap(map['dartOptions']! as Map) - : null, + gobjectOptions: map.containsKey('gobjectOptions') + ? GObjectOptions.fromMap( + map['gobjectOptions']! as Map, + ) + : null, + dartOptions: map.containsKey('dartOptions') + ? DartOptions.fromMap(map['dartOptions']! as Map) + : null, copyrightHeader: map['copyrightHeader'] as String?, astOut: map['astOut'] as String?, debugGenerators: map['debugGenerators'] as bool?, @@ -516,115 +505,113 @@ options: ${_argParser.usage}'''; } - static final ArgParser _argParser = - ArgParser() - ..addOption('input', help: 'REQUIRED: Path to pigeon file.') - ..addOption( - 'dart_out', - help: - 'Path to generated Dart source file (.dart). ' - 'Required if one_language is not specified.', - ) - ..addOption( - 'dart_test_out', - help: - 'Path to generated library for Dart tests, when using ' - '@HostApi(dartHostTestHandler:).', - ) - ..addOption( - 'objc_source_out', - help: 'Path to generated Objective-C source file (.m).', - ) - ..addOption('java_out', help: 'Path to generated Java file (.java).') - ..addOption( - 'java_package', - help: 'The package that generated Java code will be in.', - ) - ..addFlag( - 'java_use_generated_annotation', - help: 'Adds the java.annotation.Generated annotation to the output.', - ) - ..addOption( - 'swift_out', - help: 'Path to generated Swift file (.swift).', - aliases: const ['experimental_swift_out'], - ) - ..addOption( - 'kotlin_out', - help: 'Path to generated Kotlin file (.kt).', - aliases: const ['experimental_kotlin_out'], - ) - ..addOption( - 'kotlin_package', - help: 'The package that generated Kotlin code will be in.', - aliases: const ['experimental_kotlin_package'], - ) - ..addOption( - 'cpp_header_out', - help: 'Path to generated C++ header file (.h).', - aliases: const ['experimental_cpp_header_out'], - ) - ..addOption( - 'cpp_source_out', - help: 'Path to generated C++ classes file (.cpp).', - aliases: const ['experimental_cpp_source_out'], - ) - ..addOption( - 'cpp_namespace', - help: 'The namespace that generated C++ code will be in.', - ) - ..addOption( - 'gobject_header_out', - help: 'Path to generated GObject header file (.h).', - aliases: const ['experimental_gobject_header_out'], - ) - ..addOption( - 'gobject_source_out', - help: 'Path to generated GObject classes file (.cc).', - aliases: const ['experimental_gobject_source_out'], - ) - ..addOption( - 'gobject_module', - help: 'The module that generated GObject code will be in.', - ) - ..addOption( - 'objc_header_out', - help: 'Path to generated Objective-C header file (.h).', - ) - ..addOption( - 'objc_prefix', - help: 'Prefix for generated Objective-C classes and protocols.', - ) - ..addOption( - 'copyright_header', - help: - 'Path to file with copyright header to be prepended to generated code.', - ) - ..addFlag( - 'one_language', - hide: true, - help: 'Does nothing, only here to avoid breaking changes', - ) - ..addOption( - 'ast_out', - help: - 'Path to generated AST debugging info. (Warning: format subject to change)', - ) - ..addFlag( - 'debug_generators', - help: - 'Print the line number of the generator in comments at newlines.', - ) - ..addOption( - 'base_path', - help: - 'A base path to be prefixed to all outputs and copyright header path. Generally used for testing', - hide: true, - ) - ..addOption( - 'package_name', - help: 'The package that generated code will be in.', - ); + static final ArgParser _argParser = ArgParser() + ..addOption('input', help: 'REQUIRED: Path to pigeon file.') + ..addOption( + 'dart_out', + help: + 'Path to generated Dart source file (.dart). ' + 'Required if one_language is not specified.', + ) + ..addOption( + 'dart_test_out', + help: + 'Path to generated library for Dart tests, when using ' + '@HostApi(dartHostTestHandler:).', + ) + ..addOption( + 'objc_source_out', + help: 'Path to generated Objective-C source file (.m).', + ) + ..addOption('java_out', help: 'Path to generated Java file (.java).') + ..addOption( + 'java_package', + help: 'The package that generated Java code will be in.', + ) + ..addFlag( + 'java_use_generated_annotation', + help: 'Adds the java.annotation.Generated annotation to the output.', + ) + ..addOption( + 'swift_out', + help: 'Path to generated Swift file (.swift).', + aliases: const ['experimental_swift_out'], + ) + ..addOption( + 'kotlin_out', + help: 'Path to generated Kotlin file (.kt).', + aliases: const ['experimental_kotlin_out'], + ) + ..addOption( + 'kotlin_package', + help: 'The package that generated Kotlin code will be in.', + aliases: const ['experimental_kotlin_package'], + ) + ..addOption( + 'cpp_header_out', + help: 'Path to generated C++ header file (.h).', + aliases: const ['experimental_cpp_header_out'], + ) + ..addOption( + 'cpp_source_out', + help: 'Path to generated C++ classes file (.cpp).', + aliases: const ['experimental_cpp_source_out'], + ) + ..addOption( + 'cpp_namespace', + help: 'The namespace that generated C++ code will be in.', + ) + ..addOption( + 'gobject_header_out', + help: 'Path to generated GObject header file (.h).', + aliases: const ['experimental_gobject_header_out'], + ) + ..addOption( + 'gobject_source_out', + help: 'Path to generated GObject classes file (.cc).', + aliases: const ['experimental_gobject_source_out'], + ) + ..addOption( + 'gobject_module', + help: 'The module that generated GObject code will be in.', + ) + ..addOption( + 'objc_header_out', + help: 'Path to generated Objective-C header file (.h).', + ) + ..addOption( + 'objc_prefix', + help: 'Prefix for generated Objective-C classes and protocols.', + ) + ..addOption( + 'copyright_header', + help: + 'Path to file with copyright header to be prepended to generated code.', + ) + ..addFlag( + 'one_language', + hide: true, + help: 'Does nothing, only here to avoid breaking changes', + ) + ..addOption( + 'ast_out', + help: + 'Path to generated AST debugging info. (Warning: format subject to change)', + ) + ..addFlag( + 'debug_generators', + help: 'Print the line number of the generator in comments at newlines.', + ) + ..addOption( + 'base_path', + help: + 'A base path to be prefixed to all outputs and copyright header path. Generally used for testing', + hide: true, + ) + ..addOption( + 'package_name', + help: 'The package that generated code will be in.', + ); /// Convert command-line arguments to [PigeonOptions]. static PigeonOptions parseArgs(List args) { diff --git a/packages/pigeon/lib/src/pigeon_lib_internal.dart b/packages/pigeon/lib/src/pigeon_lib_internal.dart index 19c3be1fef9..3c5c67946e3 100644 --- a/packages/pigeon/lib/src/pigeon_lib_internal.dart +++ b/packages/pigeon/lib/src/pigeon_lib_internal.dart @@ -53,81 +53,74 @@ class InternalPigeonOptions { ) : input = options.input, objcOptions = (options.objcHeaderOut == null || options.objcSourceOut == null) - ? null - : InternalObjcOptions.fromObjcOptions( - options.objcOptions ?? const ObjcOptions(), - objcHeaderOut: options.objcHeaderOut!, - objcSourceOut: options.objcSourceOut!, - fileSpecificClassNameComponent: - options.objcSourceOut - ?.split('/') - .lastOrNull - ?.split('.') - .firstOrNull ?? - '', - copyrightHeader: copyrightHeader, - ), - javaOptions = - options.javaOut == null - ? null - : InternalJavaOptions.fromJavaOptions( - options.javaOptions ?? const JavaOptions(), - javaOut: options.javaOut!, - copyrightHeader: copyrightHeader, - ), - swiftOptions = - options.swiftOut == null - ? null - : InternalSwiftOptions.fromSwiftOptions( - options.swiftOptions ?? const SwiftOptions(), - swiftOut: options.swiftOut!, - copyrightHeader: copyrightHeader, - ), - kotlinOptions = - options.kotlinOut == null - ? null - : InternalKotlinOptions.fromKotlinOptions( - options.kotlinOptions ?? const KotlinOptions(), - kotlinOut: options.kotlinOut!, - copyrightHeader: copyrightHeader, - ), + ? null + : InternalObjcOptions.fromObjcOptions( + options.objcOptions ?? const ObjcOptions(), + objcHeaderOut: options.objcHeaderOut!, + objcSourceOut: options.objcSourceOut!, + fileSpecificClassNameComponent: + options.objcSourceOut + ?.split('/') + .lastOrNull + ?.split('.') + .firstOrNull ?? + '', + copyrightHeader: copyrightHeader, + ), + javaOptions = options.javaOut == null + ? null + : InternalJavaOptions.fromJavaOptions( + options.javaOptions ?? const JavaOptions(), + javaOut: options.javaOut!, + copyrightHeader: copyrightHeader, + ), + swiftOptions = options.swiftOut == null + ? null + : InternalSwiftOptions.fromSwiftOptions( + options.swiftOptions ?? const SwiftOptions(), + swiftOut: options.swiftOut!, + copyrightHeader: copyrightHeader, + ), + kotlinOptions = options.kotlinOut == null + ? null + : InternalKotlinOptions.fromKotlinOptions( + options.kotlinOptions ?? const KotlinOptions(), + kotlinOut: options.kotlinOut!, + copyrightHeader: copyrightHeader, + ), cppOptions = (options.cppHeaderOut == null || options.cppSourceOut == null) - ? null - : InternalCppOptions.fromCppOptions( - options.cppOptions ?? const CppOptions(), - cppHeaderOut: options.cppHeaderOut!, - cppSourceOut: options.cppSourceOut!, - copyrightHeader: copyrightHeader, - ), + ? null + : InternalCppOptions.fromCppOptions( + options.cppOptions ?? const CppOptions(), + cppHeaderOut: options.cppHeaderOut!, + cppSourceOut: options.cppSourceOut!, + copyrightHeader: copyrightHeader, + ), gobjectOptions = options.gobjectHeaderOut == null || options.gobjectSourceOut == null - ? null - : InternalGObjectOptions.fromGObjectOptions( - options.gobjectOptions ?? const GObjectOptions(), - gobjectHeaderOut: options.gobjectHeaderOut!, - gobjectSourceOut: options.gobjectSourceOut!, - copyrightHeader: copyrightHeader, - ), + ? null + : InternalGObjectOptions.fromGObjectOptions( + options.gobjectOptions ?? const GObjectOptions(), + gobjectHeaderOut: options.gobjectHeaderOut!, + gobjectSourceOut: options.gobjectSourceOut!, + copyrightHeader: copyrightHeader, + ), dartOptions = (options.dartOut == null && - options.dartOptions?.sourceOutPath == null) - ? null - : InternalDartOptions.fromDartOptions( - options.dartOptions ?? const DartOptions(), - dartOut: options.dartOut, - testOut: options.dartTestOut, - copyrightHeader: copyrightHeader, - ), - copyrightHeader = - options.copyrightHeader != null - ? _lineReader( - path.posix.join( - options.basePath ?? '', - options.copyrightHeader, - ), - ) - : null, + options.dartOptions?.sourceOutPath == null) + ? null + : InternalDartOptions.fromDartOptions( + options.dartOptions ?? const DartOptions(), + dartOut: options.dartOut, + testOut: options.dartTestOut, + copyrightHeader: copyrightHeader, + ), + copyrightHeader = options.copyrightHeader != null + ? _lineReader( + path.posix.join(options.basePath ?? '', options.copyrightHeader), + ) + : null, astOut = options.astOut, debugGenerators = options.debugGenerators, basePath = options.basePath, @@ -135,12 +128,11 @@ class InternalPigeonOptions { /// Creates a instance of InternalPigeonOptions from PigeonOptions. static InternalPigeonOptions fromPigeonOptions(PigeonOptions options) { - final Iterable? copyrightHeader = - options.copyrightHeader != null - ? _lineReader( - path.posix.join(options.basePath ?? '', options.copyrightHeader), - ) - : null; + final Iterable? copyrightHeader = options.copyrightHeader != null + ? _lineReader( + path.posix.join(options.basePath ?? '', options.copyrightHeader), + ) + : null; return InternalPigeonOptions._fromPigeonOptionsWithHeader( options, @@ -719,8 +711,9 @@ extension _ObjectAs on Object { List _validateAst(Root root, String source) { final List result = []; - final List customClasses = - root.classes.map((Class x) => x.name).toList(); + final List customClasses = root.classes + .map((Class x) => x.name) + .toList(); final Iterable customEnums = root.enums.map((Enum x) => x.name); for (final Enum enumDefinition in root.enums) { final String? matchingPrefix = _findMatchingPrefixOrNull( @@ -1308,8 +1301,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { _apis, _classes, ); - final Set referencedTypeNames = - referencedTypes.keys.map((TypeDeclaration e) => e.baseName).toSet(); + final Set referencedTypeNames = referencedTypes.keys + .map((TypeDeclaration e) => e.baseName) + .toSet(); final List nonReferencedTypes = List.from(_classes); nonReferencedTypes.removeWhere( (Class x) => referencedTypeNames.contains(x.name), @@ -1364,10 +1358,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { element.key.baseName != 'dynamic' && element.key.baseName != 'Object' && element.key.baseName.isNotEmpty) { - final int? lineNumber = - element.value.isEmpty - ? null - : calculateLineNumber(source, element.value.first); + final int? lineNumber = element.value.isEmpty + ? null + : calculateLineNumber(source, element.value.first); totalErrors.add( Error( message: 'Unknown type: ${element.key.baseName}', @@ -1412,10 +1405,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { totalErrors.addAll(validateErrors); return ParseResults( - root: - totalErrors.isEmpty - ? completeRoot - : Root(apis: [], classes: [], enums: []), + root: totalErrors.isEmpty + ? completeRoot + : Root(apis: [], classes: [], enums: []), errors: totalErrors, pigeonOptions: _pigeonOptions, ); @@ -1804,10 +1796,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { const String docCommentPrefix = '///'; return comments ?.map( - (Token line) => - line.length > docCommentPrefix.length - ? line.toString().substring(docCommentPrefix.length) - : '', + (Token line) => line.length > docCommentPrefix.length + ? line.toString().substring(docCommentPrefix.length) + : '', ) .toList() ?? []; @@ -1892,8 +1883,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { @override Object? visitMethodDeclaration(dart_ast.MethodDeclaration node) { final dart_ast.FormalParameterList parameters = node.parameters!; - final List arguments = - parameters.parameters.map(_formalParameterToPigeonParameter).toList(); + final List arguments = parameters.parameters + .map(_formalParameterToPigeonParameter) + .toList(); final bool isAsynchronous = _hasMetadata(node.metadata, 'async'); final bool isStatic = _hasMetadata(node.metadata, 'static'); final String objcSelector = @@ -1909,14 +1901,15 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { .asNullable() ?.value ?? ''; - final dart_ast.ArgumentList? taskQueueArguments = - _findMetadata(node.metadata, 'TaskQueue')?.arguments; - final String? taskQueueTypeName = - taskQueueArguments == null - ? null - : _getFirstChildOfType( - taskQueueArguments, - )?.expression.asNullable()?.name; + final dart_ast.ArgumentList? taskQueueArguments = _findMetadata( + node.metadata, + 'TaskQueue', + )?.arguments; + final String? taskQueueTypeName = taskQueueArguments == null + ? null + : _getFirstChildOfType( + taskQueueArguments, + )?.expression.asNullable()?.name; final TaskQueueType taskQueueType = _stringToEnum(TaskQueueType.values, taskQueueTypeName) ?? TaskQueueType.serial; @@ -1971,17 +1964,16 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { _enums.add( Enum( name: node.name.lexeme, - members: - node.constants - .map( - (dart_ast.EnumConstantDeclaration e) => EnumMember( - name: e.name.lexeme, - documentationComments: _documentationCommentsParser( - e.documentationComment?.tokens, - ), - ), - ) - .toList(), + members: node.constants + .map( + (dart_ast.EnumConstantDeclaration e) => EnumMember( + name: e.name.lexeme, + documentationComments: _documentationCommentsParser( + e.documentationComment?.tokens, + ), + ), + ) + .toList(), documentationComments: _documentationCommentsParser( node.documentationComment?.tokens, ), @@ -2078,8 +2070,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { Object? visitConstructorDeclaration(dart_ast.ConstructorDeclaration node) { if (_currentApi is AstProxyApi) { final dart_ast.FormalParameterList parameters = node.parameters; - final List arguments = - parameters.parameters.map(_formalParameterToPigeonParameter).toList(); + final List arguments = parameters.parameters + .map(_formalParameterToPigeonParameter) + .toList(); final String swiftFunction = _findMetadata(node.metadata, 'SwiftFunction') ?.arguments @@ -2129,8 +2122,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { in node.parameters.parameters) { if (param is dart_ast.DefaultFormalParameter) { if (param.name != null && param.defaultValue != null) { - _currentClassDefaultValues[param.name!.toString()] = - param.defaultValue!.toString(); + _currentClassDefaultValues[param.name!.toString()] = param + .defaultValue! + .toString(); } } } @@ -2154,10 +2148,9 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { ) { final bool isStatic = _hasMetadata(node.metadata, 'static'); if (type is dart_ast.GenericFunctionType) { - final List parameters = - type.parameters.parameters - .map(_formalParameterToPigeonParameter) - .toList(); + final List parameters = type.parameters.parameters + .map(_formalParameterToPigeonParameter) + .toList(); final String swiftFunction = _findMetadata(node.metadata, 'SwiftFunction') ?.arguments @@ -2166,14 +2159,15 @@ class RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { .asNullable() ?.value ?? ''; - final dart_ast.ArgumentList? taskQueueArguments = - _findMetadata(node.metadata, 'TaskQueue')?.arguments; - final String? taskQueueTypeName = - taskQueueArguments == null - ? null - : _getFirstChildOfType( - taskQueueArguments, - )?.expression.asNullable()?.name; + final dart_ast.ArgumentList? taskQueueArguments = _findMetadata( + node.metadata, + 'TaskQueue', + )?.arguments; + final String? taskQueueTypeName = taskQueueArguments == null + ? null + : _getFirstChildOfType( + taskQueueArguments, + )?.expression.asNullable()?.name; final TaskQueueType taskQueueType = _stringToEnum(TaskQueueType.values, taskQueueTypeName) ?? TaskQueueType.serial; diff --git a/packages/pigeon/lib/src/swift/swift_generator.dart b/packages/pigeon/lib/src/swift/swift_generator.dart index 200a7951c5b..2f30a35fd4e 100644 --- a/packages/pigeon/lib/src/swift/swift_generator.dart +++ b/packages/pigeon/lib/src/swift/swift_generator.dart @@ -263,8 +263,10 @@ class SwiftGenerator extends StructuredGenerator { final String readerName = '${codecName}Reader'; final String writerName = '${codecName}Writer'; - final List enumeratedTypes = - getEnumeratedTypes(root, excludeSealedClasses: true).toList(); + final List enumeratedTypes = getEnumeratedTypes( + root, + excludeSealedClasses: true, + ).toList(); void writeDecodeLogic(EnumeratedType customType) { indent.writeln('case ${customType.enumeration}:'); @@ -347,16 +349,16 @@ class SwiftGenerator extends StructuredGenerator { indent.addScoped('{', '} else ', () { final String encodeString = customType.type == CustomTypes.customClass - ? 'toList()' - : 'rawValue'; + ? 'toList()' + : 'rawValue'; final String valueString = customType.enumeration < maximumCodecFieldKey - ? 'value.$encodeString' - : 'wrap.toList()'; + ? 'value.$encodeString' + : 'wrap.toList()'; final int enumeration = customType.enumeration < maximumCodecFieldKey - ? customType.enumeration - : maximumCodecFieldKey; + ? customType.enumeration + : maximumCodecFieldKey; if (customType.enumeration >= maximumCodecFieldKey) { indent.writeln( 'let wrap = $_overflowClassName(type: ${customType.enumeration - maximumCodecFieldKey}, wrapped: value.$encodeString)', @@ -420,12 +422,11 @@ class SwiftGenerator extends StructuredGenerator { bool hashable = true, }) { final String privateString = private ? 'private ' : ''; - final String extendsString = - classDefinition.superClass != null - ? ': ${classDefinition.superClass!.name}' - : hashable - ? ': Hashable' - : ''; + final String extendsString = classDefinition.superClass != null + ? ': ${classDefinition.superClass!.name}' + : hashable + ? ': Hashable' + : ''; if (classDefinition.isSwiftClass) { indent.write( '${privateString}class ${classDefinition.name}$extendsString ', @@ -721,18 +722,18 @@ if (wrapped == nil) { )) { final String comma = getFieldsInSerializationOrder(classDefinition).last == field - ? '' - : ','; + ? '' + : ','; // Force-casting nullable enums in maps doesn't work the same as other types. // It needs soft-casting followed by force unwrapping. final String forceUnwrapMapWithNullableEnums = (field.type.baseName == 'Map' && - !field.type.isNullable && - field.type.typeArguments.any( - (TypeDeclaration type) => type.isEnum, - )) - ? '!' - : ''; + !field.type.isNullable && + field.type.typeArguments.any( + (TypeDeclaration type) => type.isEnum, + )) + ? '!' + : ''; indent.writeln( '${field.name}: ${field.name}$forceUnwrapMapWithNullableEnums$comma', ); @@ -942,8 +943,8 @@ if (wrapped == nil) { documentationComments: method.documentationComments, serialBackgroundQueue: method.taskQueueType == TaskQueueType.serialBackgroundThread - ? serialBackgroundQueue - : null, + ? serialBackgroundQueue + : null, ); } }); @@ -1025,12 +1026,10 @@ if (wrapped == nil) { swiftFunction: 'method(withIdentifier:)', setHandlerCondition: setHandlerCondition, isAsynchronous: false, - onCreateCall: ( - List safeArgNames, { - required String apiVarName, - }) { - return 'let _: AnyObject? = try instanceManager.removeInstance(${safeArgNames.single})'; - }, + onCreateCall: + (List safeArgNames, {required String apiVarName}) { + return 'let _: AnyObject? = try instanceManager.removeInstance(${safeArgNames.single})'; + }, ); _writeHostMethodMessageHandler( indent, @@ -1041,12 +1040,10 @@ if (wrapped == nil) { setHandlerCondition: setHandlerCondition, swiftFunction: null, isAsynchronous: false, - onCreateCall: ( - List safeArgNames, { - required String apiVarName, - }) { - return 'try instanceManager.removeAllObjects()'; - }, + onCreateCall: + (List safeArgNames, {required String apiVarName}) { + return 'try instanceManager.removeAllObjects()'; + }, ); }, ); @@ -1078,8 +1075,8 @@ if (wrapped == nil) { Root root, Indent indent, ) { - final Iterable allProxyApis = - root.apis.whereType(); + final Iterable allProxyApis = root.apis + .whereType(); _writeProxyApiRegistrar( indent, @@ -1289,8 +1286,9 @@ if (wrapped == nil) { final String swiftApiDelegateName = '${hostProxyApiPrefix}Delegate${api.name}'; - final String type = - api.hasMethodsRequiringImplementation() ? 'protocol' : 'open class'; + final String type = api.hasMethodsRequiringImplementation() + ? 'protocol' + : 'open class'; indent.writeScoped('$type $swiftApiDelegateName {', '}', () { _writeProxyApiConstructorDelegateMethods( indent, @@ -1716,10 +1714,9 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has (MapEntry e) => getEnumSafeArgumentExpression(e.key, e.value), ); - final String sendArgument = - parameters.isEmpty - ? 'nil' - : '[${enumSafeArgNames.join(', ')}] as [Any?]'; + final String sendArgument = parameters.isEmpty + ? 'nil' + : '[${enumSafeArgNames.join(', ')}] as [Any?]'; const String channel = 'channel'; indent.writeln('let channelName: String = "$channelName"'); indent.writeln( @@ -1768,11 +1765,11 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has // There is a swift bug with unwrapping maps of nullable Enums; final String enumMapForceUnwrap = returnType.baseName == 'Map' && - returnType.typeArguments.any( - (TypeDeclaration type) => type.isEnum, - ) - ? '!' - : ''; + returnType.typeArguments.any( + (TypeDeclaration type) => type.isEnum, + ) + ? '!' + : ''; indent.writeln('completion(.success(result$enumMapForceUnwrap))'); } }); @@ -1845,11 +1842,11 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has // There is a swift bug with unwrapping maps of nullable Enums; final String enumMapForceUnwrap = arg.type.baseName == 'Map' && - arg.type.typeArguments.any( - (TypeDeclaration type) => type.isEnum, - ) - ? '!' - : ''; + arg.type.typeArguments.any( + (TypeDeclaration type) => type.isEnum, + ) + ? '!' + : ''; _writeGenericCasting( indent: indent, @@ -1873,18 +1870,18 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has if (onCreateCall == null) { // Empty parens are not required when calling a method whose only // argument is a trailing closure. - final String argumentString = - methodArgument.isEmpty && isAsynchronous - ? '' - : '(${methodArgument.join(', ')})'; + final String argumentString = methodArgument.isEmpty && isAsynchronous + ? '' + : '(${methodArgument.join(', ')})'; call = '${tryStatement}api.${components.name}$argumentString'; } else { call = onCreateCall(methodArgument, apiVarName: 'api'); } if (isAsynchronous) { final String resultName = returnType.isVoid ? 'nil' : 'res'; - final String successVariableInit = - returnType.isVoid ? '' : '(let res)'; + final String successVariableInit = returnType.isVoid + ? '' + : '(let res)'; indent.write('$call '); indent.addScoped('{ result in', '}', () { @@ -2082,10 +2079,9 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has } final String methodSignature = _getMethodSignature( - name: - constructor.name.isNotEmpty - ? constructor.name - : 'pigeonDefaultConstructor', + name: constructor.name.isNotEmpty + ? constructor.name + : 'pigeonDefaultConstructor', parameters: [ Parameter( name: 'pigeonApi', @@ -2375,16 +2371,14 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has } for (final Constructor constructor in api.constructors) { - final String name = - constructor.name.isNotEmpty - ? constructor.name - : 'pigeonDefaultConstructor'; + final String name = constructor.name.isNotEmpty + ? constructor.name + : 'pigeonDefaultConstructor'; final String channelName = makeChannelNameWithStrings( apiName: api.name, - methodName: - constructor.name.isNotEmpty - ? constructor.name - : '${classMemberNamePrefix}defaultConstructor', + methodName: constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor', dartPackageName: dartPackageName, ); writeWithApiCheckIfNecessary( @@ -2403,19 +2397,20 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has returnType: const TypeDeclaration.voidDeclaration(), swiftFunction: null, isAsynchronous: false, - onCreateCall: ( - List methodParameters, { - required String apiVarName, - }) { - final List parameters = [ - 'pigeonApi: $apiVarName', - // Skip the identifier used by the InstanceManager. - ...methodParameters.skip(1), - ]; - return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(\n' - 'try $apiVarName.pigeonDelegate.$name(${parameters.join(', ')}),\n' - 'withIdentifier: pigeonIdentifierArg)'; - }, + onCreateCall: + ( + List methodParameters, { + required String apiVarName, + }) { + final List parameters = [ + 'pigeonApi: $apiVarName', + // Skip the identifier used by the InstanceManager. + ...methodParameters.skip(1), + ]; + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(\n' + 'try $apiVarName.pigeonDelegate.$name(${parameters.join(', ')}),\n' + 'withIdentifier: pigeonIdentifierArg)'; + }, parameters: [ Parameter( name: 'pigeonIdentifier', @@ -2452,18 +2447,18 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has swiftFunction: null, isAsynchronous: false, returnType: const TypeDeclaration.voidDeclaration(), - onCreateCall: ( - List methodParameters, { - required String apiVarName, - }) { - final String instanceArg = - field.isStatic + onCreateCall: + ( + List methodParameters, { + required String apiVarName, + }) { + final String instanceArg = field.isStatic ? '' : ', pigeonInstance: pigeonInstanceArg'; - return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' - 'try $apiVarName.pigeonDelegate.${field.name}(pigeonApi: api$instanceArg), ' - 'withIdentifier: pigeonIdentifierArg)'; - }, + return '$apiVarName.pigeonRegistrar.instanceManager.addDartCreatedInstance(' + 'try $apiVarName.pigeonDelegate.${field.name}(pigeonApi: api$instanceArg), ' + 'withIdentifier: pigeonIdentifierArg)'; + }, parameters: [ if (!field.isStatic) Parameter( @@ -2505,20 +2500,22 @@ func deepHash${generatorOptions.fileSpecificClassNameComponent}(value: Any?, has returnType: method.returnType, isAsynchronous: method.isAsynchronous, swiftFunction: null, - onCreateCall: ( - List methodParameters, { - required String apiVarName, - }) { - final String tryStatement = - method.isAsynchronous ? '' : 'try '; - final List parameters = [ - 'pigeonApi: $apiVarName', - // Skip the identifier used by the InstanceManager. - ...methodParameters, - ]; - - return '$tryStatement$apiVarName.pigeonDelegate.${method.name}(${parameters.join(', ')})'; - }, + onCreateCall: + ( + List methodParameters, { + required String apiVarName, + }) { + final String tryStatement = method.isAsynchronous + ? '' + : 'try '; + final List parameters = [ + 'pigeonApi: $apiVarName', + // Skip the identifier used by the InstanceManager. + ...methodParameters, + ]; + + return '$tryStatement$apiVarName.pigeonDelegate.${method.name}(${parameters.join(', ')})'; + }, parameters: [ if (!method.isStatic) Parameter( @@ -2921,10 +2918,9 @@ String _getSafeArgumentName(int count, NamedType argument) { } String _camelCase(String text) { - final String pascal = - text.split('_').map((String part) { - return part.isEmpty ? '' : part[0].toUpperCase() + part.substring(1); - }).join(); + final String pascal = text.split('_').map((String part) { + return part.isEmpty ? '' : part[0].toUpperCase() + part.substring(1); + }).join(); return pascal[0].toLowerCase() + pascal.substring(1); } @@ -3021,8 +3017,9 @@ String _getMethodSignature({ returnType: returnType, swiftFunction: swiftFunction, ); - final String returnTypeString = - returnType.isVoid ? 'Void' : _nullSafeSwiftTypeForDartType(returnType); + final String returnTypeString = returnType.isVoid + ? 'Void' + : _nullSafeSwiftTypeForDartType(returnType); final Iterable types = parameters.map( (NamedType e) => _nullSafeSwiftTypeForDartType(e.type), @@ -3095,16 +3092,15 @@ class _SwiftFunctionComponents { return _SwiftFunctionComponents._( name: name, returnType: returnType, - arguments: - parameters - .map( - (NamedType field) => _SwiftFunctionArgument( - name: field.name, - type: field.type, - namedType: field, - ), - ) - .toList(), + arguments: parameters + .map( + (NamedType field) => _SwiftFunctionArgument( + name: field.name, + type: field.type, + namedType: field, + ), + ) + .toList(), ); } @@ -3112,27 +3108,23 @@ class _SwiftFunctionComponents { final RegExp signatureRegex = RegExp(r'(\w+) *\(' + argsExtractor + r'\)'); final RegExpMatch match = signatureRegex.firstMatch(swiftFunction)!; - final Iterable labels = - match - .groups( - List.generate(parameters.length, (int index) => index + 2), - ) - .whereType(); + final Iterable labels = match + .groups(List.generate(parameters.length, (int index) => index + 2)) + .whereType(); return _SwiftFunctionComponents._( name: match.group(1)!, returnType: returnType, - arguments: - map2( - parameters, - labels, - (NamedType field, String label) => _SwiftFunctionArgument( - name: field.name, - label: label == field.name ? null : label, - type: field.type, - namedType: field, - ), - ).toList(), + arguments: map2( + parameters, + labels, + (NamedType field, String label) => _SwiftFunctionArgument( + name: field.name, + label: label == field.name ? null : label, + type: field.type, + namedType: field, + ), + ).toList(), ); } diff --git a/packages/pigeon/lib/src/swift/templates.dart b/packages/pigeon/lib/src/swift/templates.dart index 03ddee44aa6..35266a2944c 100644 --- a/packages/pigeon/lib/src/swift/templates.dart +++ b/packages/pigeon/lib/src/swift/templates.dart @@ -34,7 +34,8 @@ protocol ${instanceManagerFinalizerDelegateName(options)}: AnyObject { '''; /// Template for an object that tracks when an object is deallocated. -String instanceManagerFinalizerTemplate(InternalSwiftOptions options) => ''' +String instanceManagerFinalizerTemplate(InternalSwiftOptions options) => + ''' // Attaches to an object to receive a callback when the object is deallocated. internal final class ${_instanceManagerFinalizerName(options)} { internal static let associatedObjectKey = malloc(1)! diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle index 780d1bc139a..2da1e3bc835 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/build.gradle @@ -26,8 +26,8 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle index bddef156a7c..afae2c9e3b7 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/android/app/build.gradle @@ -28,8 +28,8 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml index a902a642fd8..32c685284ff 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Pigeon test harness for alternate plugin languages. publish_to: 'none' environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: alternate_language_test_plugin: diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml b/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml index 06058dd0028..bf12dbebf17 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart index a8ef67c4107..416a524673c 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart @@ -2983,8 +2983,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('callFlutterEchoProxyApiMap', (_) async { final ProxyApiTestClass api = _createGenericProxyApiTestClass( - flutterEchoProxyApiMap: - (_, Map aMap) => aMap, + flutterEchoProxyApiMap: (_, Map aMap) => + aMap, ); final Map value = @@ -3087,8 +3087,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('callFlutterEchoNullableProxyApi', (_) async { final ProxyApiTestClass api = _createGenericProxyApiTestClass( - flutterEchoNullableProxyApi: - (_, ProxyApiSuperClass? aProxyApi) => aProxyApi, + flutterEchoNullableProxyApi: (_, ProxyApiSuperClass? aProxyApi) => + aProxyApi, ); expect(await api.callFlutterEchoNullableProxyApi(null), null); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart index 5b55e562a5d..5f82202deb1 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart @@ -48,8 +48,9 @@ class BackgroundApi2Host { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index fb9658aee7c..d7b4d841b24 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -245,11 +245,10 @@ class AllTypes { intMap: (result[23] as Map?)!.cast(), enumMap: (result[24] as Map?)!.cast(), objectMap: (result[25] as Map?)!.cast(), - listMap: - (result[26] as Map?)!.cast>(), - mapMap: - (result[27] as Map?)! - .cast>(), + listMap: (result[26] as Map?)! + .cast>(), + mapMap: (result[27] as Map?)! + .cast>(), ); } @@ -433,23 +432,21 @@ class AllNullableTypes { objectList: (result[19] as List?)?.cast(), listList: (result[20] as List?)?.cast?>(), mapList: (result[21] as List?)?.cast?>(), - recursiveClassList: - (result[22] as List?)?.cast(), + recursiveClassList: (result[22] as List?) + ?.cast(), map: result[23] as Map?, - stringMap: - (result[24] as Map?)?.cast(), + stringMap: (result[24] as Map?) + ?.cast(), intMap: (result[25] as Map?)?.cast(), enumMap: (result[26] as Map?)?.cast(), - objectMap: - (result[27] as Map?)?.cast(), - listMap: - (result[28] as Map?)?.cast?>(), - mapMap: - (result[29] as Map?) - ?.cast?>(), - recursiveClassMap: - (result[30] as Map?) - ?.cast(), + objectMap: (result[27] as Map?) + ?.cast(), + listMap: (result[28] as Map?) + ?.cast?>(), + mapMap: (result[29] as Map?) + ?.cast?>(), + recursiveClassMap: (result[30] as Map?) + ?.cast(), ); } @@ -623,17 +620,16 @@ class AllNullableTypesWithoutRecursion { listList: (result[19] as List?)?.cast?>(), mapList: (result[20] as List?)?.cast?>(), map: result[21] as Map?, - stringMap: - (result[22] as Map?)?.cast(), + stringMap: (result[22] as Map?) + ?.cast(), intMap: (result[23] as Map?)?.cast(), enumMap: (result[24] as Map?)?.cast(), - objectMap: - (result[25] as Map?)?.cast(), - listMap: - (result[26] as Map?)?.cast?>(), - mapMap: - (result[27] as Map?) - ?.cast?>(), + objectMap: (result[25] as Map?) + ?.cast(), + listMap: (result[26] as Map?) + ?.cast?>(), + mapMap: (result[27] as Map?) + ?.cast?>(), ); } @@ -709,13 +705,11 @@ class AllClassesWrapper { result[1] as AllNullableTypesWithoutRecursion?, allTypes: result[2] as AllTypes?, classList: (result[3] as List?)!.cast(), - nullableClassList: - (result[4] as List?) - ?.cast(), + nullableClassList: (result[4] as List?) + ?.cast(), classMap: (result[5] as Map?)!.cast(), - nullableClassMap: - (result[6] as Map?) - ?.cast(), + nullableClassMap: (result[6] as Map?) + ?.cast(), ); } @@ -845,8 +839,9 @@ class HostIntegrationCoreApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -5842,8 +5837,9 @@ abstract class FlutterIntegrationCoreApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -6274,8 +6270,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null.', ); final List args = (message as List?)!; - final List? arg_list = - (args[0] as List?)?.cast(); + final List? arg_list = (args[0] as List?) + ?.cast(); assert( arg_list != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList was null, expected non-null List.', @@ -6309,8 +6305,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList was null.', ); final List args = (message as List?)!; - final List? arg_enumList = - (args[0] as List?)?.cast(); + final List? arg_enumList = (args[0] as List?) + ?.cast(); assert( arg_enumList != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnumList was null, expected non-null List.', @@ -6381,8 +6377,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList was null.', ); final List args = (message as List?)!; - final List? arg_enumList = - (args[0] as List?)?.cast(); + final List? arg_enumList = (args[0] as List?) + ?.cast(); assert( arg_enumList != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullEnumList was null, expected non-null List.', @@ -6670,8 +6666,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap was null.', ); final List args = (message as List?)!; - final Map? arg_intMap = - (args[0] as Map?)?.cast(); + final Map? arg_intMap = (args[0] as Map?) + ?.cast(); assert( arg_intMap != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNonNullIntMap was null, expected non-null Map.', @@ -6998,8 +6994,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList was null.', ); final List args = (message as List?)!; - final List? arg_list = - (args[0] as List?)?.cast(); + final List? arg_list = (args[0] as List?) + ?.cast(); try { final List? output = api.echoNullableList(arg_list); return wrapResponse(result: output); @@ -7029,8 +7025,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnumList was null.', ); final List args = (message as List?)!; - final List? arg_enumList = - (args[0] as List?)?.cast(); + final List? arg_enumList = (args[0] as List?) + ?.cast(); try { final List? output = api.echoNullableEnumList( arg_enumList, @@ -7095,8 +7091,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullEnumList was null.', ); final List args = (message as List?)!; - final List? arg_enumList = - (args[0] as List?)?.cast(); + final List? arg_enumList = (args[0] as List?) + ?.cast(); try { final List? output = api.echoNullableNonNullEnumList( arg_enumList, @@ -7353,8 +7349,8 @@ abstract class FlutterIntegrationCoreApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableNonNullIntMap was null.', ); final List args = (message as List?)!; - final Map? arg_intMap = - (args[0] as Map?)?.cast(); + final Map? arg_intMap = (args[0] as Map?) + ?.cast(); try { final Map? output = api.echoNullableNonNullIntMap( arg_intMap, @@ -7568,8 +7564,9 @@ class HostTrivialApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -7611,8 +7608,9 @@ class HostSmallApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -7690,8 +7688,9 @@ abstract class FlutterSmallApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart index f93ad9cbda8..7a652d525b2 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart @@ -144,8 +144,9 @@ class EnumApi2Host { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -198,8 +199,9 @@ abstract class EnumApi2Flutter { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart index f4e0a5b12f2..90b95c9d3d1 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart @@ -197,25 +197,22 @@ class EventAllNullableTypes { objectList: (result[19] as List?)?.cast(), listList: (result[20] as List?)?.cast?>(), mapList: (result[21] as List?)?.cast?>(), - recursiveClassList: - (result[22] as List?)?.cast(), + recursiveClassList: (result[22] as List?) + ?.cast(), map: result[23] as Map?, - stringMap: - (result[24] as Map?)?.cast(), + stringMap: (result[24] as Map?) + ?.cast(), intMap: (result[25] as Map?)?.cast(), - enumMap: - (result[26] as Map?) - ?.cast(), - objectMap: - (result[27] as Map?)?.cast(), - listMap: - (result[28] as Map?)?.cast?>(), - mapMap: - (result[29] as Map?) - ?.cast?>(), - recursiveClassMap: - (result[30] as Map?) - ?.cast(), + enumMap: (result[26] as Map?) + ?.cast(), + objectMap: (result[27] as Map?) + ?.cast(), + listMap: (result[28] as Map?) + ?.cast?>(), + mapMap: (result[29] as Map?) + ?.cast?>(), + recursiveClassMap: (result[30] as Map?) + ?.cast(), ); } diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart index b05b0174232..b72f676e84d 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart @@ -229,8 +229,9 @@ class Api { /// BinaryMessenger will be used which routes to the host platform. Api({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart index 615ed65ee22..1d708172886 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart @@ -248,8 +248,9 @@ class MessageApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -327,8 +328,9 @@ class MessageNestedApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -383,8 +385,9 @@ abstract class MessageFlutterSearchApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart index 50e5ca83780..0fceae13166 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart @@ -62,8 +62,9 @@ class MultipleArityHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -113,8 +114,9 @@ abstract class MultipleArityFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart index a032df9d1cf..7433ca9a50c 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart @@ -234,8 +234,9 @@ class NonNullFieldHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -287,8 +288,9 @@ abstract class NonNullFieldFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart index ee515aabfba..526d2717180 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart @@ -193,8 +193,9 @@ class NullFieldsHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -244,8 +245,9 @@ abstract class NullFieldsFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart index b1d7dc486be..942aa7c039f 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart @@ -62,8 +62,9 @@ class NullableReturnHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -106,8 +107,9 @@ abstract class NullableReturnFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -143,8 +145,9 @@ class NullableArgHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -194,8 +197,9 @@ abstract class NullableArgFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -237,8 +241,9 @@ class NullableCollectionReturnHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -281,8 +286,9 @@ abstract class NullableCollectionReturnFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -318,8 +324,9 @@ class NullableCollectionArgHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -369,8 +376,9 @@ abstract class NullableCollectionArgFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -387,8 +395,8 @@ abstract class NullableCollectionArgFlutterApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.NullableCollectionArgFlutterApi.doit was null.', ); final List args = (message as List?)!; - final List? arg_x = - (args[0] as List?)?.cast(); + final List? arg_x = (args[0] as List?) + ?.cast(); try { final List output = api.doit(arg_x); return wrapResponse(result: output); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart index adedd256e5c..03becd18df6 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart @@ -62,8 +62,9 @@ class PrimitiveHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -386,8 +387,9 @@ abstract class PrimitiveFlutterApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -643,8 +645,8 @@ abstract class PrimitiveFlutterApi { 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBoolList was null.', ); final List args = (message as List?)!; - final List? arg_value = - (args[0] as List?)?.cast(); + final List? arg_value = (args[0] as List?) + ?.cast(); assert( arg_value != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.PrimitiveFlutterApi.aBoolList was null, expected non-null List.', diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart index 3b265a3092e..1e705c65071 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart @@ -517,8 +517,8 @@ class PigeonInstanceManager { final PigeonInternalProxyApiBaseClass? strongInstance = _strongInstances[identifier]; if (strongInstance != null) { - final PigeonInternalProxyApiBaseClass copy = - strongInstance.pigeon_copy(); + final PigeonInternalProxyApiBaseClass copy = strongInstance + .pigeon_copy(); _identifiers[copy] = identifier; _weakInstances[identifier] = WeakReference(copy); @@ -2278,9 +2278,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterThrowError was null, expected non-null ProxyApiTestClass.', ); try { - final Object? output = (flutterThrowError ?? - arg_pigeon_instance!.flutterThrowError) - ?.call(arg_pigeon_instance!); + final Object? output = + (flutterThrowError ?? arg_pigeon_instance!.flutterThrowError) + ?.call(arg_pigeon_instance!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2359,9 +2359,11 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoBool was null, expected non-null bool.', ); try { - final bool output = (flutterEchoBool ?? - arg_pigeon_instance!.flutterEchoBool) - .call(arg_pigeon_instance!, arg_aBool!); + final bool output = + (flutterEchoBool ?? arg_pigeon_instance!.flutterEchoBool).call( + arg_pigeon_instance!, + arg_aBool!, + ); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2402,9 +2404,11 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoInt was null, expected non-null int.', ); try { - final int output = (flutterEchoInt ?? - arg_pigeon_instance!.flutterEchoInt) - .call(arg_pigeon_instance!, arg_anInt!); + final int output = + (flutterEchoInt ?? arg_pigeon_instance!.flutterEchoInt).call( + arg_pigeon_instance!, + arg_anInt!, + ); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2445,9 +2449,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoDouble was null, expected non-null double.', ); try { - final double output = (flutterEchoDouble ?? - arg_pigeon_instance!.flutterEchoDouble) - .call(arg_pigeon_instance!, arg_aDouble!); + final double output = + (flutterEchoDouble ?? arg_pigeon_instance!.flutterEchoDouble) + .call(arg_pigeon_instance!, arg_aDouble!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2488,9 +2492,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoString was null, expected non-null String.', ); try { - final String output = (flutterEchoString ?? - arg_pigeon_instance!.flutterEchoString) - .call(arg_pigeon_instance!, arg_aString!); + final String output = + (flutterEchoString ?? arg_pigeon_instance!.flutterEchoString) + .call(arg_pigeon_instance!, arg_aString!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2531,9 +2535,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoUint8List was null, expected non-null Uint8List.', ); try { - final Uint8List output = (flutterEchoUint8List ?? - arg_pigeon_instance!.flutterEchoUint8List) - .call(arg_pigeon_instance!, arg_aList!); + final Uint8List output = + (flutterEchoUint8List ?? + arg_pigeon_instance!.flutterEchoUint8List) + .call(arg_pigeon_instance!, arg_aList!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2568,16 +2573,18 @@ class ProxyApiTestClass extends ProxyApiSuperClass arg_pigeon_instance != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList was null, expected non-null ProxyApiTestClass.', ); - final List? arg_aList = - (args[1] as List?)?.cast(); + final List? arg_aList = (args[1] as List?) + ?.cast(); assert( arg_aList != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoList was null, expected non-null List.', ); try { - final List output = (flutterEchoList ?? - arg_pigeon_instance!.flutterEchoList) - .call(arg_pigeon_instance!, arg_aList!); + final List output = + (flutterEchoList ?? arg_pigeon_instance!.flutterEchoList).call( + arg_pigeon_instance!, + arg_aList!, + ); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2619,9 +2626,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApiList was null, expected non-null List.', ); try { - final List output = (flutterEchoProxyApiList ?? - arg_pigeon_instance!.flutterEchoProxyApiList) - .call(arg_pigeon_instance!, arg_aList!); + final List output = + (flutterEchoProxyApiList ?? + arg_pigeon_instance!.flutterEchoProxyApiList) + .call(arg_pigeon_instance!, arg_aList!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2663,9 +2671,11 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoMap was null, expected non-null Map.', ); try { - final Map output = (flutterEchoMap ?? - arg_pigeon_instance!.flutterEchoMap) - .call(arg_pigeon_instance!, arg_aMap!); + final Map output = + (flutterEchoMap ?? arg_pigeon_instance!.flutterEchoMap).call( + arg_pigeon_instance!, + arg_aMap!, + ); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2752,9 +2762,11 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoEnum was null, expected non-null ProxyApiTestEnum.', ); try { - final ProxyApiTestEnum output = (flutterEchoEnum ?? - arg_pigeon_instance!.flutterEchoEnum) - .call(arg_pigeon_instance!, arg_anEnum!); + final ProxyApiTestEnum output = + (flutterEchoEnum ?? arg_pigeon_instance!.flutterEchoEnum).call( + arg_pigeon_instance!, + arg_anEnum!, + ); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2796,9 +2808,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoProxyApi was null, expected non-null ProxyApiSuperClass.', ); try { - final ProxyApiSuperClass output = (flutterEchoProxyApi ?? - arg_pigeon_instance!.flutterEchoProxyApi) - .call(arg_pigeon_instance!, arg_aProxyApi!); + final ProxyApiSuperClass output = + (flutterEchoProxyApi ?? + arg_pigeon_instance!.flutterEchoProxyApi) + .call(arg_pigeon_instance!, arg_aProxyApi!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2835,9 +2848,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final bool? arg_aBool = (args[1] as bool?); try { - final bool? output = (flutterEchoNullableBool ?? - arg_pigeon_instance!.flutterEchoNullableBool) - ?.call(arg_pigeon_instance!, arg_aBool); + final bool? output = + (flutterEchoNullableBool ?? + arg_pigeon_instance!.flutterEchoNullableBool) + ?.call(arg_pigeon_instance!, arg_aBool); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2874,9 +2888,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final int? arg_anInt = (args[1] as int?); try { - final int? output = (flutterEchoNullableInt ?? - arg_pigeon_instance!.flutterEchoNullableInt) - ?.call(arg_pigeon_instance!, arg_anInt); + final int? output = + (flutterEchoNullableInt ?? + arg_pigeon_instance!.flutterEchoNullableInt) + ?.call(arg_pigeon_instance!, arg_anInt); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2913,9 +2928,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final double? arg_aDouble = (args[1] as double?); try { - final double? output = (flutterEchoNullableDouble ?? - arg_pigeon_instance!.flutterEchoNullableDouble) - ?.call(arg_pigeon_instance!, arg_aDouble); + final double? output = + (flutterEchoNullableDouble ?? + arg_pigeon_instance!.flutterEchoNullableDouble) + ?.call(arg_pigeon_instance!, arg_aDouble); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2952,9 +2968,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final String? arg_aString = (args[1] as String?); try { - final String? output = (flutterEchoNullableString ?? - arg_pigeon_instance!.flutterEchoNullableString) - ?.call(arg_pigeon_instance!, arg_aString); + final String? output = + (flutterEchoNullableString ?? + arg_pigeon_instance!.flutterEchoNullableString) + ?.call(arg_pigeon_instance!, arg_aString); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -2991,9 +3008,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final Uint8List? arg_aList = (args[1] as Uint8List?); try { - final Uint8List? output = (flutterEchoNullableUint8List ?? - arg_pigeon_instance!.flutterEchoNullableUint8List) - ?.call(arg_pigeon_instance!, arg_aList); + final Uint8List? output = + (flutterEchoNullableUint8List ?? + arg_pigeon_instance!.flutterEchoNullableUint8List) + ?.call(arg_pigeon_instance!, arg_aList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3028,12 +3046,13 @@ class ProxyApiTestClass extends ProxyApiSuperClass arg_pigeon_instance != null, 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoNullableList was null, expected non-null ProxyApiTestClass.', ); - final List? arg_aList = - (args[1] as List?)?.cast(); + final List? arg_aList = (args[1] as List?) + ?.cast(); try { - final List? output = (flutterEchoNullableList ?? - arg_pigeon_instance!.flutterEchoNullableList) - ?.call(arg_pigeon_instance!, arg_aList); + final List? output = + (flutterEchoNullableList ?? + arg_pigeon_instance!.flutterEchoNullableList) + ?.call(arg_pigeon_instance!, arg_aList); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3071,9 +3090,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass final Map? arg_aMap = (args[1] as Map?)?.cast(); try { - final Map? output = (flutterEchoNullableMap ?? - arg_pigeon_instance!.flutterEchoNullableMap) - ?.call(arg_pigeon_instance!, arg_aMap); + final Map? output = + (flutterEchoNullableMap ?? + arg_pigeon_instance!.flutterEchoNullableMap) + ?.call(arg_pigeon_instance!, arg_aMap); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3110,9 +3130,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass ); final ProxyApiTestEnum? arg_anEnum = (args[1] as ProxyApiTestEnum?); try { - final ProxyApiTestEnum? output = (flutterEchoNullableEnum ?? - arg_pigeon_instance!.flutterEchoNullableEnum) - ?.call(arg_pigeon_instance!, arg_anEnum); + final ProxyApiTestEnum? output = + (flutterEchoNullableEnum ?? + arg_pigeon_instance!.flutterEchoNullableEnum) + ?.call(arg_pigeon_instance!, arg_anEnum); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3150,9 +3171,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass final ProxyApiSuperClass? arg_aProxyApi = (args[1] as ProxyApiSuperClass?); try { - final ProxyApiSuperClass? output = (flutterEchoNullableProxyApi ?? - arg_pigeon_instance!.flutterEchoNullableProxyApi) - ?.call(arg_pigeon_instance!, arg_aProxyApi); + final ProxyApiSuperClass? output = + (flutterEchoNullableProxyApi ?? + arg_pigeon_instance!.flutterEchoNullableProxyApi) + ?.call(arg_pigeon_instance!, arg_aProxyApi); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); @@ -3230,9 +3252,10 @@ class ProxyApiTestClass extends ProxyApiSuperClass 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiTestClass.flutterEchoAsyncString was null, expected non-null String.', ); try { - final String output = await (flutterEchoAsyncString ?? - arg_pigeon_instance!.flutterEchoAsyncString) - .call(arg_pigeon_instance!, arg_aString!); + final String output = + await (flutterEchoAsyncString ?? + arg_pigeon_instance!.flutterEchoAsyncString) + .call(arg_pigeon_instance!, arg_aString!); return wrapResponse(result: output); } on PlatformException catch (e) { return wrapResponse(error: e); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml b/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml index 234f018c1dc..995b01de0f5 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: build_runner: ^2.1.10 diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index e51401f5b23..c6c4506c972 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -103,8 +103,9 @@ void main() { instanceManager.addHostCreatedInstance(object, 0); expect(instanceManager.removeWeakReference(object), 0); - final CopyableObject copy = - instanceManager.getInstanceWithWeakReference(0)!; + final CopyableObject copy = instanceManager.getInstanceWithWeakReference( + 0, + )!; expect(identical(object, copy), isFalse); }); @@ -148,8 +149,8 @@ void main() { instanceManager.addHostCreatedInstance(object, 0); instanceManager.removeWeakReference(object); - final CopyableObject newWeakCopy = - instanceManager.getInstanceWithWeakReference(0)!; + final CopyableObject newWeakCopy = instanceManager + .getInstanceWithWeakReference(0)!; expect(identical(object, newWeakCopy), isFalse); }); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/multiple_arity_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/multiple_arity_test.dart index 786f5ade6b4..f7c8585bbdb 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/multiple_arity_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/multiple_arity_test.dart @@ -20,10 +20,8 @@ void main() { any, ), ).thenAnswer((Invocation realInvocation) async { - final Object input = - MultipleArityHostApi.pigeonChannelCodec.decodeMessage( - realInvocation.positionalArguments[1] as ByteData?, - )!; + final Object input = MultipleArityHostApi.pigeonChannelCodec + .decodeMessage(realInvocation.positionalArguments[1] as ByteData?)!; final List args = input as List; final int x = (args[0] as int?)!; final int y = (args[1] as int?)!; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/null_safe_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/null_safe_test.dart index d8f04619d15..405f48343b6 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/null_safe_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/null_safe_test.dart @@ -26,10 +26,9 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); test('with values filled', () { - final FlutterSearchReply reply = - FlutterSearchReply() - ..result = 'foo' - ..error = 'bar'; + final FlutterSearchReply reply = FlutterSearchReply() + ..result = 'foo' + ..error = 'bar'; final List encoded = reply.encode() as List; final FlutterSearchReply decoded = FlutterSearchReply.decode(encoded); expect(reply.result, decoded.result); @@ -37,10 +36,9 @@ void main() { }); test('with null value', () { - final FlutterSearchReply reply = - FlutterSearchReply() - ..result = 'foo' - ..error = null; + final FlutterSearchReply reply = FlutterSearchReply() + ..result = 'foo' + ..error = null; final List encoded = reply.encode() as List; final FlutterSearchReply decoded = FlutterSearchReply.decode(encoded); expect(reply.result, decoded.result); @@ -68,8 +66,8 @@ void main() { test('send/receive list classes', () async { final FlutterSearchRequest request = FlutterSearchRequest()..query = 'hey'; - final FlutterSearchRequests requests = - FlutterSearchRequests()..requests = [request]; + final FlutterSearchRequests requests = FlutterSearchRequests() + ..requests = [request]; final BinaryMessenger mockMessenger = MockBinaryMessenger(); echoOneArgument( mockMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart index 4ebdbc11914..3c0e4b8e334 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart @@ -36,8 +36,8 @@ void main() { }); test('pigeon_reset sets constructor overrides to null', () { - PigeonOverrides.proxyApiSuperClass_new = - () => ProxyApiSuperClass.pigeon_detached(); + PigeonOverrides.proxyApiSuperClass_new = () => + ProxyApiSuperClass.pigeon_detached(); PigeonOverrides.pigeon_reset(); expect(PigeonOverrides.proxyApiSuperClass_new, isNull); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart index 8dba8c376fd..59d3481b3af 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_message.gen.dart @@ -77,8 +77,9 @@ abstract class TestHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -171,8 +172,9 @@ abstract class TestNestedApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_util.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_util.dart index 35470b71d65..abea719758a 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_util.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/test_util.dart @@ -13,10 +13,9 @@ void echoOneArgument( when(mockMessenger.send(channel, any)).thenAnswer(( Invocation realInvocation, ) async { - final Object input = - codec.decodeMessage( - realInvocation.positionalArguments[1] as ByteData?, - )!; + final Object input = codec.decodeMessage( + realInvocation.positionalArguments[1] as ByteData?, + )!; final List args = input as List; return codec.encodeMessage([args[0]!]); }); diff --git a/packages/pigeon/platform_tests/test_plugin/android/build.gradle b/packages/pigeon/platform_tests/test_plugin/android/build.gradle index 9933786c0de..90231752191 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/build.gradle +++ b/packages/pigeon/platform_tests/test_plugin/android/build.gradle @@ -29,12 +29,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() allWarningsAsErrors = true } diff --git a/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle b/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle index 590e71037f6..551d7ce3a9b 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle +++ b/packages/pigeon/platform_tests/test_plugin/example/android/app/build.gradle @@ -28,12 +28,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } lint { diff --git a/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml index e63f596204d..96edc8061b7 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml +++ b/packages/pigeon/platform_tests/test_plugin/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Pigeon test harness for primary plugin languages. publish_to: 'none' environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: flutter: diff --git a/packages/pigeon/platform_tests/test_plugin/pubspec.yaml b/packages/pigeon/platform_tests/test_plugin/pubspec.yaml index 13121627204..1c32f7b749b 100644 --- a/packages/pigeon/platform_tests/test_plugin/pubspec.yaml +++ b/packages/pigeon/platform_tests/test_plugin/pubspec.yaml @@ -4,8 +4,8 @@ version: 0.0.1 publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 3197a83dd4e..e64dfb628bb 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,10 +2,10 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22 -version: 26.0.1 # This must match the version in lib/src/generator_tools.dart +version: 26.1.0 # This must match the version in lib/src/generator_tools.dart environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: analyzer: ">=6.0.0 <8.0.0" diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 30c7dca3212..f159cdaf48d 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -63,7 +63,10 @@ void main() { test('gen one enum', () { final Enum anEnum = Enum( name: 'Foobar', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [], diff --git a/packages/pigeon/test/functional_test.dart b/packages/pigeon/test/functional_test.dart index b4c38bd5e96..4e83c21031e 100644 --- a/packages/pigeon/test/functional_test.dart +++ b/packages/pigeon/test/functional_test.dart @@ -8,11 +8,10 @@ import 'package:test/test.dart'; void main() { test('indexMap', () { final List items = ['a', 'b', 'c']; - final List result = - indexMap( - items, - (int index, String value) => value + index.toString(), - ).toList(); + final List result = indexMap( + items, + (int index, String value) => value + index.toString(), + ).toList(); expect(result[0], 'a0'); expect(result[1], 'b1'); expect(result[2], 'c2'); @@ -37,8 +36,11 @@ void main() { }); test('map2', () { - final List result = - map2([3, 5, 7], [1, 2, 3], (int x, int y) => x * y).toList(); + final List result = map2( + [3, 5, 7], + [1, 2, 3], + (int x, int y) => x * y, + ).toList(); expect(result[0], 3); expect(result[1], 10); expect(result[2], 21); @@ -52,12 +54,11 @@ void main() { }); test('map3', () { - final List result = - map3([3, 5, 7], [1, 2, 3], [ - 2, - 2, - 2, - ], (int x, int y, int z) => x * y * z).toList(); + final List result = map3([3, 5, 7], [1, 2, 3], [ + 2, + 2, + 2, + ], (int x, int y, int z) => x * y * z).toList(); expect(result[0], 6); expect(result[1], 20); expect(result[2], 42); @@ -65,13 +66,12 @@ void main() { test('map3 unequal', () { expect( - () => - map3( - [], - [1, 2, 3], - [], - (int x, int y, int z) => x * y * z, - ).toList(), + () => map3( + [], + [1, 2, 3], + [], + (int x, int y, int z) => x * y * z, + ).toList(), throwsArgumentError, ); }); diff --git a/packages/pigeon/test/gobject_generator_test.dart b/packages/pigeon/test/gobject_generator_test.dart index aca83f4c99b..2c66b13afe0 100644 --- a/packages/pigeon/test/gobject_generator_test.dart +++ b/packages/pigeon/test/gobject_generator_test.dart @@ -954,7 +954,10 @@ void main() { final Class objectClass = Class(name: 'Object', fields: []); final Enum anEnum = Enum( name: 'enum', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [ diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 358fb6eff8b..5deeb11a3f8 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -60,7 +60,10 @@ void main() { test('gen one enum', () { final Enum anEnum = Enum( name: 'Foobar', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [], diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 41b51562209..2c806907828 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -3883,7 +3883,10 @@ void main() { test('header of FlutterApi uses correct enum name with prefix', () { final Enum enum1 = Enum( name: 'Enum1', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [ @@ -3933,7 +3936,10 @@ void main() { test('source of FlutterApi uses correct enum name with prefix', () { final Enum enum1 = Enum( name: 'Enum1', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [ @@ -3983,7 +3989,10 @@ void main() { test('header of HostApi uses correct enum name with prefix', () { final Enum enum1 = Enum( name: 'Enum1', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final TypeDeclaration enumType = TypeDeclaration( baseName: 'Enum1', @@ -4034,7 +4043,10 @@ void main() { test('source of HostApi uses correct enum name with prefix', () { final Enum enum1 = Enum( name: 'Enum1', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final TypeDeclaration enumType = TypeDeclaration( baseName: 'Enum1', diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 420b34b6d3d..b2409c4dbc5 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -472,8 +472,9 @@ abstract class NestorApi { final ParseResults results = parseSource(code); expect(results.errors.length, 0); expect(results.root.apis.length, 1); - final List classNames = - results.root.classes.map((Class x) => x.name).toList(); + final List classNames = results.root.classes + .map((Class x) => x.name) + .toList(); expect(classNames.length, 2); expect(classNames.contains('Nestor'), true); expect(classNames.contains('OnlyVisibleFromNesting'), true); diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 4344b203ae5..d30cd8ae4ed 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -64,7 +64,10 @@ void main() { test('gen one enum', () { final Enum anEnum = Enum( name: 'Foobar', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Root root = Root( apis: [], @@ -872,7 +875,10 @@ void main() { test('gen one enum class', () { final Enum anEnum = Enum( name: 'Enum1', - members: [EnumMember(name: 'one'), EnumMember(name: 'two')], + members: [ + EnumMember(name: 'one'), + EnumMember(name: 'two'), + ], ); final Class classDefinition = Class( name: 'EnumClass', diff --git a/packages/pigeon/tool/generate.dart b/packages/pigeon/tool/generate.dart index 5c7b4c703f3..b32381eb09b 100644 --- a/packages/pigeon/tool/generate.dart +++ b/packages/pigeon/tool/generate.dart @@ -28,40 +28,39 @@ const String _overflowFiller = 'overflow'; const List _fileGroups = [_test, _example]; Future main(List args) async { - final ArgParser parser = - ArgParser() - ..addFlag( - _formatFlag, - abbr: 'f', - help: - 'Autoformat after generation. This flag is no longer needed, as this behavior is the default', - defaultsTo: true, - hide: true, - ) - ..addFlag( - _noFormatFlag, - abbr: 'n', - help: 'Do not autoformat after generation.', - ) - ..addFlag( - _helpFlag, - negatable: false, - abbr: 'h', - help: 'Print this reference.', - ) - ..addFlag( - _overflowFiller, - abbr: 'o', - help: - 'Injects 120 Enums into the pigeon ast, used for testing overflow utilities.', - hide: true, - ) - ..addMultiOption( - _files, - help: - 'Select specific groups of files to generate; $_test or $_example. Defaults to both.', - allowed: _fileGroups, - ); + final ArgParser parser = ArgParser() + ..addFlag( + _formatFlag, + abbr: 'f', + help: + 'Autoformat after generation. This flag is no longer needed, as this behavior is the default', + defaultsTo: true, + hide: true, + ) + ..addFlag( + _noFormatFlag, + abbr: 'n', + help: 'Do not autoformat after generation.', + ) + ..addFlag( + _helpFlag, + negatable: false, + abbr: 'h', + help: 'Print this reference.', + ) + ..addFlag( + _overflowFiller, + abbr: 'o', + help: + 'Injects 120 Enums into the pigeon ast, used for testing overflow utilities.', + hide: true, + ) + ..addMultiOption( + _files, + help: + 'Select specific groups of files to generate; $_test or $_example. Defaults to both.', + allowed: _fileGroups, + ); final ArgResults argResults = parser.parse(args); if (argResults.wasParsed(_helpFlag)) { @@ -76,10 +75,9 @@ ${parser.usage}'''); final bool includeOverflow = argResults.wasParsed(_overflowFiller); - final List toGenerate = - argResults.wasParsed(_files) - ? argResults[_files] as List - : _fileGroups; + final List toGenerate = argResults.wasParsed(_files) + ? argResults[_files] as List + : _fileGroups; if (toGenerate.contains(_test)) { print('Generating platform_test/ output...'); diff --git a/packages/pigeon/tool/run_tests.dart b/packages/pigeon/tool/run_tests.dart index 54146d15403..b0885d01b59 100644 --- a/packages/pigeon/tool/run_tests.dart +++ b/packages/pigeon/tool/run_tests.dart @@ -114,11 +114,10 @@ Future _validateGeneratedFiles( repositoryRoot: repositoryRoot, relativePigeonPath: relativePigeonPath, ); - final Set extensions = - languagesToValidate - .map((GeneratorLanguage lang) => _extensionsForLanguage(lang)) - .flattened - .toSet(); + final Set extensions = languagesToValidate + .map((GeneratorLanguage lang) => _extensionsForLanguage(lang)) + .flattened + .toSet(); final Iterable filteredFiles = modifiedFiles.where( (String path) => extensions.contains(p.extension(path).replaceFirst('.', '')), diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index e72da975794..48ee3daf16a 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -118,61 +118,54 @@ Future generateTestPigeons({ final bool kotlinErrorClassGenerationTestFiles = input == 'core_tests' || input == 'primitive'; - final String kotlinErrorName = - kotlinErrorClassGenerationTestFiles - ? 'FlutterError' - : '${pascalCaseName}Error'; + final String kotlinErrorName = kotlinErrorClassGenerationTestFiles + ? 'FlutterError' + : '${pascalCaseName}Error'; final bool swiftErrorUseDefaultErrorName = input == 'core_tests' || input == 'primitive'; - final String? swiftErrorClassName = - swiftErrorUseDefaultErrorName ? null : '${pascalCaseName}Error'; + final String? swiftErrorClassName = swiftErrorUseDefaultErrorName + ? null + : '${pascalCaseName}Error'; // Generate the default language test plugin output. int generateCode = await runPigeon( input: './pigeons/$input.dart', dartOut: '$sharedDartOutputBase/lib/src/generated/$input.gen.dart', - dartTestOut: - input == 'message' - ? '$sharedDartOutputBase/test/test_message.gen.dart' - : null, + dartTestOut: input == 'message' + ? '$sharedDartOutputBase/test/test_message.gen.dart' + : null, dartPackageName: 'pigeon_integration_tests', suppressVersion: true, // Android - kotlinOut: - skipLanguages.contains(GeneratorLanguage.kotlin) - ? null - : '$outputBase/android/src/main/kotlin/com/example/test_plugin/$pascalCaseName.gen.kt', + kotlinOut: skipLanguages.contains(GeneratorLanguage.kotlin) + ? null + : '$outputBase/android/src/main/kotlin/com/example/test_plugin/$pascalCaseName.gen.kt', kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: kotlinErrorName, kotlinIncludeErrorClass: input != 'primitive', // iOS/macOS - swiftOut: - skipLanguages.contains(GeneratorLanguage.swift) - ? null - : '$outputBase/darwin/$testPluginName/Sources/$testPluginName/$pascalCaseName.gen.swift', + swiftOut: skipLanguages.contains(GeneratorLanguage.swift) + ? null + : '$outputBase/darwin/$testPluginName/Sources/$testPluginName/$pascalCaseName.gen.swift', swiftErrorClassName: swiftErrorClassName, swiftIncludeErrorClass: input != 'primitive', // Linux - gobjectHeaderOut: - skipLanguages.contains(GeneratorLanguage.gobject) - ? null - : '$outputBase/linux/pigeon/$input.gen.h', - gobjectSourceOut: - skipLanguages.contains(GeneratorLanguage.gobject) - ? null - : '$outputBase/linux/pigeon/$input.gen.cc', + gobjectHeaderOut: skipLanguages.contains(GeneratorLanguage.gobject) + ? null + : '$outputBase/linux/pigeon/$input.gen.h', + gobjectSourceOut: skipLanguages.contains(GeneratorLanguage.gobject) + ? null + : '$outputBase/linux/pigeon/$input.gen.cc', gobjectModule: '${pascalCaseName}PigeonTest', // Windows - cppHeaderOut: - skipLanguages.contains(GeneratorLanguage.cpp) - ? null - : '$outputBase/windows/pigeon/$input.gen.h', - cppSourceOut: - skipLanguages.contains(GeneratorLanguage.cpp) - ? null - : '$outputBase/windows/pigeon/$input.gen.cpp', + cppHeaderOut: skipLanguages.contains(GeneratorLanguage.cpp) + ? null + : '$outputBase/windows/pigeon/$input.gen.h', + cppSourceOut: skipLanguages.contains(GeneratorLanguage.cpp) + ? null + : '$outputBase/windows/pigeon/$input.gen.cpp', cppNamespace: '${input}_pigeontest', injectOverflowTypes: includeOverflow && input == 'core_tests', ); @@ -190,28 +183,24 @@ Future generateTestPigeons({ // Android // This doesn't use the '.gen' suffix since Java has strict file naming // rules. - javaOut: - skipLanguages.contains(GeneratorLanguage.java) - ? null - : '$alternateOutputBase/android/src/main/java/com/example/' - 'alternate_language_test_plugin/${_javaFilenameForName(input)}.java', + javaOut: skipLanguages.contains(GeneratorLanguage.java) + ? null + : '$alternateOutputBase/android/src/main/java/com/example/' + 'alternate_language_test_plugin/${_javaFilenameForName(input)}.java', javaPackage: 'com.example.alternate_language_test_plugin', // iOS/macOS - objcHeaderOut: - skipLanguages.contains(GeneratorLanguage.objc) - ? null - : '$objcBase/$objcBaseRelativeHeaderPath', - objcSourceOut: - skipLanguages.contains(GeneratorLanguage.objc) - ? null - : '$objcBase/$pascalCaseName.gen.m', + objcHeaderOut: skipLanguages.contains(GeneratorLanguage.objc) + ? null + : '$objcBase/$objcBaseRelativeHeaderPath', + objcSourceOut: skipLanguages.contains(GeneratorLanguage.objc) + ? null + : '$objcBase/$pascalCaseName.gen.m', objcHeaderIncludePath: './$objcBaseRelativeHeaderPath', - objcPrefix: - input == 'core_tests' - ? 'FLT' - : input == 'enum' - ? 'PGN' - : '', + objcPrefix: input == 'core_tests' + ? 'FLT' + : input == 'enum' + ? 'PGN' + : '', suppressVersion: true, dartPackageName: 'pigeon_integration_tests', injectOverflowTypes: includeOverflow && input == 'core_tests', @@ -295,8 +284,9 @@ Future runPigeon({ cppOptions: CppOptions(namespace: cppNamespace), gobjectHeaderOut: injectOverflowTypes ? null : gobjectHeaderOut, gobjectSourceOut: injectOverflowTypes ? null : gobjectSourceOut, - gobjectOptions: - injectOverflowTypes ? null : GObjectOptions(module: gobjectModule), + gobjectOptions: injectOverflowTypes + ? null + : GObjectOptions(module: gobjectModule), javaOut: javaOut, javaOptions: JavaOptions(package: javaPackage), kotlinOut: kotlinOut, diff --git a/packages/pigeon/tool/shared/process_utils.dart b/packages/pigeon/tool/shared/process_utils.dart index 8d5e54b35d0..2055ecd4fec 100644 --- a/packages/pigeon/tool/shared/process_utils.dart +++ b/packages/pigeon/tool/shared/process_utils.dart @@ -16,8 +16,9 @@ Future runProcess( command, arguments, workingDirectory: workingDirectory, - mode: - streamOutput ? ProcessStartMode.inheritStdio : ProcessStartMode.normal, + mode: streamOutput + ? ProcessStartMode.inheritStdio + : ProcessStartMode.normal, ); if (streamOutput) { diff --git a/packages/pigeon/tool/test.dart b/packages/pigeon/tool/test.dart index b274d97bb98..5754778c191 100644 --- a/packages/pigeon/tool/test.dart +++ b/packages/pigeon/tool/test.dart @@ -26,42 +26,37 @@ const String _format = 'format'; const String _overflow = 'overflow'; Future main(List args) async { - final ArgParser parser = - ArgParser() - ..addMultiOption( - _testFlag, - abbr: 't', - help: 'Only run specified tests.', - ) - ..addFlag( - _noGen, - abbr: 'g', - help: 'Skips the generation step.', - negatable: false, - ) - ..addFlag( - _format, - abbr: 'f', - help: 'Formats generated test files before running tests.', - ) - ..addFlag( - _overflow, - help: - 'Generates overflow files for integration tests, runs tests with and without overflow files.', - abbr: 'o', - ) - ..addFlag( - _listFlag, - negatable: false, - abbr: 'l', - help: 'List available tests.', - ) - ..addFlag( - 'help', - negatable: false, - abbr: 'h', - help: 'Print this reference.', - ); + final ArgParser parser = ArgParser() + ..addMultiOption(_testFlag, abbr: 't', help: 'Only run specified tests.') + ..addFlag( + _noGen, + abbr: 'g', + help: 'Skips the generation step.', + negatable: false, + ) + ..addFlag( + _format, + abbr: 'f', + help: 'Formats generated test files before running tests.', + ) + ..addFlag( + _overflow, + help: + 'Generates overflow files for integration tests, runs tests with and without overflow files.', + abbr: 'o', + ) + ..addFlag( + _listFlag, + negatable: false, + abbr: 'l', + help: 'List available tests.', + ) + ..addFlag( + 'help', + negatable: false, + abbr: 'h', + help: 'Print this reference.', + ); final ArgResults argResults = parser.parse(args); List testsToRun = []; diff --git a/packages/rfw/CHANGELOG.md b/packages/rfw/CHANGELOG.md index 02234a2b447..83ecc21fc6b 100644 --- a/packages/rfw/CHANGELOG.md +++ b/packages/rfw/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 1.1.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. * Removes the wasm example. ## 1.0.31 diff --git a/packages/rfw/README.md b/packages/rfw/README.md index b43a2caa071..245b29ba804 100644 --- a/packages/rfw/README.md +++ b/packages/rfw/README.md @@ -440,9 +440,15 @@ a map with a `name` subkey, or a scalar String: ```dart 'Foo': (BuildContext context, DataSource source) { if (source.isMap(['bar'])) { - return Text('${source.v(['bar', 'name'])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['bar', 'name'])}', + textDirection: TextDirection.ltr, + ); } - return Text('${source.v(['bar'])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['bar'])}', + textDirection: TextDirection.ltr, + ); }, ``` @@ -474,9 +480,15 @@ method is similar but reports on whether the specified key identifies a list: ```dart 'Foo': (BuildContext context, DataSource source) { if (source.isList(['bar', 'quux'])) { - return Text('${source.v(['bar', 'quux', 2])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['bar', 'quux', 2])}', + textDirection: TextDirection.ltr, + ); } - return Text('${source.v(['baz'])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['baz'])}', + textDirection: TextDirection.ltr, + ); }, ``` @@ -527,7 +539,10 @@ to obtain the widget, in a manner similar to the `v` method: ```rfwtxt 'GreenBox': (BuildContext context, DataSource source) { - return ColoredBox(color: const Color(0xFF002211), child: source.child(['child'])); + return ColoredBox( + color: const Color(0xFF002211), + child: source.child(['child']), + ); }, ``` @@ -539,7 +554,10 @@ argument that isn't a widget, the `child` method returns an ```rfwtxt 'GreenBox': (BuildContext context, DataSource source) { - return ColoredBox(color: const Color(0xFF002211), child: source.optionalChild(['child'])); + return ColoredBox( + color: const Color(0xFF002211), + child: source.optionalChild(['child']), + ); }, ``` @@ -554,15 +572,48 @@ method can be used. For example, this is how `Row` is defined in ```rfwtxt 'Row': (BuildContext context, DataSource source) { return Row( - mainAxisAlignment: ArgumentDecoders.enumValue(MainAxisAlignment.values, source, ['mainAxisAlignment']) ?? MainAxisAlignment.start, - mainAxisSize: ArgumentDecoders.enumValue(MainAxisSize.values, source, ['mainAxisSize']) ?? MainAxisSize.max, - crossAxisAlignment: ArgumentDecoders.enumValue(CrossAxisAlignment.values, source, ['crossAxisAlignment']) ?? CrossAxisAlignment.center, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), - verticalDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['verticalDirection']) ?? VerticalDirection.down, - textBaseline: ArgumentDecoders.enumValue(TextBaseline.values, source, ['textBaseline']), + mainAxisAlignment: + ArgumentDecoders.enumValue( + MainAxisAlignment.values, + source, + ['mainAxisAlignment'], + ) ?? + MainAxisAlignment.start, + mainAxisSize: + ArgumentDecoders.enumValue( + MainAxisSize.values, + source, + ['mainAxisSize'], + ) ?? + MainAxisSize.max, + crossAxisAlignment: + ArgumentDecoders.enumValue( + CrossAxisAlignment.values, + source, + ['crossAxisAlignment'], + ) ?? + CrossAxisAlignment.center, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), + verticalDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['verticalDirection'], + ) ?? + VerticalDirection.down, + textBaseline: ArgumentDecoders.enumValue( + TextBaseline.values, + source, + ['textBaseline'], + ), children: source.childList(['children']), ); }, + ``` #### `ArgumentDecoders` @@ -676,7 +727,11 @@ This is usually written something like the following: ```dart return GestureDetector( - onTapDown: source.handler(['onTapDown'], (HandlerTrigger trigger) => (TapDownDetails details) => trigger()), + onTapDown: source.handler( + ['onTapDown'], + (HandlerTrigger trigger) => + (TapDownDetails details) => trigger(), + ), child: source.optionalChild(['child']), ); ``` @@ -687,10 +742,13 @@ To break this down more clearly: ```dart return GestureDetector( // onTapDown expects a function that takes a TapDownDetails - onTapDown: source.handler( // this returns a function that takes a TapDownDetails + onTapDown: source.handler( + // this returns a function that takes a TapDownDetails ['onTapDown'], - (HandlerTrigger trigger) { // "trigger" is the function that will send the event to RemoteWidget.onEvent - return (TapDownDetails details) { // this is the function that is returned by handler() above + (HandlerTrigger trigger) { + // "trigger" is the function that will send the event to RemoteWidget.onEvent + return (TapDownDetails details) { + // this is the function that is returned by handler() above trigger(); // the function calls "trigger" }; }, @@ -707,7 +765,9 @@ passing some values to the `trigger` method, as in: ```dart return GestureDetector( - onTapDown: source.handler(['onTapDown'], (HandlerTrigger trigger) { + onTapDown: source.handler(['onTapDown'], ( + HandlerTrigger trigger, + ) { return (TapDownDetails details) => trigger({ 'x': details.globalPosition.dx, 'y': details.globalPosition.dy, diff --git a/packages/rfw/example/hello/android/app/build.gradle b/packages/rfw/example/hello/android/app/build.gradle index a5ff7fce83f..a59d6c8b6be 100644 --- a/packages/rfw/example/hello/android/app/build.gradle +++ b/packages/rfw/example/hello/android/app/build.gradle @@ -27,12 +27,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/rfw/example/hello/pubspec.yaml b/packages/rfw/example/hello/pubspec.yaml index 83c7475ee70..a0dea2f21be 100644 --- a/packages/rfw/example/hello/pubspec.yaml +++ b/packages/rfw/example/hello/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/rfw/example/local/android/app/build.gradle b/packages/rfw/example/local/android/app/build.gradle index 4eb04538d03..959ac2b1053 100644 --- a/packages/rfw/example/local/android/app/build.gradle +++ b/packages/rfw/example/local/android/app/build.gradle @@ -27,12 +27,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17 } sourceSets { diff --git a/packages/rfw/example/local/pubspec.yaml b/packages/rfw/example/local/pubspec.yaml index 4bd596c8775..05c568e0de6 100644 --- a/packages/rfw/example/local/pubspec.yaml +++ b/packages/rfw/example/local/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/rfw/example/remote/android/app/build.gradle b/packages/rfw/example/remote/android/app/build.gradle index a3b54fc7ba3..8c6b377f98f 100644 --- a/packages/rfw/example/remote/android/app/build.gradle +++ b/packages/rfw/example/remote/android/app/build.gradle @@ -27,12 +27,12 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/rfw/example/remote/lib/main.dart b/packages/rfw/example/remote/lib/main.dart index 82885cd3fa3..8ddb51172ef 100644 --- a/packages/rfw/example/remote/lib/main.dart +++ b/packages/rfw/example/remote/lib/main.dart @@ -11,7 +11,8 @@ import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; import 'package:rfw/rfw.dart'; -const String urlPrefix = 'https://raw.githubusercontent.com/flutter/packages/main/packages/rfw/example/remote/remote_widget_libraries'; +const String urlPrefix = + 'https://raw.githubusercontent.com/flutter/packages/main/packages/rfw/example/remote/remote_widget_libraries'; void main() { runApp(const MaterialApp(home: Example())); @@ -34,8 +35,14 @@ class _ExampleState extends State { @override void initState() { super.initState(); - _runtime.update(const LibraryName(['core', 'widgets']), createCoreWidgets()); - _runtime.update(const LibraryName(['core', 'material']), createMaterialWidgets()); + _runtime.update( + const LibraryName(['core', 'widgets']), + createCoreWidgets(), + ); + _runtime.update( + const LibraryName(['core', 'material']), + createMaterialWidgets(), + ); _updateData(); _updateWidgets(); } @@ -57,17 +64,26 @@ class _ExampleState extends State { final File currentFile = File(path.join(home.path, 'current.rfw')); if (currentFile.existsSync()) { try { - _runtime.update(const LibraryName(['main']), decodeLibraryBlob(await currentFile.readAsBytes())); + _runtime.update( + const LibraryName(['main']), + decodeLibraryBlob(await currentFile.readAsBytes()), + ); setState(() { _ready = true; }); } catch (e, stack) { - FlutterError.reportError(FlutterErrorDetails(exception: e, stack: stack)); + FlutterError.reportError( + FlutterErrorDetails(exception: e, stack: stack), + ); } } print('Fetching: $urlPrefix/$nextFile'); // ignore: avoid_print - final HttpClientResponse client = await (await HttpClient().getUrl(Uri.parse('$urlPrefix/$nextFile'))).close(); - await currentFile.writeAsBytes(await client.expand((List chunk) => chunk).toList()); + final HttpClientResponse client = await (await HttpClient().getUrl( + Uri.parse('$urlPrefix/$nextFile'), + )).close(); + await currentFile.writeAsBytes( + await client.expand((List chunk) => chunk).toList(), + ); await settingsFile.writeAsString(nextFile); } @@ -78,7 +94,10 @@ class _ExampleState extends State { result = RemoteWidget( runtime: _runtime, data: _data, - widget: const FullyQualifiedWidgetName(LibraryName(['main']), 'Counter'), + widget: const FullyQualifiedWidgetName( + LibraryName(['main']), + 'Counter', + ), onEvent: (String name, DynamicMap arguments) { if (name == 'increment') { _counter += 1; @@ -94,19 +113,59 @@ class _ExampleState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Padding(padding: EdgeInsets.only(right: 100.0), child: Text('REMOTE', textAlign: TextAlign.center, style: TextStyle(letterSpacing: 12.0))), - Expanded(child: DecoratedBox(decoration: FlutterLogoDecoration(style: FlutterLogoStyle.horizontal))), - Padding(padding: EdgeInsets.only(left: 100.0), child: Text('WIDGETS', textAlign: TextAlign.center, style: TextStyle(letterSpacing: 12.0))), + Padding( + padding: EdgeInsets.only(right: 100.0), + child: Text( + 'REMOTE', + textAlign: TextAlign.center, + style: TextStyle(letterSpacing: 12.0), + ), + ), + Expanded( + child: DecoratedBox( + decoration: FlutterLogoDecoration( + style: FlutterLogoStyle.horizontal, + ), + ), + ), + Padding( + padding: EdgeInsets.only(left: 100.0), + child: Text( + 'WIDGETS', + textAlign: TextAlign.center, + style: TextStyle(letterSpacing: 12.0), + ), + ), Spacer(), - Expanded(child: Text('Every time this program is run, it fetches a new remote widgets library.', textAlign: TextAlign.center)), - Expanded(child: Text('The interface that it shows is whatever library was last fetched.', textAlign: TextAlign.center)), - Expanded(child: Text('Restart this application to see the new interface!', textAlign: TextAlign.center)), + Expanded( + child: Text( + 'Every time this program is run, it fetches a new remote widgets library.', + textAlign: TextAlign.center, + ), + ), + Expanded( + child: Text( + 'The interface that it shows is whatever library was last fetched.', + textAlign: TextAlign.center, + ), + ), + Expanded( + child: Text( + 'Restart this application to see the new interface!', + textAlign: TextAlign.center, + ), + ), ], ), ), ), ); } - return AnimatedSwitcher(duration: const Duration(milliseconds: 1250), switchOutCurve: Curves.easeOut, switchInCurve: Curves.easeOut, child: result); + return AnimatedSwitcher( + duration: const Duration(milliseconds: 1250), + switchOutCurve: Curves.easeOut, + switchInCurve: Curves.easeOut, + child: result, + ); } } diff --git a/packages/rfw/example/remote/pubspec.yaml b/packages/rfw/example/remote/pubspec.yaml index 47cdb0e225b..f7ac93e35b8 100644 --- a/packages/rfw/example/remote/pubspec.yaml +++ b/packages/rfw/example/remote/pubspec.yaml @@ -4,8 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/rfw/example/remote/remote_widget_libraries/encode.dart b/packages/rfw/example/remote/remote_widget_libraries/encode.dart index 93c63e9dc48..73cf9a08f40 100644 --- a/packages/rfw/example/remote/remote_widget_libraries/encode.dart +++ b/packages/rfw/example/remote/remote_widget_libraries/encode.dart @@ -10,7 +10,11 @@ import 'package:rfw/formats.dart'; void main() { final String counterApp1 = File('counter_app1.rfwtxt').readAsStringSync(); - File('counter_app1.rfw').writeAsBytesSync(encodeLibraryBlob(parseLibraryFile(counterApp1))); + File( + 'counter_app1.rfw', + ).writeAsBytesSync(encodeLibraryBlob(parseLibraryFile(counterApp1))); final String counterApp2 = File('counter_app2.rfwtxt').readAsStringSync(); - File('counter_app2.rfw').writeAsBytesSync(encodeLibraryBlob(parseLibraryFile(counterApp2))); + File( + 'counter_app2.rfw', + ).writeAsBytesSync(encodeLibraryBlob(parseLibraryFile(counterApp2))); } diff --git a/packages/rfw/lib/src/dart/binary.dart b/packages/rfw/lib/src/dart/binary.dart index 1d516b4d41b..d404f904d19 100644 --- a/packages/rfw/lib/src/dart/binary.dart +++ b/packages/rfw/lib/src/dart/binary.dart @@ -65,7 +65,9 @@ Uint8List encodeDataBlob(Object value) { /// Remote Flutter Widgets binary library blobs. /// * [parseDataFile], which parses the text variant of this format. Object decodeDataBlob(Uint8List bytes) { - final _BlobDecoder decoder = _BlobDecoder(bytes.buffer.asByteData(bytes.offsetInBytes, bytes.lengthInBytes)); + final _BlobDecoder decoder = _BlobDecoder( + bytes.buffer.asByteData(bytes.offsetInBytes, bytes.lengthInBytes), + ); decoder.expectSignature(dataBlobSignature); final Object result = decoder.readValue(); if (!decoder.finished) { @@ -276,11 +278,15 @@ Uint8List encodeLibraryBlob(RemoteWidgetLibrary value) { /// Remote Flutter Widgets binary data blobs. /// * [parseDataFile], which parses the text variant of this format. RemoteWidgetLibrary decodeLibraryBlob(Uint8List bytes) { - final _BlobDecoder decoder = _BlobDecoder(bytes.buffer.asByteData(bytes.offsetInBytes, bytes.lengthInBytes)); + final _BlobDecoder decoder = _BlobDecoder( + bytes.buffer.asByteData(bytes.offsetInBytes, bytes.lengthInBytes), + ); decoder.expectSignature(libraryBlobSignature); final RemoteWidgetLibrary result = decoder.readLibrary(); if (!decoder.finished) { - throw const FormatException('Unexpected trailing bytes after constructors.'); + throw const FormatException( + 'Unexpected trailing bytes after constructors.', + ); } return result; } @@ -332,7 +338,9 @@ class _BlobDecoder { void _advance(String context, int length) { if (_cursor + length > bytes.lengthInBytes) { - throw FormatException('Could not read $context at offset $_cursor: unexpected end of file.'); + throw FormatException( + 'Could not read $context at offset $_cursor: unexpected end of file.', + ); } _cursor += length; } @@ -351,8 +359,14 @@ class _BlobDecoder { } // We use multiplication rather than bit shifts because << truncates to 32 bits when compiled to JS: // https://dart.dev/guides/language/numbers#bitwise-operations - final int a = bytes.getUint32(byteOffset, _blobEndian); // dead code on VM target - final int b = bytes.getInt32(byteOffset + 4, _blobEndian); // dead code on VM target + final int a = bytes.getUint32( + byteOffset, + _blobEndian, + ); // dead code on VM target + final int b = bytes.getInt32( + byteOffset + 4, + _blobEndian, + ); // dead code on VM target return a + (b * 0x100000000); // dead code on VM target } @@ -366,7 +380,9 @@ class _BlobDecoder { final int length = _readInt64(); final int byteOffset = _cursor; _advance('string', length); - return utf8.decode(bytes.buffer.asUint8List(bytes.offsetInBytes + byteOffset, length)); + return utf8.decode( + bytes.buffer.asUint8List(bytes.offsetInBytes + byteOffset, length), + ); } List _readPartList() { @@ -378,12 +394,17 @@ class _BlobDecoder { case _msInt64: return _readInt64(); default: - throw FormatException('Invalid reference type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding blob.'); + throw FormatException( + 'Invalid reference type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding blob.', + ); } }); } - Map? _readMap(Object Function() readNode, { bool nullIfEmpty = false }) { + Map? _readMap( + Object Function() readNode, { + bool nullIfEmpty = false, + }) { final int count = _readInt64(); if (count == 0 && nullIfEmpty) { return null; @@ -391,10 +412,7 @@ class _BlobDecoder { return DynamicMap.fromEntries( Iterable>.generate( count, - (int index) => MapEntry( - _readString(), - readNode(), - ), + (int index) => MapEntry(_readString(), readNode()), ), ); } @@ -413,10 +431,8 @@ class _BlobDecoder { final Map cases = Map.fromEntries( Iterable>.generate( count, - (int index) => MapEntry( - _readSwitchKey(), - _readArgument(), - ), + (int index) => + MapEntry(_readSwitchKey(), _readArgument()), ), ); return Switch(value, cases); @@ -438,7 +454,10 @@ class _BlobDecoder { return DynamicList.generate(_readInt64(), (int index) => readNode()); case _msMap: return _readMap(readNode)!; - default: throw FormatException('Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding blob.'); + default: + throw FormatException( + 'Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding blob.', + ); } } @@ -466,7 +485,10 @@ class _BlobDecoder { case _msSwitch: return _readSwitch(); case _msSetState: - return SetStateHandler(StateReference(_readPartList()), _readArgument()); + return SetStateHandler( + StateReference(_readPartList()), + _readArgument(), + ); case _msWidgetBuilder: return _readWidgetBuilder(); case _msWidgetBuilderArgReference: @@ -490,7 +512,9 @@ class _BlobDecoder { final String argumentName = _readString(); final int type = _readByte(); if (type != _msWidget && type != _msSwitch) { - throw FormatException('Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding widget builder blob.'); + 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); @@ -507,17 +531,26 @@ class _BlobDecoder { case _msWidget: root = _readWidget(); default: - throw FormatException('Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding widget declaration root.'); + throw FormatException( + 'Unrecognized data type 0x${type.toRadixString(16).toUpperCase().padLeft(2, "0")} while decoding widget declaration root.', + ); } return WidgetDeclaration(name, initialState, root); } List _readDeclarationList() { - return List.generate(_readInt64(), (int index) => _readDeclaration()); + return List.generate( + _readInt64(), + (int index) => _readDeclaration(), + ); } Import _readImport() { - return Import(LibraryName(List.generate(_readInt64(), (int index) => _readString()))); + return Import( + LibraryName( + List.generate(_readInt64(), (int index) => _readString()), + ), + ); } List _readImportList() { @@ -543,7 +576,7 @@ class _BlobDecoder { throw FormatException( 'File signature mismatch. ' 'Expected ${signature.map((int byte) => byte.toRadixString(16).toUpperCase().padLeft(2, "0")).join(" ")} ' - 'but found ${bytes.map((int byte) => byte.toRadixString(16).toUpperCase().padLeft(2, "0")).join(" ")}.' + 'but found ${bytes.map((int byte) => byte.toRadixString(16).toUpperCase().padLeft(2, "0")).join(" ")}.', ); } } @@ -560,9 +593,13 @@ class _BlobEncoder { _BlobEncoder(); static final Uint8List _scratchOut = Uint8List(8); - static final ByteData _scratchIn = _scratchOut.buffer.asByteData(_scratchOut.offsetInBytes, _scratchOut.lengthInBytes); + static final ByteData _scratchIn = _scratchOut.buffer.asByteData( + _scratchOut.offsetInBytes, + _scratchOut.lengthInBytes, + ); - final BytesBuilder bytes = BytesBuilder(); // copying builder -- we repeatedly add _scratchOut after changing it + final BytesBuilder bytes = + BytesBuilder(); // copying builder -- we repeatedly add _scratchOut after changing it void _writeInt64(int value) { if (_has64Bits) { @@ -570,12 +607,21 @@ class _BlobEncoder { } else { // We use division rather than bit shifts because >> truncates to 32 bits when compiled to JS: // https://dart.dev/guides/language/numbers#bitwise-operations - if (value >= 0) { // dead code on VM target + if (value >= 0) { + // dead code on VM target _scratchIn.setInt32(0, value, _blobEndian); // dead code on VM target - _scratchIn.setInt32(4, value ~/ 0x100000000, _blobEndian); // dead code on VM target + _scratchIn.setInt32( + 4, + value ~/ 0x100000000, + _blobEndian, + ); // dead code on VM target } else { _scratchIn.setInt32(0, value, _blobEndian); // dead code on VM target - _scratchIn.setInt32(4, -((-value) ~/ 0x100000000 + 1), _blobEndian); // dead code on VM target + _scratchIn.setInt32( + 4, + -((-value) ~/ 0x100000000 + 1), + _blobEndian, + ); // dead code on VM target } } bytes.add(_scratchOut); @@ -603,7 +649,9 @@ class _BlobEncoder { bytes.addByte(_msString); _writeString(value); } else { - throw StateError('Unexpected type ${value.runtimeType} while encoding blob.'); + throw StateError( + 'Unexpected type ${value.runtimeType} while encoding blob.', + ); } } @@ -612,7 +660,8 @@ class _BlobEncoder { bytes.addByte(_msFalse); } else if (value == true) { bytes.addByte(_msTrue); - } else if (value is double && value is! int) { // When compiled to JS, a Number can be both. + } else if (value is double && value is! int) { + // When compiled to JS, a Number can be both. bytes.addByte(_msBinary64); _scratchIn.setFloat64(0, value, _blobEndian); bytes.add(_scratchOut); diff --git a/packages/rfw/lib/src/dart/model.dart b/packages/rfw/lib/src/dart/model.dart index 90d5420b20f..d834fe997ee 100644 --- a/packages/rfw/lib/src/dart/model.dart +++ b/packages/rfw/lib/src/dart/model.dart @@ -61,9 +61,9 @@ class SourceLocation implements Comparable { if (other.runtimeType != SourceLocation) { return false; } - return other is SourceLocation - && source == other.source - && offset == other.offset; + return other is SourceLocation && + source == other.source && + offset == other.offset; } @override @@ -137,8 +137,14 @@ class SourceRange { /// /// They must have identical [SourceLocation.source] objects. SourceRange(this.start, this.end) - : assert(start.source == end.source, 'The start and end locations have inconsistent source information.'), - assert(start < end, 'The start location must be before the end location.'); + : assert( + start.source == end.source, + 'The start and end locations have inconsistent source information.', + ), + assert( + start < end, + 'The start location must be before the end location.', + ); /// The start of a contiguous region of a source file that corresponds to a /// particular [BlobNode]. @@ -157,9 +163,7 @@ class SourceRange { if (other.runtimeType != SourceRange) { return false; } - return other is SourceRange - && start == other.start - && end == other.end; + return other is SourceRange && start == other.start && end == other.end; } @override @@ -194,7 +198,9 @@ abstract class BlobNode { // to do so. However, that would require growing the size of every [BlobNode] // object, and would require additional logic even in the binary parser (which // does not track source locations currently). - static final Expando _sources = Expando('BlobNode._sources'); + static final Expando _sources = Expando( + 'BlobNode._sources', + ); /// The source location that corresponds to this [BlobNode], if known. /// @@ -278,8 +284,7 @@ class LibraryName implements Comparable { if (other.runtimeType != runtimeType) { return false; } - return other is LibraryName - && _listEquals(parts, other.parts); + return other is LibraryName && _listEquals(parts, other.parts); } @override @@ -323,8 +328,9 @@ class FullyQualifiedWidgetName implements Comparable { if (other.runtimeType != runtimeType) { return false; } - return other is FullyQualifiedWidgetName - && library == other.library && widget == other.widget; + return other is FullyQualifiedWidgetName && + library == other.library && + widget == other.widget; } @override @@ -514,7 +520,7 @@ class BoundArgsReference extends Reference { /// The parameters must not be mutated after the object is created. /// /// Generally this class is created using [ArgsReference.bind]. - const BoundArgsReference(this.arguments, List parts): super(parts); + const BoundArgsReference(this.arguments, List parts) : super(parts); /// The object into which [parts] will be indexed. /// @@ -586,7 +592,7 @@ class LoopReference extends Reference { /// Wraps the given [loop] and [parts] as a [LoopReference]. /// /// The [parts] must not be mutated after the object is created. - const LoopReference(this.loop, List parts): super(parts); + const LoopReference(this.loop, List parts) : super(parts); /// The index to the referenced loop. /// @@ -643,7 +649,7 @@ class BoundLoopReference extends Reference { /// The [parts] must not be mutated after the object is created. /// /// Generally this class is created using [LoopReference.bind]. - const BoundLoopReference(this.value, List parts): super(parts); + const BoundLoopReference(this.value, List parts) : super(parts); /// The object into which [parts] will index. /// @@ -724,7 +730,7 @@ class BoundStateReference extends AnyStateReference { /// The [parts] must not be mutated after the object is created. /// /// Generally this class is created using [StateReference.bind]. - const BoundStateReference(this.depth, List parts): super(parts); + const BoundStateReference(this.depth, List parts) : super(parts); /// The widget to whose state the state reference refers. /// @@ -849,7 +855,8 @@ class WidgetDeclaration extends BlobNode { /// Binds the given [name] to the definition given by [root]. /// /// The [initialState] may be null. If it is not, this represents a stateful widget. - const WidgetDeclaration(this.name, this.initialState, this.root) : assert(root is ConstructorCall || root is Switch); + const WidgetDeclaration(this.name, this.initialState, this.root) + : assert(root is ConstructorCall || root is Switch); /// The name of the widget that this declaration represents. /// @@ -900,5 +907,8 @@ class RemoteWidgetLibrary extends WidgetLibrary { final List widgets; @override - String toString() => const Iterable.empty().followedBy(imports).followedBy(widgets).join('\n'); + String toString() => const Iterable.empty() + .followedBy(imports) + .followedBy(widgets) + .join('\n'); } diff --git a/packages/rfw/lib/src/dart/text.dart b/packages/rfw/lib/src/dart/text.dart index 81f2ef8f6d3..13f8cdeb42d 100644 --- a/packages/rfw/lib/src/dart/text.dart +++ b/packages/rfw/lib/src/dart/text.dart @@ -627,7 +627,7 @@ DynamicMap parseDataFile(String file) { /// * [parseDataFile], which uses a subset of this format to decode /// Remote Flutter Widgets text data files. /// * [decodeLibraryBlob], which decodes the binary variant of this format. -RemoteWidgetLibrary parseLibraryFile(String file, { Object? sourceIdentifier }) { +RemoteWidgetLibrary parseLibraryFile(String file, {Object? sourceIdentifier}) { final _Parser parser = _Parser(_tokenize(file), sourceIdentifier); return parser.readLibraryFile(); } @@ -644,7 +644,10 @@ const Set _reservedWords = { void _checkIsNotReservedWord(String identifier, _Token identifierToken) { if (_reservedWords.contains(identifier)) { - throw ParserException._fromToken('$identifier is a reserved word', identifierToken); + throw ParserException._fromToken( + '$identifier is a reserved word', + identifierToken, + ); } } @@ -657,7 +660,8 @@ sealed class _Token { } class _SymbolToken extends _Token { - _SymbolToken(this.symbol, int line, int column, int start, int end): super(line, column, start, end); + _SymbolToken(this.symbol, int line, int column, int start, int end) + : super(line, column, start, end); final int symbol; static const int dot = 0x2E; @@ -669,17 +673,21 @@ class _SymbolToken extends _Token { 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 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 ({) - static const int closeBrace = 0x7D; // U+007D RIGHT CURLY BRACKET character (}) + static const int closeBrace = + 0x7D; // U+007D RIGHT CURLY BRACKET character (}) @override String toString() => String.fromCharCode(symbol); } class _IntegerToken extends _Token { - _IntegerToken(this.value, int line, int column, int start, int end): super(line, column, start, end); + _IntegerToken(this.value, int line, int column, int start, int end) + : super(line, column, start, end); final int value; @override @@ -687,7 +695,8 @@ class _IntegerToken extends _Token { } class _DoubleToken extends _Token { - _DoubleToken(this.value, int line, int column, int start, int end): super(line, column, start, end); + _DoubleToken(this.value, int line, int column, int start, int end) + : super(line, column, start, end); final double value; @override @@ -695,7 +704,8 @@ class _DoubleToken extends _Token { } class _IdentifierToken extends _Token { - _IdentifierToken(this.value, int line, int column, int start, int end): super(line, column, start, end); + _IdentifierToken(this.value, int line, int column, int start, int end) + : super(line, column, start, end); final String value; @override @@ -703,7 +713,8 @@ class _IdentifierToken extends _Token { } class _StringToken extends _Token { - _StringToken(this.value, int line, int column, int start, int end): super(line, column, start, end); + _StringToken(this.value, int line, int column, int start, int end) + : super(line, column, start, end); final String value; @override @@ -739,7 +750,11 @@ class ParserException implements Exception { } factory ParserException._expected(String what, _Token token) { - return ParserException('Expected $what but found $token', token.line, token.column); + return ParserException( + 'Expected $what but found $token', + token.line, + token.column, + ); } factory ParserException._unexpected(_Token token) { @@ -836,7 +851,6 @@ Iterable<_Token> _tokenize(String file) sync* { } index += 1; switch (mode) { - case _TokenizerMode.main: switch (current) { case -1: @@ -945,14 +959,22 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.identifier; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)}', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)}', + line, + column, + ); } case _TokenizerMode.minus: // "-" assert(buffer.length == 1 && buffer[0] == 0x2D); switch (current) { case -1: - throw ParserException('Unexpected end of file after minus sign', line, column); + throw ParserException( + 'Unexpected end of file after minus sign', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -966,7 +988,11 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.minusInteger; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} after minus sign (expected digit)', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after minus sign (expected digit)', + line, + column, + ); } case _TokenizerMode.zero: // "0" @@ -1021,18 +1047,34 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.x; buffer.clear(); default: - throw ParserException('Unexpected character ${_describeRune(current)} after zero', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after zero', + line, + column, + ); } case _TokenizerMode.minusInteger: // "-0" switch (current) { case -1: - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1046,7 +1088,13 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; @@ -1071,19 +1119,35 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.e; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} after negative zero', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after negative zero', + line, + column, + ); } case _TokenizerMode.integer: // "00", "1", "-00" switch (current) { case -1: - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1097,7 +1161,13 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; @@ -1121,19 +1191,35 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.e; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)}', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)}', + line, + column, + ); } case _TokenizerMode.integerOnly: switch (current) { case -1: - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1147,13 +1233,25 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; mode = _TokenizerMode.main; case 0x2E: // U+002E FULL STOP character (.) - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 10), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 10), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.dot1; @@ -1167,15 +1265,25 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x37: // U+0037 DIGIT SEVEN character (7) case 0x38: // U+0038 DIGIT EIGHT character (8) case 0x39: // U+0039 DIGIT NINE character (9) - buffer.add(current); // https://github.com/dart-lang/sdk/issues/53349 + buffer.add( + current, + ); // https://github.com/dart-lang/sdk/issues/53349 default: - throw ParserException('Unexpected character ${_describeRune(current)} in integer', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in integer', + line, + column, + ); } case _TokenizerMode.numericDot: // "0.", "-0.", "00.", "1.", "-00." switch (current) { case -1: - throw ParserException('Unexpected end of file after decimal point', line, column); + throw ParserException( + 'Unexpected end of file after decimal point', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1189,18 +1297,34 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.fraction; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} in fraction component', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in fraction component', + line, + column, + ); } case _TokenizerMode.fraction: // "0.0", "-0.0", "00.0", "1.0", "-00.0" switch (current) { case -1: - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1214,7 +1338,13 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; @@ -1235,13 +1365,22 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.e; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} in fraction component', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in fraction component', + line, + column, + ); } - case _TokenizerMode.e: // "0e", "-0e", "00e", "1e", "-00e", "0.0e", "-0.0e", "00.0e", "1.0e", "-00.0e" + case _TokenizerMode + .e: // "0e", "-0e", "00e", "1e", "-00e", "0.0e", "-0.0e", "00.0e", "1.0e", "-00.0e" switch (current) { case -1: - throw ParserException('Unexpected end of file after exponent separator', line, column); + throw ParserException( + 'Unexpected end of file after exponent separator', + line, + column, + ); case 0x2D: // U+002D HYPHEN-MINUS character (-) mode = _TokenizerMode.negativeExponent; buffer.add(current); @@ -1258,13 +1397,22 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.exponent; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} after exponent separator', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after exponent separator', + line, + column, + ); } - case _TokenizerMode.negativeExponent: // "0e-", "-0e-", "00e-", "1e-", "-00e-", "0.0e-", "-0.0e-", "00.0e-", "1.0e-", "-00.0e-" + case _TokenizerMode + .negativeExponent: // "0e-", "-0e-", "00e-", "1e-", "-00e-", "0.0e-", "-0.0e-", "00.0e-", "1.0e-", "-00.0e-" switch (current) { case -1: - throw ParserException('Unexpected end of file after exponent separator and minus sign', line, column); + throw ParserException( + 'Unexpected end of file after exponent separator and minus sign', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1278,18 +1426,35 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.exponent; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} in exponent', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in exponent', + line, + column, + ); } - case _TokenizerMode.exponent: // "0e0", "-0e0", "00e0", "1e0", "-00e0", "0.0e0", "-0.0e0", "00.0e0", "1.0e0", "-00.0e0", "0e-0", "-0e-0", "00e-0", "1e-0", "-00e-0", "0.0e-0", "-0.0e-0", "00.0e-0", "1.0e-0", "-00.0e-0" + case _TokenizerMode + .exponent: // "0e0", "-0e0", "00e0", "1e0", "-00e0", "0.0e0", "-0.0e0", "00.0e0", "1.0e0", "-00.0e0", "0e-0", "-0e-0", "00e-0", "1e-0", "-00e-0", "0.0e-0", "-0.0e-0", "00.0e-0", "1.0e-0", "-00.0e-0" switch (current) { case -1: - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1303,7 +1468,13 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _DoubleToken(double.parse(String.fromCharCodes(buffer)), line, column, start, index - 1); + yield _DoubleToken( + double.parse(String.fromCharCodes(buffer)), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; @@ -1320,13 +1491,21 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x39: // U+0039 DIGIT NINE character (9) buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} in exponent', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in exponent', + line, + column, + ); } case _TokenizerMode.x: // "0x", "0X" switch (current) { case -1: - throw ParserException('Unexpected end of file after 0x prefix', line, column); + throw ParserException( + 'Unexpected end of file after 0x prefix', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1352,18 +1531,34 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.hex; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} after 0x prefix', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after 0x prefix', + line, + column, + ); } case _TokenizerMode.hex: switch (current) { case -1: - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 16), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 16), + line, + column, + start, + index - 1, + ); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 16), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 16), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1377,7 +1572,13 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _IntegerToken(int.parse(String.fromCharCodes(buffer), radix: 16), line, column, start, index - 1); + yield _IntegerToken( + int.parse(String.fromCharCodes(buffer), radix: 16), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; @@ -1406,7 +1607,11 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x66: // U+0066 LATIN SMALL LETTER F character buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} in hex literal', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in hex literal', + line, + column, + ); } case _TokenizerMode.dot1: // "." @@ -1520,30 +1725,60 @@ Iterable<_Token> _tokenize(String file) sync* { mode = _TokenizerMode.identifier; buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} after period', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after period', + line, + column, + ); } case _TokenizerMode.dot2: // ".." switch (current) { case -1: - throw ParserException('Unexpected end of file inside "..." symbol', line, column); + throw ParserException( + 'Unexpected end of file inside "..." symbol', + line, + column, + ); case 0x2E: // U+002E FULL STOP character (.) - yield _SymbolToken(_SymbolToken.tripleDot, line, column, start, index); + yield _SymbolToken( + _SymbolToken.tripleDot, + line, + column, + start, + index, + ); start = index; mode = _TokenizerMode.main; default: - throw ParserException('Unexpected character ${_describeRune(current)} inside "..." symbol', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} inside "..." symbol', + line, + column, + ); } case _TokenizerMode.identifier: switch (current) { case -1: - yield _IdentifierToken(String.fromCharCodes(buffer), line, column, start, index - 1); + yield _IdentifierToken( + String.fromCharCodes(buffer), + line, + column, + start, + index - 1, + ); yield _EofToken(line, column, index - 1, index); return; case 0x0A: // U+000A LINE FEED (LF) case 0x20: // U+0020 SPACE character - yield _IdentifierToken(String.fromCharCodes(buffer), line, column, start, index - 1); + yield _IdentifierToken( + String.fromCharCodes(buffer), + line, + column, + start, + index - 1, + ); buffer.clear(); start = index; mode = _TokenizerMode.main; @@ -1557,13 +1792,25 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5D: // U+005D RIGHT SQUARE BRACKET character (]) case 0x7B: // U+007B LEFT CURLY BRACKET character ({) case 0x7D: // U+007D RIGHT CURLY BRACKET character (}) - yield _IdentifierToken(String.fromCharCodes(buffer), line, column, start, index - 1); + yield _IdentifierToken( + String.fromCharCodes(buffer), + line, + column, + start, + index - 1, + ); buffer.clear(); yield _SymbolToken(current, line, column, index - 1, index); start = index; mode = _TokenizerMode.main; case 0x2E: // U+002E FULL STOP character (.) - yield _IdentifierToken(String.fromCharCodes(buffer), line, column, start, index); + yield _IdentifierToken( + String.fromCharCodes(buffer), + line, + column, + start, + index, + ); buffer.clear(); start = index; mode = _TokenizerMode.dot1; @@ -1632,17 +1879,35 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x5F: // U+005F LOW LINE character (_) buffer.add(current); default: - throw ParserException('Unexpected character ${_describeRune(current)} inside identifier', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} inside identifier', + line, + column, + ); } case _TokenizerMode.quote: switch (current) { case -1: - throw ParserException('Unexpected end of file inside string', line, column); + throw ParserException( + 'Unexpected end of file inside string', + line, + column, + ); case 0x0A: // U+000A LINE FEED (LF) - throw ParserException('Unexpected end of line inside string', line, column); + throw ParserException( + 'Unexpected end of line inside string', + line, + column, + ); case 0x27: // U+0027 APOSTROPHE character (') - yield _StringToken(String.fromCharCodes(buffer), line, column, start, index); + yield _StringToken( + String.fromCharCodes(buffer), + line, + column, + start, + index, + ); buffer.clear(); start = index; mode = _TokenizerMode.endQuote; @@ -1655,7 +1920,11 @@ Iterable<_Token> _tokenize(String file) sync* { case _TokenizerMode.quoteEscape: switch (current) { case -1: - throw ParserException('Unexpected end of file inside string', line, column); + throw ParserException( + 'Unexpected end of file inside string', + line, + column, + ); case 0x22: // U+0022 QUOTATION MARK character (") case 0x27: // U+0027 APOSTROPHE character (') case 0x5C: // U+005C REVERSE SOLIDUS character (\) @@ -1681,13 +1950,21 @@ Iterable<_Token> _tokenize(String file) sync* { assert(buffer2.isEmpty); mode = _TokenizerMode.quoteEscapeUnicode1; default: - throw ParserException('Unexpected character ${_describeRune(current)} after backslash in string', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after backslash in string', + line, + column, + ); } case _TokenizerMode.quoteEscapeUnicode1: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1713,13 +1990,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.quoteEscapeUnicode2; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.quoteEscapeUnicode2: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1745,13 +2030,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.quoteEscapeUnicode3; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.quoteEscapeUnicode3: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1777,13 +2070,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.quoteEscapeUnicode4; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.quoteEscapeUnicode4: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1811,17 +2112,35 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.clear(); mode = _TokenizerMode.quote; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.doubleQuote: switch (current) { case -1: - throw ParserException('Unexpected end of file inside string', line, column); + throw ParserException( + 'Unexpected end of file inside string', + line, + column, + ); case 0x0A: // U+000A LINE FEED (LF) - throw ParserException('Unexpected end of line inside string', line, column); + throw ParserException( + 'Unexpected end of line inside string', + line, + column, + ); case 0x22: // U+0022 QUOTATION MARK character (") - yield _StringToken(String.fromCharCodes(buffer), line, column, start, index); + yield _StringToken( + String.fromCharCodes(buffer), + line, + column, + start, + index, + ); buffer.clear(); start = index; mode = _TokenizerMode.endQuote; @@ -1834,7 +2153,11 @@ Iterable<_Token> _tokenize(String file) sync* { case _TokenizerMode.doubleQuoteEscape: switch (current) { case -1: - throw ParserException('Unexpected end of file inside string', line, column); + throw ParserException( + 'Unexpected end of file inside string', + line, + column, + ); case 0x22: // U+0022 QUOTATION MARK character (") case 0x27: // U+0027 APOSTROPHE character (') case 0x5C: // U+005C REVERSE SOLIDUS character (\) @@ -1860,13 +2183,21 @@ Iterable<_Token> _tokenize(String file) sync* { assert(buffer2.isEmpty); mode = _TokenizerMode.doubleQuoteEscapeUnicode1; default: - throw ParserException('Unexpected character ${_describeRune(current)} after backslash in string', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after backslash in string', + line, + column, + ); } case _TokenizerMode.doubleQuoteEscapeUnicode1: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1892,13 +2223,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.doubleQuoteEscapeUnicode2; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.doubleQuoteEscapeUnicode2: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1924,13 +2263,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.doubleQuoteEscapeUnicode3; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.doubleQuoteEscapeUnicode3: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1956,13 +2303,21 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.add(current); mode = _TokenizerMode.doubleQuoteEscapeUnicode4; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.doubleQuoteEscapeUnicode4: switch (current) { case -1: - throw ParserException('Unexpected end of file inside Unicode escape', line, column); + throw ParserException( + 'Unexpected end of file inside Unicode escape', + line, + column, + ); case 0x30: // U+0030 DIGIT ZERO character (0) case 0x31: // U+0031 DIGIT ONE character (1) case 0x32: // U+0032 DIGIT TWO character (2) @@ -1990,7 +2345,11 @@ Iterable<_Token> _tokenize(String file) sync* { buffer2.clear(); mode = _TokenizerMode.doubleQuote; default: - throw ParserException('Unexpected character ${_describeRune(current)} in Unicode escape', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} in Unicode escape', + line, + column, + ); } case _TokenizerMode.endQuote: @@ -2018,19 +2377,31 @@ Iterable<_Token> _tokenize(String file) sync* { case 0x2E: // U+002E FULL STOP character (.) mode = _TokenizerMode.dot1; default: - throw ParserException('Unexpected character ${_describeRune(current)} after end quote', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} after end quote', + line, + column, + ); } case _TokenizerMode.slash: switch (current) { case -1: - throw ParserException('Unexpected end of file inside comment delimiter', line, column); + throw ParserException( + 'Unexpected end of file inside comment delimiter', + line, + column, + ); case 0x2A: // U+002A ASTERISK character (*) mode = _TokenizerMode.blockComment; case 0x2F: // U+002F SOLIDUS character (/) mode = _TokenizerMode.comment; default: - throw ParserException('Unexpected character ${_describeRune(current)} inside comment delimiter', line, column); + throw ParserException( + 'Unexpected character ${_describeRune(current)} inside comment delimiter', + line, + column, + ); } case _TokenizerMode.comment: @@ -2048,7 +2419,11 @@ Iterable<_Token> _tokenize(String file) sync* { case _TokenizerMode.blockComment: switch (current) { case -1: - throw ParserException('Unexpected end of file in block comment', line, column); + throw ParserException( + 'Unexpected end of file in block comment', + line, + column, + ); case 0x2A: // U+002A ASTERISK character (*) mode = _TokenizerMode.blockCommentEnd; default: @@ -2059,7 +2434,11 @@ Iterable<_Token> _tokenize(String file) sync* { case _TokenizerMode.blockCommentEnd: switch (current) { case -1: - throw ParserException('Unexpected end of file in block comment', line, column); + throw ParserException( + 'Unexpected end of file in block comment', + line, + column, + ); case 0x2F: // U+002F SOLIDUS character (/) mode = _TokenizerMode.main; default: @@ -2077,7 +2456,8 @@ Iterable<_Token> _tokenize(String file) sync* { /// /// Test library files can be parsed by using [readLibraryFile]. class _Parser { - _Parser(Iterable<_Token> source, this.sourceIdentifier) : _source = source.iterator..moveNext(); + _Parser(Iterable<_Token> source, this.sourceIdentifier) + : _source = source.iterator..moveNext(); final Iterator<_Token> _source; final Object? sourceIdentifier; @@ -2100,17 +2480,16 @@ class _Parser { T _withSourceRange(T node, SourceLocation? start) { if (sourceIdentifier != null && start != null) { - node.associateSource(SourceRange( - start, - SourceLocation(sourceIdentifier!, _previousEnd), - )); + node.associateSource( + SourceRange(start, SourceLocation(sourceIdentifier!, _previousEnd)), + ); } return node; } bool _foundIdentifier(String identifier) { - return (_source.current is _IdentifierToken) - && ((_source.current as _IdentifierToken).value == identifier); + return (_source.current is _IdentifierToken) && + ((_source.current as _IdentifierToken).value == identifier); } void _expectIdentifier(String value) { @@ -2142,8 +2521,8 @@ class _Parser { } bool _foundSymbol(int symbol) { - return (_source.current is _SymbolToken) - && ((_source.current as _SymbolToken).symbol == symbol); + return (_source.current is _SymbolToken) && + ((_source.current as _SymbolToken).symbol == symbol); } bool _maybeReadSymbol(int symbol) { @@ -2156,10 +2535,16 @@ class _Parser { void _expectSymbol(int symbol) { if (_source.current is! _SymbolToken) { - throw ParserException._expected('symbol "${String.fromCharCode(symbol)}"', _source.current); + throw ParserException._expected( + 'symbol "${String.fromCharCode(symbol)}"', + _source.current, + ); } if ((_source.current as _SymbolToken).symbol != symbol) { - throw ParserException._expected('symbol "${String.fromCharCode(symbol)}"', _source.current); + throw ParserException._expected( + 'symbol "${String.fromCharCode(symbol)}"', + _source.current, + ); } _advance(); } @@ -2188,11 +2573,15 @@ class _Parser { required bool extended, List widgetBuilderScope = const [], }) { - final DynamicMap results = DynamicMap(); // ignore: prefer_collection_literals + final DynamicMap results = + DynamicMap(); // ignore: prefer_collection_literals while (_source.current is! _SymbolToken) { final String key = _readKey(); if (results.containsKey(key)) { - throw ParserException._fromToken('Duplicate key "$key" in map', _source.current); + throw ParserException._fromToken( + 'Duplicate key "$key" in map', + _source.current, + ); } _expectSymbol(_SymbolToken.colon); final Object value = _readValue( @@ -2259,28 +2648,44 @@ class _Parser { return results; } - Switch _readSwitch(SourceLocation? start, { + Switch _readSwitch( + SourceLocation? start, { List widgetBuilderScope = const [], }) { - final Object value = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); + final Object value = _readValue( + extended: true, + widgetBuilderScope: widgetBuilderScope, + ); final Map cases = {}; _expectSymbol(_SymbolToken.openBrace); while (_source.current is! _SymbolToken) { final Object? key; if (_foundIdentifier('default')) { if (cases.containsKey(null)) { - throw ParserException._fromToken('Switch has multiple default cases', _source.current); + throw ParserException._fromToken( + 'Switch has multiple default cases', + _source.current, + ); } key = null; _advance(); } else { - key = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); + key = _readValue( + extended: true, + widgetBuilderScope: widgetBuilderScope, + ); if (cases.containsKey(key)) { - throw ParserException._fromToken('Switch has duplicate cases for key $key', _source.current); + throw ParserException._fromToken( + 'Switch has duplicate cases for key $key', + _source.current, + ); } } _expectSymbol(_SymbolToken.colon); - final Object value = _readValue(extended: true, widgetBuilderScope: widgetBuilderScope); + final Object value = _readValue( + extended: true, + widgetBuilderScope: widgetBuilderScope, + ); cases[key] = value; if (_foundSymbol(_SymbolToken.comma)) { _advance(); @@ -2292,7 +2697,7 @@ class _Parser { return _withSourceRange(Switch(value, cases), start); } - List _readParts({ bool optional = false }) { + List _readParts({bool optional = false}) { if (optional && !_foundSymbol(_SymbolToken.dot)) { return const []; } @@ -2321,11 +2726,19 @@ class _Parser { if (_source.current is _SymbolToken) { switch ((_source.current as _SymbolToken).symbol) { case _SymbolToken.openBracket: - return _readList(widgetBuilderScope: widgetBuilderScope, extended: extended); + return _readList( + widgetBuilderScope: widgetBuilderScope, + extended: extended, + ); case _SymbolToken.openBrace: - return _readMap(widgetBuilderScope: widgetBuilderScope, extended: extended); + return _readMap( + widgetBuilderScope: widgetBuilderScope, + extended: extended, + ); case _SymbolToken.openParen: - return _readWidgetBuilderDeclaration(widgetBuilderScope: widgetBuilderScope); + return _readWidgetBuilderDeclaration( + widgetBuilderScope: widgetBuilderScope, + ); } } else if (_source.current is _IntegerToken) { final Object result = (_source.current as _IntegerToken).value; @@ -2392,21 +2805,36 @@ class _Parser { _advance(); final SourceLocation? innerStart = _getSourceLocation(); _expectIdentifier('state'); - final StateReference stateReference = _withSourceRange(StateReference(_readParts()), innerStart); + final StateReference stateReference = _withSourceRange( + StateReference(_readParts()), + innerStart, + ); _expectSymbol(_SymbolToken.equals); - final Object value = _readValue(widgetBuilderScope: widgetBuilderScope, extended: true); + 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); + return _withSourceRange( + WidgetBuilderArgReference(identifier, _readParts()), + start, + ); } final int index = _loopIdentifiers.lastIndexOf(identifier) + 1; if (index > 0) { final SourceLocation? start = _getSourceLocation(); _advance(); - return _withSourceRange(LoopReference(_loopIdentifiers.length - index, _readParts(optional: true)), start); + return _withSourceRange( + LoopReference( + _loopIdentifiers.length - index, + _readParts(optional: true), + ), + start, + ); } return _readConstructorCall(widgetBuilderScope: widgetBuilderScope); } @@ -2429,7 +2857,10 @@ class _Parser { widgetBuilderScope: [...widgetBuilderScope, argumentName], ); if (widget is! ConstructorCall && widget is! Switch) { - throw ParserException._fromToken('Expecting a switch or constructor call got $widget', valueToken); + 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/argument_decoders.dart b/packages/rfw/lib/src/flutter/argument_decoders.dart index ae02b59c89b..12bce90196b 100644 --- a/packages/rfw/lib/src/flutter/argument_decoders.dart +++ b/packages/rfw/lib/src/flutter/argument_decoders.dart @@ -10,7 +10,9 @@ import 'dart:math' as math show pi; // ignore: unnecessary_import, see https://github.com/flutter/flutter/pull/138881 -import 'dart:ui' show FontFeature; // TODO(ianh): https://github.com/flutter/flutter/issues/87235 +import 'dart:ui' + show + FontFeature; // TODO(ianh): https://github.com/flutter/flutter/issues/87235 import 'package:flutter/material.dart'; @@ -48,18 +50,25 @@ class AnimationDefaults extends InheritedWidget { /// ambient [AnimationDefaults] or if the nearest [AnimationDefaults] has a /// null [duration]. static Duration durationOf(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType()?.duration ?? const Duration(milliseconds: 200); + return context + .dependOnInheritedWidgetOfExactType() + ?.duration ?? + const Duration(milliseconds: 200); } /// Return the ambient [AnimationDefaults.curve], or [Curves.fastOutSlowIn] if /// there is no ambient [AnimationDefaults] or if the nearest /// [AnimationDefaults] has a null [curve]. static Curve curveOf(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType()?.curve ?? Curves.fastOutSlowIn; + return context + .dependOnInheritedWidgetOfExactType() + ?.curve ?? + Curves.fastOutSlowIn; } @override - bool updateShouldNotify(AnimationDefaults oldWidget) => duration != oldWidget.duration || curve != oldWidget.curve; + bool updateShouldNotify(AnimationDefaults oldWidget) => + duration != oldWidget.duration || curve != oldWidget.curve; } /// Signature for methods that decode structured values from a [DataSource], @@ -81,7 +90,9 @@ class ArgumentDecoders { const ArgumentDecoders._(); /// This is a workaround for https://github.com/dart-lang/sdk/issues/47021 - static const ArgumentDecoders __ = ArgumentDecoders._(); // ignore: unused_field + // ignore: unused_field + static const ArgumentDecoders __ = + ArgumentDecoders._(); // (in alphabetical order) @@ -167,7 +178,10 @@ class ArgumentDecoders { /// * topEnd: second value, defaulting to same as topStart. /// * bottomStart: third value, defaulting to same as topStart. /// * bottomEnd: fourth value, defaulting to same as topEnd. - static BorderRadiusGeometry? borderRadius(DataSource source, List key) { + static BorderRadiusGeometry? borderRadius( + DataSource source, + List key, + ) { final Radius? a = radius(source, [...key, 0]); if (a == null) { return null; @@ -198,7 +212,12 @@ class ArgumentDecoders { return BorderSide( color: color(source, [...key, 'color']) ?? const Color(0xFF000000), width: source.v([...key, 'width']) ?? 1.0, - style: enumValue(BorderStyle.values, source, [...key, 'style']) ?? BorderStyle.solid, + style: + enumValue(BorderStyle.values, source, [ + ...key, + 'style', + ]) ?? + BorderStyle.solid, ); } @@ -270,12 +289,17 @@ class ArgumentDecoders { case 'mode': return ColorFilter.mode( color(source, [...key, 'color']) ?? const Color(0xFF000000), - enumValue(BlendMode.values, source, [...key, 'blendMode']) ?? BlendMode.srcOver, + enumValue(BlendMode.values, source, [ + ...key, + 'blendMode', + ]) ?? + BlendMode.srcOver, ); case 'srgbToLinearGamma': return const ColorFilter.srgbToLinearGamma(); default: - final ArgumentDecoder? decoder = colorFilterDecoders[type]; + final ArgumentDecoder? decoder = + colorFilterDecoders[type]; if (decoder == null) { return null; } @@ -284,7 +308,8 @@ class ArgumentDecoders { } /// Extension mechanism for [colorFilter]. - static final Map> colorFilterDecoders = >{}; + static final Map> colorFilterDecoders = + >{}; /// Returns a list of 20 doubles from the specified list. /// @@ -342,7 +367,11 @@ class ArgumentDecoders { /// in the [curveDecoders] map, then the matching decoder from that map is /// invoked. Otherwise, the default obtained from [AnimationDefaults.curveOf] /// is used (which is why a [BuildContext] is required). - static Curve curve(DataSource source, List key, BuildContext context) { + static Curve curve( + DataSource source, + List key, + BuildContext context, + ) { final String? type = source.v(key); switch (type) { case 'linear': @@ -446,7 +475,8 @@ class ArgumentDecoders { /// /// The given key will specify a string, which is known to not match any of /// the values in [Curves]. - static final Map> curveDecoders = >{}; + static final Map> curveDecoders = + >{}; /// Returns a [Decoration] from the specified map. /// @@ -489,14 +519,26 @@ class ArgumentDecoders { borderRadius: borderRadius(source, [...key, 'borderRadius']), boxShadow: list(source, [...key, 'boxShadow'], boxShadow), gradient: gradient(source, [...key, 'gradient']), - backgroundBlendMode: enumValue(BlendMode.values, source, [...key, 'backgroundBlendMode']), - shape: enumValue(BoxShape.values, source, [...key, 'shape']) ?? BoxShape.rectangle, + backgroundBlendMode: enumValue(BlendMode.values, source, [ + ...key, + 'backgroundBlendMode', + ]), + shape: + enumValue(BoxShape.values, source, [...key, 'shape']) ?? + BoxShape.rectangle, ); case 'flutterLogo': return FlutterLogoDecoration( - textColor: color(source, [...key, 'color']) ?? const Color(0xFF757575), - style: enumValue(FlutterLogoStyle.values, source, [...key, 'style']) ?? FlutterLogoStyle.markOnly, - margin: (edgeInsets(source, [...key, 'margin']) ?? EdgeInsets.zero).resolve(TextDirection.ltr), + textColor: + color(source, [...key, 'color']) ?? const Color(0xFF757575), + style: + enumValue(FlutterLogoStyle.values, source, [ + ...key, + 'style', + ]) ?? + FlutterLogoStyle.markOnly, + margin: (edgeInsets(source, [...key, 'margin']) ?? EdgeInsets.zero) + .resolve(TextDirection.ltr), ); case 'shape': return ShapeDecoration( @@ -516,7 +558,8 @@ class ArgumentDecoders { } /// Extension mechanism for [decoration]. - static final Map> decorationDecoders = >{}; + static final Map> decorationDecoders = + >{}; /// Returns a [DecorationImage] from the specified map. /// @@ -539,7 +582,13 @@ class ArgumentDecoders { return DecorationImage( image: provider, onError: (Object exception, StackTrace? stackTrace) { - final VoidCallback? handler = source.voidHandler([...key, 'onError'], { 'exception': exception.toString(), 'stackTrack': stackTrace.toString() }); + final VoidCallback? handler = source.voidHandler( + [...key, 'onError'], + { + 'exception': exception.toString(), + 'stackTrack': stackTrace.toString(), + }, + ); if (handler != null) { handler(); } @@ -548,9 +597,20 @@ class ArgumentDecoders { fit: enumValue(BoxFit.values, source, [...key, 'fit']), alignment: alignment(source, [...key, 'alignment']) ?? Alignment.center, centerSlice: rect(source, [...key, 'centerSlice']), - repeat: enumValue(ImageRepeat.values, source, [...key, 'repeat']) ?? ImageRepeat.noRepeat, - matchTextDirection: source.v([...key, 'matchTextDirection']) ?? false, - filterQuality: enumValue(FilterQuality.values, source, [...key, 'filterQuality']) ?? FilterQuality.medium, + repeat: + enumValue(ImageRepeat.values, source, [ + ...key, + 'repeat', + ]) ?? + ImageRepeat.noRepeat, + matchTextDirection: + source.v([...key, 'matchTextDirection']) ?? false, + filterQuality: + enumValue(FilterQuality.values, source, [ + ...key, + 'filterQuality', + ]) ?? + FilterQuality.medium, ); } @@ -570,7 +630,11 @@ class ArgumentDecoders { /// If it's not an integer, the default obtained from /// [AnimationDefaults.durationOf] is used (which is why a [BuildContext] is /// required). - static Duration duration(DataSource source, List key, BuildContext context) { + static Duration duration( + DataSource source, + List key, + BuildContext context, + ) { final int? value = source.v(key); if (value == null) { return AnimationDefaults.durationOf(context); @@ -598,12 +662,7 @@ class ArgumentDecoders { final double? b = source.v([...key, 1]); final double? c = source.v([...key, 2]); final double? d = source.v([...key, 3]); - return EdgeInsetsDirectional.fromSTEB( - a, - b ?? a, - c ?? a, - d ?? b ?? a, - ); + return EdgeInsetsDirectional.fromSTEB(a, b ?? a, c ?? a, d ?? b ?? a); } /// Returns one of the values of the specified enum `T`, from the specified string. @@ -639,7 +698,10 @@ class ArgumentDecoders { /// /// As this never returns null, it is possible to use it with [list]. static FontFeature fontFeature(DataSource source, List key) { - return FontFeature(source.v([...key, 'feature']) ?? 'NONE', source.v([...key, 'value']) ?? 1); + return FontFeature( + source.v([...key, 'feature']) ?? 'NONE', + source.v([...key, 'value']) ?? 1, + ); } /// Returns a [Gradient] from the specified map. @@ -688,18 +750,32 @@ class ArgumentDecoders { return LinearGradient( begin: alignment(source, [...key, 'begin']) ?? Alignment.centerLeft, end: alignment(source, [...key, 'end']) ?? Alignment.centerRight, - colors: list(source, [...key, 'colors'], colorOrBlack) ?? const [Color(0xFF000000), Color(0xFFFFFFFF)], + colors: + list(source, [...key, 'colors'], colorOrBlack) ?? + const [Color(0xFF000000), Color(0xFFFFFFFF)], stops: list(source, [...key, 'stops'], doubleOrZero), - tileMode: enumValue(TileMode.values, source, [...key, 'tileMode']) ?? TileMode.clamp, + tileMode: + enumValue(TileMode.values, source, [ + ...key, + 'tileMode', + ]) ?? + TileMode.clamp, // transform: GradientTransformMatrix(matrix(source, [...key, 'transform'])), // blocked by https://github.com/flutter/flutter/issues/87208 ); case 'radial': return RadialGradient( center: alignment(source, [...key, 'center']) ?? Alignment.center, radius: source.v([...key, 'radius']) ?? 0.5, - colors: list(source, [...key, 'colors'], colorOrBlack) ?? const [Color(0xFF000000), Color(0xFFFFFFFF)], + colors: + list(source, [...key, 'colors'], colorOrBlack) ?? + const [Color(0xFF000000), Color(0xFFFFFFFF)], stops: list(source, [...key, 'stops'], doubleOrZero), - tileMode: enumValue(TileMode.values, source, [...key, 'tileMode']) ?? TileMode.clamp, + tileMode: + enumValue(TileMode.values, source, [ + ...key, + 'tileMode', + ]) ?? + TileMode.clamp, focal: alignment(source, [...key, 'focal']), focalRadius: source.v([...key, 'focalRadius']) ?? 0.0, // transform: GradientTransformMatrix(matrix(source, [...key, 'transform'])), // blocked by https://github.com/flutter/flutter/issues/87208 @@ -709,9 +785,16 @@ class ArgumentDecoders { center: alignment(source, [...key, 'center']) ?? Alignment.center, startAngle: source.v([...key, 'startAngle']) ?? 0.0, endAngle: source.v([...key, 'endAngle']) ?? math.pi * 2, - colors: list(source, [...key, 'colors'], colorOrBlack) ?? const [Color(0xFF000000), Color(0xFFFFFFFF)], + colors: + list(source, [...key, 'colors'], colorOrBlack) ?? + const [Color(0xFF000000), Color(0xFFFFFFFF)], stops: list(source, [...key, 'stops'], doubleOrZero), - tileMode: enumValue(TileMode.values, source, [...key, 'tileMode']) ?? TileMode.clamp, + tileMode: + enumValue(TileMode.values, source, [ + ...key, + 'tileMode', + ]) ?? + TileMode.clamp, // transform: GradientTransformMatrix(matrix(source, [...key, 'transform'])), // blocked by https://github.com/flutter/flutter/issues/87208 ); default: @@ -724,7 +807,8 @@ class ArgumentDecoders { } /// Extension mechanism for [gradient]. - static final Map> gradientDecoders = >{}; + static final Map> gradientDecoders = + >{}; /// Returns a [SliverGridDelegate] from the specified map. /// @@ -757,20 +841,26 @@ class ArgumentDecoders { return SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: source.v([...key, 'crossAxisCount']) ?? 2, mainAxisSpacing: source.v([...key, 'mainAxisSpacing']) ?? 0.0, - crossAxisSpacing: source.v([...key, 'crossAxisSpacing']) ?? 0.0, - childAspectRatio: source.v([...key, 'childAspectRatio']) ?? 1.0, + crossAxisSpacing: + source.v([...key, 'crossAxisSpacing']) ?? 0.0, + childAspectRatio: + source.v([...key, 'childAspectRatio']) ?? 1.0, mainAxisExtent: source.v([...key, 'mainAxisExtent']), ); case 'maxCrossAxisExtent': return SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: source.v([...key, 'maxCrossAxisExtent']) ?? 100.0, + maxCrossAxisExtent: + source.v([...key, 'maxCrossAxisExtent']) ?? 100.0, mainAxisSpacing: source.v([...key, 'mainAxisSpacing']) ?? 0.0, - crossAxisSpacing: source.v([...key, 'crossAxisSpacing']) ?? 0.0, - childAspectRatio: source.v([...key, 'childAspectRatio']) ?? 1.0, + crossAxisSpacing: + source.v([...key, 'crossAxisSpacing']) ?? 0.0, + childAspectRatio: + source.v([...key, 'childAspectRatio']) ?? 1.0, mainAxisExtent: source.v([...key, 'mainAxisExtent']), ); default: - final ArgumentDecoder? decoder = gridDelegateDecoders[type]; + final ArgumentDecoder? decoder = + gridDelegateDecoders[type]; if (decoder == null) { return null; } @@ -779,7 +869,8 @@ class ArgumentDecoders { } /// Extension mechanism for [gridDelegate]. - static final Map> gridDelegateDecoders = >{}; + static final Map> + gridDelegateDecoders = >{}; /// Returns an [IconData] from the specified map. /// @@ -806,7 +897,8 @@ class ArgumentDecoders { return IconData( icon, fontFamily: source.v([...key, 'fontFamily']), - matchTextDirection: source.v([...key, 'matchTextDirection']) ?? false, + matchTextDirection: + source.v([...key, 'matchTextDirection']) ?? false, ); } @@ -860,11 +952,15 @@ class ArgumentDecoders { if (!imageUrl.hasScheme) { return AssetImage(image); } - return NetworkImage(image, scale: source.v([...key, 'scale']) ?? 1.0); + return NetworkImage( + image, + scale: source.v([...key, 'scale']) ?? 1.0, + ); } /// Extension mechanism for [imageProvider]. - static final Map> imageProviderDecoders = >{}; + static final Map> + imageProviderDecoders = >{}; /// Returns a [List] of `T` values from the specified list, using the given /// `decoder` to parse each value. @@ -875,7 +971,11 @@ class ArgumentDecoders { /// each entry in the list decoded using `decoder`. /// /// If `T` is non-nullable, the decoder must also be non-nullable. - static List? list(DataSource source, List key, ArgumentDecoder decoder) { + static List? list( + DataSource source, + List key, + ArgumentDecoder decoder, + ) { final int count = source.length(key); if (count == 0) { return null; @@ -915,7 +1015,11 @@ class ArgumentDecoders { return Locale(subtags[0], subtags[1]); } // TODO(ianh): verify this is correct (I tried looking up the Unicode spec but it was... confusing) - return Locale.fromSubtags(languageCode: subtags[0], scriptCode: subtags[1], countryCode: subtags[2]); + return Locale.fromSubtags( + languageCode: subtags[0], + scriptCode: subtags[1], + countryCode: subtags[2], + ); } /// Returns a list of 16 doubles from the specified list. @@ -969,7 +1073,8 @@ class ArgumentDecoders { return null; case 'blur': return MaskFilter.blur( - enumValue(BlurStyle.values, source, [...key, 'style']) ?? BlurStyle.normal, + enumValue(BlurStyle.values, source, [...key, 'style']) ?? + BlurStyle.normal, source.v([...key, 'sigma']) ?? 1.0, ); default: @@ -982,7 +1087,8 @@ class ArgumentDecoders { } /// Extension mechanism for [maskFilter]. - static final Map> maskFilterDecoders = >{}; + static final Map> maskFilterDecoders = + >{}; /// Returns an [Offset] from the specified map. /// @@ -1029,7 +1135,11 @@ class ArgumentDecoders { return null; } final Paint result = Paint(); - final BlendMode? paintBlendMode = enumValue(BlendMode.values, source, [...key, 'blendMode']); + final BlendMode? paintBlendMode = enumValue( + BlendMode.values, + source, + [...key, 'blendMode'], + ); if (paintBlendMode != null) { result.blendMode = paintBlendMode; } @@ -1037,11 +1147,18 @@ class ArgumentDecoders { if (paintColor != null) { result.color = paintColor; } - final ColorFilter? paintColorFilter = colorFilter(source, [...key, 'colorFilter']); + final ColorFilter? paintColorFilter = colorFilter(source, [ + ...key, + 'colorFilter', + ]); if (paintColorFilter != null) { result.colorFilter = paintColorFilter; } - final FilterQuality? paintFilterQuality = enumValue(FilterQuality.values, source, [...key, 'filterQuality']); + final FilterQuality? paintFilterQuality = enumValue( + FilterQuality.values, + source, + [...key, 'filterQuality'], + ); if (paintFilterQuality != null) { result.filterQuality = paintFilterQuality; } @@ -1057,7 +1174,10 @@ class ArgumentDecoders { if (paintIsAntiAlias != null) { result.isAntiAlias = paintIsAntiAlias; } - final MaskFilter? paintMaskFilter = maskFilter(source, [...key, 'maskFilter']); + final MaskFilter? paintMaskFilter = maskFilter(source, [ + ...key, + 'maskFilter', + ]); if (paintMaskFilter != null) { result.maskFilter = paintMaskFilter; } @@ -1168,9 +1288,15 @@ class ArgumentDecoders { /// /// Otherwise, if type is null or is not found in [shapeBorderDecoders], returns null. static ShapeBorder? shapeBorder(DataSource source, List key) { - final List? shapes = list(source, key, shapeBorder); + final List? shapes = list( + source, + key, + shapeBorder, + ); if (shapes != null) { - return shapes.where((ShapeBorder? a) => a != null).reduce((ShapeBorder? a, ShapeBorder? b) => a! + b!); + return shapes + .where((ShapeBorder? a) => a != null) + .reduce((ShapeBorder? a, ShapeBorder? b) => a! + b!); } final String? type = source.v([...key, 'type']); switch (type) { @@ -1181,7 +1307,9 @@ class ArgumentDecoders { case 'beveled': return BeveledRectangleBorder( side: borderSide(source, [...key, 'side']) ?? BorderSide.none, - borderRadius: borderRadius(source, [...key, 'borderRadius']) ?? BorderRadius.zero, + borderRadius: + borderRadius(source, [...key, 'borderRadius']) ?? + BorderRadius.zero, ); case 'circle': return CircleBorder( @@ -1190,12 +1318,16 @@ class ArgumentDecoders { case 'continuous': return ContinuousRectangleBorder( side: borderSide(source, [...key, 'side']) ?? BorderSide.none, - borderRadius: borderRadius(source, [...key, 'borderRadius']) ?? BorderRadius.zero, + borderRadius: + borderRadius(source, [...key, 'borderRadius']) ?? + BorderRadius.zero, ); case 'rounded': return RoundedRectangleBorder( side: borderSide(source, [...key, 'side']) ?? BorderSide.none, - borderRadius: borderRadius(source, [...key, 'borderRadius']) ?? BorderRadius.zero, + borderRadius: + borderRadius(source, [...key, 'borderRadius']) ?? + BorderRadius.zero, ); case 'stadium': return StadiumBorder( @@ -1211,7 +1343,8 @@ class ArgumentDecoders { } /// Extension mechanism for [shapeBorder]. - static final Map> shapeBorderDecoders = >{}; + static final Map> shapeBorderDecoders = + >{}; /// Returns a [Shader] based on the specified map. /// @@ -1237,7 +1370,11 @@ class ArgumentDecoders { case 'sweep': return gradient(source, key)!.createShader( rect(source, [...key, 'rect']) ?? Rect.zero, - textDirection: enumValue(TextDirection.values, source, ['textDirection']) ?? TextDirection.ltr, + textDirection: + enumValue(TextDirection.values, source, [ + 'textDirection', + ]) ?? + TextDirection.ltr, ); default: final ArgumentDecoder? decoder = shaderDecoders[type]; @@ -1249,7 +1386,8 @@ class ArgumentDecoders { } /// Extension mechanism for [shader]. - static final Map> shaderDecoders = >{}; + static final Map> shaderDecoders = + >{}; /// Returns a string from the specified string. /// @@ -1278,13 +1416,26 @@ class ArgumentDecoders { } return StrutStyle( fontFamily: source.v([...key, 'fontFamily']), - fontFamilyFallback: list(source, [...key, 'fontFamilyFallback'], string), + fontFamilyFallback: list(source, [ + ...key, + 'fontFamilyFallback', + ], string), fontSize: source.v([...key, 'fontSize']), height: source.v([...key, 'height']), - leadingDistribution: enumValue(TextLeadingDistribution.values, source, [...key, 'leadingDistribution']), + leadingDistribution: enumValue( + TextLeadingDistribution.values, + source, + [...key, 'leadingDistribution'], + ), leading: source.v([...key, 'leading']), - fontWeight: enumValue(FontWeight.values, source, [...key, 'fontWeight']), - fontStyle: enumValue(FontStyle.values, source, [...key, 'fontStyle']), + fontWeight: enumValue(FontWeight.values, source, [ + ...key, + 'fontWeight', + ]), + fontStyle: enumValue(FontStyle.values, source, [ + ...key, + 'fontStyle', + ]), forceStrutHeight: source.v([...key, 'forceStrutHeight']), ); } @@ -1298,14 +1449,25 @@ class ArgumentDecoders { /// true), `applyHeightToLastDescent` (boolean, defaults to true), and /// `leadingDistribution` ([enumValue] of [TextLeadingDistribution], deafults /// to [TextLeadingDistribution.proportional]). - static TextHeightBehavior? textHeightBehavior(DataSource source, List key) { + static TextHeightBehavior? textHeightBehavior( + DataSource source, + List key, + ) { if (!source.isMap(key)) { return null; } return TextHeightBehavior( - applyHeightToFirstAscent: source.v([...key, 'applyHeightToFirstAscent']) ?? true, - applyHeightToLastDescent: source.v([...key, 'applyHeightToLastDescent']) ?? true, - leadingDistribution: enumValue(TextLeadingDistribution.values, source, [...key, 'leadingDistribution']) ?? TextLeadingDistribution.proportional, + applyHeightToFirstAscent: + source.v([...key, 'applyHeightToFirstAscent']) ?? true, + applyHeightToLastDescent: + source.v([...key, 'applyHeightToLastDescent']) ?? true, + leadingDistribution: + enumValue( + TextLeadingDistribution.values, + source, + [...key, 'leadingDistribution'], + ) ?? + TextLeadingDistribution.proportional, ); } @@ -1322,7 +1484,11 @@ class ArgumentDecoders { /// Other values (and the abscence of a value) are interpreted as /// [TextDecoration.none]. static TextDecoration textDecoration(DataSource source, List key) { - final List? decorations = list(source, key, textDecoration); + final List? decorations = list( + source, + key, + textDecoration, + ); if (decorations != null) { return TextDecoration.combine(decorations); } @@ -1363,25 +1529,49 @@ class ArgumentDecoders { color: color(source, [...key, 'color']), backgroundColor: color(source, [...key, 'backgroundColor']), fontSize: source.v([...key, 'fontSize']), - fontWeight: enumValue(FontWeight.values, source, [...key, 'fontWeight']), - fontStyle: enumValue(FontStyle.values, source, [...key, 'fontStyle']), + fontWeight: enumValue(FontWeight.values, source, [ + ...key, + 'fontWeight', + ]), + fontStyle: enumValue(FontStyle.values, source, [ + ...key, + 'fontStyle', + ]), letterSpacing: source.v([...key, 'letterSpacing']), wordSpacing: source.v([...key, 'wordSpacing']), - textBaseline: enumValue(TextBaseline.values, source, ['textBaseline']), + textBaseline: enumValue(TextBaseline.values, source, [ + 'textBaseline', + ]), height: source.v([...key, 'height']), - leadingDistribution: enumValue(TextLeadingDistribution.values, source, [...key, 'leadingDistribution']), + leadingDistribution: enumValue( + TextLeadingDistribution.values, + source, + [...key, 'leadingDistribution'], + ), locale: locale(source, [...key, 'locale']), foreground: paint(source, [...key, 'foreground']), background: paint(source, [...key, 'background']), shadows: list(source, [...key, 'shadows'], boxShadow), - fontFeatures: list(source, [...key, 'fontFeatures'], fontFeature), + fontFeatures: list(source, [ + ...key, + 'fontFeatures', + ], fontFeature), decoration: textDecoration(source, [...key, 'decoration']), decorationColor: color(source, [...key, 'decorationColor']), - decorationStyle: enumValue(TextDecorationStyle.values, source, [...key, 'decorationStyle']), + decorationStyle: enumValue( + TextDecorationStyle.values, + source, + [...key, 'decorationStyle'], + ), decorationThickness: source.v([...key, 'decorationThickness']), fontFamily: source.v([...key, 'fontFamily']), - fontFamilyFallback: list(source, [...key, 'fontFamilyFallback'], string), - overflow: enumValue(TextOverflow.values, source, ['overflow']), + fontFamilyFallback: list(source, [ + ...key, + 'fontFamilyFallback', + ], string), + overflow: enumValue(TextOverflow.values, source, [ + 'overflow', + ]), ); } diff --git a/packages/rfw/lib/src/flutter/content.dart b/packages/rfw/lib/src/flutter/content.dart index 949f1f624e3..8d3fa5a1be8 100644 --- a/packages/rfw/lib/src/flutter/content.dart +++ b/packages/rfw/lib/src/flutter/content.dart @@ -26,11 +26,20 @@ Object? deepClone(Object? template) { if (template == null) { return null; } else if (template is DynamicMap) { - return template.map((String key, Object? value) => MapEntry(key, deepClone(value))); + return template.map( + (String key, Object? value) => + MapEntry(key, deepClone(value)), + ); } else if (template is DynamicList) { return template.map((Object? value) => deepClone(value)).toList(); } else { - assert(template is int || template is double || template is bool || template is String, 'unexpected state object type: ${template.runtimeType} ($template)'); + assert( + template is int || + template is double || + template is bool || + template is String, + 'unexpected state object type: ${template.runtimeType} ($template)', + ); return template; } } @@ -134,7 +143,7 @@ class DynamicContent { /// /// The `initialData` argument, if provided, is used to update all the keys /// in the [DynamicContent], as if [updateAll] had been called. - DynamicContent([ DynamicMap? initialData ]) { + DynamicContent([DynamicMap? initialData]) { if (initialData != null) { updateAll(initialData); } @@ -219,9 +228,13 @@ class DynamicContent { // Node in the [DynamicContent] tree. This should contain no [BlobNode]s. class _DynamicNode { - _DynamicNode(this._key, this._parent, this._value) : assert(_value == missing || _hasValidType(_value)); + _DynamicNode(this._key, this._parent, this._value) + : assert(_value == missing || _hasValidType(_value)); - _DynamicNode.root() : _key = missing, _parent = null, _value = DynamicMap(); // ignore: prefer_collection_literals + _DynamicNode.root() + : _key = missing, + _parent = null, + _value = DynamicMap(); // ignore: prefer_collection_literals final Object _key; final _DynamicNode? _parent; @@ -269,10 +282,7 @@ class _DynamicNode { if (value is DynamicList) { return value.every(_hasValidType); } - return value is int - || value is double - || value is bool - || value is String; + return value is int || value is double || value is bool || value is String; } _DynamicNode _prepare(Object childKey) { @@ -280,13 +290,16 @@ class _DynamicNode { if (!_children.containsKey(childKey)) { Object value; if (_value is DynamicMap) { - if (childKey is String && (_value as DynamicMap).containsKey(childKey)) { + if (childKey is String && + (_value as DynamicMap).containsKey(childKey)) { value = (_value as DynamicMap)[childKey]!; } else { value = missing; } } else if (_value is DynamicList) { - if (childKey is int && childKey >= 0 && childKey < (_value as DynamicList).length) { + if (childKey is int && + childKey >= 0 && + childKey < (_value as DynamicList).length) { value = (_value as DynamicList)[childKey]!; } else { value = missing; @@ -324,7 +337,10 @@ class _DynamicNode { } void update(Object value) { - assert(value == missing || _hasValidType(value), 'cannot update $this using $value'); + assert( + value == missing || _hasValidType(value), + 'cannot update $this using $value', + ); if (value == _value) { return; } diff --git a/packages/rfw/lib/src/flutter/core_widgets.dart b/packages/rfw/lib/src/flutter/core_widgets.dart index 8100a14c2df..e3d41d92540 100644 --- a/packages/rfw/lib/src/flutter/core_widgets.dart +++ b/packages/rfw/lib/src/flutter/core_widgets.dart @@ -227,14 +227,14 @@ import 'runtime.dart'; /// argument and `curve` argument. It sets the default animation duration and /// curve for widgets in the library that use the animated variants. If absent, /// a default of 200ms and [Curves.fastOutSlowIn] is used. -LocalWidgetLibrary createCoreWidgets() => LocalWidgetLibrary(_coreWidgetsDefinitions); +LocalWidgetLibrary createCoreWidgets() => + LocalWidgetLibrary(_coreWidgetsDefinitions); // In these widgets we make an effort to expose every single argument available. -Map get _coreWidgetsDefinitions => { - +Map +get _coreWidgetsDefinitions => { // Keep these in alphabetical order and add any new widgets to the list // in the documentation above. - 'AnimationDefaults': (BuildContext context, DataSource source) { return AnimationDefaults( duration: ArgumentDecoders.duration(source, ['duration'], context), @@ -247,7 +247,8 @@ Map get _coreWidgetsDefinitions => (['widthFactor']), heightFactor: source.v(['heightFactor']), onEnd: source.voidHandler(['onEnd']), @@ -272,28 +273,67 @@ Map get _coreWidgetsDefinitions => clipper, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.antiAlias, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.antiAlias, child: source.optionalChild(['child']), ); }, 'ColoredBox': (BuildContext context, DataSource source) { return ColoredBox( - color: ArgumentDecoders.color(source, ['color']) ?? const Color(0xFF000000), + color: + ArgumentDecoders.color(source, ['color']) ?? const Color(0xFF000000), child: source.optionalChild(['child']), ); }, 'Column': (BuildContext context, DataSource source) { return Column( - mainAxisAlignment: ArgumentDecoders.enumValue(MainAxisAlignment.values, source, ['mainAxisAlignment']) ?? MainAxisAlignment.start, - mainAxisSize: ArgumentDecoders.enumValue(MainAxisSize.values, source, ['mainAxisSize']) ?? MainAxisSize.max, - crossAxisAlignment: ArgumentDecoders.enumValue(CrossAxisAlignment.values, source, ['crossAxisAlignment']) ?? CrossAxisAlignment.center, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), - verticalDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['verticalDirection']) ?? VerticalDirection.down, - textBaseline: ArgumentDecoders.enumValue(TextBaseline.values, source, ['textBaseline']), + mainAxisAlignment: + ArgumentDecoders.enumValue( + MainAxisAlignment.values, + source, + ['mainAxisAlignment'], + ) ?? + MainAxisAlignment.start, + mainAxisSize: + ArgumentDecoders.enumValue( + MainAxisSize.values, + source, + ['mainAxisSize'], + ) ?? + MainAxisSize.max, + crossAxisAlignment: + ArgumentDecoders.enumValue( + CrossAxisAlignment.values, + source, + ['crossAxisAlignment'], + ) ?? + CrossAxisAlignment.center, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), + verticalDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['verticalDirection'], + ) ?? + VerticalDirection.down, + textBaseline: ArgumentDecoders.enumValue( + TextBaseline.values, + source, + ['textBaseline'], + ), children: source.childList(['children']), ); }, @@ -306,14 +346,22 @@ Map get _coreWidgetsDefinitions => (['width']), height: source.v(['height']), constraints: ArgumentDecoders.boxConstraints(source, ['constraints']), margin: ArgumentDecoders.edgeInsets(source, ['margin']), transform: ArgumentDecoders.matrix(source, ['transform']), - transformAlignment: ArgumentDecoders.alignment(source, ['transformAlignment']), - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + transformAlignment: ArgumentDecoders.alignment(source, [ + 'transformAlignment', + ]), + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, onEnd: source.voidHandler(['onEnd']), child: source.optionalChild(['child']), ); @@ -324,12 +372,30 @@ Map get _coreWidgetsDefinitions => (TextAlign.values, source, ['textAlign']), + textAlign: ArgumentDecoders.enumValue( + TextAlign.values, + source, + ['textAlign'], + ), softWrap: source.v(['softWrap']) ?? true, - overflow: ArgumentDecoders.enumValue(TextOverflow.values, source, ['overflow']) ?? TextOverflow.clip, + overflow: + ArgumentDecoders.enumValue( + TextOverflow.values, + source, + ['overflow'], + ) ?? + TextOverflow.clip, maxLines: source.v(['maxLines']), - textWidthBasis: ArgumentDecoders.enumValue(TextWidthBasis.values, source, ['textWidthBasis']) ?? TextWidthBasis.parent, - textHeightBehavior: ArgumentDecoders.textHeightBehavior(source, ['textHeightBehavior']), + textWidthBasis: + ArgumentDecoders.enumValue( + TextWidthBasis.values, + source, + ['textWidthBasis'], + ) ?? + TextWidthBasis.parent, + textHeightBehavior: ArgumentDecoders.textHeightBehavior(source, [ + 'textHeightBehavior', + ]), onEnd: source.voidHandler(['onEnd']), child: source.child(['child']), ); @@ -337,7 +403,13 @@ Map get _coreWidgetsDefinitions => (TextDirection.values, source, ['textDirection']) ?? TextDirection.ltr, + textDirection: + ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ) ?? + TextDirection.ltr, child: source.child(['child']), ); }, @@ -351,16 +423,24 @@ Map get _coreWidgetsDefinitions => (BoxFit.values, source, ['fit']) ?? BoxFit.contain, - alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + fit: + ArgumentDecoders.enumValue(BoxFit.values, source, ['fit']) ?? + BoxFit.contain, + alignment: + ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, child: source.optionalChild(['child']), ); }, 'FractionallySizedBox': (BuildContext context, DataSource source) { return FractionallySizedBox( - alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, + alignment: + ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, widthFactor: source.v(['widthFactor']), heightFactor: source.v(['heightFactor']), child: source.child(['child']), @@ -370,37 +450,73 @@ Map get _coreWidgetsDefinitions => (TapDownDetails details) => trigger()), - onTapUp: source.handler(['onTapUp'], (VoidCallback trigger) => (TapUpDetails details) => trigger()), + onTapDown: source.handler( + ['onTapDown'], + (VoidCallback trigger) => + (TapDownDetails details) => trigger(), + ), + onTapUp: source.handler( + ['onTapUp'], + (VoidCallback trigger) => + (TapUpDetails details) => trigger(), + ), onTapCancel: source.voidHandler(['onTapCancel']), onDoubleTap: source.voidHandler(['onDoubleTap']), onLongPress: source.voidHandler(['onLongPress']), - behavior: ArgumentDecoders.enumValue(HitTestBehavior.values, source, ['behavior']), + behavior: ArgumentDecoders.enumValue( + HitTestBehavior.values, + source, + ['behavior'], + ), child: source.optionalChild(['child']), ); }, 'GridView': (BuildContext context, DataSource source) { return GridView.builder( - scrollDirection: ArgumentDecoders.enumValue(Axis.values, source, ['scrollDirection']) ?? Axis.vertical, + scrollDirection: + ArgumentDecoders.enumValue(Axis.values, source, [ + 'scrollDirection', + ]) ?? + Axis.vertical, reverse: source.v(['reverse']) ?? false, // controller, primary: source.v(['primary']), // physics, shrinkWrap: source.v(['shrinkWrap']) ?? false, padding: ArgumentDecoders.edgeInsets(source, ['padding']), - gridDelegate: ArgumentDecoders.gridDelegate(source, ['gridDelegate']) ?? const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), - itemBuilder: (BuildContext context, int index) => source.child(['children', index]), + gridDelegate: + ArgumentDecoders.gridDelegate(source, ['gridDelegate']) ?? + const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), + itemBuilder: (BuildContext context, int index) => + source.child(['children', index]), itemCount: source.length(['children']), - addAutomaticKeepAlives: source.v(['addAutomaticKeepAlives']) ?? true, + addAutomaticKeepAlives: + source.v(['addAutomaticKeepAlives']) ?? true, addRepaintBoundaries: source.v(['addRepaintBoundaries']) ?? true, addSemanticIndexes: source.v(['addSemanticIndexes']) ?? true, cacheExtent: source.v(['cacheExtent']), semanticChildCount: source.v(['semanticChildCount']), - dragStartBehavior: ArgumentDecoders.enumValue(DragStartBehavior.values, source, ['dragStartBehavior']) ?? DragStartBehavior.start, - keyboardDismissBehavior: ArgumentDecoders.enumValue(ScrollViewKeyboardDismissBehavior.values, source, ['keyboardDismissBehavior']) ?? ScrollViewKeyboardDismissBehavior.manual, + dragStartBehavior: + ArgumentDecoders.enumValue( + DragStartBehavior.values, + source, + ['dragStartBehavior'], + ) ?? + DragStartBehavior.start, + keyboardDismissBehavior: + ArgumentDecoders.enumValue( + ScrollViewKeyboardDismissBehavior.values, + source, + ['keyboardDismissBehavior'], + ) ?? + ScrollViewKeyboardDismissBehavior.manual, restorationId: source.v(['restorationId']), - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.hardEdge, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.hardEdge, ); }, @@ -410,7 +526,11 @@ Map get _coreWidgetsDefinitions => (['size']), color: ArgumentDecoders.color(source, ['color']), semanticLabel: source.v(['semanticLabel']), - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), ); }, @@ -422,9 +542,7 @@ Map get _coreWidgetsDefinitions => get _coreWidgetsDefinitions => get _coreWidgetsDefinitions => (['height']), color: ArgumentDecoders.color(source, ['color']), // Animation? opacity, - colorBlendMode: ArgumentDecoders.enumValue(BlendMode.values, source, ['blendMode']), + colorBlendMode: ArgumentDecoders.enumValue( + BlendMode.values, + source, + ['blendMode'], + ), fit: ArgumentDecoders.enumValue(BoxFit.values, source, ['fit']), - alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, - repeat: ArgumentDecoders.enumValue(ImageRepeat.values, source, ['repeat']) ?? ImageRepeat.noRepeat, + alignment: + ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center, + repeat: + ArgumentDecoders.enumValue(ImageRepeat.values, source, [ + 'repeat', + ]) ?? + ImageRepeat.noRepeat, centerSlice: ArgumentDecoders.rect(source, ['centerSlice']), matchTextDirection: source.v(['matchTextDirection']) ?? false, gaplessPlayback: source.v(['gaplessPlayback']) ?? false, isAntiAlias: source.v(['isAntiAlias']) ?? false, - filterQuality: ArgumentDecoders.enumValue(FilterQuality.values, source, ['filterQuality']) ?? FilterQuality.low, + filterQuality: + ArgumentDecoders.enumValue( + FilterQuality.values, + source, + ['filterQuality'], + ) ?? + FilterQuality.low, ); }, 'ListBody': (BuildContext context, DataSource source) { return ListBody( - mainAxis: ArgumentDecoders.enumValue(Axis.values, source, ['mainAxis']) ?? Axis.vertical, + mainAxis: + ArgumentDecoders.enumValue(Axis.values, source, ['mainAxis']) ?? + Axis.vertical, reverse: source.v(['reverse']) ?? false, children: source.childList(['children']), ); @@ -469,7 +606,11 @@ Map get _coreWidgetsDefinitions => (Axis.values, source, ['scrollDirection']) ?? Axis.vertical, + scrollDirection: + ArgumentDecoders.enumValue(Axis.values, source, [ + 'scrollDirection', + ]) ?? + Axis.vertical, reverse: source.v(['reverse']) ?? false, // ScrollController? controller, primary: source.v(['primary']), @@ -479,15 +620,33 @@ Map get _coreWidgetsDefinitions => (['itemExtent']), prototypeItem: source.optionalChild(['prototypeItem']), itemCount: source.length(['children']), - itemBuilder: (BuildContext context, int index) => source.child(['children', index]), - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.hardEdge, - addAutomaticKeepAlives: source.v(['addAutomaticKeepAlives']) ?? true, + itemBuilder: (BuildContext context, int index) => + source.child(['children', index]), + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.hardEdge, + addAutomaticKeepAlives: + source.v(['addAutomaticKeepAlives']) ?? true, addRepaintBoundaries: source.v(['addRepaintBoundaries']) ?? true, addSemanticIndexes: source.v(['addSemanticIndexes']) ?? true, cacheExtent: source.v(['cacheExtent']), semanticChildCount: source.v(['semanticChildCount']), - dragStartBehavior: ArgumentDecoders.enumValue(DragStartBehavior.values, source, ['dragStartBehavior']) ?? DragStartBehavior.start, - keyboardDismissBehavior: ArgumentDecoders.enumValue(ScrollViewKeyboardDismissBehavior.values, source, ['keyboardDismissBehavior']) ?? ScrollViewKeyboardDismissBehavior.manual, + dragStartBehavior: + ArgumentDecoders.enumValue( + DragStartBehavior.values, + source, + ['dragStartBehavior'], + ) ?? + DragStartBehavior.start, + keyboardDismissBehavior: + ArgumentDecoders.enumValue( + ScrollViewKeyboardDismissBehavior.values, + source, + ['keyboardDismissBehavior'], + ) ?? + ScrollViewKeyboardDismissBehavior.manual, restorationId: source.v(['restorationId']), ); }, @@ -498,7 +657,8 @@ Map get _coreWidgetsDefinitions => (['opacity']) ?? 0.0, onEnd: source.voidHandler(['onEnd']), - alwaysIncludeSemantics: source.v(['alwaysIncludeSemantics']) ?? true, + alwaysIncludeSemantics: + source.v(['alwaysIncludeSemantics']) ?? true, child: source.optionalChild(['child']), ); }, @@ -507,7 +667,8 @@ Map get _coreWidgetsDefinitions => get _coreWidgetsDefinitions => (['strokeWidth']) ?? 2.0, fallbackWidth: source.v(['placeholderWidth']) ?? 400.0, fallbackHeight: source.v(['placeholderHeight']) ?? 400.0, @@ -542,8 +704,15 @@ Map get _coreWidgetsDefinitions => (['turns']) ?? 0.0, - alignment: (ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center).resolve(Directionality.of(context)), - filterQuality: ArgumentDecoders.enumValue(FilterQuality.values, source, ['filterQuality']), + alignment: + (ArgumentDecoders.alignment(source, ['alignment']) ?? + Alignment.center) + .resolve(Directionality.of(context)), + filterQuality: ArgumentDecoders.enumValue( + FilterQuality.values, + source, + ['filterQuality'], + ), onEnd: source.voidHandler(['onEnd']), child: source.optionalChild(['child']), ); @@ -553,25 +722,60 @@ Map get _coreWidgetsDefinitions => (MainAxisAlignment.values, source, ['mainAxisAlignment']) ?? MainAxisAlignment.start, - mainAxisSize: ArgumentDecoders.enumValue(MainAxisSize.values, source, ['mainAxisSize']) ?? MainAxisSize.max, - crossAxisAlignment: ArgumentDecoders.enumValue(CrossAxisAlignment.values, source, ['crossAxisAlignment']) ?? CrossAxisAlignment.center, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), - verticalDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['verticalDirection']) ?? VerticalDirection.down, - textBaseline: ArgumentDecoders.enumValue(TextBaseline.values, source, ['textBaseline']), + mainAxisAlignment: + ArgumentDecoders.enumValue( + MainAxisAlignment.values, + source, + ['mainAxisAlignment'], + ) ?? + MainAxisAlignment.start, + mainAxisSize: + ArgumentDecoders.enumValue( + MainAxisSize.values, + source, + ['mainAxisSize'], + ) ?? + MainAxisSize.max, + crossAxisAlignment: + ArgumentDecoders.enumValue( + CrossAxisAlignment.values, + source, + ['crossAxisAlignment'], + ) ?? + CrossAxisAlignment.center, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), + verticalDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['verticalDirection'], + ) ?? + VerticalDirection.down, + textBaseline: ArgumentDecoders.enumValue( + TextBaseline.values, + source, + ['textBaseline'], + ), children: source.childList(['children']), ); }, - // #enddocregion Row + // #enddocregion Row 'SafeArea': (BuildContext context, DataSource source) { return SafeArea( left: source.v(['left']) ?? true, top: source.v(['top']) ?? true, right: source.v(['right']) ?? true, bottom: source.v(['bottom']) ?? true, - minimum: (ArgumentDecoders.edgeInsets(source, ['minimum']) ?? EdgeInsets.zero).resolve(Directionality.of(context)), - maintainBottomViewPadding: source.v(['maintainBottomViewPadding']) ?? false, + minimum: + (ArgumentDecoders.edgeInsets(source, ['minimum']) ?? EdgeInsets.zero) + .resolve(Directionality.of(context)), + maintainBottomViewPadding: + source.v(['maintainBottomViewPadding']) ?? false, child: source.child(['child']), ); }, @@ -581,8 +785,15 @@ Map get _coreWidgetsDefinitions => (['scale']) ?? 1.0, - alignment: (ArgumentDecoders.alignment(source, ['alignment']) ?? Alignment.center).resolve(Directionality.of(context)), - filterQuality: ArgumentDecoders.enumValue(FilterQuality.values, source, ['filterQuality']), + alignment: + (ArgumentDecoders.alignment(source, ['alignment']) ?? + Alignment.center) + .resolve(Directionality.of(context)), + filterQuality: ArgumentDecoders.enumValue( + FilterQuality.values, + source, + ['filterQuality'], + ), onEnd: source.voidHandler(['onEnd']), child: source.optionalChild(['child']), ); @@ -590,14 +801,34 @@ Map get _coreWidgetsDefinitions => (Axis.values, source, ['scrollDirection']) ?? Axis.vertical, + scrollDirection: + ArgumentDecoders.enumValue(Axis.values, source, [ + 'scrollDirection', + ]) ?? + Axis.vertical, reverse: source.v(['reverse']) ?? false, padding: ArgumentDecoders.edgeInsets(source, ['padding']), primary: source.v(['primary']) ?? true, - dragStartBehavior: ArgumentDecoders.enumValue(DragStartBehavior.values, source, ['dragStartBehavior']) ?? DragStartBehavior.start, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.hardEdge, + dragStartBehavior: + ArgumentDecoders.enumValue( + DragStartBehavior.values, + source, + ['dragStartBehavior'], + ) ?? + DragStartBehavior.start, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.hardEdge, restorationId: source.v(['restorationId']), - keyboardDismissBehavior: ArgumentDecoders.enumValue(ScrollViewKeyboardDismissBehavior.values, source, ['keyboardDismissBehavior']) ?? ScrollViewKeyboardDismissBehavior.manual, + keyboardDismissBehavior: + ArgumentDecoders.enumValue( + ScrollViewKeyboardDismissBehavior.values, + source, + ['keyboardDismissBehavior'], + ) ?? + ScrollViewKeyboardDismissBehavior.manual, // ScrollPhysics? physics, // ScrollController? controller, child: source.optionalChild(['child']), @@ -613,29 +844,37 @@ Map get _coreWidgetsDefinitions => (['flex']) ?? 1, - ); + return Spacer(flex: source.v(['flex']) ?? 1); }, 'Stack': (BuildContext context, DataSource source) { return Stack( - alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? AlignmentDirectional.topStart, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), - fit: ArgumentDecoders.enumValue(StackFit.values, source, ['fit']) ?? StackFit.loose, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.hardEdge, + alignment: + ArgumentDecoders.alignment(source, ['alignment']) ?? + AlignmentDirectional.topStart, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), + fit: + ArgumentDecoders.enumValue(StackFit.values, source, [ + 'fit', + ]) ?? + StackFit.loose, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.hardEdge, children: source.childList(['children']), ); }, @@ -655,32 +894,87 @@ Map get _coreWidgetsDefinitions => (TextAlign.values, source, ['textAlign']), - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), + textAlign: ArgumentDecoders.enumValue( + TextAlign.values, + source, + ['textAlign'], + ), + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), locale: ArgumentDecoders.locale(source, ['locale']), softWrap: source.v(['softWrap']), - overflow: ArgumentDecoders.enumValue(TextOverflow.values, source, ['overflow']), - textScaler: textScaleFactor == null ? null : TextScaler.linear(textScaleFactor), + overflow: ArgumentDecoders.enumValue( + TextOverflow.values, + source, + ['overflow'], + ), + textScaler: textScaleFactor == null + ? null + : TextScaler.linear(textScaleFactor), maxLines: source.v(['maxLines']), semanticsLabel: source.v(['semanticsLabel']), - textWidthBasis: ArgumentDecoders.enumValue(TextWidthBasis.values, source, ['textWidthBasis']), - textHeightBehavior: ArgumentDecoders.textHeightBehavior(source, ['textHeightBehavior']), + textWidthBasis: ArgumentDecoders.enumValue( + TextWidthBasis.values, + source, + ['textWidthBasis'], + ), + textHeightBehavior: ArgumentDecoders.textHeightBehavior(source, [ + 'textHeightBehavior', + ]), ); }, 'Wrap': (BuildContext context, DataSource source) { return Wrap( - direction: ArgumentDecoders.enumValue(Axis.values, source, ['direction']) ?? Axis.horizontal, - alignment: ArgumentDecoders.enumValue(WrapAlignment.values, source, ['alignment']) ?? WrapAlignment.start, + direction: + ArgumentDecoders.enumValue(Axis.values, source, [ + 'direction', + ]) ?? + Axis.horizontal, + alignment: + ArgumentDecoders.enumValue( + WrapAlignment.values, + source, + ['alignment'], + ) ?? + WrapAlignment.start, spacing: source.v(['spacing']) ?? 0.0, - runAlignment: ArgumentDecoders.enumValue(WrapAlignment.values, source, ['runAlignment']) ?? WrapAlignment.start, + runAlignment: + ArgumentDecoders.enumValue( + WrapAlignment.values, + source, + ['runAlignment'], + ) ?? + WrapAlignment.start, runSpacing: source.v(['runSpacing']) ?? 0.0, - crossAxisAlignment: ArgumentDecoders.enumValue(WrapCrossAlignment.values, source, ['crossAxisAlignment']) ?? WrapCrossAlignment.start, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), - verticalDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['verticalDirection']) ?? VerticalDirection.down, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + crossAxisAlignment: + ArgumentDecoders.enumValue( + WrapCrossAlignment.values, + source, + ['crossAxisAlignment'], + ) ?? + WrapCrossAlignment.start, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), + verticalDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['verticalDirection'], + ) ?? + VerticalDirection.down, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, children: source.childList(['children']), ); }, - }; diff --git a/packages/rfw/lib/src/flutter/material_widgets.dart b/packages/rfw/lib/src/flutter/material_widgets.dart index 3f7afc253f2..ae1762f45c6 100644 --- a/packages/rfw/lib/src/flutter/material_widgets.dart +++ b/packages/rfw/lib/src/flutter/material_widgets.dart @@ -104,12 +104,12 @@ import 'runtime.dart'; /// JSON-like structures of RFW. For example, [WidgetStateProperty] is /// designed to be used with code to select the values, which doesn't work well /// in the RFW structure. -LocalWidgetLibrary createMaterialWidgets() => LocalWidgetLibrary(_materialWidgetsDefinitions); - -Map get _materialWidgetsDefinitions => { +LocalWidgetLibrary createMaterialWidgets() => + LocalWidgetLibrary(_materialWidgetsDefinitions); +Map +get _materialWidgetsDefinitions => { // Keep these in alphabetical order. - 'AboutListTile': (BuildContext context, DataSource source) { return AboutListTile( icon: source.optionalChild(['icon']), @@ -127,7 +127,8 @@ Map get _materialWidgetsDefinitions => (['automaticallyImplyLeading']) ?? true, + automaticallyImplyLeading: + source.v(['automaticallyImplyLeading']) ?? true, title: source.optionalChild(['title']), actions: source.childList(['actions']), elevation: source.v(['elevation']), @@ -136,15 +137,20 @@ Map get _materialWidgetsDefinitions => (['primary']) ?? true, centerTitle: source.v(['centerTitle']), - excludeHeaderSemantics: source.v(['excludeHeaderSemantics']) ?? false, + excludeHeaderSemantics: + source.v(['excludeHeaderSemantics']) ?? false, titleSpacing: source.v(['titleSpacing']), toolbarOpacity: source.v(['toolbarOpacity']) ?? 1.0, toolbarHeight: source.v(['toolbarHeight']), leadingWidth: source.v(['leadingWidth']), - toolbarTextStyle: ArgumentDecoders.textStyle(source, ['toolbarTextStyle']), + toolbarTextStyle: ArgumentDecoders.textStyle(source, [ + 'toolbarTextStyle', + ]), titleTextStyle: ArgumentDecoders.textStyle(source, ['titleTextStyle']), ); }, @@ -162,14 +168,33 @@ Map get _materialWidgetsDefinitions => (ButtonBarLayoutBehavior.values, source, ['layoutBehavior']) - ?? ButtonBarLayoutBehavior.padded; + final EdgeInsetsGeometry buttonPadding = + ArgumentDecoders.edgeInsets(source, ['buttonPadding']) ?? + const EdgeInsets.all(8.0); + final ButtonBarLayoutBehavior layoutBehavior = + ArgumentDecoders.enumValue( + ButtonBarLayoutBehavior.values, + source, + ['layoutBehavior'], + ) ?? + ButtonBarLayoutBehavior.padded; Widget overflowBar = OverflowBar( - alignment: ArgumentDecoders.enumValue(MainAxisAlignment.values, source, ['alignment']) ?? MainAxisAlignment.start, + alignment: + ArgumentDecoders.enumValue( + MainAxisAlignment.values, + source, + ['alignment'], + ) ?? + MainAxisAlignment.start, spacing: buttonPadding.horizontal / 2, - overflowDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['overflowDirection']) ?? VerticalDirection.down, + overflowDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['overflowDirection'], + ) ?? + VerticalDirection.down, overflowSpacing: source.v(['overflowButtonSpacing']) ?? 0.0, children: source.childList(['children']), ); @@ -185,14 +210,19 @@ Map get _materialWidgetsDefinitions => (MainAxisSize.values, source, ['mainAxisSize']) == MainAxisSize.min) { + if (ArgumentDecoders.enumValue(MainAxisSize.values, source, [ + 'mainAxisSize', + ]) == + MainAxisSize.min) { return IntrinsicWidth(child: overflowBar); } @@ -202,13 +232,31 @@ Map get _materialWidgetsDefinitions => (['spacing']) ?? 0.0, - alignment: ArgumentDecoders.enumValue(MainAxisAlignment.values, source, ['alignment']), + alignment: ArgumentDecoders.enumValue( + MainAxisAlignment.values, + source, + ['alignment'], + ), overflowSpacing: source.v(['overflowSpacing']) ?? 0.0, - overflowAlignment: ArgumentDecoders.enumValue(OverflowBarAlignment.values, source, ['overflowAlignment']) - ?? OverflowBarAlignment.start, - overflowDirection: ArgumentDecoders.enumValue(VerticalDirection.values, source, ['overflowDirection']) - ?? VerticalDirection.down, - textDirection: ArgumentDecoders.enumValue(TextDirection.values, source, ['textDirection']), + overflowAlignment: + ArgumentDecoders.enumValue( + OverflowBarAlignment.values, + source, + ['overflowAlignment'], + ) ?? + OverflowBarAlignment.start, + overflowDirection: + ArgumentDecoders.enumValue( + VerticalDirection.values, + source, + ['overflowDirection'], + ) ?? + VerticalDirection.down, + textDirection: ArgumentDecoders.enumValue( + TextDirection.values, + source, + ['textDirection'], + ), children: source.childList(['children']), ); }, @@ -221,7 +269,11 @@ Map get _materialWidgetsDefinitions => (['borderOnForeground']) ?? true, margin: ArgumentDecoders.edgeInsets(source, ['margin']), - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, semanticContainer: source.v(['semanticContainer']) ?? true, child: source.optionalChild(['child']), ); @@ -262,30 +314,53 @@ Map get _materialWidgetsDefinitions => > dropdownMenuItems = List>.generate( - length, - (int index) => DropdownMenuItem( - onTap: source.voidHandler(['items', index, 'onTap']), - value: source.v(['items', index, 'value']) ?? source.v(['items', index, 'value']) ?? source.v(['items', index, 'value']) ?? source.v(['items', index, 'value']), - enabled: source.v(['items', index, 'enabled']) ?? true, - alignment: ArgumentDecoders.alignment(source, ['items', index, 'alignment']) ?? AlignmentDirectional.centerStart, - child: source.child(['items', index, 'child']), - ), - ); + final List> dropdownMenuItems = + List>.generate( + length, + (int index) => DropdownMenuItem( + onTap: source.voidHandler(['items', index, 'onTap']), + value: + source.v(['items', index, 'value']) ?? + source.v(['items', index, 'value']) ?? + source.v(['items', index, 'value']) ?? + source.v(['items', index, 'value']), + enabled: source.v(['items', index, 'enabled']) ?? true, + alignment: + ArgumentDecoders.alignment(source, [ + 'items', + index, + 'alignment', + ]) ?? + AlignmentDirectional.centerStart, + child: source.child(['items', index, 'child']), + ), + ); return DropdownButton( items: dropdownMenuItems, - value: source.v(['value']) ?? source.v(['value']) ?? source.v(['value']) ?? source.v(['value']), + value: + source.v(['value']) ?? + source.v(['value']) ?? + source.v(['value']) ?? + source.v(['value']), disabledHint: source.optionalChild(['disabledHint']), - onChanged: source.handler(['onChanged'], (HandlerTrigger trigger) => (Object? value) => trigger({'value': value})), + onChanged: source.handler( + ['onChanged'], + (HandlerTrigger trigger) => + (Object? value) => trigger({'value': value}), + ), onTap: source.voidHandler(['onTap']), elevation: source.v(['elevation']) ?? 8, style: ArgumentDecoders.textStyle(source, ['style']), @@ -302,8 +377,12 @@ Map get _materialWidgetsDefinitions => (['menuMaxHeight']), enableFeedback: source.v(['enableFeedback']), - alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? AlignmentDirectional.centerStart, - borderRadius: ArgumentDecoders.borderRadius(source, ['borderRadius'])?.resolve(Directionality.of(context)), + alignment: + ArgumentDecoders.alignment(source, ['alignment']) ?? + AlignmentDirectional.centerStart, + borderRadius: ArgumentDecoders.borderRadius(source, [ + 'borderRadius', + ])?.resolve(Directionality.of(context)), padding: ArgumentDecoders.edgeInsets(source, ['padding']), ); }, @@ -314,7 +393,11 @@ Map get _materialWidgetsDefinitions => (['autofocus']) ?? false, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, child: source.child(['child']), ); }, @@ -337,9 +420,17 @@ Map get _materialWidgetsDefinitions => (['mini']) ?? false, shape: ArgumentDecoders.shapeBorder(source, ['shape']), - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, autofocus: source.v(['autofocus']) ?? false, - materialTapTargetSize: ArgumentDecoders.enumValue(MaterialTapTargetSize.values, source, ['materialTapTargetSize']), + materialTapTargetSize: ArgumentDecoders.enumValue( + MaterialTapTargetSize.values, + source, + ['materialTapTargetSize'], + ), isExtended: source.v(['isExtended']) ?? false, enableFeedback: source.v(['enableFeedback']), child: source.child(['child']), @@ -350,21 +441,51 @@ Map get _materialWidgetsDefinitions => (TapDownDetails details) => trigger()), - onTapUp: source.handler(['onTapUp'], (VoidCallback trigger) => (TapUpDetails details) => trigger()), + onTapDown: source.handler( + ['onTapDown'], + (VoidCallback trigger) => + (TapDownDetails details) => trigger(), + ), + onTapUp: source.handler( + ['onTapUp'], + (VoidCallback trigger) => + (TapUpDetails details) => trigger(), + ), onTapCancel: source.voidHandler(['onTapCancel']), onDoubleTap: source.voidHandler(['onDoubleTap']), onLongPress: source.voidHandler(['onLongPress']), onSecondaryTap: source.voidHandler(['onSecondaryTap']), - onSecondaryTapUp: source.handler(['onSecondaryTapUp'], (VoidCallback trigger) => (TapUpDetails details) => trigger()), - onSecondaryTapDown: source.handler(['onSecondaryTapDown'], (VoidCallback trigger) => (TapDownDetails details) => trigger()), + onSecondaryTapUp: source.handler( + ['onSecondaryTapUp'], + (VoidCallback trigger) => + (TapUpDetails details) => trigger(), + ), + onSecondaryTapDown: source.handler( + ['onSecondaryTapDown'], + (VoidCallback trigger) => + (TapDownDetails details) => trigger(), + ), onSecondaryTapCancel: source.voidHandler(['onSecondaryTapCancel']), - onHighlightChanged: source.handler(['onHighlightChanged'], (VoidCallback trigger) => (bool highlighted) => trigger()), - onHover: source.handler(['onHover'], (VoidCallback trigger) => (bool hovered) => trigger()), + onHighlightChanged: source.handler( + ['onHighlightChanged'], + (VoidCallback trigger) => + (bool highlighted) => trigger(), + ), + onHover: source.handler( + ['onHover'], + (VoidCallback trigger) => + (bool hovered) => trigger(), + ), containedInkWell: source.v(['containedInkWell']) ?? false, - highlightShape: ArgumentDecoders.enumValue(BoxShape.values, source, ['highlightShape']) ?? BoxShape.circle, + highlightShape: + ArgumentDecoders.enumValue(BoxShape.values, source, [ + 'highlightShape', + ]) ?? + BoxShape.circle, radius: source.v(['radius']), - borderRadius: ArgumentDecoders.borderRadius(source, ['borderRadius'])?.resolve(Directionality.of(context)), + borderRadius: ArgumentDecoders.borderRadius(source, [ + 'borderRadius', + ])?.resolve(Directionality.of(context)), customBorder: ArgumentDecoders.shapeBorder(source, ['customBorder']), focusColor: ArgumentDecoders.color(source, ['focusColor']), hoverColor: ArgumentDecoders.color(source, ['hoverColor']), @@ -373,9 +494,15 @@ Map get _materialWidgetsDefinitions => (['enableFeedback']) ?? true, excludeFromSemantics: source.v(['excludeFromSemantics']) ?? false, canRequestFocus: source.v(['canRequestFocus']) ?? true, - onFocusChange: source.handler(['onFocusChange'], (VoidCallback trigger) => (bool focus) => trigger()), + onFocusChange: source.handler( + ['onFocusChange'], + (VoidCallback trigger) => + (bool focus) => trigger(), + ), autofocus: source.v(['autofocus']) ?? false, - hoverDuration: ArgumentDecoders.duration(source, ['hoverDuration'], context), + hoverDuration: ArgumentDecoders.duration(source, [ + 'hoverDuration', + ], context), child: source.optionalChild(['child']), ); }, @@ -386,20 +513,42 @@ Map get _materialWidgetsDefinitions => (TapDownDetails details) => trigger()), + onTapDown: source.handler( + ['onTapDown'], + (VoidCallback trigger) => + (TapDownDetails details) => trigger(), + ), onTapCancel: source.voidHandler(['onTapCancel']), onSecondaryTap: source.voidHandler(['onSecondaryTap']), - onSecondaryTapUp: source.handler(['onSecondaryTapUp'], (VoidCallback trigger) => (TapUpDetails details) => trigger()), - onSecondaryTapDown: source.handler(['onSecondaryTapDown'], (VoidCallback trigger) => (TapDownDetails details) => trigger()), + onSecondaryTapUp: source.handler( + ['onSecondaryTapUp'], + (VoidCallback trigger) => + (TapUpDetails details) => trigger(), + ), + onSecondaryTapDown: source.handler( + ['onSecondaryTapDown'], + (VoidCallback trigger) => + (TapDownDetails details) => trigger(), + ), onSecondaryTapCancel: source.voidHandler(['onSecondaryTapCancel']), - onHighlightChanged: source.handler(['onHighlightChanged'], (VoidCallback trigger) => (bool highlighted) => trigger()), - onHover: source.handler(['onHover'], (VoidCallback trigger) => (bool hovered) => trigger()), + onHighlightChanged: source.handler( + ['onHighlightChanged'], + (VoidCallback trigger) => + (bool highlighted) => trigger(), + ), + onHover: source.handler( + ['onHover'], + (VoidCallback trigger) => + (bool hovered) => trigger(), + ), focusColor: ArgumentDecoders.color(source, ['focusColor']), hoverColor: ArgumentDecoders.color(source, ['hoverColor']), highlightColor: ArgumentDecoders.color(source, ['highlightColor']), splashColor: ArgumentDecoders.color(source, ['splashColor']), radius: source.v(['radius']), - borderRadius: ArgumentDecoders.borderRadius(source, ['borderRadius'])?.resolve(Directionality.of(context)), + borderRadius: ArgumentDecoders.borderRadius(source, [ + 'borderRadius', + ])?.resolve(Directionality.of(context)), customBorder: ArgumentDecoders.shapeBorder(source, ['customBorder']), enableFeedback: source.v(['enableFeedback']) ?? true, excludeFromSemantics: source.v(['excludeFromSemantics']) ?? false, @@ -450,7 +599,13 @@ Map get _materialWidgetsDefinitions => (MaterialType.values,source, ['type']) ?? MaterialType.canvas, + type: + ArgumentDecoders.enumValue( + MaterialType.values, + source, + ['type'], + ) ?? + MaterialType.canvas, elevation: source.v(['elevation']) ?? 0.0, color: ArgumentDecoders.color(source, ['color']), shadowColor: ArgumentDecoders.color(source, ['shadowColor']), @@ -459,8 +614,14 @@ Map get _materialWidgetsDefinitions => (['borderOnForeground']) ?? true, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, - animationDuration: ArgumentDecoders.duration(source, ['animationDuration'], context), + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, + animationDuration: ArgumentDecoders.duration(source, [ + 'animationDuration', + ], context), child: source.child(['child']), ); }, @@ -471,7 +632,11 @@ Map get _materialWidgetsDefinitions => (['autofocus']) ?? false, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, child: source.child(['child']), ); }, @@ -479,15 +644,23 @@ Map get _materialWidgetsDefinitions => persistentFooterButtons = source.childList(['persistentFooterButtons']); + final List persistentFooterButtons = source.childList([ + 'persistentFooterButtons', + ]); return Scaffold( - appBar: appBarWidget == null ? null : PreferredSize( - preferredSize: Size.fromHeight(source.v(['bottomHeight']) ?? 56.0), - child: appBarWidget, - ), + appBar: appBarWidget == null + ? null + : PreferredSize( + preferredSize: Size.fromHeight( + source.v(['bottomHeight']) ?? 56.0, + ), + child: appBarWidget, + ), body: source.optionalChild(['body']), floatingActionButton: source.optionalChild(['floatingActionButton']), - persistentFooterButtons: persistentFooterButtons.isEmpty ? null : persistentFooterButtons, + persistentFooterButtons: persistentFooterButtons.isEmpty + ? null + : persistentFooterButtons, drawer: source.optionalChild(['drawer']), endDrawer: source.optionalChild(['endDrawer']), bottomNavigationBar: source.optionalChild(['bottomNavigationBar']), @@ -495,13 +668,22 @@ Map get _materialWidgetsDefinitions => (['resizeToAvoidBottomInset']), primary: source.v(['primary']) ?? true, - drawerDragStartBehavior: ArgumentDecoders.enumValue(DragStartBehavior.values, source, ['drawerDragStartBehavior']) ?? DragStartBehavior.start, + drawerDragStartBehavior: + ArgumentDecoders.enumValue( + DragStartBehavior.values, + source, + ['drawerDragStartBehavior'], + ) ?? + DragStartBehavior.start, extendBody: source.v(['extendBody']) ?? false, - extendBodyBehindAppBar: source.v(['extendBodyBehindAppBar']) ?? false, + extendBodyBehindAppBar: + source.v(['extendBodyBehindAppBar']) ?? false, drawerScrimColor: ArgumentDecoders.color(source, ['drawerScrimColor']), drawerEdgeDragWidth: source.v(['drawerEdgeDragWidth']), - drawerEnableOpenDragGesture: source.v(['drawerEnableOpenDragGesture']) ?? true, - endDrawerEnableOpenDragGesture: source.v(['endDrawerEnableOpenDragGesture']) ?? true, + drawerEnableOpenDragGesture: + source.v(['drawerEnableOpenDragGesture']) ?? true, + endDrawerEnableOpenDragGesture: + source.v(['endDrawerEnableOpenDragGesture']) ?? true, restorationId: source.v(['restorationId']), ); }, @@ -511,31 +693,45 @@ Map get _materialWidgetsDefinitions => (['min']) ?? 0.0; final value = source.v(['value']) ?? min; final labelText = source.v(['label']); - final label = labelText != null ? '$labelText: ${value.toStringAsFixed(2)}' : value.toStringAsFixed(2); + final label = labelText != null + ? '$labelText: ${value.toStringAsFixed(2)}' + : value.toStringAsFixed(2); return Slider( value: value, secondaryTrackValue: source.v(['secondaryTrackValue']), - onChanged: source.handler(['onChanged'], - (HandlerTrigger trigger) => (double value) { - trigger({'value': value}); - }), - onChangeStart: source.handler(['onChangeStart'], - (HandlerTrigger trigger) => (double value) { - trigger({'value': value}); - }), - onChangeEnd: source.handler(['onChangeEnd'], - (HandlerTrigger trigger) => (double value) { - trigger({'value': value}); - }), + onChanged: source.handler( + ['onChanged'], + (HandlerTrigger trigger) => (double value) { + trigger({'value': value}); + }, + ), + onChangeStart: source.handler( + ['onChangeStart'], + (HandlerTrigger trigger) => (double value) { + trigger({'value': value}); + }, + ), + onChangeEnd: source.handler( + ['onChangeEnd'], + (HandlerTrigger trigger) => (double value) { + trigger({'value': value}); + }, + ), min: min, max: source.v(['max']) ?? 1.0, divisions: source.v(['divisions']), label: label, activeColor: ArgumentDecoders.color(source, ['activeColor']), inactiveColor: ArgumentDecoders.color(source, ['inactiveColor']), - secondaryActiveColor: ArgumentDecoders.color(source, ['secondaryActiveColor']), + secondaryActiveColor: ArgumentDecoders.color(source, [ + 'secondaryActiveColor', + ]), thumbColor: ArgumentDecoders.color(source, ['thumbColor']), - allowedInteraction: ArgumentDecoders.enumValue(SliderInteraction.values, source, ['allowedInteraction']), + allowedInteraction: ArgumentDecoders.enumValue( + SliderInteraction.values, + source, + ['allowedInteraction'], + ), ); }, @@ -545,7 +741,11 @@ Map get _materialWidgetsDefinitions => (['autofocus']) ?? false, - clipBehavior: ArgumentDecoders.enumValue(Clip.values, source, ['clipBehavior']) ?? Clip.none, + clipBehavior: + ArgumentDecoders.enumValue(Clip.values, source, [ + 'clipBehavior', + ]) ?? + Clip.none, child: source.child(['child']), ); }, @@ -559,5 +759,4 @@ Map get _materialWidgetsDefinitions => { } void _runtimeChanged() { - setState(() { /* widget probably changed */ }); + setState(() { + /* widget probably changed */ + }); } void _eventHandler(String eventName, DynamicMap eventArguments) { @@ -94,6 +102,11 @@ class _RemoteWidgetState extends State { @override Widget build(BuildContext context) { - return widget.runtime.build(context, widget.widget, widget.data, _eventHandler); + return widget.runtime.build( + context, + widget.widget, + widget.data, + _eventHandler, + ); } } diff --git a/packages/rfw/lib/src/flutter/runtime.dart b/packages/rfw/lib/src/flutter/runtime.dart index b3363214e63..aed3c8c49d0 100644 --- a/packages/rfw/lib/src/flutter/runtime.dart +++ b/packages/rfw/lib/src/flutter/runtime.dart @@ -17,7 +17,8 @@ import 'content.dart'; /// /// The [LocalWidgetLibrary] class wraps a map of widget names to /// [LocalWidgetBuilder] callbacks. -typedef LocalWidgetBuilder = Widget Function(BuildContext context, DataSource source); +typedef LocalWidgetBuilder = + Widget Function(BuildContext context, DataSource source); /// Signature of builders for remote widgets. typedef _RemoteWidgetBuilder = _CurriedWidget Function(DynamicMap builderArg); @@ -26,7 +27,8 @@ typedef _RemoteWidgetBuilder = _CurriedWidget Function(DynamicMap builderArg); /// /// This is used by [RemoteWidget] and [Runtime.build] as the callback for /// events triggered by remote widgets. -typedef RemoteEventHandler = void Function(String eventName, DynamicMap eventArguments); +typedef RemoteEventHandler = + void Function(String eventName, DynamicMap eventArguments); /// Signature of the callback passed to [DataSource.handler]. /// @@ -34,7 +36,8 @@ typedef RemoteEventHandler = void Function(String eventName, DynamicMap eventArg /// `trigger`. /// /// See [DataSource.handler] for details. -typedef HandlerGenerator = T Function(HandlerTrigger trigger); +typedef HandlerGenerator = + T Function(HandlerTrigger trigger); /// Signature of the callback passed to a [HandlerGenerator]. /// @@ -157,7 +160,7 @@ abstract class DataSource { /// both the arguments specified in the remote widget declaration and the /// argument provided to this method have the same name), the arguments /// specified here take precedence. - VoidCallback? voidHandler(List argsKey, [ DynamicMap? extraArguments ]); + VoidCallback? voidHandler(List argsKey, [DynamicMap? extraArguments]); /// Gets an event handler at the given key. /// @@ -176,7 +179,10 @@ abstract class DataSource { /// of the right type (`T`), and therefore a callback (`generator`) that knows /// how to wrap a function body (`trigger`) in the right signature (`T`) is /// needed to actually build that function (_entrypoint_). - T? handler(List argsKey, HandlerGenerator generator); + T? handler( + List argsKey, + HandlerGenerator generator, + ); } /// Widgets defined by the client application. All remote widgets eventually @@ -234,7 +240,8 @@ class Runtime extends ChangeNotifier { /// This object should be [dispose]d when it is no longer needed. Runtime(); - final Map _libraries = {}; + final Map _libraries = + {}; /// Replace the definitions of the specified library (`name`). /// @@ -282,11 +289,15 @@ class Runtime extends ChangeNotifier { /// /// * [update] and [clearLibraries], functions that populate this map. UnmodifiableMapView get libraries { - return UnmodifiableMapView(Map.from(_libraries)); + return UnmodifiableMapView( + Map.from(_libraries), + ); } - final Map _cachedConstructors = {}; - final Map _widgets = {}; + final Map + _cachedConstructors = {}; + final Map _widgets = + {}; void _clearCache() { _cachedConstructors.clear(); @@ -325,7 +336,12 @@ class Runtime extends ChangeNotifier { ); _widgets[widget] = boundWidget; } - return boundWidget.build(context, data, remoteEventTarget, const <_WidgetState>[]); + return boundWidget.build( + context, + data, + remoteEventTarget, + const <_WidgetState>[], + ); } /// Returns the [BlobNode] that most closely corresponds to a given [BuildContext]. @@ -356,7 +372,7 @@ class Runtime extends ChangeNotifier { return (context.widget as _Widget).curriedWidget; } - void _checkForImportLoops(LibraryName name, [ Set? visited ]) { + void _checkForImportLoops(LibraryName name, [Set? visited]) { final WidgetLibrary? library = _libraries[name]; if (library is RemoteWidgetLibrary) { visited ??= {}; @@ -373,9 +389,13 @@ class Runtime extends ChangeNotifier { } if (path.length == 1) { assert(path.single == dependency); - throw RemoteFlutterWidgetsException('Library $dependency depends on itself.'); + throw RemoteFlutterWidgetsException( + 'Library $dependency depends on itself.', + ); } else { - throw RemoteFlutterWidgetsException('Library $dependency indirectly depends on itself via ${path.reversed.join(" which depends on ")}.'); + throw RemoteFlutterWidgetsException( + 'Library $dependency indirectly depends on itself via ${path.reversed.join(" which depends on ")}.', + ); } } _checkForImportLoops(dependency, visited.toSet()); @@ -392,12 +412,17 @@ class Runtime extends ChangeNotifier { if (library is RemoteWidgetLibrary) { for (final WidgetDeclaration constructor in library.widgets) { if (constructor.name == fullName.widget) { - return _cachedConstructors[fullName] = _ResolvedConstructor(fullName, constructor); + return _cachedConstructors[fullName] = _ResolvedConstructor( + fullName, + constructor, + ); } } for (final Import import in library.imports) { final LibraryName dependency = import.name; - final _ResolvedConstructor? result = _findConstructor(FullyQualifiedWidgetName(dependency, fullName.widget)); + final _ResolvedConstructor? result = _findConstructor( + FullyQualifiedWidgetName(dependency, fullName.widget), + ); if (result != null) { // We cache the constructor under each name that we tried to look it up with, so // that next time it takes less time to find it. @@ -405,12 +430,20 @@ class Runtime extends ChangeNotifier { } } } else if (library is LocalWidgetLibrary) { - final LocalWidgetBuilder? constructor = library.findConstructor(fullName.widget); + final LocalWidgetBuilder? constructor = library.findConstructor( + fullName.widget, + ); if (constructor != null) { - return _cachedConstructors[fullName] = _ResolvedConstructor(fullName, constructor); + return _cachedConstructors[fullName] = _ResolvedConstructor( + fullName, + constructor, + ); } } else { - assert(library is Null); // ignore: prefer_void_to_null, type_check_with_null, https://github.com/dart-lang/sdk/issues/47017#issuecomment-907562014 + assert( + // ignore: prefer_void_to_null, type_check_with_null, https://github.com/dart-lang/sdk/issues/47017#issuecomment-907562014 + library is Null, + ); } _cachedConstructors[fullName] = null; return null; @@ -462,7 +495,8 @@ class Runtime extends ChangeNotifier { )..propagateSource(source); } usedWidgets = usedWidgets.toSet()..add(widget.fullName); - final WidgetDeclaration constructor = widget.constructor as WidgetDeclaration; + final WidgetDeclaration constructor = + widget.constructor as WidgetDeclaration; final int newDepth; if (constructor.initialState != null) { newDepth = stateDepth + 1; @@ -507,7 +541,9 @@ class Runtime extends ChangeNotifier { widgetBuilderScope, )..propagateSource(source); } - final Set missingLibraries = _findMissingLibraries(fullName.library).toSet(); + final Set missingLibraries = _findMissingLibraries( + fullName.library, + ).toSet(); if (missingLibraries.isNotEmpty) { return _CurriedLocalWidget.error( fullName, @@ -515,26 +551,31 @@ class Runtime extends ChangeNotifier { 'possibly because some dependencies were missing: ${missingLibraries.join(", ")}', )..propagateSource(source); } - return _CurriedLocalWidget.error(fullName, 'Could not find remote widget named ${fullName.widget} in ${fullName.library}.') - ..propagateSource(source); + return _CurriedLocalWidget.error( + fullName, + 'Could not find remote widget named ${fullName.widget} in ${fullName.library}.', + )..propagateSource(source); } Object _bindArguments( FullyQualifiedWidgetName context, - Object node, Object arguments, + Object node, + Object arguments, DynamicMap widgetBuilderScope, int stateDepth, Set usedWidgets, ) { if (node is ConstructorCall) { - final DynamicMap subArguments = _bindArguments( - context, - node.arguments, - arguments, - widgetBuilderScope, - stateDepth, - usedWidgets, - ) as DynamicMap; + final DynamicMap subArguments = + _bindArguments( + context, + node.arguments, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ) + as DynamicMap; return _applyConstructorAndBindArguments( FullyQualifiedWidgetName(context.library, node.name), subArguments, @@ -546,7 +587,7 @@ class Runtime extends ChangeNotifier { } if (node is WidgetBuilderDeclaration) { return (DynamicMap widgetBuilderArg) { - final DynamicMap newWidgetBuilderScope = { + final DynamicMap newWidgetBuilderScope = { ...widgetBuilderScope, node.argumentName: widgetBuilderArg, }; @@ -569,12 +610,19 @@ class Runtime extends ChangeNotifier { } return result as _CurriedWidget; }; - } + } if (node is DynamicMap) { return node.map( (String name, Object? value) => MapEntry( name, - _bindArguments(context, value!, arguments, widgetBuilderScope, stateDepth, usedWidgets), + _bindArguments( + context, + value!, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ), ), ); } @@ -593,22 +641,56 @@ class Runtime extends ChangeNotifier { ); } if (node is Loop) { - 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); + 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, widgetBuilderScope, stateDepth, usedWidgets), - node.outputs.map( - (Object? key, Object value) { - return MapEntry( - key == null ? key : _bindArguments(context, key, arguments, widgetBuilderScope, stateDepth, usedWidgets), - _bindArguments(context, value, arguments, widgetBuilderScope, 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, + widgetBuilderScope, + stateDepth, + usedWidgets, + ), + _bindArguments( + context, + value, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ), + ); + }), )..propagateSource(node); } if (node is ArgsReference) { @@ -621,21 +703,30 @@ class Runtime extends ChangeNotifier { return EventHandler( node.eventName, _bindArguments( - context, - node.eventArguments, - arguments, - widgetBuilderScope, - stateDepth, - usedWidgets, - ) as DynamicMap, + 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); + final BoundStateReference stateReference = + (node.stateReference as StateReference).bind(stateDepth); return SetStateHandler( stateReference, - _bindArguments(context, node.value, arguments, widgetBuilderScope, stateDepth, usedWidgets), + _bindArguments( + context, + node.value, + arguments, + widgetBuilderScope, + stateDepth, + usedWidgets, + ), )..propagateSource(node); } assert(node is! WidgetDeclaration); @@ -658,8 +749,10 @@ class _ResolvedDynamicList { } typedef _DataResolverCallback = Object Function(List dataKey); -typedef _StateResolverCallback = Object Function(List stateKey, int depth); -typedef _WidgetBuilderArgResolverCallback = Object Function(List argKey); +typedef _StateResolverCallback = + Object Function(List stateKey, int depth); +typedef _WidgetBuilderArgResolverCallback = + Object Function(List argKey); abstract class _CurriedWidget extends BlobNode { const _CurriedWidget( @@ -677,7 +770,10 @@ abstract class _CurriedWidget extends BlobNode { static Object _bindLoopVariable(Object node, Object argument, int depth) { if (node is DynamicMap) { return node.map( - (String name, Object? value) => MapEntry(name, _bindLoopVariable(value!, argument, depth)), + (String name, Object? value) => MapEntry( + name, + _bindLoopVariable(value!, argument, depth), + ), ); } if (node is DynamicList) { @@ -688,8 +784,10 @@ abstract class _CurriedWidget extends BlobNode { ); } if (node is Loop) { - return Loop(_bindLoopVariable(node.input, argument, depth), _bindLoopVariable(node.output, argument, depth + 1)) - ..propagateSource(node); + return Loop( + _bindLoopVariable(node.input, argument, depth), + _bindLoopVariable(node.output, argument, depth + 1), + )..propagateSource(node); } if (node is Switch) { return Switch( @@ -699,7 +797,7 @@ abstract class _CurriedWidget extends BlobNode { key == null ? null : _bindLoopVariable(key, argument, depth), _bindLoopVariable(value, argument, depth), ), - ) + ), )..propagateSource(node); } if (node is _CurriedLocalWidget) { @@ -707,7 +805,8 @@ abstract class _CurriedWidget extends BlobNode { node.fullName, node.child, _bindLoopVariable(node.arguments, argument, depth) as DynamicMap, - _bindLoopVariable(node.widgetBuilderScope, argument, depth) as DynamicMap, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) + as DynamicMap, )..propagateSource(node); } if (node is _CurriedRemoteWidget) { @@ -715,7 +814,8 @@ 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, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) + as DynamicMap, node.initialState, )..propagateSource(node); } @@ -724,7 +824,8 @@ 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, + _bindLoopVariable(node.widgetBuilderScope, argument, depth) + as DynamicMap, node.initialState, )..propagateSource(node); } @@ -735,16 +836,22 @@ abstract class _CurriedWidget extends BlobNode { return node; } if (node is BoundArgsReference) { - return BoundArgsReference(_bindLoopVariable(node.arguments, argument, depth), node.parts) - ..propagateSource(node); + return BoundArgsReference( + _bindLoopVariable(node.arguments, argument, depth), + node.parts, + )..propagateSource(node); } if (node is EventHandler) { - return EventHandler(node.eventName, _bindLoopVariable(node.eventArguments, argument, depth) as DynamicMap) - ..propagateSource(node); + return EventHandler( + node.eventName, + _bindLoopVariable(node.eventArguments, argument, depth) as DynamicMap, + )..propagateSource(node); } if (node is SetStateHandler) { - return SetStateHandler(node.stateReference, _bindLoopVariable(node.value, argument, depth)) - ..propagateSource(node); + return SetStateHandler( + node.stateReference, + _bindLoopVariable(node.value, argument, depth), + )..propagateSource(node); } return node; } @@ -763,9 +870,13 @@ abstract class _CurriedWidget extends BlobNode { _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) { + 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) { final Object node = list[currentIndex]!; if (node is Loop) { Object inputList = node.input; @@ -781,9 +892,10 @@ abstract class _CurriedWidget extends BlobNode { } else if (inputList is DataReference) { inputList = dataResolver(inputList.parts); } else if (inputList is WidgetBuilderArgReference) { - inputList = widgetBuilderArgResolver( - [inputList.argumentName, ...inputList.parts], - ); + inputList = widgetBuilderArgResolver([ + inputList.argumentName, + ...inputList.parts, + ]); } else if (inputList is BoundStateReference) { inputList = stateResolver(inputList.parts, inputList.depth); } else if (inputList is BoundLoopReference) { @@ -810,17 +922,24 @@ abstract class _CurriedWidget extends BlobNode { } final _ResolvedDynamicList entry = _listLookup( inputList, - targetEffectiveIndex >= 0 ? targetEffectiveIndex - effectiveIndex : -1, + targetEffectiveIndex >= 0 + ? targetEffectiveIndex - effectiveIndex + : -1, stateResolver, dataResolver, widgetBuilderArgResolver, ); if (entry.result != null) { - final Object boundResult = _bindLoopVariable(node.output, entry.result!, 0); + final Object boundResult = _bindLoopVariable( + node.output, + entry.result!, + 0, + ); return _ResolvedDynamicList(null, boundResult, null); } effectiveIndex += entry.length!; - } else { // list[currentIndex] is not a Loop + } else { + // list[currentIndex] is not a Loop if (effectiveIndex == targetEffectiveIndex) { return _ResolvedDynamicList(null, list[currentIndex], null); } @@ -849,7 +968,10 @@ abstract class _CurriedWidget extends BlobNode { current = dataResolver(current.parts); continue; } else if (current is WidgetBuilderArgReference) { - current = widgetBuilderArgResolver([current.argumentName, ...current.parts]); + current = widgetBuilderArgResolver([ + current.argumentName, + ...current.parts, + ]); continue; } else if (current is BoundArgsReference) { List nextParts = current.parts; @@ -899,12 +1021,23 @@ abstract class _CurriedWidget extends BlobNode { if (current is EventHandler) { current = EventHandler( current.eventName, - _fix(current.eventArguments, stateResolver, dataResolver, widgetBuilderArgResolver) as DynamicMap, + _fix( + current.eventArguments, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ) + as DynamicMap, ); } else if (current is SetStateHandler) { current = SetStateHandler( current.stateReference, - _fix(current.value, stateResolver, dataResolver, widgetBuilderArgResolver), + _fix( + current.value, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ), ); } // else `current` is nothing special, and we'll just return it below. @@ -921,13 +1054,15 @@ abstract class _CurriedWidget extends BlobNode { if (parts[index] is! int) { return missing; } - current = _listLookup( - current, - parts[index] as int, - stateResolver, - dataResolver, - widgetBuilderArgResolver, - ).result ?? missing; + current = + _listLookup( + current, + parts[index] as int, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ).result ?? + missing; } else { assert(current is! ArgsReference); assert(current is! StateReference); @@ -936,7 +1071,10 @@ abstract class _CurriedWidget extends BlobNode { } index += 1; } - assert(current is! Reference, 'Unexpected unbound reference (of type ${current.runtimeType}): $current'); + assert( + current is! Reference, + 'Unexpected unbound reference (of type ${current.runtimeType}): $current', + ); assert(current is! Switch); assert(current is! Loop); return current; @@ -949,10 +1087,15 @@ abstract class _CurriedWidget extends BlobNode { _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, ) { if (root is DynamicMap) { - return root.map((String key, Object? value) => - MapEntry( + return root.map( + (String key, Object? value) => MapEntry( key, - _fix(root[key]!, stateResolver, dataResolver, widgetBuilderArgResolver), + _fix( + root[key]!, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ), ), ); } else if (root is DynamicList) { @@ -967,7 +1110,13 @@ abstract class _CurriedWidget extends BlobNode { return DynamicList.generate( length, (int index) => _fix( - _listLookup(root, index, stateResolver, dataResolver, widgetBuilderArgResolver).result!, + _listLookup( + root, + index, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ).result!, stateResolver, dataResolver, widgetBuilderArgResolver, @@ -976,11 +1125,22 @@ abstract class _CurriedWidget extends BlobNode { } else { return DynamicList.generate( root.length, - (int index) => _fix(root[index]!, stateResolver, dataResolver, widgetBuilderArgResolver), + (int index) => _fix( + root[index]!, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ), ); } } else if (root is BlobNode) { - return _resolveFrom(root, const [], stateResolver, dataResolver, widgetBuilderArgResolver); + return _resolveFrom( + root, + const [], + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); } else { return root; } @@ -993,9 +1153,21 @@ abstract class _CurriedWidget extends BlobNode { _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, { required bool expandLists, }) { - Object result = _resolveFrom(arguments, parts, stateResolver, dataResolver, widgetBuilderArgResolver); + Object result = _resolveFrom( + arguments, + parts, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); if (result is DynamicList && expandLists) { - result = _listLookup(result, -1, stateResolver, dataResolver, widgetBuilderArgResolver); + result = _listLookup( + result, + -1, + stateResolver, + dataResolver, + widgetBuilderArgResolver, + ); } assert(result is! Reference); assert(result is! Switch); @@ -1039,9 +1211,12 @@ class _CurriedLocalWidget extends _CurriedWidget { this.child, DynamicMap arguments, DynamicMap widgetBuilderScope, - ) : super(fullName, arguments, widgetBuilderScope, null); + ) : super(fullName, arguments, widgetBuilderScope, null); - factory _CurriedLocalWidget.error(FullyQualifiedWidgetName fullName, String message) { + factory _CurriedLocalWidget.error( + FullyQualifiedWidgetName fullName, + String message, + ) { return _CurriedLocalWidget( fullName, (BuildContext context, DataSource data) => _buildErrorWidget(message), @@ -1062,7 +1237,7 @@ class _CurriedLocalWidget extends _CurriedWidget { _StateResolverCallback stateResolver, _DataResolverCallback dataResolver, _WidgetBuilderArgResolverCallback widgetBuilderArgResolver, - ) { + ) { return child(context, source); } } @@ -1128,7 +1303,9 @@ class _CurriedSwitch extends _CurriedWidget { if (resolvedWidget is _CurriedWidget) { return resolvedWidget.build(context, data, remoteEventTarget, states); } - return _buildErrorWidget('Switch in $fullName did not resolve to a widget (got $resolvedWidget).'); + return _buildErrorWidget( + 'Switch in $fullName did not resolve to a widget (got $resolvedWidget).', + ); } @override @@ -1142,7 +1319,7 @@ class _Widget extends StatefulWidget { required this.widgetBuilderScope, required this.remoteEventTarget, required this.states, - }); + }); final _CurriedWidget curriedWidget; @@ -1175,7 +1352,9 @@ class _WidgetState extends State<_Widget> implements DataSource { if (oldWidget.curriedWidget != widget.curriedWidget) { _updateState(); } - if (oldWidget.data != widget.data || oldWidget.curriedWidget != widget.curriedWidget || oldWidget.states != widget.states) { + if (oldWidget.data != widget.data || + oldWidget.curriedWidget != widget.curriedWidget || + oldWidget.states != widget.states) { _unsubscribe(); } } @@ -1213,10 +1392,14 @@ class _WidgetState extends State<_Widget> implements DataSource { final Object subindex = parts[index]; if (current is DynamicMap) { if (subindex is! String) { - throw RemoteFlutterWidgetsException('${parts.join(".")} does not identify existing state.'); + throw RemoteFlutterWidgetsException( + '${parts.join(".")} does not identify existing state.', + ); } if (!current.containsKey(subindex)) { - throw RemoteFlutterWidgetsException('${parts.join(".")} does not identify existing state.'); + throw RemoteFlutterWidgetsException( + '${parts.join(".")} does not identify existing state.', + ); } if (index == parts.length - 1) { current[subindex] = value; @@ -1225,10 +1408,14 @@ class _WidgetState extends State<_Widget> implements DataSource { } } else if (current is DynamicList) { if (subindex is! int) { - throw RemoteFlutterWidgetsException('${parts.join(".")} does not identify existing state.'); + throw RemoteFlutterWidgetsException( + '${parts.join(".")} does not identify existing state.', + ); } if (subindex < 0 || subindex >= current.length) { - throw RemoteFlutterWidgetsException('${parts.join(".")} does not identify existing state.'); + throw RemoteFlutterWidgetsException( + '${parts.join(".")} does not identify existing state.', + ); } if (index == parts.length - 1) { current[subindex] = value; @@ -1236,7 +1423,9 @@ class _WidgetState extends State<_Widget> implements DataSource { current = current[subindex]!; } } else { - throw RemoteFlutterWidgetsException('${parts.join(".")} does not identify existing state.'); + throw RemoteFlutterWidgetsException( + '${parts.join(".")} does not identify existing state.', + ); } index += 1; } @@ -1266,8 +1455,7 @@ class _WidgetState extends State<_Widget> implements DataSource { @override bool isList(List argsKey) { final Object value = _fetch(argsKey, expandLists: false); - return value is _ResolvedDynamicList - || value is DynamicList; + return value is _ResolvedDynamicList || value is DynamicList; } @override @@ -1293,16 +1481,28 @@ class _WidgetState extends State<_Widget> implements DataSource { Widget child(List argsKey) { final Object value = _fetch(argsKey, expandLists: false); if (value is _CurriedWidget) { - return value.build(context, widget.data, widget.remoteEventTarget, widget.states); + return value.build( + context, + widget.data, + widget.remoteEventTarget, + widget.states, + ); } - return _buildErrorWidget('Not a widget at $argsKey (got $value) for ${widget.curriedWidget.fullName}.'); + return _buildErrorWidget( + 'Not a widget at $argsKey (got $value) for ${widget.curriedWidget.fullName}.', + ); } @override Widget? optionalChild(List argsKey) { final Object value = _fetch(argsKey, expandLists: false); if (value is _CurriedWidget) { - return value.build(context, widget.data, widget.remoteEventTarget, widget.states); + return value.build( + context, + widget.data, + widget.remoteEventTarget, + widget.states, + ); } return null; } @@ -1313,26 +1513,32 @@ class _WidgetState extends State<_Widget> implements DataSource { if (value is _ResolvedDynamicList) { assert(value.length != null); final DynamicList fullList = _fetchList(argsKey, value.length!); - return List.generate( - fullList.length, - (int index) { - final Object? node = fullList[index]; - if (node is _CurriedWidget) { - return node.build(context, widget.data, widget.remoteEventTarget, _states); - } - return _buildErrorWidget('Not a widget at $argsKey (got $node) for ${widget.curriedWidget.fullName}.'); - }, - ); + return List.generate(fullList.length, (int index) { + final Object? node = fullList[index]; + if (node is _CurriedWidget) { + return node.build( + context, + widget.data, + widget.remoteEventTarget, + _states, + ); + } + return _buildErrorWidget( + 'Not a widget at $argsKey (got $node) for ${widget.curriedWidget.fullName}.', + ); + }); } if (value == missing) { return const []; } return [ - _buildErrorWidget('Not a widget list at $argsKey (got $value) for ${widget.curriedWidget.fullName}.'), + _buildErrorWidget( + 'Not a widget list at $argsKey (got $value) for ${widget.curriedWidget.fullName}.', + ), ]; } - @override + @override Widget builder(List argsKey, DynamicMap builderArg) { return _fetchBuilder(argsKey, builderArg, optional: false)!; } @@ -1358,37 +1564,57 @@ class _WidgetState extends State<_Widget> implements DataSource { ); } return optional - ? null - : _buildErrorWidget('Not a builder at $argsKey (got $value) for ${widget.curriedWidget.fullName}.'); + ? 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)); + VoidCallback? voidHandler( + List argsKey, [ + DynamicMap? extraArguments, + ]) { + return handler( + argsKey, + (HandlerTrigger callback) => + () => callback(extraArguments), + ); } @override - T? handler(List argsKey, HandlerGenerator generator) { + T? handler( + List argsKey, + HandlerGenerator generator, + ) { Object value = _fetch(argsKey, expandLists: true); if (value is AnyEventHandler) { - value = [ value ]; + value = [value]; } else if (value is _ResolvedDynamicList) { value = _fetchList(argsKey, value.length!); } if (value is DynamicList) { - final List handlers = value.whereType().toList(); + final List handlers = value + .whereType() + .toList(); if (handlers.isNotEmpty) { return generator(([DynamicMap? extraArguments]) { for (final AnyEventHandler entry in handlers) { if (entry is EventHandler) { DynamicMap arguments = entry.eventArguments; if (extraArguments != null) { - arguments = DynamicMap.fromEntries(arguments.entries.followedBy(extraArguments.entries)); + arguments = DynamicMap.fromEntries( + arguments.entries.followedBy(extraArguments.entries), + ); } widget.remoteEventTarget(entry.eventName, arguments); } else if (entry is SetStateHandler) { assert(entry.stateReference is BoundStateReference); - _handleSetState((entry.stateReference as BoundStateReference).depth, entry.stateReference.parts, entry.value); + _handleSetState( + (entry.stateReference as BoundStateReference).depth, + entry.stateReference.parts, + entry.value, + ); } } }); @@ -1403,7 +1629,7 @@ class _WidgetState extends State<_Widget> implements DataSource { bool _debugFetching = false; final List<_Subscription> _dependencies = <_Subscription>[]; - Object _fetch(List argsKey, { required bool expandLists }) { + Object _fetch(List argsKey, {required bool expandLists}) { final _Key key = _Key(_kArgsSection, argsKey); final Object? value = _argsCache[key]; if (value != null && (value is! DynamicList || !expandLists)) { @@ -1450,12 +1676,12 @@ class _WidgetState extends State<_Widget> implements DataSource { } Object _widgetBuilderArgResolver(List rawDataKey) { - final _Key widgetBuilderArgKey = _Key(_kWidgetBuilderArgSection, rawDataKey); - final _Subscription subscription = _subscriptions[widgetBuilderArgKey] ??= _Subscription( - widget.widgetBuilderScope, - this, + final _Key widgetBuilderArgKey = _Key( + _kWidgetBuilderArgSection, rawDataKey, ); + final _Subscription subscription = _subscriptions[widgetBuilderArgKey] ??= + _Subscription(widget.widgetBuilderScope, this, rawDataKey); _dependencies.add(subscription); return subscription.value; } @@ -1465,7 +1691,9 @@ class _WidgetState extends State<_Widget> implements DataSource { final _Subscription subscription; if (!_subscriptions.containsKey(stateKey)) { if (depth >= _states.length) { - throw const RemoteFlutterWidgetsException('Reference to state value did not correspond to any stateful remote widget.'); + throw const RemoteFlutterWidgetsException( + 'Reference to state value did not correspond to any stateful remote widget.', + ); } final DynamicContent? state = _states[depth]._state; if (state == null) { @@ -1516,7 +1744,8 @@ const int _kWidgetBuilderArgSection = -3; @immutable class _Key { - _Key(this.section, this.parts) : assert(_isValidKey(parts), '$parts is not a valid key'); + _Key(this.section, this.parts) + : assert(_isValidKey(parts), '$parts is not a valid key'); static bool _isValidKey(List parts) { return parts.every((Object segment) => segment is int || segment is String); @@ -1527,9 +1756,11 @@ class _Key { @override bool operator ==(Object other) { - return other is _Key // _Key has no subclasses, don't need to check runtimeType - && section == other.section - && listEquals(parts, other.parts); + return other + is _Key // _Key has no subclasses, don't need to check runtimeType + && + section == other.section && + listEquals(parts, other.parts); } @override diff --git a/packages/rfw/pubspec.yaml b/packages/rfw/pubspec.yaml index 574faad5ee1..475eb126d12 100644 --- a/packages/rfw/pubspec.yaml +++ b/packages/rfw/pubspec.yaml @@ -2,11 +2,11 @@ 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.31 +version: 1.1.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/rfw/test/argument_decoders_test.dart b/packages/rfw/test/argument_decoders_test.dart index e668283e89c..fa7498175a0 100644 --- a/packages/rfw/test/argument_decoders_test.dart +++ b/packages/rfw/test/argument_decoders_test.dart @@ -62,15 +62,21 @@ void main() { int buildCount = 0; final Runtime runtime = Runtime() ..update(const LibraryName(['core']), createCoreWidgets()) - ..update(const LibraryName(['builder']), LocalWidgetLibrary({ - 'Test': (BuildContext context, DataSource source) { - buildCount += 1; - duration = AnimationDefaults.durationOf(context); - curve = AnimationDefaults.curveOf(context); - return const SizedBox.shrink(); - }, - })) - ..update(const LibraryName(['test']), parseLibraryFile('import core; widget root = SizedBox();')); + ..update( + const LibraryName(['builder']), + LocalWidgetLibrary({ + 'Test': (BuildContext context, DataSource source) { + buildCount += 1; + duration = AnimationDefaults.durationOf(context); + curve = AnimationDefaults.curveOf(context); + return const SizedBox.shrink(); + }, + }), + ) + ..update( + const LibraryName(['test']), + parseLibraryFile('import core; widget root = SizedBox();'), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); final List eventLog = []; @@ -78,137 +84,217 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { eventLog.add(eventName); - expect(eventArguments, const { 'argument': true }); + expect(eventArguments, const {'argument': true}); }, ), ); expect(find.byType(SizedBox), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Align(alignment: { x: 0.25, y: 0.75 }); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Align)).alignment, const Alignment(0.25, 0.75)); + expect( + tester.widget(find.byType(Align)).alignment, + const Alignment(0.25, 0.75), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Align(alignment: { start: 0.25, y: 0.75 }); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Align)).alignment, const Alignment(0.25, 0.75)); + expect( + tester.widget(find.byType(Align)).alignment, + const Alignment(0.25, 0.75), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; import builder; widget root = AnimationDefaults(curve: "easeOut", duration: 5000, child: Test()); - ''')); + '''), + ); await tester.pump(); expect(buildCount, 1); expect(duration, const Duration(seconds: 5)); expect(curve, Curves.easeOut); - ArgumentDecoders.curveDecoders['saw3'] = (DataSource source, List key) => const SawTooth(3); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + ArgumentDecoders.curveDecoders['saw3'] = + (DataSource source, List key) => const SawTooth(3); + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; import builder; widget root = AnimationDefaults(curve: "saw3", child: Test()); - ''')); + '''), + ); await tester.pump(); expect(curve, isA()); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = AspectRatio(aspectRatio: 0.5); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(AspectRatio)).aspectRatio, 0.5); + expect( + tester.widget(find.byType(AspectRatio)).aspectRatio, + 0.5, + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Center(widthFactor: 0.25); - ''')); + '''), + ); await tester.pump(); expect(tester.widget
(find.byType(Center)).widthFactor, 0.25); expect(tester.widget
(find.byType(Center)).heightFactor, null); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ColoredBox(color: 0xFF112233); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF112233)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF112233), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Column( mainAxisAlignment: "center", children: [ ColoredBox(color: 1), ColoredBox(color: 2) ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Column)).mainAxisAlignment, MainAxisAlignment.center); - expect(tester.widget(find.byType(Column)).crossAxisAlignment, CrossAxisAlignment.center); - expect(tester.widget(find.byType(Column)).verticalDirection, VerticalDirection.down); + expect( + tester.widget(find.byType(Column)).mainAxisAlignment, + MainAxisAlignment.center, + ); + expect( + tester.widget(find.byType(Column)).crossAxisAlignment, + CrossAxisAlignment.center, + ); + expect( + tester.widget(find.byType(Column)).verticalDirection, + VerticalDirection.down, + ); expect(tester.widget(find.byType(Column)).children, hasLength(2)); - expect(tester.widgetList(find.byType(ColoredBox)).toList()[0].color, const Color(0x00000001)); - expect(tester.widgetList(find.byType(ColoredBox)).toList()[1].color, const Color(0x00000002)); + expect( + tester.widgetList(find.byType(ColoredBox)).toList()[0].color, + const Color(0x00000001), + ); + expect( + tester.widgetList(find.byType(ColoredBox)).toList()[1].color, + const Color(0x00000002), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ColoredBox(color: 0xFF112233); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF112233)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF112233), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = DefaultTextStyle( textHeightBehavior: { applyHeightToLastDescent: false }, child: SizedBoxShrink(), ); - ''')); + '''), + ); await tester.pump(); expect( - tester.widget(find.byType(DefaultTextStyle)).textHeightBehavior, + tester + .widget(find.byType(DefaultTextStyle)) + .textHeightBehavior, const TextHeightBehavior(applyHeightToLastDescent: false), ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "ltr", child: SizedBoxShrink(), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Directionality)).textDirection, TextDirection.ltr); + expect( + tester.widget(find.byType(Directionality)).textDirection, + TextDirection.ltr, + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = FittedBox( fit: "cover", ); - ''')); + '''), + ); await tester.pump(); expect(tester.widget(find.byType(FittedBox)).fit, BoxFit.cover); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GestureDetector( onTap: event 'tap' { argument: true }, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); expect(eventLog, ['tap']); eventLog.clear(); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "ltr", @@ -217,66 +303,95 @@ void main() { fontFamily: 'FONT', ), ); - ''')); + '''), + ); await tester.pump(); expect(tester.widget(find.byType(Icon)).icon!.codePoint, 1); expect(tester.widget(find.byType(Icon)).icon!.fontFamily, 'FONT'); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = IconTheme( color: 0x12345678, child: SizedBoxShrink(), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(IconTheme)).data.color, const Color(0x12345678)); + expect( + tester.widget(find.byType(IconTheme)).data.color, + const Color(0x12345678), + ); }); - testWidgets('golden checks', (WidgetTester tester) async { - final Runtime runtime = Runtime() - ..update(const LibraryName(['core']), createCoreWidgets()) - ..update(const LibraryName(['test']), parseLibraryFile('import core; widget root = SizedBox();')); + testWidgets( + 'golden checks', + (WidgetTester tester) async { + final Runtime runtime = Runtime() + ..update(const LibraryName(['core']), createCoreWidgets()) + ..update( + const LibraryName(['test']), + parseLibraryFile('import core; widget root = SizedBox();'), + ); addTearDown(runtime.dispose); - final DynamicContent data = DynamicContent(); - final List eventLog = []; - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.rtl, - child: RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), - onEvent: (String eventName, DynamicMap eventArguments) { - eventLog.add('$eventName $eventArguments'); - }, + final DynamicContent data = DynamicContent(); + final List eventLog = []; + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.rtl, + child: RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), + onEvent: (String eventName, DynamicMap eventArguments) { + eventLog.add('$eventName $eventArguments'); + }, + ), ), - ), - ); - expect(find.byType(RemoteWidget), findsOneWidget); - - ArgumentDecoders.decorationDecoders['tab'] = (DataSource source, List key) { - return UnderlineTabIndicator( - borderSide: ArgumentDecoders.borderSide(source, [...key, 'side']) ?? const BorderSide(width: 2.0, color: Color(0xFFFFFFFF)), - insets: ArgumentDecoders.edgeInsets(source, ['insets']) ?? EdgeInsets.zero, - ); - }; - ArgumentDecoders.gradientDecoders['custom'] = (DataSource source, List key) { - return const RadialGradient( - center: Alignment(0.7, -0.6), - radius: 0.2, - colors: [ Color(0xFFFFFF00), Color(0xFF0099FF) ], - stops: [0.4, 1.0], - ); - }; - ArgumentDecoders.shapeBorderDecoders['custom'] = (DataSource source, List key) { - return StarBorder( - side: ArgumentDecoders.borderSide(source, [...key, 'side']) ?? const BorderSide(width: 2.0, color: Color(0xFFFFFFFF)), - points: source.v([...key, 'points']) ?? 5.0, ); - }; - - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + expect(find.byType(RemoteWidget), findsOneWidget); + + ArgumentDecoders + .decorationDecoders['tab'] = (DataSource source, List key) { + return UnderlineTabIndicator( + borderSide: + ArgumentDecoders.borderSide(source, [...key, 'side']) ?? + const BorderSide(width: 2.0, color: Color(0xFFFFFFFF)), + insets: + ArgumentDecoders.edgeInsets(source, ['insets']) ?? + EdgeInsets.zero, + ); + }; + ArgumentDecoders.gradientDecoders['custom'] = + (DataSource source, List key) { + return const RadialGradient( + center: Alignment(0.7, -0.6), + radius: 0.2, + colors: [Color(0xFFFFFF00), Color(0xFF0099FF)], + stops: [0.4, 1.0], + ); + }; + ArgumentDecoders.shapeBorderDecoders['custom'] = + (DataSource source, List key) { + return StarBorder( + side: + ArgumentDecoders.borderSide(source, [ + ...key, + 'side', + ]) ?? + const BorderSide(width: 2.0, color: Color(0xFFFFFFFF)), + points: source.v([...key, 'points']) ?? 5.0, + ); + }; + + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Container( margin: [20.0, 10.0, 30.0, 5.0], @@ -369,48 +484,103 @@ void main() { ), ), ); - ''')); - await tester.pump(); - if (!kIsWeb) { - expect(eventLog, hasLength(1)); - expect(eventLog.first, startsWith('image-error-event {exception: HTTP request failed, statusCode: 400, x-invalid:')); - eventLog.clear(); - } - await expectLater( - find.byType(RemoteWidget), - matchesGoldenFile('goldens/argument_decoders_test.containers.png'), - // TODO(louisehsu): Unskip once golden file is updated. See - // https://github.com/flutter/flutter/issues/151995 - skip: !runGoldens || true, - ); - expect(find.byType(DecoratedBox), findsNWidgets(6)); - - final DecorationImage assetImage = (tester.widgetList(find.byType(DecoratedBox)).toList()[1].decoration as BoxDecoration).image!; - expect(assetImage.image, isA()); - expect((assetImage.image as AssetImage).assetName, 'asset'); - expect( + '''), + ); + await tester.pump(); + if (!kIsWeb) { + expect(eventLog, hasLength(1)); + expect( + eventLog.first, + startsWith( + 'image-error-event {exception: HTTP request failed, statusCode: 400, x-invalid:', + ), + ); + eventLog.clear(); + } + await expectLater( + find.byType(RemoteWidget), + matchesGoldenFile('goldens/argument_decoders_test.containers.png'), + // TODO(louisehsu): Unskip once golden file is updated. See + // https://github.com/flutter/flutter/issues/151995 + skip: !runGoldens || true, + ); + expect(find.byType(DecoratedBox), findsNWidgets(6)); + + final DecorationImage assetImage = + (tester + .widgetList(find.byType(DecoratedBox)) + .toList()[1] + .decoration + as BoxDecoration) + .image!; + expect(assetImage.image, isA()); + expect((assetImage.image as AssetImage).assetName, 'asset'); + expect( assetImage.colorFilter, - const ColorFilter.matrix([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])); - expect(assetImage.centerSlice, const Rect.fromLTRB(5.0, 8.0, 105.0, 78.0)); - expect(assetImage.filterQuality, FilterQuality.none); - - final DecorationImage networkImage = (tester.widgetList(find.byType(DecoratedBox)).toList()[0].decoration as BoxDecoration).image!; - expect(networkImage.image, isA()); - expect((networkImage.image as NetworkImage).url, 'x-invalid://'); - expect(networkImage.colorFilter, const ColorFilter.mode(Color(0xFF8811FF), BlendMode.xor)); - expect(networkImage.filterQuality, FilterQuality.high); - - ArgumentDecoders.colorFilterDecoders['custom'] = (DataSource source, List key) { - return const ColorFilter.mode(Color(0x12345678), BlendMode.xor); - }; - ArgumentDecoders.maskFilterDecoders['custom'] = (DataSource source, List key) { - return const MaskFilter.blur(BlurStyle.outer, 0.5); - }; - ArgumentDecoders.shaderDecoders['custom'] = (DataSource source, List key) { - return ui.Gradient.linear(Offset.zero, const Offset(100.0, 100.0), const [Color(0xFFFFFF00), Color(0xFF00FFFF)]); - }; - - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + const ColorFilter.matrix([ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ]), + ); + expect( + assetImage.centerSlice, + const Rect.fromLTRB(5.0, 8.0, 105.0, 78.0), + ); + expect(assetImage.filterQuality, FilterQuality.none); + + final DecorationImage networkImage = + (tester + .widgetList(find.byType(DecoratedBox)) + .toList()[0] + .decoration + as BoxDecoration) + .image!; + expect(networkImage.image, isA()); + expect((networkImage.image as NetworkImage).url, 'x-invalid://'); + expect( + networkImage.colorFilter, + const ColorFilter.mode(Color(0xFF8811FF), BlendMode.xor), + ); + expect(networkImage.filterQuality, FilterQuality.high); + + ArgumentDecoders.colorFilterDecoders['custom'] = + (DataSource source, List key) { + return const ColorFilter.mode(Color(0x12345678), BlendMode.xor); + }; + ArgumentDecoders.maskFilterDecoders['custom'] = + (DataSource source, List key) { + return const MaskFilter.blur(BlurStyle.outer, 0.5); + }; + ArgumentDecoders.shaderDecoders['custom'] = + (DataSource source, List key) { + return ui.Gradient.linear( + Offset.zero, + const Offset(100.0, 100.0), + const [Color(0xFFFFFF00), Color(0xFF00FFFF)], + ); + }; + + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Column( children: [ @@ -463,17 +633,36 @@ void main() { ), ], ); - ''')); - await tester.pump(); - expect(tester.firstWidget(find.byType(Text)).style!.fontFamilyFallback, [ 'a', 'b' ]); - expect(tester.widgetList(find.byType(Text)).map((Text widget) => widget.locale!), const [Locale('en', 'US'), Locale('en'), Locale.fromSubtags(languageCode: 'en', scriptCode: 'latin', countryCode: 'GB')]); - await expectLater( - find.byType(RemoteWidget), - matchesGoldenFile('goldens/argument_decoders_test.text.png'), - skip: !runGoldens, - ); + '''), + ); + await tester.pump(); + expect( + tester.firstWidget(find.byType(Text)).style!.fontFamilyFallback, + ['a', 'b'], + ); + expect( + tester + .widgetList(find.byType(Text)) + .map((Text widget) => widget.locale!), + const [ + Locale('en', 'US'), + Locale('en'), + Locale.fromSubtags( + languageCode: 'en', + scriptCode: 'latin', + countryCode: 'GB', + ), + ], + ); + await expectLater( + find.byType(RemoteWidget), + matchesGoldenFile('goldens/argument_decoders_test.text.png'), + skip: !runGoldens, + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GridView( gridDelegate: { type: 'fixedCrossAxisCount', crossAxisCount: 3 }, @@ -488,15 +677,18 @@ void main() { ColoredBox(color: 0xFF992288), ], ); - ''')); - await tester.pump(); - await expectLater( - find.byType(RemoteWidget), - matchesGoldenFile('goldens/argument_decoders_test.gridview.fixed.png'), - skip: !runGoldens, - ); + '''), + ); + await tester.pump(); + await expectLater( + find.byType(RemoteWidget), + matchesGoldenFile('goldens/argument_decoders_test.gridview.fixed.png'), + skip: !runGoldens, + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GridView( gridDelegate: { type: 'maxCrossAxisExtent', maxCrossAxisExtent: 50.0 }, @@ -511,20 +703,24 @@ void main() { ColoredBox(color: 0xFF992288), ], ); - ''')); - await tester.pump(); - await expectLater( - find.byType(RemoteWidget), - matchesGoldenFile('goldens/argument_decoders_test.gridview.max.png'), - skip: !runGoldens, - ); - - int sawGridDelegateDecoder = 0; - ArgumentDecoders.gridDelegateDecoders['custom'] = (DataSource source, List key) { - sawGridDelegateDecoder += 1; - return null; - }; - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + '''), + ); + await tester.pump(); + await expectLater( + find.byType(RemoteWidget), + matchesGoldenFile('goldens/argument_decoders_test.gridview.max.png'), + skip: !runGoldens, + ); + + int sawGridDelegateDecoder = 0; + ArgumentDecoders.gridDelegateDecoders['custom'] = + (DataSource source, List key) { + sawGridDelegateDecoder += 1; + return null; + }; + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GridView( gridDelegate: { type: 'custom' }, @@ -539,16 +735,19 @@ void main() { ColoredBox(color: 0xFF992288), ], ); - ''')); - expect(sawGridDelegateDecoder, 0); - await tester.pump(); - expect(sawGridDelegateDecoder, 1); - await expectLater( - find.byType(RemoteWidget), - matchesGoldenFile('goldens/argument_decoders_test.gridview.custom.png'), - skip: !runGoldens, - ); + '''), + ); + expect(sawGridDelegateDecoder, 0); + await tester.pump(); + expect(sawGridDelegateDecoder, 1); + await expectLater( + find.byType(RemoteWidget), + matchesGoldenFile('goldens/argument_decoders_test.gridview.custom.png'), + skip: !runGoldens, + ); - expect(eventLog, isEmpty); - }, skip: kIsWeb || !isMainChannel); // https://github.com/flutter/flutter/pull/129851 + expect(eventLog, isEmpty); + }, + skip: kIsWeb || !isMainChannel, + ); // https://github.com/flutter/flutter/pull/129851 } diff --git a/packages/rfw/test/binary_test.dart b/packages/rfw/test/binary_test.dart index 827ed59c184..23151c9a34a 100644 --- a/packages/rfw/test/binary_test.dart +++ b/packages/rfw/test/binary_test.dart @@ -17,7 +17,26 @@ const int largeNumber = 9007199254730661; void main() { testWidgets('String example', (WidgetTester tester) async { final Uint8List bytes = encodeDataBlob('Hello'); - expect(bytes, [ 0xFE, 0x52, 0x57, 0x44, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F ]); + expect(bytes, [ + 0xFE, + 0x52, + 0x57, + 0x44, + 0x04, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x48, + 0x65, + 0x6C, + 0x6C, + 0x6F, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, 'Hello'); @@ -26,7 +45,21 @@ void main() { testWidgets('Big integer example', (WidgetTester tester) async { // This value is intentionally inside the JS Number range but above 2^32. final Uint8List bytes = encodeDataBlob(largeNumber); - expect(bytes, [ 0xfe, 0x52, 0x57, 0x44, 0x02, 0xa5, 0xd7, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, ]); + expect(bytes, [ + 0xfe, + 0x52, + 0x57, + 0x44, + 0x02, + 0xa5, + 0xd7, + 0xff, + 0xff, + 0xff, + 0xff, + 0x1f, + 0x00, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, largeNumber); @@ -34,7 +67,21 @@ void main() { testWidgets('Big negative integer example', (WidgetTester tester) async { final Uint8List bytes = encodeDataBlob(-largeNumber); - expect(bytes, [ 0xfe, 0x52, 0x57, 0x44, 0x02, 0x5b, 0x28, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, ]); + expect(bytes, [ + 0xfe, + 0x52, + 0x57, + 0x44, + 0x02, + 0x5b, + 0x28, + 0x00, + 0x00, + 0x00, + 0x00, + 0xe0, + 0xff, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, -largeNumber); @@ -42,7 +89,21 @@ void main() { testWidgets('Small integer example', (WidgetTester tester) async { final Uint8List bytes = encodeDataBlob(1); - expect(bytes, [ 0xfe, 0x52, 0x57, 0x44, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]); + expect(bytes, [ + 0xfe, + 0x52, + 0x57, + 0x44, + 0x02, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, 1); @@ -50,7 +111,21 @@ void main() { testWidgets('Small negative integer example', (WidgetTester tester) async { final Uint8List bytes = encodeDataBlob(-1); - expect(bytes, [ 0xfe, 0x52, 0x57, 0x44, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]); + expect(bytes, [ + 0xfe, + 0x52, + 0x57, + 0x44, + 0x02, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, -1); @@ -59,47 +134,168 @@ void main() { testWidgets('Zero integer example', (WidgetTester tester) async { // This value is intentionally inside the JS Number range but above 2^32. final Uint8List bytes = encodeDataBlob(0); - expect(bytes, [ 0xfe, 0x52, 0x57, 0x44, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]); + expect(bytes, [ + 0xfe, + 0x52, + 0x57, + 0x44, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, 0); }); testWidgets('Map example', (WidgetTester tester) async { - final Uint8List bytes = encodeDataBlob(const { 'a': 15 }); + final Uint8List bytes = encodeDataBlob(const {'a': 15}); expect(bytes, [ - 0xFE, 0x52, 0x57, 0x44, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, + 0x52, + 0x57, + 0x44, + 0x07, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x02, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); - expect(value, const { 'a': 15 }); + expect(value, const {'a': 15}); }); testWidgets('Signature check in decoders', (WidgetTester tester) async { try { - decodeDataBlob(Uint8List.fromList([ 0xFE, 0x52, 0x46, 0x57, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F ])); + decodeDataBlob( + Uint8List.fromList([ + 0xFE, + 0x52, + 0x46, + 0x57, + 0x04, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x48, + 0x65, + 0x6C, + 0x6C, + 0x6F, + ]), + ); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('File signature mismatch. Expected FE 52 57 44 but found FE 52 46 57.')); + expect( + '$e', + contains( + 'File signature mismatch. Expected FE 52 57 44 but found FE 52 46 57.', + ), + ); } try { - decodeLibraryBlob(Uint8List.fromList([ 0xFE, 0x52, 0x57, 0x44, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F ])); + decodeLibraryBlob( + Uint8List.fromList([ + 0xFE, + 0x52, + 0x57, + 0x44, + 0x04, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x48, + 0x65, + 0x6C, + 0x6C, + 0x6F, + ]), + ); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('File signature mismatch. Expected FE 52 46 57 but found FE 52 57 44.')); + expect( + '$e', + contains( + 'File signature mismatch. Expected FE 52 46 57 but found FE 52 57 44.', + ), + ); } }); testWidgets('Trailing byte check', (WidgetTester tester) async { try { - decodeDataBlob(Uint8List.fromList([ 0xFE, 0x52, 0x57, 0x44, 0x00, 0x00 ])); + decodeDataBlob( + Uint8List.fromList([0xFE, 0x52, 0x57, 0x44, 0x00, 0x00]), + ); fail('did not throw exception'); } on FormatException catch (e) { expect('$e', contains('Unexpected trailing bytes after value.')); } try { - decodeLibraryBlob(Uint8List.fromList([ 0xFE, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])); + decodeLibraryBlob( + Uint8List.fromList([ + 0xFE, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ]), + ); fail('did not throw exception'); } on FormatException catch (e) { expect('$e', contains('Unexpected trailing bytes after constructors.')); @@ -108,57 +304,133 @@ void main() { testWidgets('Incomplete files in signatures', (WidgetTester tester) async { try { - decodeDataBlob(Uint8List.fromList([ 0xFE, 0x52, 0x57 ])); + decodeDataBlob(Uint8List.fromList([0xFE, 0x52, 0x57])); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Could not read byte at offset 3: unexpected end of file.')); + expect( + '$e', + contains('Could not read byte at offset 3: unexpected end of file.'), + ); } try { - decodeLibraryBlob(Uint8List.fromList([ 0xFE, 0x52, 0x46 ])); + decodeLibraryBlob(Uint8List.fromList([0xFE, 0x52, 0x46])); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Could not read byte at offset 3: unexpected end of file.')); + expect( + '$e', + contains('Could not read byte at offset 3: unexpected end of file.'), + ); } }); testWidgets('Incomplete files after signatures', (WidgetTester tester) async { try { - decodeDataBlob(Uint8List.fromList([ 0xFE, 0x52, 0x57, 0x44 ])); + decodeDataBlob(Uint8List.fromList([0xFE, 0x52, 0x57, 0x44])); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Could not read byte at offset 4: unexpected end of file.')); + expect( + '$e', + contains('Could not read byte at offset 4: unexpected end of file.'), + ); } try { - decodeLibraryBlob(Uint8List.fromList([ 0xFE, 0x52, 0x46, 0x57 ])); + decodeLibraryBlob(Uint8List.fromList([0xFE, 0x52, 0x46, 0x57])); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Could not read int64 at offset 4: unexpected end of file.')); + expect( + '$e', + contains('Could not read int64 at offset 4: unexpected end of file.'), + ); } }); testWidgets('Invalid value tag', (WidgetTester tester) async { try { - decodeDataBlob(Uint8List.fromList([ 0xFE, 0x52, 0x57, 0x44, 0xCC ])); + decodeDataBlob(Uint8List.fromList([0xFE, 0x52, 0x57, 0x44, 0xCC])); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Unrecognized data type 0xCC while decoding blob.')); + expect( + '$e', + contains('Unrecognized data type 0xCC while decoding blob.'), + ); } }); testWidgets('Library encoder smoke test', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [])); - expect(bytes, [ 0xFE, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], []), + ); + expect(bytes, [ + 0xFE, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); expect(value.widgets, isEmpty); }); testWidgets('Library encoder: imports', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([Import(LibraryName(['a']))], [])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([ + Import(LibraryName(['a'])), + ], []), + ); expect(bytes, [ - 0xFE, 0x52, 0x46, 0x57, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, + 0x52, + 0x46, + 0x57, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, hasLength(1)); @@ -168,37 +440,197 @@ void main() { testWidgets('Doubles', (WidgetTester tester) async { final Uint8List bytes = encodeDataBlob(0.25); - expect(bytes, [ 0xFE, 0x52, 0x57, 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x3F ]); + expect(bytes, [ + 0xFE, + 0x52, + 0x57, + 0x44, + 0x03, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xD0, + 0x3F, + ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); expect(value, 0.25); }); - testWidgets('Library decoder: invalid widget declaration root', (WidgetTester tester) async { + testWidgets('Library decoder: invalid widget declaration root', ( + WidgetTester tester, + ) async { final Uint8List bytes = Uint8List.fromList([ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xEF, ]); try { decodeLibraryBlob(bytes); } on FormatException catch (e) { - expect('$e', contains('Unrecognized data type 0xEF while decoding widget declaration root.')); + expect( + '$e', + contains( + 'Unrecognized data type 0xEF while decoding widget declaration root.', + ), + ); } }); testWidgets('Library encoder: args references', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': [ ArgsReference(['d', 5]) ] })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': [ + ArgsReference(['d', 5]), + ], + }), + ), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x02, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x05, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0a, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + 0x02, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -207,51 +639,240 @@ void main() { expect(value.widgets.first.initialState, isNull); expect(value.widgets.first.root, isA()); expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], hasLength(1)); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0], isA()); - expect((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as ArgsReference).parts, hasLength(2)); - expect((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as ArgsReference).parts[0], 'd'); - expect((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as ArgsReference).parts[1], 5); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + hasLength(1), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0], + isA(), + ); + expect( + (((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as ArgsReference) + .parts, + hasLength(2), + ); + expect( + (((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as ArgsReference) + .parts[0], + 'd', + ); + expect( + (((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as ArgsReference) + .parts[1], + 5, + ); }); - testWidgets('Library encoder: invalid args references', (WidgetTester tester) async { + testWidgets('Library encoder: invalid args references', ( + WidgetTester tester, + ) async { try { - encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': [ ArgsReference([false]) ] })), - ])); + encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': [ + ArgsReference([false]), + ], + }), + ), + ]), + ); } on StateError catch (e) { expect('$e', contains('Unexpected type bool while encoding blob.')); } }); - testWidgets('Library decoder: invalid args references', (WidgetTester tester) async { + testWidgets('Library decoder: invalid args references', ( + WidgetTester tester, + ) async { final Uint8List bytes = Uint8List.fromList([ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xAC, - ]); - try { - decodeLibraryBlob(bytes); + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x05, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0a, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xAC, + ]); + try { + decodeLibraryBlob(bytes); } on FormatException catch (e) { - expect('$e', contains('Invalid reference type 0xAC while decoding blob.')); + expect( + '$e', + contains('Invalid reference type 0xAC while decoding blob.'), + ); } }); testWidgets('Library encoder: switches', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, Switch('b', { null: 'c' })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration('a', null, Switch('b', {null: 'c'})), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x63, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0f, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x10, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -266,15 +887,88 @@ void main() { }); testWidgets('Library encoder: switches', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, Switch('b', { 'c': 'd' })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration('a', null, Switch('b', {'c': 'd'})), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x63, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0f, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -289,112 +983,609 @@ void main() { }); testWidgets('Bools', (WidgetTester tester) async { - final Uint8List bytes = encodeDataBlob(const [ false, true ]); + final Uint8List bytes = encodeDataBlob(const [false, true]); expect(bytes, [ - 0xFE, 0x52, 0x57, 0x44, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFE, + 0x52, + 0x57, + 0x44, + 0x05, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, ]); final Object value = decodeDataBlob(bytes); expect(value, isA()); - expect(value, const { false, true }); + expect(value, const {false, true}); }); testWidgets('Library encoder: loops', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': [ - Loop([], ConstructorCall('d', { 'e': LoopReference(0, []) })), - ] })), - ])); - expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - ]); - final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); - expect(value.imports, isEmpty); - expect(value.widgets, hasLength(1)); - expect(value.widgets.first.name, 'a'); - expect(value.widgets.first.initialState, isNull); - expect(value.widgets.first.root, isA()); - expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], hasLength(1)); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0], isA()); - expect((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).input, isEmpty); - expect((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output, isA()); - expect(((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output as ConstructorCall).name, 'd'); - expect(((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output as ConstructorCall).arguments, hasLength(1)); - expect(((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output as ConstructorCall).arguments['e'], isA()); - expect((((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output as ConstructorCall).arguments['e']! as LoopReference).loop, 0); - expect((((((value.widgets.first.root as ConstructorCall).arguments['c']! as DynamicList)[0]! as Loop).output as ConstructorCall).arguments['e']! as LoopReference).parts, isEmpty); - }); - - testWidgets('Library encoder: data references', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': DataReference(['d']) })), - ])); - expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x64, - ]); - final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); - expect(value.imports, isEmpty); - expect(value.widgets, hasLength(1)); - expect(value.widgets.first.name, 'a'); - expect(value.widgets.first.initialState, isNull); - expect(value.widgets.first.root, isA()); - expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], isA()); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as DataReference).parts, const [ 'd' ]); - }); - - testWidgets('Library encoder: state references', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': StateReference(['d']) })), - ])); - expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x64, - ]); - final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); - expect(value.imports, isEmpty); - expect(value.widgets, hasLength(1)); - expect(value.widgets.first.name, 'a'); - expect(value.widgets.first.initialState, isNull); - expect(value.widgets.first.root, isA()); - expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], isA()); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as StateReference).parts, const [ 'd' ]); - }); - - testWidgets('Library encoder: event handler', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': EventHandler('d', {}) })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': [ + Loop( + [], + ConstructorCall('d', { + 'e': LoopReference(0, []), + }), + ), + ], + }), + ), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x05, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x08, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x65, + 0x0c, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ]); + final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); + expect(value.imports, isEmpty); + expect(value.widgets, hasLength(1)); + expect(value.widgets.first.name, 'a'); + expect(value.widgets.first.initialState, isNull); + expect(value.widgets.first.root, isA()); + expect((value.widgets.first.root as ConstructorCall).name, 'b'); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + hasLength(1), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0], + isA(), + ); + expect( + (((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .input, + isEmpty, + ); + expect( + (((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output, + isA(), + ); + expect( + ((((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output + as ConstructorCall) + .name, + 'd', + ); + expect( + ((((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output + as ConstructorCall) + .arguments, + hasLength(1), + ); + expect( + ((((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output + as ConstructorCall) + .arguments['e'], + isA(), + ); + expect( + (((((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output + as ConstructorCall) + .arguments['e']! + as LoopReference) + .loop, + 0, + ); + expect( + (((((value.widgets.first.root as ConstructorCall).arguments['c']! + as DynamicList)[0]! + as Loop) + .output + as ConstructorCall) + .arguments['e']! + as LoopReference) + .parts, + isEmpty, + ); + }); + + testWidgets('Library encoder: data references', (WidgetTester tester) async { + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': DataReference(['d']), + }), + ), + ]), + ); + expect(bytes, [ + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x0B, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + ]); + final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); + expect(value.imports, isEmpty); + expect(value.widgets, hasLength(1)); + expect(value.widgets.first.name, 'a'); + expect(value.widgets.first.initialState, isNull); + expect(value.widgets.first.root, isA()); + expect((value.widgets.first.root as ConstructorCall).name, 'b'); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + isA(), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as DataReference) + .parts, + const ['d'], + ); + }); + + testWidgets('Library encoder: state references', (WidgetTester tester) async { + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': StateReference(['d']), + }), + ), + ]), + ); + expect(bytes, [ + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x0D, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + ]); + final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); + expect(value.imports, isEmpty); + expect(value.widgets, hasLength(1)); + expect(value.widgets.first.name, 'a'); + expect(value.widgets.first.initialState, isNull); + expect(value.widgets.first.root, isA()); + expect((value.widgets.first.root as ConstructorCall).name, 'b'); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + isA(), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as StateReference) + .parts, + const ['d'], + ); + }); + + testWidgets('Library encoder: event handler', (WidgetTester tester) async { + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': EventHandler('d', {}), + }), + ), + ]), + ); + expect(bytes, [ + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x0E, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -403,24 +1594,129 @@ void main() { expect(value.widgets.first.initialState, isNull); expect(value.widgets.first.root, isA()); expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], isA()); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as EventHandler).eventName, 'd'); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as EventHandler).eventArguments, isEmpty); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + isA(), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as EventHandler) + .eventName, + 'd', + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as EventHandler) + .eventArguments, + isEmpty, + ); }); testWidgets('Library encoder: state setter', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': SetStateHandler(StateReference(['d']), false) })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': SetStateHandler(StateReference(['d']), false), + }), + ), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x64, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x11, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x64, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -429,23 +1725,120 @@ void main() { expect(value.widgets.first.initialState, isNull); expect(value.widgets.first.root, isA()); expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], isA()); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as SetStateHandler).stateReference.parts, ['d']); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as SetStateHandler).value, false); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + isA(), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as SetStateHandler) + .stateReference + .parts, + ['d'], + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! + as SetStateHandler) + .value, + false, + ); }); testWidgets('Library encoder: switch', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', null, ConstructorCall('b', { 'c': Switch(false, {} ) })), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + null, + ConstructorCall('b', { + 'c': Switch(false, {}), + }), + ), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -454,22 +1847,96 @@ void main() { expect(value.widgets.first.initialState, isNull); expect(value.widgets.first.root, isA()); expect((value.widgets.first.root as ConstructorCall).name, 'b'); - expect((value.widgets.first.root as ConstructorCall).arguments, hasLength(1)); - expect((value.widgets.first.root as ConstructorCall).arguments.keys, ['c']); - expect((value.widgets.first.root as ConstructorCall).arguments['c'], isA()); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as Switch).input, false); - expect(((value.widgets.first.root as ConstructorCall).arguments['c']! as Switch).outputs, isEmpty); + expect( + (value.widgets.first.root as ConstructorCall).arguments, + hasLength(1), + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments.keys, + ['c'], + ); + expect( + (value.widgets.first.root as ConstructorCall).arguments['c'], + isA(), + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! as Switch) + .input, + false, + ); + expect( + ((value.widgets.first.root as ConstructorCall).arguments['c']! as Switch) + .outputs, + isEmpty, + ); }); testWidgets('Library encoder: initial state', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', {}, ConstructorCall('b', {})), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration( + 'a', + {}, + ConstructorCall('b', {}), + ), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); expect(value.imports, isEmpty); @@ -482,14 +1949,78 @@ void main() { }); testWidgets('Library encoder: initial state', (WidgetTester tester) async { - final Uint8List bytes = encodeLibraryBlob(const RemoteWidgetLibrary([], [ - WidgetDeclaration('a', { 'b': false }, ConstructorCall('c', {})), - ])); + final Uint8List bytes = encodeLibraryBlob( + const RemoteWidgetLibrary([], [ + WidgetDeclaration('a', { + 'b': false, + }, ConstructorCall('c', {})), + ]), + ); expect(bytes, [ - 0xfe, 0x52, 0x46, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x09, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, + 0x52, + 0x46, + 0x57, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x61, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x62, + 0x00, + 0x09, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x63, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, 0x00, ]); final RemoteWidgetLibrary value = decodeLibraryBlob(bytes); @@ -504,7 +2035,9 @@ void main() { expect((value.widgets.first.root as ConstructorCall).arguments, isEmpty); }); - testWidgets('Library encoder: widget builders work', (WidgetTester tester) async { + testWidgets('Library encoder: widget builders work', ( + WidgetTester tester, + ) async { const String source = ''' widget Foo = Builder( builder: (scope) => Text(text: scope.text), @@ -517,19 +2050,21 @@ void main() { expect(library.toString(), decoded.toString()); }); - testWidgets('Library encoder: widget builders throws', (WidgetTester tester) async { + testWidgets('Library encoder: widget builders throws', ( + WidgetTester tester, + ) async { const RemoteWidgetLibrary remoteWidgetLibrary = RemoteWidgetLibrary( - [], + [], [ WidgetDeclaration( - 'a', + 'a', {}, - ConstructorCall( - 'c', - { - 'builder': WidgetBuilderDeclaration('scope', ArgsReference([])), - }, - ), + ConstructorCall('c', { + 'builder': WidgetBuilderDeclaration( + 'scope', + ArgsReference([]), + ), + }), ), ], ); @@ -537,7 +2072,12 @@ void main() { decodeLibraryBlob(encodeLibraryBlob(remoteWidgetLibrary)); fail('did not throw exception'); } on FormatException catch (e) { - expect('$e', contains('Unrecognized data type 0x0A while decoding widget builder blob.')); + expect( + '$e', + contains( + 'Unrecognized data type 0x0A while decoding widget builder blob.', + ), + ); } }); } diff --git a/packages/rfw/test/core_widgets_test.dart b/packages/rfw/test/core_widgets_test.dart index 5710747eb2d..01d79ca103a 100644 --- a/packages/rfw/test/core_widgets_test.dart +++ b/packages/rfw/test/core_widgets_test.dart @@ -23,15 +23,23 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { eventLog.add('$eventName $eventArguments'); }, ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GestureDetector( onTapDown: event 'tapdown' { }, @@ -39,49 +47,107 @@ void main() { onTap: event 'tap' { }, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); expect(eventLog, ['tapdown {}', 'tapup {}', 'tap {}']); eventLog.clear(); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = IntrinsicHeight(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(IntrinsicHeight), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = IntrinsicWidth(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(IntrinsicWidth), findsOneWidget); - ArgumentDecoders.imageProviderDecoders['beepboop'] = (DataSource source, List key) { - return MemoryImage(Uint8List.fromList([ - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0xff, 0x00, 0xc0, 0xc0, 0xc0, - 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b, - ])); - }; - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + ArgumentDecoders.imageProviderDecoders['beepboop'] = + (DataSource source, List key) { + return MemoryImage( + Uint8List.fromList([ + 0x47, + 0x49, + 0x46, + 0x38, + 0x39, + 0x61, + 0x01, + 0x00, + 0x01, + 0x00, + 0x80, + 0xff, + 0x00, + 0xc0, + 0xc0, + 0xc0, + 0x00, + 0x00, + 0x00, + 0x21, + 0xf9, + 0x04, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x2c, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x01, + 0x00, + 0x00, + 0x02, + 0x02, + 0x44, + 0x01, + 0x00, + 0x3b, + ]), + ); + }; + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Image(source: 'beepboop'); - ''')); + '''), + ); await tester.pump(); expect(find.byType(Image), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = SingleChildScrollView(child: ListBody()); - ''')); + '''), + ); await tester.pump(); expect(find.byType(SingleChildScrollView), findsOneWidget); expect(find.byType(ListBody), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "rtl", @@ -100,46 +166,82 @@ void main() { ], ), ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(ListView), findsOneWidget); expect(find.byType(Container), findsNWidgets(9)); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Opacity( onEnd: event 'end' {}, child: Placeholder(), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(AnimatedOpacity)).onEnd, isNot(isNull)); + expect( + tester.widget(find.byType(AnimatedOpacity)).onEnd, + isNot(isNull), + ); expect(eventLog, isEmpty); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality(textDirection: "ltr", child: Padding(padding: [12.0])); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Padding)).padding.resolve(TextDirection.ltr), const EdgeInsets.all(12.0)); + expect( + tester + .widget(find.byType(Padding)) + .padding + .resolve(TextDirection.ltr), + const EdgeInsets.all(12.0), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality(textDirection: "ltr", child: Padding(padding: [24.0])); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(Padding)).padding.resolve(TextDirection.ltr), const EdgeInsets.all(12.0)); + expect( + tester + .widget(find.byType(Padding)) + .padding + .resolve(TextDirection.ltr), + const EdgeInsets.all(12.0), + ); await tester.pump(const Duration(seconds: 4)); - expect(tester.widget(find.byType(Padding)).padding.resolve(TextDirection.ltr), const EdgeInsets.all(24.0)); + expect( + tester + .widget(find.byType(Padding)) + .padding + .resolve(TextDirection.ltr), + const EdgeInsets.all(24.0), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Placeholder(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(Placeholder), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "ltr", @@ -155,35 +257,44 @@ void main() { ], ), ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(Stack), findsOneWidget); expect(find.byType(Positioned), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "rtl", child: Rotation(turns: 0.0), ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(AnimatedRotation), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "rtl", child: Rotation(turns: 1.0, onEnd: event 'end' { from: "rotation" }), ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(AnimatedRotation), findsOneWidget); expect(eventLog, isEmpty); await tester.pump(const Duration(seconds: 1)); expect(eventLog, ['end {from: rotation}']); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "rtl", @@ -192,11 +303,14 @@ void main() { children: [SizedBox(width: 10.0)] ), ); - ''')); + '''), + ); await tester.pump(); expect(tester.getTopLeft(find.byType(SizedBox)), const Offset(790.0, 0.0)); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "rtl", @@ -205,25 +319,34 @@ void main() { children: [Spacer()] ), ); - ''')); + '''), + ); await tester.pump(); expect(tester.getTopLeft(find.byType(SizedBox)), Offset.zero); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = SizedBoxExpand(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(SizedBox), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = SizedBoxShrink(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(SizedBox), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Directionality( textDirection: "ltr", @@ -236,14 +359,25 @@ void main() { ), ), ); - ''')); + '''), + ); await tester.pump(); - final Size fractionallySizedBoxSize = tester.getSize(find.byType(FractionallySizedBox)); + final Size fractionallySizedBoxSize = tester.getSize( + find.byType(FractionallySizedBox), + ); final Size childSize = tester.getSize(find.text('test')); expect(childSize.width, fractionallySizedBoxSize.width * 0.5); expect(childSize.height, fractionallySizedBoxSize.height * 0.8); - expect(tester.widget(find.text('test')).textScaler, const TextScaler.linear(3)); - expect(tester.widget(find.byType(FractionallySizedBox)).alignment, Alignment.center); + expect( + tester.widget(find.text('test')).textScaler, + const TextScaler.linear(3), + ); + expect( + tester + .widget(find.byType(FractionallySizedBox)) + .alignment, + Alignment.center, + ); imageCache.clear(); }); @@ -258,45 +392,65 @@ void main() { home: RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { eventLog.add('$eventName $eventArguments'); }, ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = SafeArea( child: SizedBoxShrink(), ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(SafeArea), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Scale(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(AnimatedScale), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Wrap(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(Wrap), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ClipRRect(); - ''')); + '''), + ); await tester.pump(); expect(find.byType(ClipRRect), findsOneWidget); - final RenderClipRRect renderClip = tester.allRenderObjects.whereType().first; + final RenderClipRRect renderClip = tester.allRenderObjects + .whereType() + .first; expect(renderClip.clipBehavior, equals(Clip.antiAlias)); expect(renderClip.borderRadius, equals(BorderRadius.zero)); }); diff --git a/packages/rfw/test/material_widgets_test.dart b/packages/rfw/test/material_widgets_test.dart index f11f1e5e96d..e227b416cdf 100644 --- a/packages/rfw/test/material_widgets_test.dart +++ b/packages/rfw/test/material_widgets_test.dart @@ -27,10 +27,9 @@ void main() { const LibraryName testName = LibraryName(['test']); Runtime setupRuntime() { - final Runtime runtime = - Runtime() - ..update(coreName, createCoreWidgets()) - ..update(materialName, createMaterialWidgets()); + final Runtime runtime = Runtime() + ..update(coreName, createCoreWidgets()) + ..update(materialName, createMaterialWidgets()); addTearDown(runtime.dispose); return runtime; } diff --git a/packages/rfw/test/model_test.dart b/packages/rfw/test/model_test.dart index 5deebb1966f..f33c0c973a2 100644 --- a/packages/rfw/test/model_test.dart +++ b/packages/rfw/test/model_test.dart @@ -10,9 +10,18 @@ import 'package:rfw/formats.dart'; void main() { testWidgets('$LibraryName', (WidgetTester tester) async { T deconst(T value) => value; - final LibraryName a = LibraryName(['core', deconst('widgets')]); - final LibraryName b = LibraryName(['core', deconst('widgets')]); - final LibraryName c = LibraryName(['core', deconst('material')]); + final LibraryName a = LibraryName([ + 'core', + deconst('widgets'), + ]); + final LibraryName b = LibraryName([ + 'core', + deconst('widgets'), + ]); + final LibraryName c = LibraryName([ + 'core', + deconst('material'), + ]); const LibraryName d = LibraryName(['core']); expect('$a', 'core.widgets'); expect('$c', 'core.material'); @@ -35,9 +44,18 @@ void main() { }); testWidgets('$FullyQualifiedWidgetName', (WidgetTester tester) async { - const FullyQualifiedWidgetName aa = FullyQualifiedWidgetName(LibraryName(['a']), 'a'); - const FullyQualifiedWidgetName ab = FullyQualifiedWidgetName(LibraryName(['a']), 'b'); - const FullyQualifiedWidgetName bb = FullyQualifiedWidgetName(LibraryName(['b']), 'b'); + const FullyQualifiedWidgetName aa = FullyQualifiedWidgetName( + LibraryName(['a']), + 'a', + ); + const FullyQualifiedWidgetName ab = FullyQualifiedWidgetName( + LibraryName(['a']), + 'b', + ); + const FullyQualifiedWidgetName bb = FullyQualifiedWidgetName( + LibraryName(['b']), + 'b', + ); expect('$aa', 'a:a'); expect(aa, isNot(equals(bb))); expect(aa.hashCode, isNot(equals(bb.hashCode))); @@ -58,46 +76,73 @@ void main() { expect('${const Switch(0, {1: 2})}', 'switch 0 {1: 2}'); expect('${const ConstructorCall("a", {})}', 'a({})'); expect('${const ArgsReference(["a"])}', 'args.a'); - expect('${const BoundArgsReference(false, ["a"])}', 'args(false).a'); + expect( + '${const BoundArgsReference(false, ["a"])}', + 'args(false).a', + ); expect('${const DataReference(["a"])}', 'data.a'); expect('${const LoopReference(0, ["a"])}', 'loop0.a'); expect('${const BoundLoopReference(0, ["a"])}', 'loop(0).a'); expect('${const StateReference(["a"])}', 'state.a'); expect('${const BoundStateReference(0, ["a"])}', 'state^0.a'); expect('${const EventHandler("a", {})}', 'event a {}'); - expect('${const SetStateHandler(StateReference(["a"]), false)}', 'set state.a = false'); + expect( + '${const SetStateHandler(StateReference(["a"]), false)}', + 'set state.a = false', + ); expect('${const Import(LibraryName(["a"]))}', 'import a;'); - expect('${const WidgetDeclaration("a", null, ConstructorCall("b", {}))}', 'widget a = b({});'); - expect('${const WidgetDeclaration("a", { "x": false }, ConstructorCall("b", {}))}', 'widget a = b({});'); - expect('${const RemoteWidgetLibrary([Import(LibraryName(["a"]))], [WidgetDeclaration("a", null, ConstructorCall("b", {}))])}', 'import a;\nwidget a = b({});'); + expect( + '${const WidgetDeclaration("a", null, ConstructorCall("b", {}))}', + 'widget a = b({});', + ); + expect( + '${const WidgetDeclaration("a", {"x": false}, ConstructorCall("b", {}))}', + 'widget a = b({});', + ); + expect( + '${const RemoteWidgetLibrary([ + Import(LibraryName(["a"])), + ], [WidgetDeclaration("a", null, ConstructorCall("b", {}))])}', + 'import a;\nwidget a = b({});', + ); }); testWidgets('$BoundArgsReference', (WidgetTester tester) async { final Object target = Object(); - final BoundArgsReference result = const ArgsReference([0]).bind(target); + final BoundArgsReference result = const ArgsReference([ + 0, + ]).bind(target); expect(result.arguments, target); expect(result.parts, const [0]); }); testWidgets('$DataReference', (WidgetTester tester) async { - final DataReference result = const DataReference([0]).constructReference([1]); + final DataReference result = const DataReference([ + 0, + ]).constructReference([1]); expect(result.parts, const [0, 1]); }); testWidgets('$LoopReference', (WidgetTester tester) async { - final LoopReference result = const LoopReference(9, [0]).constructReference([1]); + final LoopReference result = const LoopReference(9, [ + 0, + ]).constructReference([1]); expect(result.parts, const [0, 1]); }); testWidgets('$BoundLoopReference', (WidgetTester tester) async { final Object target = Object(); - final BoundLoopReference result = const LoopReference(9, [0]).bind(target).constructReference([1]); + final BoundLoopReference result = const LoopReference(9, [ + 0, + ]).bind(target).constructReference([1]); expect(result.value, target); expect(result.parts, const [0, 1]); }); testWidgets('$BoundStateReference', (WidgetTester tester) async { - final BoundStateReference result = const StateReference([0]).bind(9).constructReference([1]); + final BoundStateReference result = const StateReference([ + 0, + ]).bind(9).constructReference([1]); expect(result.depth, 9); expect(result.parts, const [0, 1]); }); @@ -125,15 +170,15 @@ void main() { expect(test2 > test1, isTrue); expect(test2 >= test1, isTrue); // map - final Map map = { - test1: test1, - test2: test2, - }; + final Map map = + {test1: test1, test2: test2}; expect(map[test1], test1); expect(map[test2], test2); }); - testWidgets('$SourceLocation with non-matching sources', (WidgetTester tester) async { + testWidgets('$SourceLocation with non-matching sources', ( + WidgetTester tester, + ) async { const SourceLocation test1 = SourceLocation('test1', 123); const SourceLocation test2 = SourceLocation('test2', 234); expect(() => test1.compareTo(test2), throwsA(anything)); diff --git a/packages/rfw/test/readme_test.dart b/packages/rfw/test/readme_test.dart index b859637bac9..85baa581176 100644 --- a/packages/rfw/test/readme_test.dart +++ b/packages/rfw/test/readme_test.dart @@ -12,7 +12,7 @@ import 'package:rfw/formats.dart'; import 'package:rfw/rfw.dart'; const Map rawRemoteWidgetSnippets = { -'root': ''' + 'root': ''' // #docregion root import local; widget root = GreenBox( @@ -21,7 +21,7 @@ widget root = GreenBox( // #enddocregion root ''', -'fruit': ''' + 'fruit': ''' import local; // #docregion fruit widget fruit = Foo( @@ -30,7 +30,7 @@ widget fruit = Foo( // #enddocregion fruit ''', -'example1': ''' + 'example1': ''' import local; // #docregion example1 widget example1 = GreenBox( @@ -41,7 +41,7 @@ widget example1 = GreenBox( // #enddocregion example1 ''', -'example2': ''' + 'example2': ''' import local; // #docregion example2 widget example2 = GreenBox( @@ -52,7 +52,7 @@ widget example2 = GreenBox( // #enddocregion example2 ''', -'example3': ''' + 'example3': ''' import local; // #docregion example3 widget example3 = GreenBox( @@ -63,7 +63,7 @@ widget example3 = GreenBox( // #enddocregion example3 ''', -'tap': ''' + 'tap': ''' import local; import core; widget tap = GestureDetector( @@ -72,7 +72,7 @@ widget tap = GestureDetector( ); ''', -'tapDown': ''' + 'tapDown': ''' import local; import core; widget tapDown = GestureDetector( @@ -81,7 +81,7 @@ widget tapDown = GestureDetector( ); ''', -'Shop': ''' + 'Shop': ''' // #docregion Shop import core; @@ -97,7 +97,7 @@ widget Product = Text(text: args.product.name, softWrap: false, overflow: "fade" // #enddocregion Shop ''', -'MaterialShop': ''' + 'MaterialShop': ''' // #docregion MaterialShop import core; import material; @@ -121,7 +121,7 @@ widget Product = ListTile( // #enddocregion MaterialShop ''', -'CalculatorPad': ''' + 'CalculatorPad': ''' import core; widget CalculatorPad = Column( @@ -142,7 +142,7 @@ widget CalculatorPad = Column( ); ''', -'CalculatorButton': ''' + 'CalculatorButton': ''' import core; // #docregion CalculatorButton @@ -162,8 +162,7 @@ widget CalculatorButton = Padding( }; // The empty docregion at the end of the following causes the snippet to end with "// ...". -const String gameData = -''' +const String gameData = ''' // #docregion game-data { "games": [ {"rating": 8.219, "users-rated": 16860, "name": "Twilight Struggle", "rank": 1, "link": "/boardgame/12333/twilight-struggle", "id": 12333}, @@ -179,16 +178,26 @@ const String gameData = List _createLocalWidgets(String region) { switch (region) { case 'root': - return [LocalWidgetLibrary({ - // #docregion defaultLocalWidgets - 'GreenBox': (BuildContext context, DataSource source) { - return ColoredBox(color: const Color(0xFF002211), child: source.child(['child'])); - }, - 'Hello': (BuildContext context, DataSource source) { - return Center(child: Text('Hello, ${source.v(["name"])}!', textDirection: TextDirection.ltr)); - }, - // #enddocregion defaultLocalWidgets - })]; + return [ + LocalWidgetLibrary({ + // #docregion defaultLocalWidgets + 'GreenBox': (BuildContext context, DataSource source) { + return ColoredBox( + color: const Color(0xFF002211), + child: source.child(['child']), + ); + }, + 'Hello': (BuildContext context, DataSource source) { + return Center( + child: Text( + 'Hello, ${source.v(["name"])}!', + textDirection: TextDirection.ltr, + ), + ); + }, + // #enddocregion defaultLocalWidgets + }), + ]; case 'fruit': return [ LocalWidgetLibrary({ @@ -202,51 +211,73 @@ List _createLocalWidgets(String region) { // #docregion isList 'Foo': (BuildContext context, DataSource source) { if (source.isList(['bar', 'quux'])) { - return Text('${source.v(['bar', 'quux', 2])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['bar', 'quux', 2])}', + textDirection: TextDirection.ltr, + ); } - return Text('${source.v(['baz'])}', textDirection: TextDirection.ltr); + return Text( + '${source.v(['baz'])}', + textDirection: TextDirection.ltr, + ); }, // #enddocregion isList }), ]; case 'example1': case 'example2': - return [LocalWidgetLibrary({ - // #docregion child - 'GreenBox': (BuildContext context, DataSource source) { - return ColoredBox(color: const Color(0xFF002211), child: source.child(['child'])); - }, - // #enddocregion child - // #docregion isMap - 'Foo': (BuildContext context, DataSource source) { - if (source.isMap(['bar'])) { - return Text('${source.v(['bar', 'name'])}', textDirection: TextDirection.ltr); - } - return Text('${source.v(['bar'])}', textDirection: TextDirection.ltr); - }, - // #enddocregion isMap - })]; + return [ + LocalWidgetLibrary({ + // #docregion child + 'GreenBox': (BuildContext context, DataSource source) { + return ColoredBox( + color: const Color(0xFF002211), + child: source.child(['child']), + ); + }, + // #enddocregion child + // #docregion isMap + 'Foo': (BuildContext context, DataSource source) { + if (source.isMap(['bar'])) { + return Text( + '${source.v(['bar', 'name'])}', + textDirection: TextDirection.ltr, + ); + } + return Text( + '${source.v(['bar'])}', + textDirection: TextDirection.ltr, + ); + }, + // #enddocregion isMap + }), + ]; case 'example3': - return [LocalWidgetLibrary({ - // #docregion optionalChild - 'GreenBox': (BuildContext context, DataSource source) { - return ColoredBox(color: const Color(0xFF002211), child: source.optionalChild(['child'])); - }, - // #enddocregion optionalChild - // #docregion length - 'Foo': (BuildContext context, DataSource source) { - final int length = source.length(['text']); - if (length > 0) { - final StringBuffer text = StringBuffer(); - for (int index = 0; index < length; index += 1) { - text.write(source.v(['text', index])); + return [ + LocalWidgetLibrary({ + // #docregion optionalChild + 'GreenBox': (BuildContext context, DataSource source) { + return ColoredBox( + color: const Color(0xFF002211), + child: source.optionalChild(['child']), + ); + }, + // #enddocregion optionalChild + // #docregion length + 'Foo': (BuildContext context, DataSource source) { + final int length = source.length(['text']); + if (length > 0) { + final StringBuffer text = StringBuffer(); + for (int index = 0; index < length; index += 1) { + text.write(source.v(['text', index])); + } + return Text(text.toString(), textDirection: TextDirection.ltr); } - return Text(text.toString(), textDirection: TextDirection.ltr); - } - return const Text('', textDirection: TextDirection.ltr); - }, - // #enddocregion length - })]; + return const Text('', textDirection: TextDirection.ltr); + }, + // #enddocregion length + }), + ]; case 'tap': // #docregion onTap return [ @@ -264,14 +295,18 @@ List _createLocalWidgets(String region) { }, }), ]; - // #enddocregion onTap + // #enddocregion onTap case 'tapDown': return [ LocalWidgetLibrary({ 'GestureDetector': (BuildContext context, DataSource source) { // #docregion onTapDown return GestureDetector( - onTapDown: source.handler(['onTapDown'], (HandlerTrigger trigger) => (TapDownDetails details) => trigger()), + onTapDown: source.handler( + ['onTapDown'], + (HandlerTrigger trigger) => + (TapDownDetails details) => trigger(), + ), child: source.optionalChild(['child']), ); // #enddocregion onTapDown @@ -282,10 +317,13 @@ List _createLocalWidgets(String region) { // #docregion onTapDown-long return GestureDetector( // onTapDown expects a function that takes a TapDownDetails - onTapDown: source.handler( // this returns a function that takes a TapDownDetails + onTapDown: source.handler( + // this returns a function that takes a TapDownDetails ['onTapDown'], - (HandlerTrigger trigger) { // "trigger" is the function that will send the event to RemoteWidget.onEvent - return (TapDownDetails details) { // this is the function that is returned by handler() above + (HandlerTrigger trigger) { + // "trigger" is the function that will send the event to RemoteWidget.onEvent + return (TapDownDetails details) { + // this is the function that is returned by handler() above trigger(); // the function calls "trigger" }; }, @@ -299,7 +337,9 @@ List _createLocalWidgets(String region) { 'GestureDetector': (BuildContext context, DataSource source) { // #docregion onTapDown-position return GestureDetector( - onTapDown: source.handler(['onTapDown'], (HandlerTrigger trigger) { + onTapDown: source.handler(['onTapDown'], ( + HandlerTrigger trigger, + ) { return (TapDownDetails details) => trigger({ 'x': details.globalPosition.dx, 'y': details.globalPosition.dy, @@ -325,7 +365,10 @@ void main() { testWidgets('readme snippets', (WidgetTester tester) async { final Runtime runtime = Runtime() ..update(const LibraryName(['core']), createCoreWidgets()) - ..update(const LibraryName(['material']), createMaterialWidgets()); + ..update( + const LibraryName(['material']), + createMaterialWidgets(), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(parseDataFile(gameData)); for (final String region in rawRemoteWidgetSnippets.keys) { @@ -340,7 +383,10 @@ void main() { runtime: runtime ..update(const LibraryName(['local']), localWidgets), data: data, - widget: FullyQualifiedWidgetName(LibraryName([region]), region), + widget: FullyQualifiedWidgetName( + LibraryName([region]), + region, + ), ), ), ); diff --git a/packages/rfw/test/remote_widget_test.dart b/packages/rfw/test/remote_widget_test.dart index 5ec03353d58..b9f075e8ace 100644 --- a/packages/rfw/test/remote_widget_test.dart +++ b/packages/rfw/test/remote_widget_test.dart @@ -9,27 +9,25 @@ import 'package:rfw/rfw.dart'; void main() { testWidgets('RemoteWidget', (WidgetTester tester) async { - final Runtime runtime1 = - Runtime() - ..update(const LibraryName(['core']), createCoreWidgets()) - ..update( - const LibraryName(['test']), - parseLibraryFile(''' + final Runtime runtime1 = Runtime() + ..update(const LibraryName(['core']), createCoreWidgets()) + ..update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Placeholder(); '''), - ); + ); addTearDown(runtime1.dispose); - final Runtime runtime2 = - Runtime() - ..update(const LibraryName(['core']), createCoreWidgets()) - ..update( - const LibraryName(['test']), - parseLibraryFile(''' + final Runtime runtime2 = Runtime() + ..update(const LibraryName(['core']), createCoreWidgets()) + ..update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Container(); '''), - ); + ); addTearDown(runtime2.dispose); final DynamicContent data = DynamicContent(); await tester.pumpWidget( diff --git a/packages/rfw/test/runtime_test.dart b/packages/rfw/test/runtime_test.dart index 6ab795f1830..a0a7b25fac3 100644 --- a/packages/rfw/test/runtime_test.dart +++ b/packages/rfw/test/runtime_test.dart @@ -20,27 +20,36 @@ void main() { ..update(const LibraryName(['core']), createCoreWidgets()); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent({ - 'list': [ 0, 1, 2, 3, 4 ], + 'list': [0, 1, 2, 3, 4], }); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); expect(find.byType(RemoteWidget), findsOneWidget); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(find.byType(ErrorWidget), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Column( children: [ ...for v in data.list: Text(text: v, textDirection: "ltr"), ], ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(Text), findsNWidgets(5)); }); @@ -49,67 +58,79 @@ void main() { int buildCount = 0; int? lastValue; final Runtime runtime = Runtime() - ..update(const LibraryName(['core']), LocalWidgetLibrary({ - 'Test': (BuildContext context, DataSource source) { - buildCount += 1; - lastValue = source.v(['value']); - return const SizedBox.shrink(); - }, - })); + ..update( + const LibraryName(['core']), + LocalWidgetLibrary({ + 'Test': (BuildContext context, DataSource source) { + buildCount += 1; + lastValue = source.v(['value']); + return const SizedBox.shrink(); + }, + }), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent({ 'list': [ - { 'a': 0 }, - { 'a': 1 }, - { 'a': 2 }, + {'a': 0}, + {'a': 1}, + {'a': 2}, ], }); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(buildCount, 0); expect(lastValue, isNull); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Test(value: data.list.1.a); - ''')); + '''), + ); await tester.pump(); expect(buildCount, 1); expect(lastValue, 1); data.update('list', [ - { 'a': 0 }, - { 'a': 3 }, - { 'a': 2 }, + {'a': 0}, + {'a': 3}, + {'a': 2}, ]); await tester.pump(); expect(buildCount, 2); expect(lastValue, 3); data.update('list', [ - { 'a': 1 }, - { 'a': 3 }, + {'a': 1}, + {'a': 3}, ]); await tester.pump(); expect(buildCount, 2); expect(lastValue, 3); data.update('list', [ - { 'a': 1 }, - { }, + {'a': 1}, + {}, ]); await tester.pump(); expect(buildCount, 3); expect(lastValue, null); data.update('list', [ - { 'a': 1 }, + {'a': 1}, ]); await tester.pump(); expect(buildCount, 3); @@ -122,15 +143,15 @@ void main() { testWidgets('deepClone', (WidgetTester tester) async { final Map map = { - 'outer': { - 'inner': true, - } + 'outer': {'inner': true}, }; expect(identical(deepClone(map), map), isFalse); expect(deepClone(map), equals(map)); }); - testWidgets('updateText, updateBinary, clearLibraries', (WidgetTester tester) async { + testWidgets('updateText, updateBinary, clearLibraries', ( + WidgetTester tester, + ) async { final Runtime runtime = Runtime() ..update(const LibraryName(['core']), createCoreWidgets()); addTearDown(runtime.dispose); @@ -139,31 +160,56 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); expect(find.byType(RemoteWidget), findsOneWidget); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(find.byType(ErrorWidget), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ColoredBox(color: 0xFF000000); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); - runtime.update(const LibraryName(['test']), decodeLibraryBlob(encodeLibraryBlob(parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + decodeLibraryBlob( + encodeLibraryBlob( + parseLibraryFile(''' import core; widget root = ColoredBox(color: 0xFF000001); - ''')))); + '''), + ), + ), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000001), + ); runtime.clearLibraries(); await tester.pump(); expect(find.byType(RemoteWidget), findsOneWidget); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(find.byType(ErrorWidget), findsOneWidget); }); @@ -176,7 +222,10 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['core']), 'Placeholder'), + widget: const FullyQualifiedWidgetName( + LibraryName(['core']), + 'Placeholder', + ), ), ); @@ -185,7 +234,10 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['core']), 'SizedBoxShrink'), + widget: const FullyQualifiedWidgetName( + LibraryName(['core']), + 'SizedBoxShrink', + ), ), ); expect(find.byType(Placeholder), findsNothing); @@ -193,7 +245,10 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['core']), 'Placeholder'), + widget: const FullyQualifiedWidgetName( + LibraryName(['core']), + 'Placeholder', + ), ), ); expect(find.byType(Placeholder), findsOneWidget); @@ -201,36 +256,54 @@ void main() { testWidgets('Import loops', (WidgetTester tester) async { final Runtime runtime = Runtime() - ..update(const LibraryName(['a']), parseLibraryFile(''' + ..update( + const LibraryName(['a']), + parseLibraryFile(''' import b; - ''')) - ..update(const LibraryName(['b']), parseLibraryFile(''' + '''), + ) + ..update( + const LibraryName(['b']), + parseLibraryFile(''' import a; - ''')); + '''), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), ), ); - expect(tester.takeException().toString(), 'Library a indirectly depends on itself via b which depends on a.'); + expect( + tester.takeException().toString(), + 'Library a indirectly depends on itself via b which depends on a.', + ); }); testWidgets('Import loops', (WidgetTester tester) async { final Runtime runtime = Runtime() - ..update(const LibraryName(['a']), parseLibraryFile(''' + ..update( + const LibraryName(['a']), + parseLibraryFile(''' import a; - ''')); + '''), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), ), ); expect(tester.takeException().toString(), 'Library a depends on itself.'); @@ -238,23 +311,39 @@ void main() { testWidgets('Missing libraries in import', (WidgetTester tester) async { final Runtime runtime = Runtime() - ..update(const LibraryName(['a']), parseLibraryFile(''' + ..update( + const LibraryName(['a']), + parseLibraryFile(''' import b; - ''')); + '''), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), + ), + ); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); + expect( + tester.widget(find.byType(ErrorWidget)).message, + contains( + 'Could not find remote widget named widget in a, possibly because some dependencies were missing: b', ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); - expect(tester.widget(find.byType(ErrorWidget)).message, contains('Could not find remote widget named widget in a, possibly because some dependencies were missing: b')); }); - testWidgets('Missing libraries in specified widget', (WidgetTester tester) async { + testWidgets('Missing libraries in specified widget', ( + WidgetTester tester, + ) async { final Runtime runtime = Runtime(); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); @@ -262,30 +351,57 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), + ), + ); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); + expect( + tester.widget(find.byType(ErrorWidget)).message, + contains( + 'Could not find remote widget named widget in a, possibly because some dependencies were missing: a', ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); - expect(tester.widget(find.byType(ErrorWidget)).message, contains('Could not find remote widget named widget in a, possibly because some dependencies were missing: a')); }); - testWidgets('Missing libraries in import via dependency', (WidgetTester tester) async { + testWidgets('Missing libraries in import via dependency', ( + WidgetTester tester, + ) async { final Runtime runtime = Runtime() - ..update(const LibraryName(['a']), parseLibraryFile(''' + ..update( + const LibraryName(['a']), + parseLibraryFile(''' import b; widget widget = test(); - ''')); + '''), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), + ), + ); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); + expect( + tester.widget(find.byType(ErrorWidget)).message, + contains( + 'Could not find remote widget named test in a, possibly because some dependencies were missing: b', ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); - expect(tester.widget(find.byType(ErrorWidget)).message, contains('Could not find remote widget named test in a, possibly because some dependencies were missing: b')); }); testWidgets('Missing widget', (WidgetTester tester) async { @@ -297,11 +413,20 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); - expect(tester.widget(find.byType(ErrorWidget)).message, contains('Could not find remote widget named widget in a.')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); + expect( + tester.widget(find.byType(ErrorWidget)).message, + contains('Could not find remote widget named widget in a.'), + ); }); testWidgets('Runtime', (WidgetTester tester) async { @@ -313,26 +438,44 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { level: 0 } = inner(level: state.level); widget inner { level: 1 } = ColoredBox(color: args.level); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000000), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { level: 0 } = inner(level: state.level); widget inner { level: 1 } = ColoredBox(color: state.level); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); }); testWidgets('Runtime', (WidgetTester tester) async { @@ -344,24 +487,36 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { level: 0 } = switch state.level { 0: ColoredBox(color: 2), }; - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000002)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000002), + ); }); testWidgets('Runtime', (WidgetTester tester) async { final Runtime runtime = Runtime() - ..update(const LibraryName(['core']), createCoreWidgets()); + ..update(const LibraryName(['core']), createCoreWidgets()); addTearDown(runtime.dispose); expect(runtime.libraries.length, 1); final LibraryName libraryName = runtime.libraries.entries.first.key; @@ -381,23 +536,38 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { level: 0 } = GestureDetector( onTap: set state.level = 1, child: ColoredBox(color: state.level), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000000), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); }); testWidgets('DynamicContent', (WidgetTester tester) async { @@ -409,41 +579,90 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ColoredBox(color: data.color.value); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); data.update('color', json.decode('{"value":1}') as Object); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); data.update('color', parseDataFile('{value:2}')); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000002)); - - data.update('color', decodeDataBlob(Uint8List.fromList([ - 0xFE, 0x52, 0x57, 0x44, // signature - 0x07, // data is a map - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...which has one key - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...which has five letters - 0x76, 0x61, 0x6c, 0x75, 0x65, // ...which are "value" - 0x02, // and the value is an integer - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...which is the number 2 - ]))); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000002), + ); + + data.update( + 'color', + decodeDataBlob( + Uint8List.fromList([ + 0xFE, 0x52, 0x57, 0x44, // signature + 0x07, // data is a map + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // ...which has one key + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // ...which has five letters + 0x76, 0x61, 0x6c, 0x75, 0x65, // ...which are "value" + 0x02, // and the value is an integer + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, // ...which is the number 2 + ]), + ), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000002)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000002), + ); }); testWidgets('DynamicContent', (WidgetTester tester) async { - final DynamicContent data = DynamicContent({'hello': 'world'}); + final DynamicContent data = DynamicContent({ + 'hello': 'world', + }); expect(data.toString(), 'DynamicContent({hello: world})'); }); @@ -454,8 +673,8 @@ void main() { final DynamicContent data = DynamicContent({ 'list': [ { - 'a': { 'b': 0xEE }, - 'c': [ 0xDD ], + 'a': {'b': 0xEE}, + 'c': [0xDD], }, ], }); @@ -464,17 +683,25 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { eventLog.add('$eventName $eventArguments'); }, ), ); expect(find.byType(RemoteWidget), findsOneWidget); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(find.byType(ErrorWidget), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify = ColoredBox(color: args.value.0.q.0); widget root = verify( @@ -484,11 +711,17 @@ void main() { }, ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000EE)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000EE), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify = ColoredBox(color: args.value.0.q.0); widget root = verify( @@ -498,11 +731,17 @@ void main() { }, ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000DD)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000DD), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify = ColoredBox(color: args.value.0.q); widget root = verify( @@ -515,11 +754,17 @@ void main() { }, ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000CC)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000CC), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify { state: true } = ColoredBox(color: args.value.c.0); widget remote = SizedBox(child: args.corn.0); @@ -529,11 +774,17 @@ void main() { verify(value: v), ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000DD)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000DD), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify { state: true } = ColoredBox(color: args.value); widget remote = SizedBox(child: args.corn.0); @@ -547,11 +798,17 @@ void main() { }), ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF0D0D0D)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF0D0D0D), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify { state: true } = switch args.value.c.0 { 0xDD: ColoredBox(color: 0xFF0D0D0D), @@ -564,11 +821,17 @@ void main() { verify(value: v), ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF0D0D0D)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF0D0D0D), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify { state: true } = GestureDetector( onTap: event 'test' { test: args.value.a.b }, @@ -581,14 +844,17 @@ void main() { verify(value: v), ], ); - ''')); + '''), + ); expect(eventLog, isEmpty); await tester.pump(); await tester.tap(find.byType(ColoredBox)); expect(eventLog, ['test {test: ${0xEE}}']); eventLog.clear(); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget verify { state: 0x00 } = GestureDetector( onTap: set state.state = args.value.a.b, @@ -604,13 +870,19 @@ void main() { verify(value: v), ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000001), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000002)); - + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000002), + ); }); testWidgets('list lookup of esoteric values', (WidgetTester tester) async { @@ -622,12 +894,20 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = test(list: ['A'], loop: [...for b in ["B", "C"]: b]); widget test = Text( @@ -639,11 +919,14 @@ void main() { '<', ], ); - ''')); + '''), + ); await tester.pump(); expect(find.text('>ABC<'), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Text( textDirection: "ltr", @@ -653,11 +936,14 @@ void main() { '<', ], ); - ''')); + '''), + ); await tester.pump(); expect(find.text('><'), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = test(list: [test()]); widget test = Text( @@ -668,11 +954,14 @@ void main() { '<', ], ); - ''')); + '''), + ); await tester.pump(); expect(find.text('><'), findsOneWidget); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { list: [ 0x01 ] } = GestureDetector( onTap: set state.list = [ 0x02, 0x03 ], @@ -683,15 +972,24 @@ void main() { ], ), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.firstWidget(find.byType(ColoredBox)).color, const Color(0x00000002)); + expect( + tester.firstWidget(find.byType(ColoredBox)).color, + const Color(0x00000002), + ); expect(find.byType(ColoredBox), findsNWidgets(2)); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Column( children: [ @@ -701,11 +999,17 @@ void main() { }: v, ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = Column( children: [ @@ -715,11 +1019,14 @@ void main() { }: v, ], ); - ''')); + '''), + ); await tester.pump(); expect(find.byType(ColoredBox), findsNothing); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = test( list: [...for w in [ColoredBox(color: 0xFF00FF00)]: w], @@ -729,9 +1036,13 @@ void main() { ...for v in args.list: v, ], ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF00FF00)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF00FF00), + ); }); testWidgets('data lookup', (WidgetTester tester) async { @@ -739,24 +1050,38 @@ void main() { ..update(const LibraryName(['core']), createCoreWidgets()); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent({ - 'map': { 'list': [ 0xAB ] }, + 'map': { + 'list': [0xAB], + }, }); await tester.pumpWidget( RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = test(list: data.map.list); widget test = ColoredBox(color: args.list.0); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000AB)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000AB), + ); }); testWidgets('args lookup', (WidgetTester tester) async { @@ -768,19 +1093,31 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = test1(map: { 'list': [ 0xAC ] }); widget test1 = test2(list: args.map.list); widget test2 = ColoredBox(color: args.list.0); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000AC)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000AC), + ); }); testWidgets('state lookup', (WidgetTester tester) async { @@ -792,18 +1129,30 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { map: { 'list': [ 0xAD ] } } = test(list: state.map.list); widget test = ColoredBox(color: args.list.0); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x000000AD)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x000000AD), + ); }); testWidgets('switch', (WidgetTester tester) async { @@ -815,31 +1164,52 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = ColoredBox(color: switch data.a.b { 0: 0x11111111, default: 0x22222222, }); - ''')); + '''), + ); data.update('a', parseDataFile('{ b: 1 }')); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x22222222)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x22222222), + ); data.update('a', parseDataFile('{ b: 0 }')); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x11111111)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x11111111), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = switch true {}; - ''')); + '''), + ); await tester.pump(); - expect(tester.takeException().toString(), 'Switch in test:root did not resolve to a widget (got ).'); + expect( + tester.takeException().toString(), + 'Switch in test:root did not resolve to a widget (got ).', + ); }); testWidgets('events with arguments', (WidgetTester tester) async { @@ -852,15 +1222,23 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { eventLog.add('$eventName $eventArguments'); }, ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GestureDetector( onTap: event 'tap' { @@ -868,23 +1246,33 @@ void main() { }, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); expect(eventLog, isEmpty); await tester.tap(find.byType(ColoredBox)); expect(eventLog, ['tap {list: [0, 1]}']); eventLog.clear(); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root = GestureDetector( onTap: [ event 'tap' { a: 1 }, event 'tap' { a: 2 }, event 'final tap' { } ], child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); expect(eventLog, isEmpty); await tester.tap(find.byType(ColoredBox)); expect(eventLog, ['tap {a: 1}', 'tap {a: 2}', 'final tap {}']); @@ -896,37 +1284,58 @@ void main() { ..update(const LibraryName(['core']), createCoreWidgets()); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget stateless = ColoredBox(color: 0xAA); widget stateful { test: false } = ColoredBox(color: 0xBB); widget switchy = switch true { default: ColoredBox(color: 0xCC) }; - ''')); + '''), + ); expect( (runtime.build( - tester.element(find.byType(View)), - const FullyQualifiedWidgetName(LibraryName(['test']), 'stateless'), - data, - (String eventName, DynamicMap eventArguments) {}, - ) as dynamic).curriedWidget.toString(), + tester.element(find.byType(View)), + const FullyQualifiedWidgetName( + LibraryName(['test']), + 'stateless', + ), + data, + (String eventName, DynamicMap eventArguments) {}, + ) + as dynamic) + .curriedWidget + .toString(), 'core:ColoredBox {} {color: 170}', ); expect( (runtime.build( - tester.element(find.byType(View)), - const FullyQualifiedWidgetName(LibraryName(['test']), 'stateful'), - data, - (String eventName, DynamicMap eventArguments) {}, - ) as dynamic).curriedWidget.toString(), + tester.element(find.byType(View)), + const FullyQualifiedWidgetName( + LibraryName(['test']), + 'stateful', + ), + data, + (String eventName, DynamicMap eventArguments) {}, + ) + as dynamic) + .curriedWidget + .toString(), 'test:stateful {test: false} {} = core:ColoredBox {} {color: 187}', ); expect( (runtime.build( - tester.element(find.byType(View)), - const FullyQualifiedWidgetName(LibraryName(['test']), 'switchy'), - data, - (String eventName, DynamicMap eventArguments) {}, - ) as dynamic).curriedWidget.toString(), + tester.element(find.byType(View)), + const FullyQualifiedWidgetName( + LibraryName(['test']), + 'switchy', + ), + data, + (String eventName, DynamicMap eventArguments) {}, + ) + as dynamic) + .curriedWidget + .toString(), 'test:switchy {} {} = switch true {null: core:ColoredBox {} {color: 204}}', ); }); @@ -940,115 +1349,184 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: 0 } = GestureDetector( onTap: set state.b = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), 'b does not identify existing state.'); + expect( + tester.takeException().toString(), + 'b does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: 0 } = GestureDetector( onTap: set state.0 = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), '0 does not identify existing state.'); + expect( + tester.takeException().toString(), + '0 does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: [] } = GestureDetector( onTap: set state.a.b = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), 'a.b does not identify existing state.'); + expect( + tester.takeException().toString(), + 'a.b does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: [] } = GestureDetector( onTap: set state.a.0 = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), 'a.0 does not identify existing state.'); + expect( + tester.takeException().toString(), + 'a.0 does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: true } = GestureDetector( onTap: set state.a.0 = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), 'a.0 does not identify existing state.'); + expect( + tester.takeException().toString(), + 'a.0 does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: true } = GestureDetector( onTap: set state.a.b = 0, child: ColoredBox(), ); - ''')); + '''), + ); await tester.pump(); await tester.tap(find.byType(ColoredBox)); - expect(tester.takeException().toString(), 'a.b does not identify existing state.'); + expect( + tester.takeException().toString(), + 'a.b does not identify existing state.', + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: { b: 0 } } = GestureDetector( onTap: set state.a = 15, child: ColoredBox(color: state.a), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x0000000F)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x0000000F), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: [ 0 ] } = GestureDetector( onTap: set state.a = 10, child: ColoredBox(color: state.a), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xFF000000)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xFF000000), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x0000000A)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x0000000A), + ); - runtime.update(const LibraryName(['test']), parseLibraryFile(''' + runtime.update( + const LibraryName(['test']), + parseLibraryFile(''' import core; widget root { a: [ [ 1 ] ] } = GestureDetector( onTap: set state.a.0.0 = 11, child: ColoredBox(color: state.a.0.0), ); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x00000001)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x00000001), + ); await tester.tap(find.byType(ColoredBox)); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0x0000000B)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0x0000000B), + ); }); testWidgets('DataSource', (WidgetTester tester) async { @@ -1060,40 +1538,78 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['remote']), 'test'), + widget: const FullyQualifiedWidgetName( + LibraryName(['remote']), + 'test', + ), onEvent: (String name, DynamicMap arguments) { eventLog.add('$name $arguments'); }, ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); - - runtime.update(const LibraryName(['local']), LocalWidgetLibrary({ - 'Test': (BuildContext context, DataSource source) { - expect(source.isList(['a']), isFalse); - expect(source.isList(['b']), isTrue); - expect(source.length(['b']), 1); - expect(source.child(['missing']), isA()); - expect(tester.takeException().toString(), 'Not a widget at [missing] (got ) for local:Test.'); - expect(source.childList(['a']), [isA()]); - expect(tester.takeException().toString(), 'Not a widget list at [a] (got 0) for local:Test.'); - expect(source.childList(['b']), [isA()]); - expect(tester.takeException().toString(), 'Not a widget at [b] (got 1) for local:Test.'); - expect(eventLog, isEmpty); - source.voidHandler(['callback'], { 'extra': 4, 'b': 3 })!(); - expect(eventLog, ['e {a: 1, b: 3, extra: 4}']); - return const ColoredBox(color: Color(0xAABBCCDD)); - }, - })); - runtime.update(const LibraryName(['remote']), parseLibraryFile(''' + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); + + runtime.update( + const LibraryName(['local']), + LocalWidgetLibrary({ + 'Test': (BuildContext context, DataSource source) { + expect(source.isList(['a']), isFalse); + expect(source.isList(['b']), isTrue); + expect(source.length(['b']), 1); + expect(source.child(['missing']), isA()); + expect( + tester.takeException().toString(), + 'Not a widget at [missing] (got ) for local:Test.', + ); + expect(source.childList(['a']), [ + isA(), + ]); + expect( + tester.takeException().toString(), + 'Not a widget list at [a] (got 0) for local:Test.', + ); + expect(source.childList(['b']), [ + isA(), + ]); + expect( + tester.takeException().toString(), + 'Not a widget at [b] (got 1) for local:Test.', + ); + expect(eventLog, isEmpty); + source.voidHandler( + ['callback'], + {'extra': 4, 'b': 3}, + )!(); + expect(eventLog, ['e {a: 1, b: 3, extra: 4}']); + return const ColoredBox(color: Color(0xAABBCCDD)); + }, + }), + ); + runtime.update( + const LibraryName(['remote']), + parseLibraryFile(''' import local; widget test = Test(a: 0, b: [1], callback: event 'e' { a: 1, b: 2 }); - ''')); + '''), + ); await tester.pump(); - expect(tester.widget(find.byType(ColoredBox)).color, const Color(0xAABBCCDD)); + expect( + tester.widget(find.byType(ColoredBox)).color, + const Color(0xAABBCCDD), + ); bool tested = false; - tester.element(find.byType(ColoredBox)).visitAncestorElements((Element node) { - expect(node.toString(), equalsIgnoringHashCodes('_Widget(state: _WidgetState#00000(name: "local:Test"))')); + tester.element(find.byType(ColoredBox)).visitAncestorElements(( + Element node, + ) { + expect( + node.toString(), + equalsIgnoringHashCodes( + '_Widget(state: _WidgetState#00000(name: "local:Test"))', + ), + ); tested = true; return false; }); @@ -1106,15 +1622,25 @@ void main() { 'a': [0, 1], 'b': ['q', 'r'], }); - data.subscribe([], (Object value) { log.add('root: $value'); }); - data.subscribe(['a', 0], (Object value) { log.add('leaf: $value'); }); + data.subscribe([], (Object value) { + log.add('root: $value'); + }); + data.subscribe(['a', 0], (Object value) { + log.add('leaf: $value'); + }); data.update('a', [2, 3]); expect(log, ['leaf: 2', 'root: {a: [2, 3], b: [q, r]}']); data.update('c', 'test'); - expect(log, ['leaf: 2', 'root: {a: [2, 3], b: [q, r]}', 'root: {a: [2, 3], b: [q, r], c: test}']); + expect(log, [ + 'leaf: 2', + 'root: {a: [2, 3], b: [q, r]}', + 'root: {a: [2, 3], b: [q, r], c: test}', + ]); }); - testWidgets('Data source - optional builder works', (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']); @@ -1122,67 +1648,90 @@ void main() { addTearDown(runtime.dispose); 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 ?? const Text('Hello World!', textDirection: TextDirection.ltr); - }, - })); - runtime.update(remoteLibraryName, parseLibraryFile(''' + runtime.update( + localLibraryName, + LocalWidgetLibrary({ + 'Builder': (BuildContext context, DataSource source) { + final Widget? builder = source.optionalBuilder([ + 'builder', + ], {}); + return builder ?? + const 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'), - )); - + '''), + ); + 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 { + 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(); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent(); - const String 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( { - 'Builder': (BuildContext context, DataSource source) { - return source.builder(['builder'], {}); - }, - })); - runtime.update(remoteLibraryName, parseLibraryFile(''' + 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: Text(text: 'Not a builder :/'), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(tester.takeException().toString(), contains(expectedErrorMessage)); expect(find.byType(ErrorWidget), findsOneWidget); - expect(tester.widget(find.byType(ErrorWidget)).message, contains(expectedErrorMessage)); + expect( + tester.widget(find.byType(ErrorWidget)).message, + contains(expectedErrorMessage), + ); }); - testWidgets('Customized error widget', (WidgetTester tester) async { final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder; ErrorWidget.builder = (FlutterErrorDetails details) { @@ -1196,16 +1745,24 @@ void main() { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['a']), 'widget'), + widget: const FullyQualifiedWidgetName( + LibraryName(['a']), + 'widget', + ), ), ); - expect(tester.takeException().toString(), contains('Could not find remote widget named')); + expect( + tester.takeException().toString(), + contains('Could not find remote widget named'), + ); expect(find.text('oopsie!'), findsOneWidget); expect(find.byType(ErrorWidget), findsNothing); ErrorWidget.builder = oldBuilder; }); - testWidgets('Widget builders - work when scope is not used', (WidgetTester tester) async { + 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']); @@ -1215,30 +1772,40 @@ void main() { 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(''' + 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'), - )); + '''), + ); + 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 when scope is used', (WidgetTester tester) async { + 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']); @@ -1248,25 +1815,36 @@ void main() { final Finder textFinder = find.byType(Text); 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(''' + 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; widget test = HelloWorld( builder: (result) => Text(text: result.result, textDirection: 'ltr'), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(textFinder, findsOneWidget); expect(tester.widget(textFinder).data, 'Hello World!'); @@ -1282,14 +1860,22 @@ void main() { 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(''' + 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; @@ -1297,18 +1883,20 @@ void main() { value: state.value, builder: (result) => Text(text: result.result, textDirection: 'ltr'), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + 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']); @@ -1319,14 +1907,22 @@ void main() { 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(''' + 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; @@ -1334,12 +1930,15 @@ void main() { value: data.value, builder: (result) => Text(text: result.result, textDirection: 'ltr'), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(textFinder, findsOneWidget); expect(tester.widget(textFinder).data, '0'); @@ -1349,7 +1948,9 @@ void main() { expect(tester.widget(textFinder).data, '1'); }); - testWidgets('Widget builders - work with events', (WidgetTester tester) async { + testWidgets('Widget builders - work with events', ( + WidgetTester tester, + ) async { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); @@ -1360,12 +1961,20 @@ void main() { final Finder textFinder = find.byType(Text); runtime.update(coreLibraryName, createCoreWidgets()); - runtime.update(localLibraryName, LocalWidgetLibrary( { - 'Zero': (BuildContext context, DataSource source) { - return source.builder(['builder'], {'result': 0}); - }, - })); - runtime.update(remoteLibraryName, parseLibraryFile(''' + runtime.update( + localLibraryName, + LocalWidgetLibrary({ + 'Zero': (BuildContext context, DataSource source) { + return source.builder( + ['builder'], + {'result': 0}, + ); + }, + }), + ); + runtime.update( + remoteLibraryName, + parseLibraryFile(''' import core; import local; @@ -1375,14 +1984,17 @@ void main() { 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.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(); @@ -1400,20 +2012,31 @@ void main() { 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(''' + 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; @@ -1425,18 +2048,23 @@ void main() { builder: (result2) => Text(text: ['1 + 2 = ', result2.result], textDirection: 'ltr'), ), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(textFinder, findsOneWidget); expect(tester.widget(textFinder).data, '1 + 2 = 3'); }); - testWidgets('Widget builders - works nested dynamically', (WidgetTester tester) async { + testWidgets('Widget builders - works nested dynamically', ( + WidgetTester tester, + ) async { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); @@ -1450,19 +2078,27 @@ void main() { 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(''' + 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; @@ -1482,29 +2118,46 @@ void main() { ), ), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); - expect(tester.widget(textFinder).data, 'strawberry apricot apple blueberry banana'); + 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'); + 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'); + 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'); + expect( + tester.widget(textFinder).data, + 'STRAWBERRY APRICOT apple BLUEBERRY banana', + ); }); - testWidgets('Widget builders - switch works with builder', (WidgetTester tester) async { + 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']); @@ -1514,12 +2167,17 @@ void main() { 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(''' + runtime.update( + localLibraryName, + LocalWidgetLibrary({ + 'Builder': (BuildContext context, DataSource source) { + return source.builder(['builder'], {}); + }, + }), + ); + runtime.update( + remoteLibraryName, + parseLibraryFile(''' import core; import local; @@ -1536,24 +2194,28 @@ void main() { ), }, ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); - + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(textFinder, findsOneWidget); expect(tester.widget(textFinder).data, 'The builder is disabled.'); - await tester.tap(textFinder); - await tester.pump(); + 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 { + 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']); @@ -1562,13 +2224,21 @@ void main() { 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(''' + 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; @@ -1591,23 +2261,34 @@ void main() { ), }, ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + 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'); + expect( + tester.widget(textFinder).data, + 'The input is false, the output is true', + ); - await tester.tap(textFinder); - await tester.pump(); + await tester.tap(textFinder); + await tester.pump(); expect(textFinder, findsOneWidget); - expect(tester.widget(textFinder).data, 'The input is true, the output is false'); + expect( + tester.widget(textFinder).data, + 'The input is true, the output is false', + ); }); - testWidgets('Widget builders - builder works with loops', (WidgetTester tester) async { + testWidgets('Widget builders - builder works with loops', ( + WidgetTester tester, + ) async { const LibraryName coreLibraryName = LibraryName(['core']); const LibraryName localLibraryName = LibraryName(['local']); const LibraryName remoteLibraryName = LibraryName(['remote']); @@ -1618,18 +2299,21 @@ void main() { runtime.update(coreLibraryName, createCoreWidgets()); runtime.update( - localLibraryName, - LocalWidgetLibrary({ - 'Builder': (BuildContext context, DataSource source) { - return source.builder( - ['builder'], - { - 'values': ['Value1', 'Value2', 'Value3'], - }, - ); - }, - })); - runtime.update(remoteLibraryName, parseLibraryFile(''' + localLibraryName, + LocalWidgetLibrary({ + 'Builder': (BuildContext context, DataSource source) { + return source.builder( + ['builder'], + { + 'values': ['Value1', 'Value2', 'Value3'], + }, + ); + }, + }), + ); + runtime.update( + remoteLibraryName, + parseLibraryFile(''' import core; import local; @@ -1642,12 +2326,15 @@ void main() { ], ), ); - ''')); - await tester.pumpWidget(RemoteWidget( - runtime: runtime, - data: data, - widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), - )); + '''), + ); + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'), + ), + ); expect(textFinder, findsNWidgets(3)); expect((textFinder.at(0).evaluate().first.widget as Text).data, 'Value1'); diff --git a/packages/rfw/test/source_locations_test.dart b/packages/rfw/test/source_locations_test.dart index 0c272112897..1912c7fee5f 100644 --- a/packages/rfw/test/source_locations_test.dart +++ b/packages/rfw/test/source_locations_test.dart @@ -25,42 +25,62 @@ const String sourceFile = ''' );'''; void main() { - testWidgets('parseLibraryFile: source location tracking', (WidgetTester tester) async { + testWidgets('parseLibraryFile: source location tracking', ( + WidgetTester tester, + ) async { final RemoteWidgetLibrary test = parseLibraryFile(sourceFile); expect(test.widgets.first.source, isNull); }); - testWidgets('parseLibraryFile: source location tracking', (WidgetTester tester) async { - String extract(BlobNode node) => (node.source!.start.source as String).substring(node.source!.start.offset, node.source!.end.offset); + testWidgets('parseLibraryFile: source location tracking', ( + WidgetTester tester, + ) async { + String extract(BlobNode node) => (node.source!.start.source as String) + .substring(node.source!.start.offset, node.source!.end.offset); // We use the actual source text as the sourceIdentifier to make it trivial to find the source contents. // In normal operation, the sourceIdentifier would be the file name or some similar object. - final RemoteWidgetLibrary test = parseLibraryFile(sourceFile, sourceIdentifier: sourceFile); + final RemoteWidgetLibrary test = parseLibraryFile( + sourceFile, + sourceIdentifier: sourceFile, + ); expect(extract(test.widgets.first), ''' widget verify { state: true } = switch args.value.c.0 { 0xDD: ColoredBox(color: 0xFF0D0D0D), default: ColoredBox(color: args.value), };'''); - expect(extract((test.widgets.first.root as Switch).input as ArgsReference), 'args.value.c.0'); + expect( + extract((test.widgets.first.root as Switch).input as ArgsReference), + 'args.value.c.0', + ); }); testWidgets('Runtime: source location tracking', (WidgetTester tester) async { String extract(BlobNode node) { if (node.source == null) { - printOnFailure('This node had no source information: ${node.runtimeType} $node'); + printOnFailure( + 'This node had no source information: ${node.runtimeType} $node', + ); } - return (node.source!.start.source as String).substring(node.source!.start.offset, node.source!.end.offset); + return (node.source!.start.source as String).substring( + node.source!.start.offset, + node.source!.end.offset, + ); } + final Runtime runtime = Runtime() ..update(const LibraryName(['core']), createCoreWidgets()) // We use the actual source text as the sourceIdentifier to make it trivial to find the source contents. // In normal operation, the sourceIdentifier would be the file name or some similar object. - ..update(const LibraryName(['test']), parseLibraryFile(sourceFile, sourceIdentifier: sourceFile)); + ..update( + const LibraryName(['test']), + parseLibraryFile(sourceFile, sourceIdentifier: sourceFile), + ); addTearDown(runtime.dispose); final DynamicContent data = DynamicContent({ 'list': [ { - 'a': { 'b': 0xEE }, - 'c': [ 0xDD ], + 'a': {'b': 0xEE}, + 'c': [0xDD], }, ], }); @@ -68,12 +88,20 @@ widget verify { state: true } = switch args.value.c.0 { RemoteWidget( runtime: runtime, data: data, - widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + widget: const FullyQualifiedWidgetName( + LibraryName(['test']), + 'root', + ), onEvent: (String eventName, DynamicMap eventArguments) { fail('unexpected event $eventName'); }, ), ); - expect(extract(Runtime.blobNodeFor(tester.firstElement(find.byType(ColoredBox)))!), 'ColoredBox(color: 0xFF0D0D0D)'); + expect( + extract( + Runtime.blobNodeFor(tester.firstElement(find.byType(ColoredBox)))!, + ), + 'ColoredBox(color: 0xFF0D0D0D)', + ); }); } diff --git a/packages/rfw/test/text_test.dart b/packages/rfw/test/text_test.dart index 210eb7b5b59..50f9330841b 100644 --- a/packages/rfw/test/text_test.dart +++ b/packages/rfw/test/text_test.dart @@ -11,7 +11,7 @@ import 'package:rfw/formats.dart'; void main() { testWidgets('empty parseDataFile', (WidgetTester tester) async { final DynamicMap result = parseDataFile('{}'); - expect(result, { }); + expect(result, {}); }); testWidgets('empty parseLibraryFile', (WidgetTester tester) async { @@ -22,7 +22,7 @@ void main() { testWidgets('space parseDataFile', (WidgetTester tester) async { final DynamicMap result = parseDataFile(' \n {} \n '); - expect(result, { }); + expect(result, {}); }); testWidgets('space parseLibraryFile', (WidgetTester tester) async { @@ -35,11 +35,14 @@ void main() { void test(String input, String expectedMessage) { try { parseDataFile(input); - fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + fail( + 'parsing `$input` did not result in an error (expected "$expectedMessage").', + ); } on ParserException catch (e) { expect('$e', expectedMessage); } } + test('', 'Expected symbol "{" but found at line 1 column 0.'); test('}', 'Expected symbol "{" but found } at line 1 column 1.'); test('1', 'Expected symbol "{" but found 1 at line 1 column 1.'); @@ -55,229 +58,590 @@ void main() { test('{ a: a }', 'Unexpected a at line 1 column 7.'); test('{ ... }', 'Expected symbol "}" but found … at line 1 column 5.'); test('{ a: ... }', 'Unexpected … at line 1 column 8.'); - test('{ a: -', 'Unexpected end of file after minus sign at line 1 column 6.'); - test('{ a: -a', 'Unexpected character U+0061 ("a") after minus sign (expected digit) at line 1 column 7.'); + test( + '{ a: -', + 'Unexpected end of file after minus sign at line 1 column 6.', + ); + test( + '{ a: -a', + 'Unexpected character U+0061 ("a") after minus sign (expected digit) at line 1 column 7.', + ); test('{ a: 0', 'Expected symbol "}" but found at line 1 column 6.'); - test('{ a: 0e', 'Unexpected end of file after exponent separator at line 1 column 7.'); - test('{ a: 0ee', 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 8.'); - test('{ a: 0e-', 'Unexpected end of file after exponent separator and minus sign at line 1 column 8.'); - test('{ a: 0e-e', 'Unexpected character U+0065 ("e") in exponent at line 1 column 9.'); - test('{ a: 0e-f', 'Unexpected character U+0066 ("f") in exponent at line 1 column 9.'); - test('{ a: 0e-.', 'Unexpected character U+002E (".") in exponent at line 1 column 9.'); - test('{ a: 0e- ', 'Unexpected character U+0020 in exponent at line 1 column 9.'); - test('{ a: 0e-0', 'Expected symbol "}" but found at line 1 column 9.'); + test( + '{ a: 0e', + 'Unexpected end of file after exponent separator at line 1 column 7.', + ); + test( + '{ a: 0ee', + 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 8.', + ); + test( + '{ a: 0e-', + 'Unexpected end of file after exponent separator and minus sign at line 1 column 8.', + ); + test( + '{ a: 0e-e', + 'Unexpected character U+0065 ("e") in exponent at line 1 column 9.', + ); + test( + '{ a: 0e-f', + 'Unexpected character U+0066 ("f") in exponent at line 1 column 9.', + ); + test( + '{ a: 0e-.', + 'Unexpected character U+002E (".") in exponent at line 1 column 9.', + ); + test( + '{ a: 0e- ', + 'Unexpected character U+0020 in exponent at line 1 column 9.', + ); + test( + '{ a: 0e-0', + 'Expected symbol "}" but found at line 1 column 9.', + ); test('{ a: 0e-0{', 'Expected symbol "}" but found { at line 1 column 10.'); test('{ a: 0e-0;', 'Expected symbol "}" but found ; at line 1 column 10.'); - test('{ a: 0e-0e', 'Unexpected character U+0065 ("e") in exponent at line 1 column 10.'); + test( + '{ a: 0e-0e', + 'Unexpected character U+0065 ("e") in exponent at line 1 column 10.', + ); test('{ a: 0 ', 'Expected symbol "}" but found at line 1 column 7.'); - test('{ a: 0.', 'Unexpected end of file after decimal point at line 1 column 7.'); - test('{ a: 0.e', 'Unexpected character U+0065 ("e") in fraction component at line 1 column 8.'); - test('{ a: 0. ', 'Unexpected character U+0020 in fraction component at line 1 column 8.'); + test( + '{ a: 0.', + 'Unexpected end of file after decimal point at line 1 column 7.', + ); + test( + '{ a: 0.e', + 'Unexpected character U+0065 ("e") in fraction component at line 1 column 8.', + ); + test( + '{ a: 0. ', + 'Unexpected character U+0020 in fraction component at line 1 column 8.', + ); test('{ a: 00', 'Expected symbol "}" but found at line 1 column 7.'); - test('{ a: 00e', 'Unexpected end of file after exponent separator at line 1 column 8.'); - test('{ a: 00ee', 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 9.'); - test('{ a: 00e-', 'Unexpected end of file after exponent separator and minus sign at line 1 column 9.'); + test( + '{ a: 00e', + 'Unexpected end of file after exponent separator at line 1 column 8.', + ); + test( + '{ a: 00ee', + 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 9.', + ); + test( + '{ a: 00e-', + 'Unexpected end of file after exponent separator and minus sign at line 1 column 9.', + ); test('{ a: 00 ', 'Expected symbol "}" but found at line 1 column 8.'); test('{ a: -0', 'Expected symbol "}" but found at line 1 column 7.'); - test('{ a: -0.', 'Unexpected end of file after decimal point at line 1 column 8.'); - test('{ a: -0. ', 'Unexpected character U+0020 in fraction component at line 1 column 9.'); - test('{ a: -0.0', 'Expected symbol "}" but found at line 1 column 9.'); - test('{ a: -0.0 ', 'Expected symbol "}" but found at line 1 column 10.'); - test('{ a: -0.0e', 'Unexpected end of file after exponent separator at line 1 column 10.'); - test('{ a: -0.0ee', 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 11.'); - test('{ a: -0.0e-', 'Unexpected end of file after exponent separator and minus sign at line 1 column 11.'); - test('{ a: -0.0f', 'Unexpected character U+0066 ("f") in fraction component at line 1 column 10.'); + test( + '{ a: -0.', + 'Unexpected end of file after decimal point at line 1 column 8.', + ); + test( + '{ a: -0. ', + 'Unexpected character U+0020 in fraction component at line 1 column 9.', + ); + test( + '{ a: -0.0', + 'Expected symbol "}" but found at line 1 column 9.', + ); + test( + '{ a: -0.0 ', + 'Expected symbol "}" but found at line 1 column 10.', + ); + test( + '{ a: -0.0e', + 'Unexpected end of file after exponent separator at line 1 column 10.', + ); + test( + '{ a: -0.0ee', + 'Unexpected character U+0065 ("e") after exponent separator at line 1 column 11.', + ); + test( + '{ a: -0.0e-', + 'Unexpected end of file after exponent separator and minus sign at line 1 column 11.', + ); + test( + '{ a: -0.0f', + 'Unexpected character U+0066 ("f") in fraction component at line 1 column 10.', + ); test('{ a: -00', 'Expected symbol "}" but found at line 1 column 8.'); - test('{ a: 0f', 'Unexpected character U+0066 ("f") after zero at line 1 column 7.'); - test('{ a: -0f', 'Unexpected character U+0066 ("f") after negative zero at line 1 column 8.'); + test( + '{ a: 0f', + 'Unexpected character U+0066 ("f") after zero at line 1 column 7.', + ); + test( + '{ a: -0f', + 'Unexpected character U+0066 ("f") after negative zero at line 1 column 8.', + ); test('{ a: 00f', 'Unexpected character U+0066 ("f") at line 1 column 8.'); test('{ a: -00f', 'Unexpected character U+0066 ("f") at line 1 column 9.'); test('{ a: test.0', 'Unexpected test at line 1 column 10.'); test('{ a: test.0 ', 'Unexpected test at line 1 column 10.'); - test('{ a: 0x', 'Unexpected end of file after 0x prefix at line 1 column 7.'); - test('{ a: 0xg', 'Unexpected character U+0067 ("g") after 0x prefix at line 1 column 8.'); - test('{ a: 0xx', 'Unexpected character U+0078 ("x") after 0x prefix at line 1 column 8.'); - test('{ a: 0x}', 'Unexpected character U+007D ("}") after 0x prefix at line 1 column 8.'); + test( + '{ a: 0x', + 'Unexpected end of file after 0x prefix at line 1 column 7.', + ); + test( + '{ a: 0xg', + 'Unexpected character U+0067 ("g") after 0x prefix at line 1 column 8.', + ); + test( + '{ a: 0xx', + 'Unexpected character U+0078 ("x") after 0x prefix at line 1 column 8.', + ); + test( + '{ a: 0x}', + 'Unexpected character U+007D ("}") after 0x prefix at line 1 column 8.', + ); test('{ a: 0x0', 'Expected symbol "}" but found at line 1 column 8.'); - test('{ a: 0xff', 'Expected symbol "}" but found at line 1 column 9.'); - test('{ a: 0xfg', 'Unexpected character U+0067 ("g") in hex literal at line 1 column 9.'); + test( + '{ a: 0xff', + 'Expected symbol "}" but found at line 1 column 9.', + ); + test( + '{ a: 0xfg', + 'Unexpected character U+0067 ("g") in hex literal at line 1 column 9.', + ); test('{ a: ."hello"', 'Unexpected . at line 1 column 7.'); - test('{ a: "hello"."hello"', 'Expected symbol "}" but found . at line 1 column 14.'); - test('{ a: "hello"', 'Expected symbol "}" but found at line 1 column 12.'); - test('{ a: "\n"', 'Unexpected end of line inside string at line 2 column 0.'); - test('{ a: "hello\n"', 'Unexpected end of line inside string at line 2 column 0.'); - test('{ a: "\\', 'Unexpected end of file inside string at line 1 column 7.'); + test( + '{ a: "hello"."hello"', + 'Expected symbol "}" but found . at line 1 column 14.', + ); + test( + '{ a: "hello"', + 'Expected symbol "}" but found at line 1 column 12.', + ); + test( + '{ a: "\n"', + 'Unexpected end of line inside string at line 2 column 0.', + ); + test( + '{ a: "hello\n"', + 'Unexpected end of line inside string at line 2 column 0.', + ); + test( + '{ a: "\\', + 'Unexpected end of file inside string at line 1 column 7.', + ); test('{ a: ."hello"', 'Unexpected . at line 1 column 7.'); - test('{ "a": \'hello\'.\'hello\'', 'Expected symbol "}" but found . at line 1 column 16.'); - test('{ "a": \'hello\'', 'Expected symbol "}" but found at line 1 column 14.'); - test('{ "a": \'hello\'h', 'Unexpected character U+0068 ("h") after end quote at line 1 column 15.'); - test('{ "a": \'\n\'', 'Unexpected end of line inside string at line 2 column 0.'); - test('{ "a": \'hello\n\'', 'Unexpected end of line inside string at line 2 column 0.'); - test('{ "a": \'\\', 'Unexpected end of file inside string at line 1 column 9.'); - test('{ "a": \'\\\'', 'Unexpected end of file inside string at line 1 column 10.'); - test('{ "a": \'\\u', 'Unexpected end of file inside Unicode escape at line 1 column 10.'); - test('{ "a": \'\\u0', 'Unexpected end of file inside Unicode escape at line 1 column 11.'); - test('{ "a": \'\\u00', 'Unexpected end of file inside Unicode escape at line 1 column 12.'); - test('{ "a": \'\\u000', 'Unexpected end of file inside Unicode escape at line 1 column 13.'); - test('{ "a": \'\\u0000', 'Unexpected end of file inside string at line 1 column 14.'); - test('{ "a": \'\\u|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 11.'); - test('{ "a": \'\\u0|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 12.'); - test('{ "a": \'\\u00|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 13.'); - test('{ "a": \'\\u000|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 14.'); - test('{ "a": \'\\u0000|', 'Unexpected end of file inside string at line 1 column 15.'); - test('{ "a": \'\\U263A\' }', 'Unexpected character U+0055 ("U") after backslash in string at line 1 column 10.'); - test('{ "a": "\\', 'Unexpected end of file inside string at line 1 column 9.'); - test('{ "a": "\\"', 'Unexpected end of file inside string at line 1 column 10.'); - test('{ "a": "\\u', 'Unexpected end of file inside Unicode escape at line 1 column 10.'); - test('{ "a": "\\u0', 'Unexpected end of file inside Unicode escape at line 1 column 11.'); - test('{ "a": "\\u00', 'Unexpected end of file inside Unicode escape at line 1 column 12.'); - test('{ "a": "\\u000', 'Unexpected end of file inside Unicode escape at line 1 column 13.'); - test('{ "a": "\\u0000', 'Unexpected end of file inside string at line 1 column 14.'); - test('{ "a": "\\u|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 11.'); - test('{ "a": "\\u0|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 12.'); - test('{ "a": "\\u00|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 13.'); - test('{ "a": "\\u000|', 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 14.'); - test('{ "a": "\\u0000|', 'Unexpected end of file inside string at line 1 column 15.'); - test('{ "a": "\\U263A" }', 'Unexpected character U+0055 ("U") after backslash in string at line 1 column 10.'); + test( + '{ "a": \'hello\'.\'hello\'', + 'Expected symbol "}" but found . at line 1 column 16.', + ); + test( + '{ "a": \'hello\'', + 'Expected symbol "}" but found at line 1 column 14.', + ); + test( + '{ "a": \'hello\'h', + 'Unexpected character U+0068 ("h") after end quote at line 1 column 15.', + ); + test( + '{ "a": \'\n\'', + 'Unexpected end of line inside string at line 2 column 0.', + ); + test( + '{ "a": \'hello\n\'', + 'Unexpected end of line inside string at line 2 column 0.', + ); + test( + '{ "a": \'\\', + 'Unexpected end of file inside string at line 1 column 9.', + ); + test( + '{ "a": \'\\\'', + 'Unexpected end of file inside string at line 1 column 10.', + ); + test( + '{ "a": \'\\u', + 'Unexpected end of file inside Unicode escape at line 1 column 10.', + ); + test( + '{ "a": \'\\u0', + 'Unexpected end of file inside Unicode escape at line 1 column 11.', + ); + test( + '{ "a": \'\\u00', + 'Unexpected end of file inside Unicode escape at line 1 column 12.', + ); + test( + '{ "a": \'\\u000', + 'Unexpected end of file inside Unicode escape at line 1 column 13.', + ); + test( + '{ "a": \'\\u0000', + 'Unexpected end of file inside string at line 1 column 14.', + ); + test( + '{ "a": \'\\u|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 11.', + ); + test( + '{ "a": \'\\u0|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 12.', + ); + test( + '{ "a": \'\\u00|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 13.', + ); + test( + '{ "a": \'\\u000|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 14.', + ); + test( + '{ "a": \'\\u0000|', + 'Unexpected end of file inside string at line 1 column 15.', + ); + test( + '{ "a": \'\\U263A\' }', + 'Unexpected character U+0055 ("U") after backslash in string at line 1 column 10.', + ); + test( + '{ "a": "\\', + 'Unexpected end of file inside string at line 1 column 9.', + ); + test( + '{ "a": "\\"', + 'Unexpected end of file inside string at line 1 column 10.', + ); + test( + '{ "a": "\\u', + 'Unexpected end of file inside Unicode escape at line 1 column 10.', + ); + test( + '{ "a": "\\u0', + 'Unexpected end of file inside Unicode escape at line 1 column 11.', + ); + test( + '{ "a": "\\u00', + 'Unexpected end of file inside Unicode escape at line 1 column 12.', + ); + test( + '{ "a": "\\u000', + 'Unexpected end of file inside Unicode escape at line 1 column 13.', + ); + test( + '{ "a": "\\u0000', + 'Unexpected end of file inside string at line 1 column 14.', + ); + test( + '{ "a": "\\u|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 11.', + ); + test( + '{ "a": "\\u0|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 12.', + ); + test( + '{ "a": "\\u00|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 13.', + ); + test( + '{ "a": "\\u000|', + 'Unexpected character U+007C ("|") in Unicode escape at line 1 column 14.', + ); + test( + '{ "a": "\\u0000|', + 'Unexpected end of file inside string at line 1 column 15.', + ); + test( + '{ "a": "\\U263A" }', + 'Unexpected character U+0055 ("U") after backslash in string at line 1 column 10.', + ); test('{ "a": ', 'Unexpected at line 1 column 7.'); - test('{ "a": /', 'Unexpected end of file inside comment delimiter at line 1 column 8.'); - test('{ "a": /.', 'Unexpected character U+002E (".") inside comment delimiter at line 1 column 9.'); + test( + '{ "a": /', + 'Unexpected end of file inside comment delimiter at line 1 column 8.', + ); + test( + '{ "a": /.', + 'Unexpected character U+002E (".") inside comment delimiter at line 1 column 9.', + ); test('{ "a": //', 'Unexpected at line 1 column 9.'); - test('{ "a": /*', 'Unexpected end of file in block comment at line 1 column 9.'); - test('{ "a": /*/', 'Unexpected end of file in block comment at line 1 column 10.'); - test('{ "a": /**', 'Unexpected end of file in block comment at line 1 column 10.'); - test('{ "a": /* *', 'Unexpected end of file in block comment at line 1 column 11.'); + test( + '{ "a": /*', + 'Unexpected end of file in block comment at line 1 column 9.', + ); + test( + '{ "a": /*/', + 'Unexpected end of file in block comment at line 1 column 10.', + ); + test( + '{ "a": /**', + 'Unexpected end of file in block comment at line 1 column 10.', + ); + test( + '{ "a": /* *', + 'Unexpected end of file in block comment at line 1 column 11.', + ); }); testWidgets('valid values in parseDataFile', (WidgetTester tester) async { - expect(parseDataFile('{ }\n\n \n\n'), { }); - expect(parseDataFile('{ a: "b" }'), { 'a': 'b' }); - expect(parseDataFile('{ a: [ "b", 9 ] }'), { 'a': [ 'b', 9 ] }); - expect(parseDataFile('{ a: { } }'), { 'a': { } }); - expect(parseDataFile('{ a: 123.456e7 }'), { 'a': 123.456e7 }); - expect(parseDataFile('{ a: true }'), { 'a': true }); - expect(parseDataFile('{ a: false }'), { 'a': false }); - expect(parseDataFile('{ "a": 0 }'), { 'a': 0 }); - expect(parseDataFile('{ "a": -0, b: "x" }'), { 'a': 0, 'b': 'x' }); - expect(parseDataFile('{ "a": null }'), { }); - expect(parseDataFile('{ "a": -6 }'), { 'a': -6 }); - expect(parseDataFile('{ "a": -7 }'), { 'a': -7 }); - expect(parseDataFile('{ "a": -8 }'), { 'a': -8 }); - expect(parseDataFile('{ "a": -9 }'), { 'a': -9 }); - expect(parseDataFile('{ "a": 01 }'), { 'a': 1 }); - expect(parseDataFile('{ "a": 0e0 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": 0e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": 0e8 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": 1e9 }'), { 'a': 1000000000.0 }); - expect(parseDataFile('{ "a": -0e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": 00e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": -00e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": 00.0e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": -00.0e1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": -00.0e-1 }'), { 'a': 0.0 }); - expect(parseDataFile('{ "a": -1e-1 }'), { 'a': -0.1 }); - expect(parseDataFile('{ "a": -1e-2 }'), { 'a': -0.01 }); - expect(parseDataFile('{ "a": -1e-3 }'), { 'a': -0.001 }); - expect(parseDataFile('{ "a": -1e-4 }'), { 'a': -0.0001 }); - expect(parseDataFile('{ "a": -1e-5 }'), { 'a': -0.00001 }); - expect(parseDataFile('{ "a": -1e-6 }'), { 'a': -0.000001 }); - expect(parseDataFile('{ "a": -1e-7 }'), { 'a': -0.0000001 }); - expect(parseDataFile('{ "a": -1e-8 }'), { 'a': -0.00000001 }); - expect(parseDataFile('{ "a": -1e-9 }'), { 'a': -0.000000001 }); - expect(parseDataFile('{ "a": -1e-10 }'), { 'a': -0.0000000001 }); - expect(parseDataFile('{ "a": -1e-11 }'), { 'a': -0.00000000001 }); - expect(parseDataFile('{ "a": -1e-12 }'), { 'a': -0.000000000001 }); - expect(parseDataFile('{ "a": -1e-13 }'), { 'a': -0.0000000000001 }); - expect(parseDataFile('{ "a": -1e-14 }'), { 'a': -0.00000000000001 }); - expect(parseDataFile('{ "a": -1e-15 }'), { 'a': -0.000000000000001 }); - expect(parseDataFile('{ "a": -1e-16 }'), { 'a': -0.0000000000000001 }); - expect(parseDataFile('{ "a": -1e-17 }'), { 'a': -0.00000000000000001 }); - expect(parseDataFile('{ "a": -1e-18 }'), { 'a': -0.000000000000000001 }); - expect(parseDataFile('{ "a": -1e-19 }'), { 'a': -0.0000000000000000001 }); - expect(parseDataFile('{ "a": 0x0 }'), { 'a': 0 }); - expect(parseDataFile('{ "a": 0x1 }'), { 'a': 1 }); - expect(parseDataFile('{ "a": 0x01 }'), { 'a': 1 }); - expect(parseDataFile('{ "a": 0xa }'), { 'a': 10 }); - expect(parseDataFile('{ "a": 0xb }'), { 'a': 11 }); - expect(parseDataFile('{ "a": 0xc }'), { 'a': 12 }); - expect(parseDataFile('{ "a": 0xd }'), { 'a': 13 }); - expect(parseDataFile('{ "a": 0xe }'), { 'a': 14 }); - expect(parseDataFile('{ "a": 0xfa }'), { 'a': 250 }); - expect(parseDataFile('{ "a": 0xfb }'), { 'a': 251 }); - expect(parseDataFile('{ "a": 0xfc }'), { 'a': 252 }); - expect(parseDataFile('{ "a": 0xfd }'), { 'a': 253 }); - expect(parseDataFile('{ "a": 0xfe }'), { 'a': 254 }); - expect(parseDataFile('{ "a": "\\"\\/\\\'\\b\\f\\n\\r\\t\\\\" }'), { 'a': '\x22\x2F\x27\x08\x0C\x0A\x0D\x09\x5C' }); - expect(parseDataFile('{ "a": \'\\"\\/\\\'\\b\\f\\n\\r\\t\\\\\' }'), { 'a': '\x22\x2F\x27\x08\x0C\x0A\x0D\x09\x5C' }); - expect(parseDataFile('{ "a": \'\\u263A\' }'), { 'a': '☺' }); - expect(parseDataFile('{ "a": \'\\u0000\' }'), { 'a': '\x00' }); - expect(parseDataFile('{ "a": \'\\u1111\' }'), { 'a': 'ᄑ' }); - expect(parseDataFile('{ "a": \'\\u2222\' }'), { 'a': '∢' }); - expect(parseDataFile('{ "a": \'\\u3333\' }'), { 'a': '㌳' }); - expect(parseDataFile('{ "a": \'\\u4444\' }'), { 'a': '䑄' }); - expect(parseDataFile('{ "a": \'\\u5555\' }'), { 'a': '啕' }); - expect(parseDataFile('{ "a": \'\\u6666\' }'), { 'a': '晦' }); - expect(parseDataFile('{ "a": \'\\u7777\' }'), { 'a': '睷' }); - expect(parseDataFile('{ "a": \'\\u8888\' }'), { 'a': '袈' }); - expect(parseDataFile('{ "a": \'\\u9999\' }'), { 'a': '香' }); - expect(parseDataFile('{ "a": \'\\uaaaa\' }'), { 'a': 'ꪪ' }); - expect(parseDataFile('{ "a": \'\\ubbbb\' }'), { 'a': '뮻' }); - expect(parseDataFile('{ "a": \'\\ucccc\' }'), { 'a': '쳌' }); - expect(parseDataFile('{ "a": \'\\udddd\' }'), { 'a': '\u{dddd}' }); // low surragate - expect(parseDataFile('{ "a": \'\\ueeee\' }'), { 'a': '\u{eeee}' }); // private use area - expect(parseDataFile('{ "a": \'\\uffff\' }'), { 'a': '\u{ffff}' }); // not technically a valid Unicode character - expect(parseDataFile('{ "a": \'\\uAAAA\' }'), { 'a': 'ꪪ' }); - expect(parseDataFile('{ "a": \'\\uBBBB\' }'), { 'a': '뮻' }); - expect(parseDataFile('{ "a": \'\\uCCCC\' }'), { 'a': '쳌' }); - expect(parseDataFile('{ "a": \'\\uDDDD\' }'), { 'a': '\u{dddd}' }); - expect(parseDataFile('{ "a": \'\\uEEEE\' }'), { 'a': '\u{eeee}' }); - expect(parseDataFile('{ "a": \'\\uFFFF\' }'), { 'a': '\u{ffff}' }); - expect(parseDataFile('{ "a": /**/ "1" }'), { 'a': '1' }); - expect(parseDataFile('{ "a": /* */ "1" }'), { 'a': '1' }); - expect(parseDataFile('{ "a": /*\n*/ "1" }'), { 'a': '1' }); + expect(parseDataFile('{ }\n\n \n\n'), {}); + expect(parseDataFile('{ a: "b" }'), {'a': 'b'}); + expect(parseDataFile('{ a: [ "b", 9 ] }'), { + 'a': ['b', 9], + }); + expect(parseDataFile('{ a: { } }'), { + 'a': {}, + }); + expect(parseDataFile('{ a: 123.456e7 }'), { + 'a': 123.456e7, + }); + expect(parseDataFile('{ a: true }'), {'a': true}); + expect(parseDataFile('{ a: false }'), {'a': false}); + expect(parseDataFile('{ "a": 0 }'), {'a': 0}); + expect(parseDataFile('{ "a": -0, b: "x" }'), { + 'a': 0, + 'b': 'x', + }); + expect(parseDataFile('{ "a": null }'), {}); + expect(parseDataFile('{ "a": -6 }'), {'a': -6}); + expect(parseDataFile('{ "a": -7 }'), {'a': -7}); + expect(parseDataFile('{ "a": -8 }'), {'a': -8}); + expect(parseDataFile('{ "a": -9 }'), {'a': -9}); + expect(parseDataFile('{ "a": 01 }'), {'a': 1}); + expect(parseDataFile('{ "a": 0e0 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": 0e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": 0e8 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": 1e9 }'), {'a': 1000000000.0}); + expect(parseDataFile('{ "a": -0e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": 00e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": -00e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": 00.0e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": -00.0e1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": -00.0e-1 }'), {'a': 0.0}); + expect(parseDataFile('{ "a": -1e-1 }'), {'a': -0.1}); + expect(parseDataFile('{ "a": -1e-2 }'), {'a': -0.01}); + expect(parseDataFile('{ "a": -1e-3 }'), {'a': -0.001}); + expect(parseDataFile('{ "a": -1e-4 }'), {'a': -0.0001}); + expect(parseDataFile('{ "a": -1e-5 }'), {'a': -0.00001}); + expect(parseDataFile('{ "a": -1e-6 }'), {'a': -0.000001}); + expect(parseDataFile('{ "a": -1e-7 }'), {'a': -0.0000001}); + expect(parseDataFile('{ "a": -1e-8 }'), { + 'a': -0.00000001, + }); + expect(parseDataFile('{ "a": -1e-9 }'), { + 'a': -0.000000001, + }); + expect(parseDataFile('{ "a": -1e-10 }'), { + 'a': -0.0000000001, + }); + expect(parseDataFile('{ "a": -1e-11 }'), { + 'a': -0.00000000001, + }); + expect(parseDataFile('{ "a": -1e-12 }'), { + 'a': -0.000000000001, + }); + expect(parseDataFile('{ "a": -1e-13 }'), { + 'a': -0.0000000000001, + }); + expect(parseDataFile('{ "a": -1e-14 }'), { + 'a': -0.00000000000001, + }); + expect(parseDataFile('{ "a": -1e-15 }'), { + 'a': -0.000000000000001, + }); + expect(parseDataFile('{ "a": -1e-16 }'), { + 'a': -0.0000000000000001, + }); + expect(parseDataFile('{ "a": -1e-17 }'), { + 'a': -0.00000000000000001, + }); + expect(parseDataFile('{ "a": -1e-18 }'), { + 'a': -0.000000000000000001, + }); + expect(parseDataFile('{ "a": -1e-19 }'), { + 'a': -0.0000000000000000001, + }); + expect(parseDataFile('{ "a": 0x0 }'), {'a': 0}); + expect(parseDataFile('{ "a": 0x1 }'), {'a': 1}); + expect(parseDataFile('{ "a": 0x01 }'), {'a': 1}); + expect(parseDataFile('{ "a": 0xa }'), {'a': 10}); + expect(parseDataFile('{ "a": 0xb }'), {'a': 11}); + expect(parseDataFile('{ "a": 0xc }'), {'a': 12}); + expect(parseDataFile('{ "a": 0xd }'), {'a': 13}); + expect(parseDataFile('{ "a": 0xe }'), {'a': 14}); + expect(parseDataFile('{ "a": 0xfa }'), {'a': 250}); + expect(parseDataFile('{ "a": 0xfb }'), {'a': 251}); + expect(parseDataFile('{ "a": 0xfc }'), {'a': 252}); + expect(parseDataFile('{ "a": 0xfd }'), {'a': 253}); + expect(parseDataFile('{ "a": 0xfe }'), {'a': 254}); + expect( + parseDataFile('{ "a": "\\"\\/\\\'\\b\\f\\n\\r\\t\\\\" }'), + {'a': '\x22\x2F\x27\x08\x0C\x0A\x0D\x09\x5C'}, + ); + expect( + parseDataFile('{ "a": \'\\"\\/\\\'\\b\\f\\n\\r\\t\\\\\' }'), + {'a': '\x22\x2F\x27\x08\x0C\x0A\x0D\x09\x5C'}, + ); + expect(parseDataFile('{ "a": \'\\u263A\' }'), {'a': '☺'}); + expect(parseDataFile('{ "a": \'\\u0000\' }'), { + 'a': '\x00', + }); + expect(parseDataFile('{ "a": \'\\u1111\' }'), {'a': 'ᄑ'}); + expect(parseDataFile('{ "a": \'\\u2222\' }'), {'a': '∢'}); + expect(parseDataFile('{ "a": \'\\u3333\' }'), {'a': '㌳'}); + expect(parseDataFile('{ "a": \'\\u4444\' }'), {'a': '䑄'}); + expect(parseDataFile('{ "a": \'\\u5555\' }'), {'a': '啕'}); + expect(parseDataFile('{ "a": \'\\u6666\' }'), {'a': '晦'}); + expect(parseDataFile('{ "a": \'\\u7777\' }'), {'a': '睷'}); + expect(parseDataFile('{ "a": \'\\u8888\' }'), {'a': '袈'}); + expect(parseDataFile('{ "a": \'\\u9999\' }'), {'a': '香'}); + expect(parseDataFile('{ "a": \'\\uaaaa\' }'), {'a': 'ꪪ'}); + expect(parseDataFile('{ "a": \'\\ubbbb\' }'), {'a': '뮻'}); + expect(parseDataFile('{ "a": \'\\ucccc\' }'), {'a': '쳌'}); + expect(parseDataFile('{ "a": \'\\udddd\' }'), { + 'a': '\u{dddd}', + }); // low surragate + expect(parseDataFile('{ "a": \'\\ueeee\' }'), { + 'a': '\u{eeee}', + }); // private use area + expect(parseDataFile('{ "a": \'\\uffff\' }'), { + 'a': '\u{ffff}', + }); // not technically a valid Unicode character + expect(parseDataFile('{ "a": \'\\uAAAA\' }'), {'a': 'ꪪ'}); + expect(parseDataFile('{ "a": \'\\uBBBB\' }'), {'a': '뮻'}); + expect(parseDataFile('{ "a": \'\\uCCCC\' }'), {'a': '쳌'}); + expect(parseDataFile('{ "a": \'\\uDDDD\' }'), { + 'a': '\u{dddd}', + }); + expect(parseDataFile('{ "a": \'\\uEEEE\' }'), { + 'a': '\u{eeee}', + }); + expect(parseDataFile('{ "a": \'\\uFFFF\' }'), { + 'a': '\u{ffff}', + }); + expect(parseDataFile('{ "a": /**/ "1" }'), {'a': '1'}); + expect(parseDataFile('{ "a": /* */ "1" }'), {'a': '1'}); + expect(parseDataFile('{ "a": /*\n*/ "1" }'), {'a': '1'}); }); - testWidgets('error handling in parseLibraryFile', (WidgetTester tester) async { + testWidgets('error handling in parseLibraryFile', ( + WidgetTester tester, + ) async { void test(String input, String expectedMessage) { try { parseLibraryFile(input); - fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + fail( + 'parsing `$input` did not result in an error (expected "$expectedMessage").', + ); } on ParserException catch (e) { expect('$e', expectedMessage); } } - test('2', 'Expected keywords "import" or "widget", or end of file but found 2 at line 1 column 1.'); - test('impor', 'Expected keywords "import" or "widget", or end of file but found impor at line 1 column 5.'); + + test( + '2', + 'Expected keywords "import" or "widget", or end of file but found 2 at line 1 column 1.', + ); + test( + 'impor', + 'Expected keywords "import" or "widget", or end of file but found impor at line 1 column 5.', + ); test('import', 'Expected string but found at line 1 column 6.'); test('import 2', 'Expected string but found 2 at line 1 column 8.'); - test('import foo', 'Expected symbol ";" but found at line 1 column 10.'); + test( + 'import foo', + 'Expected symbol ";" but found at line 1 column 10.', + ); test('import foo.', 'Expected string but found at line 1 column 11.'); test('import foo,', 'Expected symbol ";" but found , at line 1 column 11.'); - test('import foo+', 'Unexpected character U+002B ("+") inside identifier at line 1 column 11.'); + test( + 'import foo+', + 'Unexpected character U+002B ("+") inside identifier at line 1 column 11.', + ); test('import foo.1', 'Expected string but found 1 at line 1 column 12.'); - test('import foo.+', 'Unexpected character U+002B ("+") after period at line 1 column 12.'); - test('import foo."', 'Unexpected end of file inside string at line 1 column 12.'); - test('import foo. "', 'Unexpected end of file inside string at line 1 column 13.'); - test('import foo.\'', 'Unexpected end of file inside string at line 1 column 12.'); - test('import foo. \'', 'Unexpected end of file inside string at line 1 column 13.'); - test('widget a = b(c: [ ...for args in []: "e" ]);', 'args is a reserved word at line 1 column 30.'); - test('widget a = switch 0 { 0: a(), 0: b() };', 'Switch has duplicate cases for key 0 at line 1 column 32.'); - test('widget a = switch 0 { default: a(), default: b() };', 'Switch has multiple default cases at line 1 column 44.'); - test('widget a = b(c: args)', 'Expected symbol "." but found ) at line 1 column 21.'); + test( + 'import foo.+', + 'Unexpected character U+002B ("+") after period at line 1 column 12.', + ); + test( + 'import foo."', + 'Unexpected end of file inside string at line 1 column 12.', + ); + test( + 'import foo. "', + 'Unexpected end of file inside string at line 1 column 13.', + ); + test( + 'import foo.\'', + 'Unexpected end of file inside string at line 1 column 12.', + ); + test( + 'import foo. \'', + 'Unexpected end of file inside string at line 1 column 13.', + ); + test( + 'widget a = b(c: [ ...for args in []: "e" ]);', + 'args is a reserved word at line 1 column 30.', + ); + test( + 'widget a = switch 0 { 0: a(), 0: b() };', + 'Switch has duplicate cases for key 0 at line 1 column 32.', + ); + test( + 'widget a = switch 0 { default: a(), default: b() };', + 'Switch has multiple default cases at line 1 column 44.', + ); + test( + 'widget a = b(c: args)', + 'Expected symbol "." but found ) at line 1 column 21.', + ); test('widget a = b(c: args.=)', 'Unexpected = at line 1 column 22.'); - test('widget a = b(c: args.0', 'Expected symbol ")" but found at line 1 column 22.'); - test('widget a = b(c: args.0 ', 'Expected symbol ")" but found at line 1 column 23.'); - test('widget a = b(c: args.0)', 'Expected symbol ";" but found at line 1 column 23.'); - test('widget a = b(c: args.0f', 'Unexpected character U+0066 ("f") in integer at line 1 column 23.'); - test('widget a = b(c: [ ..', 'Unexpected end of file inside "..." symbol at line 1 column 20.'); - test('widget a = b(c: [ .. ]);', 'Unexpected character U+0020 inside "..." symbol at line 1 column 21.'); - test('widget a = b(c: [ ... ]);', 'Expected identifier but found ] at line 1 column 23.'); - test('widget a = b(c: [ ...baa ]);', 'Expected for but found baa at line 1 column 25.'); - test('widget a = 0;', 'Expected identifier but found 0 at line 1 column 13.'); - test('widget a = a.', 'Expected symbol "(" but found . at line 1 column 13.'); - test('widget a = a. ', 'Expected symbol "(" but found . at line 1 column 14.'); - test('widget a = a.0', 'Expected symbol "(" but found . at line 1 column 14.'); - test('widget a = a.0 ', 'Expected symbol "(" but found . at line 1 column 14.'); + test( + 'widget a = b(c: args.0', + 'Expected symbol ")" but found at line 1 column 22.', + ); + test( + 'widget a = b(c: args.0 ', + 'Expected symbol ")" but found at line 1 column 23.', + ); + test( + 'widget a = b(c: args.0)', + 'Expected symbol ";" but found at line 1 column 23.', + ); + test( + 'widget a = b(c: args.0f', + 'Unexpected character U+0066 ("f") in integer at line 1 column 23.', + ); + test( + 'widget a = b(c: [ ..', + 'Unexpected end of file inside "..." symbol at line 1 column 20.', + ); + test( + 'widget a = b(c: [ .. ]);', + 'Unexpected character U+0020 inside "..." symbol at line 1 column 21.', + ); + test( + 'widget a = b(c: [ ... ]);', + 'Expected identifier but found ] at line 1 column 23.', + ); + test( + 'widget a = b(c: [ ...baa ]);', + 'Expected for but found baa at line 1 column 25.', + ); + test( + 'widget a = 0;', + 'Expected identifier but found 0 at line 1 column 13.', + ); + test( + 'widget a = a.', + 'Expected symbol "(" but found . at line 1 column 13.', + ); + test( + 'widget a = a. ', + 'Expected symbol "(" but found . at line 1 column 14.', + ); + test( + 'widget a = a.0', + 'Expected symbol "(" but found . at line 1 column 14.', + ); + test( + 'widget a = a.0 ', + 'Expected symbol "(" but found . at line 1 column 14.', + ); }); testWidgets('parseLibraryFile: imports', (WidgetTester tester) async { @@ -288,74 +652,196 @@ void main() { }); testWidgets('parseLibraryFile: loops', (WidgetTester tester) async { - final RemoteWidgetLibrary result = parseLibraryFile('widget a = b(c: [ ...for d in []: "e" ]);'); + final RemoteWidgetLibrary result = parseLibraryFile( + 'widget a = b(c: [ ...for d in []: "e" ]);', + ); expect(result.imports, isEmpty); expect(result.widgets, hasLength(1)); - expect(result.widgets.single.toString(), 'widget a = b({c: [...for loop in []: e]});'); + expect( + result.widgets.single.toString(), + 'widget a = b({c: [...for loop in []: e]});', + ); }); testWidgets('parseLibraryFile: switch', (WidgetTester tester) async { - expect(parseLibraryFile('widget a = switch 0 { 0: a() };').toString(), 'widget a = switch 0 {0: a({})};'); - expect(parseLibraryFile('widget a = switch 0 { default: a() };').toString(), 'widget a = switch 0 {null: a({})};'); - expect(parseLibraryFile('widget a = b(c: switch 1 { 2: 3 });').toString(), 'widget a = b({c: switch 1 {2: 3}});'); + expect( + parseLibraryFile('widget a = switch 0 { 0: a() };').toString(), + 'widget a = switch 0 {0: a({})};', + ); + expect( + parseLibraryFile('widget a = switch 0 { default: a() };').toString(), + 'widget a = switch 0 {null: a({})};', + ); + expect( + parseLibraryFile('widget a = b(c: switch 1 { 2: 3 });').toString(), + 'widget a = b({c: switch 1 {2: 3}});', + ); }); testWidgets('parseLibraryFile: references', (WidgetTester tester) async { - expect(parseLibraryFile('widget a = b(c:data.11234567890."e");').toString(), 'widget a = b({c: data.11234567890.e});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d]);').toString(), 'widget a = b({c: [...for loop in []: loop0.]});'); - expect(parseLibraryFile('widget a = b(c:args.foo.bar);').toString(), 'widget a = b({c: args.foo.bar});'); - expect(parseLibraryFile('widget a = b(c:data.foo.bar);').toString(), 'widget a = b({c: data.foo.bar});'); - expect(parseLibraryFile('widget a = b(c:state.foo.bar);').toString(), 'widget a = b({c: state.foo.bar});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d.bar]);').toString(), 'widget a = b({c: [...for loop in []: loop0.bar]});'); - expect(parseLibraryFile('widget a = b(c:args.foo."bar");').toString(), 'widget a = b({c: args.foo.bar});'); - expect(parseLibraryFile('widget a = b(c:data.foo."bar");').toString(), 'widget a = b({c: data.foo.bar});'); - expect(parseLibraryFile('widget a = b(c:state.foo."bar");').toString(), 'widget a = b({c: state.foo.bar});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d."bar"]);').toString(), 'widget a = b({c: [...for loop in []: loop0.bar]});'); - expect(parseLibraryFile('widget a = b(c:args.foo.9);').toString(), 'widget a = b({c: args.foo.9});'); - expect(parseLibraryFile('widget a = b(c:data.foo.9);').toString(), 'widget a = b({c: data.foo.9});'); - expect(parseLibraryFile('widget a = b(c:state.foo.9);').toString(), 'widget a = b({c: state.foo.9});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d.9]);').toString(), 'widget a = b({c: [...for loop in []: loop0.9]});'); - expect(parseLibraryFile('widget a = b(c:args.foo.12);').toString(), 'widget a = b({c: args.foo.12});'); - expect(parseLibraryFile('widget a = b(c:data.foo.12);').toString(), 'widget a = b({c: data.foo.12});'); - expect(parseLibraryFile('widget a = b(c:state.foo.12);').toString(), 'widget a = b({c: state.foo.12});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d.12]);').toString(), 'widget a = b({c: [...for loop in []: loop0.12]});'); - expect(parseLibraryFile('widget a = b(c:args.foo.98);').toString(), 'widget a = b({c: args.foo.98});'); - expect(parseLibraryFile('widget a = b(c:data.foo.98);').toString(), 'widget a = b({c: data.foo.98});'); - expect(parseLibraryFile('widget a = b(c:state.foo.98);').toString(), 'widget a = b({c: state.foo.98});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d.98]);').toString(), 'widget a = b({c: [...for loop in []: loop0.98]});'); - expect(parseLibraryFile('widget a = b(c:args.foo.000);').toString(), 'widget a = b({c: args.foo.0});'); - expect(parseLibraryFile('widget a = b(c:data.foo.000);').toString(), 'widget a = b({c: data.foo.0});'); - expect(parseLibraryFile('widget a = b(c:state.foo.000);').toString(), 'widget a = b({c: state.foo.0});'); - expect(parseLibraryFile('widget a = b(c: [...for d in []: d.000]);').toString(), 'widget a = b({c: [...for loop in []: loop0.0]});'); + expect( + parseLibraryFile('widget a = b(c:data.11234567890."e");').toString(), + 'widget a = b({c: data.11234567890.e});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo.bar);').toString(), + 'widget a = b({c: args.foo.bar});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo.bar);').toString(), + 'widget a = b({c: data.foo.bar});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo.bar);').toString(), + 'widget a = b({c: state.foo.bar});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d.bar]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.bar]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo."bar");').toString(), + 'widget a = b({c: args.foo.bar});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo."bar");').toString(), + 'widget a = b({c: data.foo.bar});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo."bar");').toString(), + 'widget a = b({c: state.foo.bar});', + ); + expect( + parseLibraryFile( + 'widget a = b(c: [...for d in []: d."bar"]);', + ).toString(), + 'widget a = b({c: [...for loop in []: loop0.bar]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo.9);').toString(), + 'widget a = b({c: args.foo.9});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo.9);').toString(), + 'widget a = b({c: data.foo.9});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo.9);').toString(), + 'widget a = b({c: state.foo.9});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d.9]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.9]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo.12);').toString(), + 'widget a = b({c: args.foo.12});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo.12);').toString(), + 'widget a = b({c: data.foo.12});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo.12);').toString(), + 'widget a = b({c: state.foo.12});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d.12]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.12]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo.98);').toString(), + 'widget a = b({c: args.foo.98});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo.98);').toString(), + 'widget a = b({c: data.foo.98});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo.98);').toString(), + 'widget a = b({c: state.foo.98});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d.98]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.98]});', + ); + expect( + parseLibraryFile('widget a = b(c:args.foo.000);').toString(), + 'widget a = b({c: args.foo.0});', + ); + expect( + parseLibraryFile('widget a = b(c:data.foo.000);').toString(), + 'widget a = b({c: data.foo.0});', + ); + expect( + parseLibraryFile('widget a = b(c:state.foo.000);').toString(), + 'widget a = b({c: state.foo.0});', + ); + expect( + parseLibraryFile('widget a = b(c: [...for d in []: d.000]);').toString(), + 'widget a = b({c: [...for loop in []: loop0.0]});', + ); }); testWidgets('parseLibraryFile: event handlers', (WidgetTester tester) async { - expect(parseLibraryFile('widget a = b(c: event "d" { });').toString(), 'widget a = b({c: event d {}});'); - expect(parseLibraryFile('widget a = b(c: set state.d = 0);').toString(), 'widget a = b({c: set state.d = 0});'); + expect( + parseLibraryFile('widget a = b(c: event "d" { });').toString(), + 'widget a = b({c: event d {}});', + ); + expect( + parseLibraryFile('widget a = b(c: set state.d = 0);').toString(), + 'widget a = b({c: set state.d = 0});', + ); }); - testWidgets('parseLibraryFile: stateful widgets', (WidgetTester tester) async { - expect(parseLibraryFile('widget a {} = c();').toString(), 'widget a = c({});'); - expect(parseLibraryFile('widget a {b: 0} = c();').toString(), 'widget a = c({});'); - final RemoteWidgetLibrary result = parseLibraryFile('widget a {b: 0} = c();'); + testWidgets('parseLibraryFile: stateful widgets', ( + WidgetTester tester, + ) async { + expect( + parseLibraryFile('widget a {} = c();').toString(), + 'widget a = c({});', + ); + expect( + parseLibraryFile('widget a {b: 0} = c();').toString(), + 'widget a = c({});', + ); + final RemoteWidgetLibrary result = parseLibraryFile( + 'widget a {b: 0} = c();', + ); expect(result.widgets.single.initialState, {'b': 0}); }); - testWidgets('parseLibraryFile: widgetBuilders 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({})});'); + expect( + libraryFile.toString(), + 'widget a = Builder({builder: (scope) => Container({})});', + ); }); - testWidgets('parseLibraryFile: widgetBuilders 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})});'); + expect( + libraryFile.toString(), + 'widget a = Builder({builder: (scope) => Container({width: scope.width})});', + ); }); - testWidgets('parseLibraryFile: widgetBuilder 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( @@ -363,10 +849,15 @@ void main() { ), ); '''); - expect(libraryFile.toString(), '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: widgetBuilder 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( @@ -374,55 +865,78 @@ void main() { ), ); '''); - expect(libraryFile.toString(), '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: widgetBuilders check the returned value', (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").'); + fail( + 'parsing `$input` did not result in an error (expected "$expectedMessage").', + ); } on ParserException catch (e) { expect('$e', expectedMessage); } } const String expectedErrorMessage = - 'Expecting a switch or constructor call got 1 at line 1 column 27.'; + '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 { + 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").'); + fail( + 'parsing `$input` did not result in an error (expected "$expectedMessage").', + ); } on ParserException catch (e) { expect('$e', expectedMessage); } } const String expectedErrorMessage = - 'args is a reserved word at line 1 column 34.'; - test('widget a = Builder(builder: (args) => Container(width: args.width));', 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) { + testWidgets('parseLibraryFile: widgetBuilders check reserved words', ( + WidgetTester tester, + ) async { + void test(String input, String expectedMessage) { try { parseDataFile(input); - fail('parsing `$input` did not result in an error (expected "$expectedMessage").'); + fail( + 'parsing `$input` did not result in an error (expected "$expectedMessage").', + ); } on ParserException catch (e) { expect('$e', expectedMessage); } } - const String expectedErrorMessage = - 'Expected symbol "{" but found widget at line 1 column 7.'; - test('widget a = Builder(builder: (args) => Container(width: args.width));', expectedErrorMessage); + const String 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 widgetBuilders', (WidgetTester tester) async { + testWidgets('parseLibraryFile: switch works with widgetBuilders', ( + WidgetTester tester, + ) async { final RemoteWidgetLibrary libraryFile = parseLibraryFile(''' widget a = A( b: switch args.down { @@ -431,10 +945,15 @@ void main() { } ); '''); - expect(libraryFile.toString(), '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: widgetBuilders work 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 { @@ -443,42 +962,65 @@ void main() { }, ); '''); - expect(libraryFile.toString(), '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: widgetBuilders work 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]), ); '''); - expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: [s1.c]})});' ); + expect( + libraryFile.toString(), + 'widget a = A({b: (s1) => B({c: [s1.c]})});', + ); }); - testWidgets('parseLibraryFile: widgetBuilders work 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}), ); '''); - expect(libraryFile.toString(), 'widget a = A({b: (s1) => B({c: {d: s1.d}})});'); + expect( + libraryFile.toString(), + 'widget a = A({b: (s1) => B({c: {d: s1.d}})});', + ); }); - testWidgets('parseLibraryFile: widgetBuilders work 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), ); '''); - expect(libraryFile.toString(), 'widget a = 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})});', + ); }); - testWidgets('parseLibraryFile: widgetBuilders work with events', (WidgetTester tester) async { + 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}})});'); + expect( + libraryFile.toString(), + 'widget a = A({b: (s1) => B({onTap: event foo {result: s1.result}})});', + ); }); } diff --git a/packages/rfw/test_coverage/bin/test_coverage.dart b/packages/rfw/test_coverage/bin/test_coverage.dart index d76bb52e84a..15bb2ee8613 100644 --- a/packages/rfw/test_coverage/bin/test_coverage.dart +++ b/packages/rfw/test_coverage/bin/test_coverage.dart @@ -80,12 +80,11 @@ Future main(List arguments) async { exit(0); } - final List libFiles = - Directory('lib') - .listSync(recursive: true) - .whereType() - .where((File file) => file.path.endsWith('.dart')) - .toList(); + final List libFiles = Directory('lib') + .listSync(recursive: true) + .whereType() + .where((File file) => file.path.endsWith('.dart')) + .toList(); final Set flakyLines = {}; final Set deadLines = {}; for (final File file in libFiles) { diff --git a/packages/rfw/test_coverage/pubspec.yaml b/packages/rfw/test_coverage/pubspec.yaml index 0e18f5a2842..faa9670bdc4 100644 --- a/packages/rfw/test_coverage/pubspec.yaml +++ b/packages/rfw/test_coverage/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.7.0 + sdk: ^3.9.0 dependencies: lcov_parser: 0.1.1 diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 75ba4d952bf..c82c1797b0b 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,6 +1,6 @@ -## NEXT +## 2.6.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. * Updates README to indicate that Andoid SDK <21 is no longer supported. ## 2.5.3 diff --git a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle index 10799d14f0e..2e7513c07d3 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle @@ -31,7 +31,7 @@ android { } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } defaultConfig { diff --git a/packages/shared_preferences/shared_preferences/example/lib/main.dart b/packages/shared_preferences/shared_preferences/example/lib/main.dart index 8d55b9f6645..a51bb141762 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/main.dart @@ -103,27 +103,26 @@ class SharedPreferencesDemoState extends State { body: Center( child: _WaitForInitialization( initialized: _preferencesReady.future, - builder: - (BuildContext context) => FutureBuilder( - future: _counter, - builder: (BuildContext context, AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.none: - case ConnectionState.waiting: - return const CircularProgressIndicator(); - case ConnectionState.active: - case ConnectionState.done: - if (snapshot.hasError) { - return Text('Error: ${snapshot.error}'); - } else { - return Text( - 'Button tapped ${snapshot.data ?? 0 + _externalCounter} time${(snapshot.data ?? 0 + _externalCounter) == 1 ? '' : 's'}.\n\n' - 'This should persist across restarts.', - ); - } + builder: (BuildContext context) => FutureBuilder( + future: _counter, + builder: (BuildContext context, AsyncSnapshot snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.none: + case ConnectionState.waiting: + return const CircularProgressIndicator(); + case ConnectionState.active: + case ConnectionState.done: + if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else { + return Text( + 'Button tapped ${snapshot.data ?? 0 + _externalCounter} time${(snapshot.data ?? 0 + _externalCounter) == 1 ? '' : 's'}.\n\n' + 'This should persist across restarts.', + ); } - }, - ), + } + }, + ), ), ), floatingActionButton: FloatingActionButton( diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index 0b8cb9f43ec..02b603a79ed 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart index 8768b9414f9..e7730a5b04e 100644 --- a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart @@ -281,8 +281,8 @@ Either update the implementation to support setPrefix, or do not call setPrefix. } return MapEntry(newKey, value); }); - SharedPreferencesStorePlatform - .instance = InMemorySharedPreferencesStore.withData(newValues); + SharedPreferencesStorePlatform.instance = + InMemorySharedPreferencesStore.withData(newValues); _completer = null; } } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 37a74d0fc1f..72e80410eb1 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.5.3 +version: 2.6.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/shared_preferences/shared_preferences/tool/pre_publish.dart b/packages/shared_preferences/shared_preferences/tool/pre_publish.dart index 085aabaf646..fb6ee3d81bf 100644 --- a/packages/shared_preferences/shared_preferences/tool/pre_publish.dart +++ b/packages/shared_preferences/shared_preferences/tool/pre_publish.dart @@ -13,8 +13,9 @@ Future _runCommand({ }) async { stdout.write(message); // The `packages/shared_preferences` directory. - final Directory sharedPreferencesToolParent = - Directory(p.dirname(Platform.script.path)).parent.parent; + final Directory sharedPreferencesToolParent = Directory( + p.dirname(Platform.script.path), + ).parent.parent; final ProcessResult pubGetResult = await Process.run( executable, diff --git a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md index 8f6c3b0407a..66e2d92c368 100644 --- a/packages/shared_preferences/shared_preferences_android/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.5.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.4.14 * Updates Java compatibility version to 17. diff --git a/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle b/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle index c8751755c8d..806bea4e4e6 100644 --- a/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle +++ b/packages/shared_preferences/shared_preferences_android/example/android/app/build.gradle @@ -46,7 +46,7 @@ android { } kotlinOptions { - jvmTarget = '17' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart index 77a27f8443f..f264f955742 100644 --- a/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart @@ -180,8 +180,8 @@ void main() { ), ]); final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix('prefix.'); + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); expect(values['prefix.String'], allTestValues['prefix.String']); expect(values['prefix.Bool'], allTestValues['prefix.Bool']); expect(values['prefix.Int'], allTestValues['prefix.Int']); @@ -246,8 +246,8 @@ void main() { // ignore: deprecated_member_use await preferences.clearWithPrefix('prefix.'); Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix('prefix.'); + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); expect(values['prefix.String'], null); expect(values['prefix.Bool'], null); expect(values['prefix.Int'], null); @@ -303,8 +303,8 @@ void main() { ), ]); final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix(''); + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); expect(values['String'], allTestValues['String']); expect(values['Bool'], allTestValues['Bool']); expect(values['Int'], allTestValues['Int']); @@ -360,8 +360,8 @@ void main() { // ignore: deprecated_member_use await preferences.clearWithPrefix(''); final Map values = - // ignore: deprecated_member_use - await preferences.getAllWithPrefix(''); + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); expect(values['String'], null); expect(values['Bool'], null); expect(values['Int'], null); @@ -694,14 +694,12 @@ void main() { String? fileName, }) { return SharedPreferencesAsyncAndroidOptions( - backend: - useDataStore - ? SharedPreferencesAndroidBackendLibrary.DataStore - : SharedPreferencesAndroidBackendLibrary.SharedPreferences, - originalSharedPreferencesOptions: - fileName == null - ? null - : AndroidSharedPreferencesStoreOptions(fileName: fileName), + backend: useDataStore + ? SharedPreferencesAndroidBackendLibrary.DataStore + : SharedPreferencesAndroidBackendLibrary.SharedPreferences, + originalSharedPreferencesOptions: fileName == null + ? null + : AndroidSharedPreferencesStoreOptions(fileName: fileName), ); } diff --git a/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml index 6db55ee8b12..e00a3478f45 100644 --- a/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the shared_preferences plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/shared_preferences/shared_preferences_android/pubspec.yaml b/packages/shared_preferences/shared_preferences_android/pubspec.yaml index f5593b60440..62f63ff629e 100644 --- a/packages/shared_preferences/shared_preferences_android/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_android/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences_android description: Android implementation of the shared_preferences plugin repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.4.14 +version: 2.5.0 environment: sdk: ^3.9.0 diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md index 21bce2fa2b5..07129fa01db 100644 --- a/packages/two_dimensional_scrollables/CHANGELOG.md +++ b/packages/two_dimensional_scrollables/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 0.3.8 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. ## 0.3.7 diff --git a/packages/two_dimensional_scrollables/example/android/app/build.gradle b/packages/two_dimensional_scrollables/example/android/app/build.gradle index b9ae6439d32..05fa4b14776 100644 --- a/packages/two_dimensional_scrollables/example/android/app/build.gradle +++ b/packages/two_dimensional_scrollables/example/android/app/build.gradle @@ -28,12 +28,12 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/packages/two_dimensional_scrollables/example/lib/table_view/merged_table.dart b/packages/two_dimensional_scrollables/example/lib/table_view/merged_table.dart index dc694c05c69..4c25dcb8d3a 100644 --- a/packages/two_dimensional_scrollables/example/lib/table_view/merged_table.dart +++ b/packages/two_dimensional_scrollables/example/lib/table_view/merged_table.dart @@ -101,8 +101,8 @@ class _MergedTableExampleState extends State { final ({String name, Color color}) cell = _getColorForVicinity(vicinity); final Color textColor = ThemeData.estimateBrightnessForColor(cell.color) == Brightness.light - ? Colors.black - : Colors.white; + ? Colors.black + : Colors.white; final TextStyle style = TextStyle( color: textColor, fontSize: 18.0, @@ -121,14 +121,13 @@ class _MergedTableExampleState extends State { TableSpan _buildColumnSpan(int index) { return TableSpan( extent: FixedTableSpanExtent(index == 0 ? 220 : 180), - foregroundDecoration: - index == 0 - ? const TableSpanDecoration( - border: TableSpanBorder( - trailing: BorderSide(width: 5, color: Colors.white), - ), - ) - : null, + foregroundDecoration: index == 0 + ? const TableSpanDecoration( + border: TableSpanBorder( + trailing: BorderSide(width: 5, color: Colors.white), + ), + ) + : null, ); } diff --git a/packages/two_dimensional_scrollables/example/lib/table_view/simple_table.dart b/packages/two_dimensional_scrollables/example/lib/table_view/simple_table.dart index 1acf02c0d73..0ea73b423ad 100644 --- a/packages/two_dimensional_scrollables/example/lib/table_view/simple_table.dart +++ b/packages/two_dimensional_scrollables/example/lib/table_view/simple_table.dart @@ -37,21 +37,9 @@ class _TableExampleState extends State { return Scaffold( body: Padding( padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: - _selectionMode == _TableSelection.multiCell - ? SelectionArea( - child: TableView.builder( - verticalDetails: ScrollableDetails.vertical( - controller: _verticalController, - ), - cellBuilder: _buildCell, - columnCount: 20, - columnBuilder: _buildColumnSpan, - rowCount: _rowCount, - rowBuilder: _buildRowSpan, - ), - ) - : TableView.builder( + child: _selectionMode == _TableSelection.multiCell + ? SelectionArea( + child: TableView.builder( verticalDetails: ScrollableDetails.vertical( controller: _verticalController, ), @@ -61,6 +49,17 @@ class _TableExampleState extends State { rowCount: _rowCount, rowBuilder: _buildRowSpan, ), + ) + : TableView.builder( + verticalDetails: ScrollableDetails.vertical( + controller: _verticalController, + ), + cellBuilder: _buildCell, + columnCount: 20, + columnBuilder: _buildColumnSpan, + rowCount: _rowCount, + rowBuilder: _buildRowSpan, + ), ), persistentFooterButtons: [ OverflowBar( diff --git a/packages/two_dimensional_scrollables/example/lib/tree_view/custom_tree.dart b/packages/two_dimensional_scrollables/example/lib/tree_view/custom_tree.dart index e477f603a9d..bb3cebbbf0d 100644 --- a/packages/two_dimensional_scrollables/example/lib/tree_view/custom_tree.dart +++ b/packages/two_dimensional_scrollables/example/lib/tree_view/custom_tree.dart @@ -120,10 +120,9 @@ class CustomTreeExampleState extends State { SizedBox(width: 10.0 * node.depth! + 8.0), DecoratedBox( decoration: BoxDecoration( - border: - node.parent != null - ? Border(left: border, bottom: border) - : null, + border: node.parent != null + ? Border(left: border, bottom: border) + : null, ), child: const SizedBox(height: 50.0, width: 20.0), ), @@ -148,12 +147,10 @@ class CustomTreeExampleState extends State { TreeViewNode node, ) { return { - TapGestureRecognizer: GestureRecognizerFactoryWithHandlers< - TapGestureRecognizer - >( - () => TapGestureRecognizer(), - (TapGestureRecognizer t) => - t.onTap = () { + TapGestureRecognizer: + GestureRecognizerFactoryWithHandlers( + () => TapGestureRecognizer(), + (TapGestureRecognizer t) => t.onTap = () { setState(() { // Toggling the node here instead means any tap on the row can // toggle parent nodes opened and closed. @@ -161,7 +158,7 @@ class CustomTreeExampleState extends State { _selectedNode = node; }); }, - ), + ), }; } diff --git a/packages/two_dimensional_scrollables/example/lib/tree_view/simple_tree.dart b/packages/two_dimensional_scrollables/example/lib/tree_view/simple_tree.dart index d56f9b88eb7..cdcbf15a6aa 100644 --- a/packages/two_dimensional_scrollables/example/lib/tree_view/simple_tree.dart +++ b/packages/two_dimensional_scrollables/example/lib/tree_view/simple_tree.dart @@ -71,12 +71,11 @@ class TreeExampleState extends State { TapGestureRecognizer: GestureRecognizerFactoryWithHandlers( () => TapGestureRecognizer(), - (TapGestureRecognizer t) => - t.onTap = () { - setState(() { - _selectedNode = node; - }); - }, + (TapGestureRecognizer t) => t.onTap = () { + setState(() { + _selectedNode = node; + }); + }, ), }; } diff --git a/packages/two_dimensional_scrollables/example/pubspec.yaml b/packages/two_dimensional_scrollables/example/pubspec.yaml index 5801de5d0b3..dc9626494bf 100644 --- a/packages/two_dimensional_scrollables/example/pubspec.yaml +++ b/packages/two_dimensional_scrollables/example/pubspec.yaml @@ -6,8 +6,8 @@ publish_to: 'none' version: 2.0.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/two_dimensional_scrollables/lib/src/common/span.dart b/packages/two_dimensional_scrollables/lib/src/common/span.dart index 395727235b0..6a072091d2f 100644 --- a/packages/two_dimensional_scrollables/lib/src/common/span.dart +++ b/packages/two_dimensional_scrollables/lib/src/common/span.dart @@ -383,10 +383,9 @@ class SpanDecoration { /// cells. void paint(SpanDecorationPaintDetails details) { if (color != null) { - final Paint paint = - Paint() - ..color = color! - ..isAntiAlias = borderRadius != null; + final Paint paint = Paint() + ..color = color! + ..isAntiAlias = borderRadius != null; if (borderRadius == null || borderRadius == BorderRadius.zero) { details.canvas.drawRect(details.rect, paint); } else { diff --git a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart index 43b5725fa14..e8f4f4b1cb2 100644 --- a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart +++ b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart @@ -397,14 +397,12 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { int? get _lastPinnedColumn => delegate.pinnedColumnCount > 0 ? delegate.pinnedColumnCount - 1 : null; - double get _pinnedRowsExtent => - _lastPinnedRow != null - ? _rowMetrics[_lastPinnedRow]!.trailingOffset - : 0.0; - double get _pinnedColumnsExtent => - _lastPinnedColumn != null - ? _columnMetrics[_lastPinnedColumn]!.trailingOffset - : 0.0; + double get _pinnedRowsExtent => _lastPinnedRow != null + ? _rowMetrics[_lastPinnedRow]!.trailingOffset + : 0.0; + double get _pinnedColumnsExtent => _lastPinnedColumn != null + ? _columnMetrics[_lastPinnedColumn]!.trailingOffset + : 0.0; @override TableViewParentData parentDataOf(RenderBox child) => @@ -497,8 +495,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { } // If we are computing up to a specific index, we are getting info for a // merged cell, do not change the visible cells. - _firstNonPinnedColumn = - toColumnIndex == null ? null : _firstNonPinnedColumn; + _firstNonPinnedColumn = toColumnIndex == null + ? null + : _firstNonPinnedColumn; _lastNonPinnedColumn = toColumnIndex == null ? null : _lastNonPinnedColumn; int column = appendColumns ? _columnMetrics.length : 0; @@ -522,8 +521,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { while (!reachedColumnEnd()) { final bool isPinned = column < delegate.pinnedColumnCount; - final double leadingOffset = - isPinned ? startOfPinnedColumn : startOfRegularColumn; + final double leadingOffset = isPinned + ? startOfPinnedColumn + : startOfRegularColumn; _Span? span = _columnMetrics.remove(column); final TableSpan? configuration = span?.configuration ?? delegate.buildColumn(column); @@ -623,8 +623,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { while (!reachedRowEnd()) { final bool isPinned = row < delegate.pinnedRowCount; - final double leadingOffset = - isPinned ? startOfPinnedRow : startOfRegularRow; + final double leadingOffset = isPinned + ? startOfPinnedRow + : startOfRegularRow; _Span? span = _rowMetrics.remove(row); final TableSpan? configuration = span?.configuration ?? delegate.buildRow(row); @@ -842,18 +843,16 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { return; } - final double? offsetIntoColumn = - _firstNonPinnedColumn != null - ? horizontalOffset.pixels - - _columnMetrics[_firstNonPinnedColumn]!.leadingOffset - - _pinnedColumnsExtent - : null; - final double? offsetIntoRow = - _firstNonPinnedRow != null - ? verticalOffset.pixels - - _rowMetrics[_firstNonPinnedRow]!.leadingOffset - - _pinnedRowsExtent - : null; + final double? offsetIntoColumn = _firstNonPinnedColumn != null + ? horizontalOffset.pixels - + _columnMetrics[_firstNonPinnedColumn]!.leadingOffset - + _pinnedColumnsExtent + : null; + final double? offsetIntoRow = _firstNonPinnedRow != null + ? verticalOffset.pixels - + _rowMetrics[_firstNonPinnedRow]!.leadingOffset - + _pinnedRowsExtent + : null; if (_lastPinnedRow != null && _lastPinnedColumn != null) { // Layout cells that are contained in both pinned rows and columns _layoutCells( @@ -963,10 +962,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { columnOffset += colSpan.configuration.padding.leading; final TableVicinity vicinity = TableVicinity(column: column, row: row); - final RenderBox? cell = - _mergedVicinities.keys.contains(vicinity) - ? null - : buildOrObtainChildFor(vicinity); + final RenderBox? cell = _mergedVicinities.keys.contains(vicinity) + ? null + : buildOrObtainChildFor(vicinity); if (cell != null) { final TableViewParentData cellParentData = parentDataOf(cell); @@ -975,10 +973,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { if (cellParentData.rowMergeStart != null || cellParentData.columnMergeStart != null) { final int firstRow = cellParentData.rowMergeStart ?? row; - final int lastRow = - cellParentData.rowMergeStart == null - ? row - : firstRow + cellParentData.rowMergeSpan! - 1; + final int lastRow = cellParentData.rowMergeStart == null + ? row + : firstRow + cellParentData.rowMergeSpan! - 1; assert( _debugCheckMergeBounds( spanOrientation: 'Row', @@ -992,10 +989,9 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { ); final int firstColumn = cellParentData.columnMergeStart ?? column; - final int lastColumn = - cellParentData.columnMergeStart == null - ? column - : firstColumn + cellParentData.columnMergeSpan! - 1; + final int lastColumn = cellParentData.columnMergeStart == null + ? column + : firstColumn + cellParentData.columnMergeSpan! - 1; assert( _debugCheckMergeBounds( spanOrientation: 'Column', @@ -1341,14 +1337,12 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { if (_mergedColumns.isEmpty || !_mergedColumns.contains(column)) { // One decoration across the whole column. decorationCells.add(( - leading: - getChildFor( - TableVicinity(column: column, row: leadingVicinity.row), - )!, - trailing: - getChildFor( - TableVicinity(column: column, row: trailingVicinity.row), - )!, + leading: getChildFor( + TableVicinity(column: column, row: leadingVicinity.row), + )!, + trailing: getChildFor( + TableVicinity(column: column, row: trailingVicinity.row), + )!, )); } else { // Walk through the rows to separate merged cells for decorating. A @@ -1413,11 +1407,11 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { }) { final ({double leading, double trailing}) offsetCorrection = axisDirectionIsReversed(verticalAxisDirection) - ? ( - leading: leadingCell.size.height, - trailing: trailingCell.size.height, - ) - : (leading: 0.0, trailing: 0.0); + ? ( + leading: leadingCell.size.height, + trailing: trailingCell.size.height, + ) + : (leading: 0.0, trailing: 0.0); return Rect.fromPoints( parentDataOf(leadingCell).paintOffset! + offset - @@ -1482,14 +1476,12 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { if (_mergedRows.isEmpty || !_mergedRows.contains(row)) { // One decoration across the whole row. decorationCells.add(( - leading: - getChildFor( - TableVicinity(column: leadingVicinity.column, row: row), - )!, // leading - trailing: - getChildFor( - TableVicinity(column: trailingVicinity.column, row: row), - )!, // trailing + leading: getChildFor( + TableVicinity(column: leadingVicinity.column, row: row), + )!, // leading + trailing: getChildFor( + TableVicinity(column: trailingVicinity.column, row: row), + )!, // trailing )); } else { // Walk through the columns to separate merged cells for decorating. A @@ -1554,11 +1546,11 @@ class RenderTableViewport extends RenderTwoDimensionalViewport { }) { final ({double leading, double trailing}) offsetCorrection = axisDirectionIsReversed(horizontalAxisDirection) - ? ( - leading: leadingCell.size.width, - trailing: trailingCell.size.width, - ) - : (leading: 0.0, trailing: 0.0); + ? ( + leading: leadingCell.size.width, + trailing: trailingCell.size.width, + ) + : (leading: 0.0, trailing: 0.0); return Rect.fromPoints( parentDataOf(leadingCell).paintOffset! + offset - diff --git a/packages/two_dimensional_scrollables/lib/src/table_view/table_delegate.dart b/packages/two_dimensional_scrollables/lib/src/table_view/table_delegate.dart index 7c22b4956c7..152006eae3f 100644 --- a/packages/two_dimensional_scrollables/lib/src/table_view/table_delegate.dart +++ b/packages/two_dimensional_scrollables/lib/src/table_view/table_delegate.dart @@ -159,9 +159,8 @@ class TableCellBuilderDelegate extends TwoDimensionalChildBuilderDelegate _pinnedColumnCount = pinnedColumnCount, _pinnedRowCount = pinnedRowCount, super( - builder: - (BuildContext context, ChildVicinity vicinity) => - cellBuilder(context, vicinity as TableVicinity), + builder: (BuildContext context, ChildVicinity vicinity) => + cellBuilder(context, vicinity as TableVicinity), maxXIndex: columnCount == null ? columnCount : columnCount - 1, maxYIndex: rowCount == null ? rowCount : rowCount - 1, // repaintBoundaries handled by TableViewCell diff --git a/packages/two_dimensional_scrollables/lib/src/tree_view/render_tree.dart b/packages/two_dimensional_scrollables/lib/src/tree_view/render_tree.dart index ef643532d1d..94a1acbd164 100644 --- a/packages/two_dimensional_scrollables/lib/src/tree_view/render_tree.dart +++ b/packages/two_dimensional_scrollables/lib/src/tree_view/render_tree.dart @@ -210,15 +210,11 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport { while (currentIndex <= lastIndex && currentPosition < _targetRowPixel) { _Span? span = _rowMetrics.remove(currentIndex); assert(needsDelegateRebuild || span != null); - final TreeRow configuration = - needsDelegateRebuild - ? delegate.buildRow( - TreeVicinity( - depth: _rowDepths[currentIndex]!, - row: currentIndex, - ), - ) - : span!.configuration; + final TreeRow configuration = needsDelegateRebuild + ? delegate.buildRow( + TreeVicinity(depth: _rowDepths[currentIndex]!, row: currentIndex), + ) + : span!.configuration; span ??= _Span(); final double extent = configuration.extent.calculateExtent( TreeRowExtentDelegate( @@ -250,12 +246,9 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport { final double leadingOffset = startOfRow; _Span? span = _rowMetrics.remove(row); assert(needsDelegateRebuild || span != null); - final TreeRow configuration = - needsDelegateRebuild - ? delegate.buildRow( - TreeVicinity(depth: _rowDepths[row]!, row: row), - ) - : span!.configuration; + final TreeRow configuration = needsDelegateRebuild + ? delegate.buildRow(TreeVicinity(depth: _rowDepths[row]!, row: row)) + : span!.configuration; span ??= _Span(); final double extent = configuration.extent.calculateExtent( TreeRowExtentDelegate( @@ -450,8 +443,8 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport { // We are animating. // Separate animating segments to clip for any overlap. int leadingIndex = _firstRow!; - final List animationIndices = - _animationLeadingIndices.keys.toList()..sort(); + final List animationIndices = _animationLeadingIndices.keys.toList() + ..sort(); final List<_PaintSegment> paintSegments = <_PaintSegment>[]; while (animationIndices.isNotEmpty) { final int trailingIndex = animationIndices.removeAt(0); @@ -548,10 +541,9 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport { final TreeRow configuration = rowSpan.configuration; if (configuration.backgroundDecoration != null || configuration.foregroundDecoration != null) { - final RenderBox child = - getChildFor( - TreeVicinity(depth: _rowDepths[currentRow]!, row: currentRow), - )!; + final RenderBox child = getChildFor( + TreeVicinity(depth: _rowDepths[currentRow]!, row: currentRow), + )!; Rect getRowRect(bool consumePadding) { final TwoDimensionalViewportParentData parentData = parentDataOf( @@ -597,8 +589,9 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport { }); // Child nodes. for (int row = leadingRow; row <= trailingRow; row++) { - final RenderBox child = - getChildFor(TreeVicinity(depth: _rowDepths[row]!, row: row))!; + final RenderBox child = getChildFor( + TreeVicinity(depth: _rowDepths[row]!, row: row), + )!; final TwoDimensionalViewportParentData rowParentData = parentDataOf( child, ); diff --git a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart index a6d6a9cd48d..b026767d6c0 100644 --- a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart +++ b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart @@ -219,8 +219,8 @@ class TreeViewController { /// add a [Builder] widget, which provides a new scope with a /// [BuildContext] that is "under" the [TreeView]. static TreeViewController of(BuildContext context) { - final _TreeViewState? result = - context.findAncestorStateOfType<_TreeViewState>(); + final _TreeViewState? result = context + .findAncestorStateOfType<_TreeViewState>(); if (result != null) { return result.controller; } @@ -579,17 +579,16 @@ class TreeView extends StatefulWidget { node: node, child: SizedBox.square( dimension: 30.0, - child: - node.children.isNotEmpty - ? AnimatedRotation( - key: ValueKey(index), - turns: node.isExpanded ? 0.25 : 0.0, - duration: animationDuration, - curve: animationCurve, - // Renders a unicode right-facing arrow. > - child: const Icon(IconData(0x25BA), size: 14), - ) - : null, + child: node.children.isNotEmpty + ? AnimatedRotation( + key: ValueKey(index), + turns: node.isExpanded ? 0.25 : 0.0, + duration: animationDuration, + curve: animationCurve, + // Renders a unicode right-facing arrow. > + child: const Icon(IconData(0x25BA), size: 14), + ) + : null, ), ), // Spacer @@ -606,12 +605,11 @@ class TreeView extends StatefulWidget { } // Used in TreeViewState for code simplicity. -typedef _AnimationRecord = - ({ - AnimationController controller, - CurvedAnimation animation, - UniqueKey key, - }); +typedef _AnimationRecord = ({ + AnimationController controller, + CurvedAnimation animation, + UniqueKey key, +}); class _TreeViewState extends State> with TickerProviderStateMixin, TreeViewStateMixin { diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml index 2e83c725bc7..c17706a2af6 100644 --- a/packages/two_dimensional_scrollables/pubspec.yaml +++ b/packages/two_dimensional_scrollables/pubspec.yaml @@ -1,12 +1,12 @@ name: two_dimensional_scrollables description: Widgets that scroll using the two dimensional scrolling foundation. -version: 0.3.7 +version: 0.3.8 repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+ environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/two_dimensional_scrollables/test/table_view/table_delegate_test.dart b/packages/two_dimensional_scrollables/test/table_view/table_delegate_test.dart index 55f7a1cc0d2..69a0ef23004 100644 --- a/packages/two_dimensional_scrollables/test/table_view/table_delegate_test.dart +++ b/packages/two_dimensional_scrollables/test/table_view/table_delegate_test.dart @@ -384,8 +384,8 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), rowBuilder: spanBuilder, ); expect(delegate.shouldRebuild(oldDelegate), isTrue); @@ -398,8 +398,8 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), rowBuilder: spanBuilder, ); expect(delegate.shouldRebuild(oldDelegate), isTrue); @@ -412,10 +412,10 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), - rowBuilder: - (int index) => const TableSpan(extent: RemainingTableSpanExtent()), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), + rowBuilder: (int index) => + const TableSpan(extent: RemainingTableSpanExtent()), ); expect(delegate.shouldRebuild(oldDelegate), isTrue); @@ -427,10 +427,10 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), - rowBuilder: - (int index) => const TableSpan(extent: RemainingTableSpanExtent()), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), + rowBuilder: (int index) => + const TableSpan(extent: RemainingTableSpanExtent()), pinnedRowCount: 2, ); expect(delegate.shouldRebuild(oldDelegate), isTrue); @@ -443,10 +443,10 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), - rowBuilder: - (int index) => const TableSpan(extent: RemainingTableSpanExtent()), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), + rowBuilder: (int index) => + const TableSpan(extent: RemainingTableSpanExtent()), pinnedColumnCount: 2, pinnedRowCount: 2, ); @@ -463,10 +463,10 @@ void main() { [cell, cell, cell], [cell, cell, cell], ], - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(150)), - rowBuilder: - (int index) => const TableSpan(extent: RemainingTableSpanExtent()), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(150)), + rowBuilder: (int index) => + const TableSpan(extent: RemainingTableSpanExtent()), pinnedColumnCount: 2, pinnedRowCount: 2, ); diff --git a/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart b/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart index a0ad4d13c03..d0a8010bf04 100644 --- a/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart +++ b/packages/two_dimensional_scrollables/test/table_view/table_span_test.dart @@ -925,8 +925,9 @@ void main() { } return TableSpan( extent: const FixedTableSpanExtent(100.0), - backgroundDecoration: - color == null ? null : TableSpanDecoration(color: color), + backgroundDecoration: color == null + ? null + : TableSpanDecoration(color: color), ); }, ); @@ -987,8 +988,9 @@ void main() { } return TableSpan( extent: const FixedTableSpanExtent(100.0), - backgroundDecoration: - color == null ? null : TableSpanDecoration(color: color), + backgroundDecoration: color == null + ? null + : TableSpanDecoration(color: color), ); }, ); @@ -1064,8 +1066,9 @@ void main() { } return TableSpan( extent: const FixedTableSpanExtent(100.0), - backgroundDecoration: - color == null ? null : TableSpanDecoration(color: color), + backgroundDecoration: color == null + ? null + : TableSpanDecoration(color: color), ); }, columnBuilder: (int index) { @@ -1077,8 +1080,9 @@ void main() { } return TableSpan( extent: const FixedTableSpanExtent(100.0), - backgroundDecoration: - color == null ? null : TableSpanDecoration(color: color), + backgroundDecoration: color == null + ? null + : TableSpanDecoration(color: color), ); }, ); @@ -1628,8 +1632,8 @@ void main() { child: Text('M(0,0)'), ); }, - columnBuilder: - (_) => const TableSpan(extent: FixedTableSpanExtent(100.0)), + columnBuilder: (_) => + const TableSpan(extent: FixedTableSpanExtent(100.0)), rowBuilder: (_) { return const TableSpan( extent: FixedTableSpanExtent(100.0), @@ -1657,8 +1661,8 @@ void main() { child: Text('M(0,0)'), ); }, - rowBuilder: - (_) => const TableSpan(extent: FixedTableSpanExtent(100.0)), + rowBuilder: (_) => + const TableSpan(extent: FixedTableSpanExtent(100.0)), columnBuilder: (_) { return const TableSpan( extent: FixedTableSpanExtent(100.0), diff --git a/packages/two_dimensional_scrollables/test/table_view/table_test.dart b/packages/two_dimensional_scrollables/test/table_view/table_test.dart index 6d0c1745208..8893edef189 100644 --- a/packages/two_dimensional_scrollables/test/table_view/table_test.dart +++ b/packages/two_dimensional_scrollables/test/table_view/table_test.dart @@ -2388,11 +2388,8 @@ void main() { rowCount: 50, columnCount: 50, columnBuilder: (_) => span, - rowBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => tapCounter++) - : span, + rowBuilder: (int index) => + index.isEven ? getTappableSpan(index, () => tapCounter++) : span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: SizedBox.square( @@ -2433,11 +2430,8 @@ void main() { rowCount: 50, columnCount: 50, rowBuilder: (_) => span, - columnBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => tapCounter++) - : span, + columnBuilder: (int index) => + index.isEven ? getTappableSpan(index, () => tapCounter++) : span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: SizedBox.square( @@ -2478,16 +2472,11 @@ void main() { tableView = TableView.builder( rowCount: 50, columnCount: 50, - rowBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => rowTapCounter++) - : span, - columnBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => columnTapCounter++) - : span, + rowBuilder: (int index) => + index.isEven ? getTappableSpan(index, () => rowTapCounter++) : span, + columnBuilder: (int index) => index.isEven + ? getTappableSpan(index, () => columnTapCounter++) + : span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: SizedBox.square( @@ -2535,16 +2524,11 @@ void main() { mainAxis: Axis.horizontal, rowCount: 50, columnCount: 50, - rowBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => rowTapCounter++) - : span, - columnBuilder: - (int index) => - index.isEven - ? getTappableSpan(index, () => columnTapCounter++) - : span, + rowBuilder: (int index) => + index.isEven ? getTappableSpan(index, () => rowTapCounter++) : span, + columnBuilder: (int index) => index.isEven + ? getTappableSpan(index, () => columnTapCounter++) + : span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: SizedBox.square( @@ -2631,12 +2615,11 @@ void main() { TableView tableView = TableView.builder( rowCount: 50, columnCount: 50, - columnBuilder: - (_) => const TableSpan( - extent: FixedTableSpanExtent(100), - // This padding is so high, only the first column should be laid out. - padding: TableSpanPadding(leading: 2000), - ), + columnBuilder: (_) => const TableSpan( + extent: FixedTableSpanExtent(100), + // This padding is so high, only the first column should be laid out. + padding: TableSpanPadding(leading: 2000), + ), rowBuilder: (_) => span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( @@ -2666,11 +2649,10 @@ void main() { rowCount: 50, columnCount: 50, // This padding is so high, no children should be laid out. - rowBuilder: - (_) => const TableSpan( - extent: FixedTableSpanExtent(100), - padding: TableSpanPadding(leading: 2000), - ), + rowBuilder: (_) => const TableSpan( + extent: FixedTableSpanExtent(100), + padding: TableSpanPadding(leading: 2000), + ), columnBuilder: (_) => span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( @@ -2704,8 +2686,8 @@ void main() { TableView tableView = TableView.builder( rowCount: 50, columnCount: 50, - columnBuilder: - (_) => const TableSpan(extent: FixedTableSpanExtent(200)), + columnBuilder: (_) => + const TableSpan(extent: FixedTableSpanExtent(200)), rowBuilder: (_) => span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( @@ -2732,11 +2714,10 @@ void main() { tableView = TableView.builder( rowCount: 50, columnCount: 50, - columnBuilder: - (_) => const TableSpan( - extent: FixedTableSpanExtent(200), - padding: TableSpanPadding(trailing: 200), - ), + columnBuilder: (_) => const TableSpan( + extent: FixedTableSpanExtent(200), + padding: TableSpanPadding(trailing: 200), + ), rowBuilder: (_) => span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( @@ -2790,11 +2771,10 @@ void main() { tableView = TableView.builder( rowCount: 50, columnCount: 50, - rowBuilder: - (_) => const TableSpan( - extent: FixedTableSpanExtent(200), - padding: TableSpanPadding(trailing: 200), - ), + rowBuilder: (_) => const TableSpan( + extent: FixedTableSpanExtent(200), + padding: TableSpanPadding(trailing: 200), + ), columnBuilder: (_) => span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( @@ -3216,40 +3196,38 @@ void main() { TableView tableView = TableView.builder( rowCount: 2, columnCount: 2, - columnBuilder: - (int index) => TableSpan( - extent: const FixedTableSpanExtent(200.0), - padding: index == 0 ? const TableSpanPadding(trailing: 10) : null, - foregroundDecoration: TableSpanDecoration( - consumeSpanPadding: false, - borderRadius: BorderRadius.circular(10.0), - border: const TableSpanBorder( - trailing: BorderSide(color: Colors.orange, width: 3), - ), - ), - backgroundDecoration: TableSpanDecoration( - // consumePadding true by default - color: index.isEven ? Colors.red : null, - borderRadius: BorderRadius.circular(30.0), - ), + columnBuilder: (int index) => TableSpan( + extent: const FixedTableSpanExtent(200.0), + padding: index == 0 ? const TableSpanPadding(trailing: 10) : null, + foregroundDecoration: TableSpanDecoration( + consumeSpanPadding: false, + borderRadius: BorderRadius.circular(10.0), + border: const TableSpanBorder( + trailing: BorderSide(color: Colors.orange, width: 3), ), - rowBuilder: - (int index) => TableSpan( - extent: const FixedTableSpanExtent(200.0), - padding: index == 1 ? const TableSpanPadding(leading: 10) : null, - foregroundDecoration: TableSpanDecoration( - // consumePadding true by default - borderRadius: BorderRadius.circular(30.0), - border: const TableSpanBorder( - leading: BorderSide(color: Colors.green, width: 3), - ), - ), - backgroundDecoration: TableSpanDecoration( - color: index.isOdd ? Colors.blue : null, - borderRadius: BorderRadius.circular(30.0), - consumeSpanPadding: false, - ), + ), + backgroundDecoration: TableSpanDecoration( + // consumePadding true by default + color: index.isEven ? Colors.red : null, + borderRadius: BorderRadius.circular(30.0), + ), + ), + rowBuilder: (int index) => TableSpan( + extent: const FixedTableSpanExtent(200.0), + padding: index == 1 ? const TableSpanPadding(leading: 10) : null, + foregroundDecoration: TableSpanDecoration( + // consumePadding true by default + borderRadius: BorderRadius.circular(30.0), + border: const TableSpanBorder( + leading: BorderSide(color: Colors.green, width: 3), ), + ), + backgroundDecoration: TableSpanDecoration( + color: index.isOdd ? Colors.blue : null, + borderRadius: BorderRadius.circular(30.0), + consumeSpanPadding: false, + ), + ), cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: Container( @@ -3381,30 +3359,28 @@ void main() { mainAxis: Axis.horizontal, rowCount: 2, columnCount: 2, - columnBuilder: - (int index) => TableSpan( - extent: const FixedTableSpanExtent(200.0), - foregroundDecoration: const TableSpanDecoration( - border: TableSpanBorder( - trailing: BorderSide(color: Colors.orange, width: 3), - ), - ), - backgroundDecoration: TableSpanDecoration( - color: index.isEven ? Colors.red : null, - ), + columnBuilder: (int index) => TableSpan( + extent: const FixedTableSpanExtent(200.0), + foregroundDecoration: const TableSpanDecoration( + border: TableSpanBorder( + trailing: BorderSide(color: Colors.orange, width: 3), ), - rowBuilder: - (int index) => TableSpan( - extent: const FixedTableSpanExtent(200.0), - foregroundDecoration: const TableSpanDecoration( - border: TableSpanBorder( - leading: BorderSide(color: Colors.green, width: 3), - ), - ), - backgroundDecoration: TableSpanDecoration( - color: index.isOdd ? Colors.blue : null, - ), + ), + backgroundDecoration: TableSpanDecoration( + color: index.isEven ? Colors.red : null, + ), + ), + rowBuilder: (int index) => TableSpan( + extent: const FixedTableSpanExtent(200.0), + foregroundDecoration: const TableSpanDecoration( + border: TableSpanBorder( + leading: BorderSide(color: Colors.green, width: 3), ), + ), + backgroundDecoration: TableSpanDecoration( + color: index.isOdd ? Colors.blue : null, + ), + ), cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: Container( @@ -3501,10 +3477,10 @@ void main() { pinnedRowCount: 1, columnCount: 2, pinnedColumnCount: 1, - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(200.0)), - rowBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(200.0)), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(200.0)), + rowBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(200.0)), cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: Container( @@ -3547,10 +3523,10 @@ void main() { pinnedRowCount: 1, columnCount: 2, pinnedColumnCount: 1, - columnBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(200.0)), - rowBuilder: - (int index) => const TableSpan(extent: FixedTableSpanExtent(200.0)), + columnBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(200.0)), + rowBuilder: (int index) => + const TableSpan(extent: FixedTableSpanExtent(200.0)), cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: Container( @@ -3593,15 +3569,13 @@ void main() { rowCount: 50, columnCount: 50, columnBuilder: (_) => span, - rowBuilder: - (int index) => - index.isEven - ? getMouseTrackingSpan( - index, - onEnter: (_) => enterCounter++, - onExit: (_) => exitCounter++, - ) - : span, + rowBuilder: (int index) => index.isEven + ? getMouseTrackingSpan( + index, + onEnter: (_) => enterCounter++, + onExit: (_) => exitCounter++, + ) + : span, cellBuilder: (_, TableVicinity vicinity) { return TableViewCell( child: SizedBox.square( @@ -4136,8 +4110,8 @@ void main() { final TableView tableView = TableView.builder( columnCount: 10, rowCount: 10, - columnBuilder: - (_) => const TableSpan(extent: FixedTableSpanExtent(100)), + columnBuilder: (_) => + const TableSpan(extent: FixedTableSpanExtent(100)), rowBuilder: (_) => const TableSpan(extent: FixedTableSpanExtent(100)), cellBuilder: (BuildContext context, TableVicinity vicinity) { if (mergedCell.contains(vicinity)) { diff --git a/packages/two_dimensional_scrollables/test/tree_view/render_tree_test.dart b/packages/two_dimensional_scrollables/test/tree_view/render_tree_test.dart index 3836f36b49d..f3f4b9ba204 100644 --- a/packages/two_dimensional_scrollables/test/tree_view/render_tree_test.dart +++ b/packages/two_dimensional_scrollables/test/tree_view/render_tree_test.dart @@ -87,8 +87,8 @@ void main() { delegate: TreeRowBuilderDelegate( rowCount: 0, nodeBuilder: (_, __) => const SizedBox(), - rowBuilder: - (_) => const TreeRow(extent: FixedTreeRowExtent(40.0)), + rowBuilder: (_) => + const TreeRow(extent: FixedTreeRowExtent(40.0)), ), activeAnimations: const {}, rowDepths: const {}, @@ -114,8 +114,8 @@ void main() { delegate: TreeRowBuilderDelegate( rowCount: 0, nodeBuilder: (_, __) => const SizedBox(), - rowBuilder: - (_) => const TreeRow(extent: FixedTreeRowExtent(40.0)), + rowBuilder: (_) => + const TreeRow(extent: FixedTreeRowExtent(40.0)), ), activeAnimations: const {}, rowDepths: const {}, @@ -721,14 +721,12 @@ void main() { tree: treeNodes, treeRowBuilder: (TreeViewNode node) { return row.copyWith( - backgroundDecoration: - node.depth! == 0 - ? rootBackgroundDecoration - : backgroundDecoration, - foregroundDecoration: - node.depth! == 0 - ? rootForegroundDecoration - : foregroundDecoration, + backgroundDecoration: node.depth! == 0 + ? rootBackgroundDecoration + : backgroundDecoration, + foregroundDecoration: node.depth! == 0 + ? rootForegroundDecoration + : foregroundDecoration, ); }, ); diff --git a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart index 720ad7b34a5..0bc08e8ed3b 100644 --- a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart +++ b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart @@ -128,18 +128,19 @@ void main() { home: TreeView( tree: simpleNodeSet, controller: controller, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - returnedController ??= TreeViewController.of(context); - return TreeView.defaultTreeNodeBuilder( - context, - node, - toggleAnimationStyle, - ); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + returnedController ??= TreeViewController.of(context); + return TreeView.defaultTreeNodeBuilder( + context, + node, + toggleAnimationStyle, + ); + }, ), ), ); @@ -154,18 +155,19 @@ void main() { MaterialApp( home: TreeView( tree: simpleNodeSet, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - returnedController ??= TreeViewController.maybeOf(context); - return TreeView.defaultTreeNodeBuilder( - context, - node, - toggleAnimationStyle, - ); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + returnedController ??= TreeViewController.maybeOf(context); + return TreeView.defaultTreeNodeBuilder( + context, + node, + toggleAnimationStyle, + ); + }, ), ), ); @@ -411,45 +413,49 @@ void main() { toggled = true; toggledNode = node; }, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - final Duration animationDuration = - toggleAnimationStyle.duration ?? - TreeView.defaultAnimationDuration; - final Curve animationCurve = - toggleAnimationStyle.curve ?? TreeView.defaultAnimationCurve; - // This makes the whole row trigger toggling. - return TreeView.wrapChildToToggleNode( - node: node, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - // Icon for parent nodes - SizedBox.square( - dimension: 30.0, - child: - node.children.isNotEmpty + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + final Duration animationDuration = + toggleAnimationStyle.duration ?? + TreeView.defaultAnimationDuration; + final Curve animationCurve = + toggleAnimationStyle.curve ?? + TreeView.defaultAnimationCurve; + // This makes the whole row trigger toggling. + return TreeView.wrapChildToToggleNode( + node: node, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + // Icon for parent nodes + SizedBox.square( + dimension: 30.0, + child: node.children.isNotEmpty ? AnimatedRotation( - turns: node.isExpanded ? 0.25 : 0.0, - duration: animationDuration, - curve: animationCurve, - child: const Icon(IconData(0x25BA), size: 14), - ) + turns: node.isExpanded ? 0.25 : 0.0, + duration: animationDuration, + curve: animationCurve, + child: const Icon( + IconData(0x25BA), + size: 14, + ), + ) : null, + ), + // Spacer + const SizedBox(width: 8.0), + // Content + Text(node.content), + ], ), - // Spacer - const SizedBox(width: 8.0), - // Content - Text(node.content), - ], - ), - ), - ); - }, + ), + ); + }, ), ), ); @@ -471,14 +477,15 @@ void main() { MaterialApp( home: TreeView( tree: simpleNodeSet, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - style ??= toggleAnimationStyle; - return Text(node.content); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + style ??= toggleAnimationStyle; + return Text(node.content); + }, ), ), ); @@ -497,14 +504,15 @@ void main() { home: TreeView( tree: simpleNodeSet, toggleAnimationStyle: AnimationStyle.noAnimation, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - style = toggleAnimationStyle; - return Text(node.content); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + style = toggleAnimationStyle; + return Text(node.content); + }, ), ), ); @@ -522,14 +530,15 @@ void main() { curve: Curves.easeIn, duration: const Duration(milliseconds: 200), ), - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle toggleAnimationStyle, - ) { - style ??= toggleAnimationStyle; - return Text(node.content); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle toggleAnimationStyle, + ) { + style ??= toggleAnimationStyle; + return Text(node.content); + }, ), ), ); @@ -648,13 +657,18 @@ void main() { test('should use the generic type for callbacks and builders', () { final TreeView treeView = TreeView( tree: simpleNodeSet, - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle animationStyle, - ) { - return TreeView.defaultTreeNodeBuilder(context, node, animationStyle); - }, + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + return TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ); + }, treeRowBuilder: (TreeViewNode node) { return TreeView.defaultTreeRowBuilder(node); }, @@ -710,23 +724,24 @@ void main() { curve: Curves.easeInOut, duration: Duration.zero, ), - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle animationStyle, - ) { - final Widget child = GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => controller.toggleNode(node), - child: TreeView.defaultTreeNodeBuilder( - context, - node, - animationStyle, - ), - ); + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + final Widget child = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => controller.toggleNode(node), + child: TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ), + ); - return child; - }, + return child; + }, ), ), ); @@ -800,23 +815,24 @@ void main() { curve: Curves.easeInOut, duration: const Duration(milliseconds: 200), ), - treeNodeBuilder: ( - BuildContext context, - TreeViewNode node, - AnimationStyle animationStyle, - ) { - final Widget child = GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => controller.toggleNode(node), - child: TreeView.defaultTreeNodeBuilder( - context, - node, - animationStyle, - ), - ); + treeNodeBuilder: + ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + final Widget child = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => controller.toggleNode(node), + child: TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ), + ); - return child; - }, + return child; + }, ), ), ); @@ -945,8 +961,8 @@ void main() { delegate: TreeRowBuilderDelegate( rowCount: 0, nodeBuilder: (_, __) => const SizedBox(), - rowBuilder: - (_) => const TreeRow(extent: FixedTreeRowExtent(40.0)), + rowBuilder: (_) => + const TreeRow(extent: FixedTreeRowExtent(40.0)), ), activeAnimations: const {}, rowDepths: const {}, @@ -971,8 +987,8 @@ void main() { delegate: TreeRowBuilderDelegate( rowCount: 0, nodeBuilder: (_, __) => const SizedBox(), - rowBuilder: - (_) => const TreeRow(extent: FixedTreeRowExtent(40.0)), + rowBuilder: (_) => + const TreeRow(extent: FixedTreeRowExtent(40.0)), ), activeAnimations: const {}, rowDepths: const {}, diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index d01c0ec1d9a..fd4e316edd6 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 2.11.0 -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. ## 2.10.0 diff --git a/packages/video_player/video_player/README.md b/packages/video_player/video_player/README.md index 261b68ba5c5..a5b2814c2c3 100644 --- a/packages/video_player/video_player/README.md +++ b/packages/video_player/video_player/README.md @@ -77,15 +77,16 @@ class _VideoAppState extends State { @override void initState() { super.initState(); - _controller = VideoPlayerController.networkUrl( - Uri.parse( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', - ), - ) - ..initialize().then((_) { - // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. - setState(() {}); - }); + _controller = + VideoPlayerController.networkUrl( + Uri.parse( + 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', + ), + ) + ..initialize().then((_) { + // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. + setState(() {}); + }); } @override @@ -94,13 +95,12 @@ class _VideoAppState extends State { title: 'Video Demo', home: Scaffold( body: Center( - child: - _controller.value.isInitialized - ? AspectRatio( - aspectRatio: _controller.value.aspectRatio, - child: VideoPlayer(_controller), - ) - : Container(), + child: _controller.value.isInitialized + ? AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ) + : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { diff --git a/packages/video_player/video_player/example/android/app/build.gradle b/packages/video_player/video_player/example/android/app/build.gradle index 35c15d3dd80..62cf85b288b 100644 --- a/packages/video_player/video_player/example/android/app/build.gradle +++ b/packages/video_player/video_player/example/android/app/build.gradle @@ -27,8 +27,8 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { diff --git a/packages/video_player/video_player/example/integration_test/controller_swap_test.dart b/packages/video_player/video_player/example/integration_test/controller_swap_test.dart index 2df68f07e2e..dc0f43681b2 100644 --- a/packages/video_player/video_player/example/integration_test/controller_swap_test.dart +++ b/packages/video_player/video_player/example/integration_test/controller_swap_test.dart @@ -18,8 +18,9 @@ void main() { 'can substitute one controller by another without crashing', (WidgetTester tester) async { // Use WebM for web to allow CI to use Chromium. - const String videoAssetKey = - kIsWeb ? 'assets/Butterfly-209.webm' : 'assets/Butterfly-209.mp4'; + const String videoAssetKey = kIsWeb + ? 'assets/Butterfly-209.webm' + : 'assets/Butterfly-209.mp4'; final VideoPlayerController controller = VideoPlayerController.asset( videoAssetKey, diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart index 7ddf2404957..c4e46c1cb67 100644 --- a/packages/video_player/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart @@ -16,8 +16,9 @@ import 'package:video_player/video_player.dart'; const Duration _playDuration = Duration(seconds: 1); // Use WebM for web to allow CI to use Chromium. -const String _videoAssetKey = - kIsWeb ? 'assets/Butterfly-209.webm' : 'assets/Butterfly-209.mp4'; +const String _videoAssetKey = kIsWeb + ? 'assets/Butterfly-209.webm' + : 'assets/Butterfly-209.mp4'; // Returns the URL to load an asset from this example app as a network source. // @@ -213,19 +214,17 @@ void main() { child: Center( child: FutureBuilder( future: started(), - builder: ( - BuildContext context, - AsyncSnapshot snapshot, - ) { - if (snapshot.data ?? false) { - return AspectRatio( - aspectRatio: controller.value.aspectRatio, - child: VideoPlayer(controller), - ); - } else { - return const Text('waiting for video to load'); - } - }, + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.data ?? false) { + return AspectRatio( + aspectRatio: controller.value.aspectRatio, + child: VideoPlayer(controller), + ); + } else { + return const Text('waiting for video to load'); + } + }, ), ), ), diff --git a/packages/video_player/video_player/example/lib/basic.dart b/packages/video_player/video_player/example/lib/basic.dart index f8ef6029ae6..3b9f3db665b 100644 --- a/packages/video_player/video_player/example/lib/basic.dart +++ b/packages/video_player/video_player/example/lib/basic.dart @@ -27,15 +27,16 @@ class _VideoAppState extends State { @override void initState() { super.initState(); - _controller = VideoPlayerController.networkUrl( - Uri.parse( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', - ), - ) - ..initialize().then((_) { - // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. - setState(() {}); - }); + _controller = + VideoPlayerController.networkUrl( + Uri.parse( + 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4', + ), + ) + ..initialize().then((_) { + // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. + setState(() {}); + }); } @override @@ -44,13 +45,12 @@ class _VideoAppState extends State { title: 'Video Demo', home: Scaffold( body: Center( - child: - _controller.value.isInitialized - ? AspectRatio( - aspectRatio: _controller.value.aspectRatio, - child: VideoPlayer(_controller), - ) - : Container(), + child: _controller.value.isInitialized + ? AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ) + : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index 1382af5d87d..d47a5abc601 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -50,17 +50,16 @@ class _App extends StatelessWidget { body: TabBarView( children: [ _ViewTypeTabBar( - builder: - (VideoViewType viewType) => _BumbleBeeRemoteVideo(viewType), + builder: (VideoViewType viewType) => + _BumbleBeeRemoteVideo(viewType), ), _ViewTypeTabBar( - builder: - (VideoViewType viewType) => _ButterFlyAssetVideo(viewType), + builder: (VideoViewType viewType) => + _ButterFlyAssetVideo(viewType), ), _ViewTypeTabBar( - builder: - (VideoViewType viewType) => - _ButterFlyAssetVideoInList(viewType), + builder: (VideoViewType viewType) => + _ButterFlyAssetVideoInList(viewType), ), ], ), @@ -381,20 +380,19 @@ class _ControlsOverlay extends StatelessWidget { AnimatedSwitcher( duration: const Duration(milliseconds: 50), reverseDuration: const Duration(milliseconds: 200), - child: - controller.value.isPlaying - ? const SizedBox.shrink() - : const ColoredBox( - color: Colors.black26, - child: Center( - child: Icon( - Icons.play_arrow, - color: Colors.white, - size: 100.0, - semanticLabel: 'Play', - ), + child: controller.value.isPlaying + ? const SizedBox.shrink() + : const ColoredBox( + color: Colors.black26, + child: Center( + child: Icon( + Icons.play_arrow, + color: Colors.white, + size: 100.0, + semanticLabel: 'Play', ), ), + ), ), GestureDetector( onTap: () { diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 6c990c8b34f..09dc13ba5ba 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 8f8ebf5d8dc..bd51e9d398e 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -188,10 +188,9 @@ class VideoPlayerValue { volume: volume ?? this.volume, playbackSpeed: playbackSpeed ?? this.playbackSpeed, rotationCorrection: rotationCorrection ?? this.rotationCorrection, - errorDescription: - errorDescription != _defaultErrorDescription - ? errorDescription - : this.errorDescription, + errorDescription: errorDescription != _defaultErrorDescription + ? errorDescription + : this.errorDescription, isCompleted: isCompleted ?? this.isCompleted, ); } @@ -906,11 +905,11 @@ class _VideoPlayerState extends State { return _playerId == VideoPlayerController.kUninitializedPlayerId ? Container() : _VideoPlayerWithRotation( - rotation: widget.controller.value.rotationCorrection, - child: _videoPlayerPlatform.buildViewWithOptions( - VideoViewOptions(playerId: _playerId), - ), - ); + rotation: widget.controller.value.rotationCorrection, + child: _videoPlayerPlatform.buildViewWithOptions( + VideoViewOptions(playerId: _playerId), + ), + ); } } diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index c8863f632ff..1e81f64c37a 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -3,11 +3,11 @@ description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, macOS and web. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.10.0 +version: 2.11.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 394369380f0..0a71d1c6425 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -15,8 +15,8 @@ void main() { late FakeVideoPlayerPlatform fakeVideoPlayerPlatform; setUp(() { - VideoPlayerPlatform.instance = - fakeVideoPlayerPlatform = FakeVideoPlayerPlatform(); + VideoPlayerPlatform.instance = fakeVideoPlayerPlatform = + FakeVideoPlayerPlatform(); }); test('plugin initialized', () async { diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index e87cb3296b8..7730a251b1a 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.9.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.8.14 * Restructures internal logic for player creation and tracking. diff --git a/packages/video_player/video_player_android/android/build.gradle b/packages/video_player/video_player_android/android/build.gradle index c90d8619027..4ce0516f0e6 100644 --- a/packages/video_player/video_player_android/android/build.gradle +++ b/packages/video_player/video_player_android/android/build.gradle @@ -35,8 +35,8 @@ android { disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable' } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } dependencies { diff --git a/packages/video_player/video_player_android/example/android/app/build.gradle b/packages/video_player/video_player_android/example/android/app/build.gradle index 008347495f9..8583053d9af 100644 --- a/packages/video_player/video_player_android/example/android/app/build.gradle +++ b/packages/video_player/video_player_android/example/android/app/build.gradle @@ -27,8 +27,8 @@ android { compileSdk = flutter.compileSdkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } defaultConfig { diff --git a/packages/video_player/video_player_android/example/integration_test/video_player_test.dart b/packages/video_player/video_player_android/example/integration_test/video_player_test.dart index 6fd4d6f1e45..d7e9758fec3 100644 --- a/packages/video_player/video_player_android/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player_android/example/integration_test/video_player_test.dart @@ -43,10 +43,9 @@ void main() { }); testWidgets('initializes at the start', (_) async { - final int playerId = - (await player.create( - DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), - ))!; + final int playerId = (await player.create( + DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), + ))!; expect( await _getDuration(player, playerId), @@ -57,10 +56,9 @@ void main() { }); testWidgets('can be played', (WidgetTester tester) async { - final int playerId = - (await player.create( - DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), - ))!; + final int playerId = (await player.create( + DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), + ))!; await player.play(playerId); await tester.pumpAndSettle(_playDuration); @@ -70,10 +68,9 @@ void main() { }); testWidgets('can seek', (WidgetTester tester) async { - final int playerId = - (await player.create( - DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), - ))!; + final int playerId = (await player.create( + DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), + ))!; await player.seekTo(playerId, const Duration(seconds: 3)); await tester.pumpAndSettle(_playDuration); @@ -86,10 +83,9 @@ void main() { }); testWidgets('can pause', (WidgetTester tester) async { - final int playerId = - (await player.create( - DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), - ))!; + final int playerId = (await player.create( + DataSource(sourceType: DataSourceType.asset, asset: _videoAssetKey), + ))!; await player.play(playerId); await tester.pumpAndSettle(_playDuration); @@ -112,10 +108,9 @@ void main() { ), ); - final int playerId = - (await player.create( - DataSource(sourceType: DataSourceType.file, uri: file.path), - ))!; + final int playerId = (await player.create( + DataSource(sourceType: DataSourceType.file, uri: file.path), + ))!; await player.play(playerId); await tester.pumpAndSettle(_playDuration); @@ -126,13 +121,12 @@ void main() { }); testWidgets('can play a video from network', (WidgetTester tester) async { - final int playerId = - (await player.create( - DataSource( - sourceType: DataSourceType.network, - uri: getUrlForAssetAsNetworkSource(_videoAssetKey), - ), - ))!; + final int playerId = (await player.create( + DataSource( + sourceType: DataSourceType.network, + uri: getUrlForAssetAsNetworkSource(_videoAssetKey), + ), + ))!; await player.play(playerId); await player.seekTo(playerId, const Duration(seconds: 5)); diff --git a/packages/video_player/video_player_android/example/lib/main.dart b/packages/video_player/video_player_android/example/lib/main.dart index 6f190ba5639..cf8f341e998 100644 --- a/packages/video_player/video_player_android/example/lib/main.dart +++ b/packages/video_player/video_player_android/example/lib/main.dart @@ -34,15 +34,15 @@ class _App extends StatelessWidget { body: TabBarView( children: [ _ViewTypeTabBar( - builder: - (VideoViewType viewType) => _BumbleBeeRemoteVideo(viewType), + builder: (VideoViewType viewType) => + _BumbleBeeRemoteVideo(viewType), ), _ViewTypeTabBar( builder: (VideoViewType viewType) => _RtspRemoteVideo(viewType), ), _ViewTypeTabBar( - builder: - (VideoViewType viewType) => _ButterFlyAssetVideo(viewType), + builder: (VideoViewType viewType) => + _ButterFlyAssetVideo(viewType), ), ], ), @@ -331,21 +331,20 @@ class _ControlsOverlay extends StatelessWidget { AnimatedSwitcher( duration: const Duration(milliseconds: 50), reverseDuration: const Duration(milliseconds: 200), - child: - controller.value.isPlaying - ? const SizedBox.shrink() - : const ColoredBox( - color: Colors.black26, - child: Center( - child: Icon( - key: ValueKey('Play'), - Icons.play_arrow, - color: Colors.white, - size: 100.0, - semanticLabel: 'Play', - ), + child: controller.value.isPlaying + ? const SizedBox.shrink() + : const ColoredBox( + color: Colors.black26, + child: Center( + child: Icon( + key: ValueKey('Play'), + Icons.play_arrow, + color: Colors.white, + size: 100.0, + semanticLabel: 'Play', ), ), + ), ), GestureDetector( onTap: () { diff --git a/packages/video_player/video_player_android/example/lib/mini_controller.dart b/packages/video_player/video_player_android/example/lib/mini_controller.dart index ec52735d09f..0068b25ecc4 100644 --- a/packages/video_player/video_player_android/example/lib/mini_controller.dart +++ b/packages/video_player/video_player_android/example/lib/mini_controller.dart @@ -443,11 +443,11 @@ class _VideoPlayerState extends State { return _playerId == MiniController.kUninitializedPlayerId ? Container() : _VideoPlayerWithRotation( - rotation: widget.controller.value.rotationCorrection, - child: _platform.buildViewWithOptions( - VideoViewOptions(playerId: _playerId), - ), - ); + rotation: widget.controller.value.rotationCorrection, + child: _platform.buildViewWithOptions( + VideoViewOptions(playerId: _playerId), + ), + ); } } diff --git a/packages/video_player/video_player_android/example/pubspec.yaml b/packages/video_player/video_player_android/example/pubspec.yaml index 286f6b89e69..4afc63d4990 100644 --- a/packages/video_player/video_player_android/example/pubspec.yaml +++ b/packages/video_player/video_player_android/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/packages/video_player/video_player_android/lib/src/messages.g.dart b/packages/video_player/video_player_android/lib/src/messages.g.dart index 1b79bb0678e..7701c6f4647 100644 --- a/packages/video_player/video_player_android/lib/src/messages.g.dart +++ b/packages/video_player/video_player_android/lib/src/messages.g.dart @@ -105,8 +105,8 @@ class CreationOptions { return CreationOptions( uri: result[0]! as String, formatHint: result[1] as PlatformVideoFormat?, - httpHeaders: - (result[2] as Map?)!.cast(), + httpHeaders: (result[2] as Map?)! + .cast(), userAgent: result[3] as String?, ); } @@ -265,8 +265,9 @@ class AndroidVideoPlayerApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -457,8 +458,9 @@ class VideoPlayerInstanceApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); diff --git a/packages/video_player/video_player_android/lib/src/platform_view_player.dart b/packages/video_player/video_player_android/lib/src/platform_view_player.dart index 9f32e312359..84d21540043 100644 --- a/packages/video_player/video_player_android/lib/src/platform_view_player.dart +++ b/packages/video_player/video_player_android/lib/src/platform_view_player.dart @@ -28,16 +28,15 @@ class PlatformViewPlayer extends StatelessWidget { return IgnorePointer( child: PlatformViewLink( viewType: viewType, - surfaceFactory: ( - BuildContext context, - PlatformViewController controller, - ) { - return AndroidViewSurface( - controller: controller as AndroidViewController, - gestureRecognizers: const >{}, - hitTestBehavior: PlatformViewHitTestBehavior.opaque, - ); - }, + surfaceFactory: + (BuildContext context, PlatformViewController controller) { + return AndroidViewSurface( + controller: controller as AndroidViewController, + gestureRecognizers: + const >{}, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, onCreatePlatformView: (PlatformViewCreationParams params) { return PlatformViewsService.initSurfaceAndroidView( id: params.id, diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index ac12f3df83b..17102e883df 100644 --- a/packages/video_player/video_player_android/pubspec.yaml +++ b/packages/video_player/video_player_android/pubspec.yaml @@ -2,11 +2,11 @@ name: video_player_android description: Android implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.8.14 +version: 2.9.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: diff --git a/packages/video_player/video_player_android/test/android_video_player_test.dart b/packages/video_player/video_player_android/test/android_video_player_test.dart index 1efa32459b2..efc2c2e7aec 100644 --- a/packages/video_player/video_player_android/test/android_video_player_test.dart +++ b/packages/video_player/video_player_android/test/android_video_player_test.dart @@ -45,33 +45,24 @@ void main() { group('AndroidVideoPlayer', () { test('init', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1); await player.init(); verify(api.initialize()); }); test('dispose', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1); await player.dispose(1); verify(api.dispose(1)); }); test('create with asset', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -106,11 +97,8 @@ void main() { }); test('create with network', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -141,11 +129,8 @@ void main() { }); test('create with network passes headers', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -169,11 +154,8 @@ void main() { }); test('create with network sets a default user agent', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -194,11 +176,8 @@ void main() { }); test('create with network uses user agent from headers', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -223,11 +202,8 @@ void main() { }); test('create with file', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -249,11 +225,8 @@ void main() { }); test('create with file passes headers', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -278,11 +251,8 @@ void main() { }); test('createWithOptions with asset', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -320,11 +290,8 @@ void main() { }); test('createWithOptions with network', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -358,11 +325,8 @@ void main() { }); test('createWithOptions with network passes headers', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -392,11 +356,8 @@ void main() { }); test('createWithOptions with file', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); const int newPlayerId = 2; when(api.createForTextureView(any)).thenAnswer( (_) async => TexturePlayerIds(playerId: newPlayerId, textureId: 100), @@ -424,11 +385,8 @@ void main() { }); test('createWithOptions with file passes headers', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1, textureId: 100); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1, textureId: 100); when( api.createForTextureView(any), ).thenAnswer((_) async => TexturePlayerIds(playerId: 2, textureId: 100)); @@ -457,11 +415,8 @@ void main() { }); test('createWithOptions with platform view', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1); const int newPlayerId = 2; when(api.createForPlatformView(any)).thenAnswer((_) async => newPlayerId); @@ -491,7 +446,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); await player.setLooping(1, true); verify(playerApi.setLooping(true)); @@ -502,7 +459,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); await player.play(1); verify(playerApi.play()); @@ -513,7 +472,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); await player.pause(1); verify(playerApi.pause()); @@ -521,22 +482,16 @@ void main() { group('setMixWithOthers', () { test('passes true', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1); await player.setMixWithOthers(true); verify(api.setMixWithOthers(true)); }); test('passes false', () async { - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: 1); await player.setMixWithOthers(false); verify(api.setMixWithOthers(false)); @@ -548,7 +503,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); const double volume = 0.7; await player.setVolume(1, volume); @@ -560,7 +517,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); const double speed = 1.5; await player.setPlaybackSpeed(1, speed); @@ -572,7 +531,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); const int positionMilliseconds = 12345; await player.seekTo( 1, @@ -587,7 +548,9 @@ void main() { AndroidVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi, - ) = setUpMockPlayer(playerId: 1); + ) = setUpMockPlayer( + playerId: 1, + ); const int positionMilliseconds = 12345; when(playerApi.getPlaybackState()).thenAnswer( (_) async => PlaybackState( @@ -724,11 +687,8 @@ void main() { // Creating the player triggers the stream listener, so that must be done // after setting up the mock native handler above. - final ( - AndroidVideoPlayer player, - MockAndroidVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: playerId); + final (AndroidVideoPlayer player, MockAndroidVideoPlayerApi api, _) = + setUpMockPlayer(playerId: playerId); expect( player.videoEventsFor(playerId), diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 986f9882ee3..a5e66c8e32f 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.11.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 4.10.3 * Updates Java compatibility version to 17. diff --git a/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle b/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle index d5c6de2589f..e989fd72d70 100644 --- a/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle +++ b/packages/webview_flutter/webview_flutter_android/example/android/app/build.gradle @@ -43,7 +43,7 @@ android { } kotlinOptions { - jvmTarget = '17' + jvmTarget = JavaVersion.VERSION_17.toString() } buildTypes { diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 5657dde8e98..c530c68fff8 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_android description: A Flutter plugin that provides a WebView widget on Android. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 4.10.3 +version: 4.11.0 environment: sdk: ^3.9.0 diff --git a/script/tool/lib/src/gradle_check_command.dart b/script/tool/lib/src/gradle_check_command.dart index 0e70e5f9ba8..77b8cceb8f2 100644 --- a/script/tool/lib/src/gradle_check_command.dart +++ b/script/tool/lib/src/gradle_check_command.dart @@ -357,30 +357,30 @@ build.gradle "namespace" must match the "package" attribute in AndroidManifest.x final bool hasLanguageVersion = gradleLines.any((String line) => line.contains('languageVersion') && !_isCommented(line)); final bool hasCompabilityVersions = gradleLines.any((String line) => - line.contains('sourceCompatibility') && !_isCommented(line)) && + line.contains('sourceCompatibility = ') && !_isCommented(line)) && // Newer toolchains default targetCompatibility to the same value as // sourceCompatibility, but older toolchains require it to be set // explicitly. The exact version cutoff (and of which piece of the // toolchain; likely AGP) is unknown; for context see // https://github.com/flutter/flutter/issues/125482 gradleLines.any((String line) => - line.contains('targetCompatibility') && !_isCommented(line)); + line.contains('targetCompatibility = ') && !_isCommented(line)); if (!hasLanguageVersion && !hasCompabilityVersions) { - const String errorMessage = ''' -build.gradle must set an explicit Java compatibility version. + const String javaErrorMessage = ''' +build.gradle(.kts) must set an explicit Java compatibility version. This can be done either via "sourceCompatibility"/"targetCompatibility": android { compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } or "toolchain": java { toolchain { - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(17) } } @@ -389,9 +389,32 @@ https://docs.gradle.org/current/userguide/java_plugin.html#toolchain_and_compati for more details.'''; printError( - '$indentation${errorMessage.split('\n').join('\n$indentation')}'); + '$indentation${javaErrorMessage.split('\n').join('\n$indentation')}'); + return false; + } + final bool hasKotlinOptions = gradleLines.any( + (String line) => line.contains('kotlinOptions') && !_isCommented(line)); + final bool kotlinOptionsUsesJavaVersion = gradleLines.any((String line) => + line.contains('jvmTarget = JavaVersion.VERSION_') && + !_isCommented(line)); + // Either does not set kotlinOptions or does and uses non-string based syntax. + if (hasKotlinOptions && !kotlinOptionsUsesJavaVersion) { + final String kotlinErrorMessage = ''' +If build.gradle(.kts) sets jvmTarget then it must use JavaVersion syntax. + Good: + android { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + } + BAD: + $gradleLines +'''; + printError( + '$indentation${kotlinErrorMessage.split('\n').join('\n$indentation')}'); return false; } + return true; } diff --git a/script/tool/test/gradle_check_command_test.dart b/script/tool/test/gradle_check_command_test.dart index b442ae8356b..865f37ffdfc 100644 --- a/script/tool/test/gradle_check_command_test.dart +++ b/script/tool/test/gradle_check_command_test.dart @@ -17,6 +17,8 @@ const String _defaultFakeNamespace = 'dev.flutter.foo'; void main() { late CommandRunner runner; late Directory packagesDir; + const String javaIncompatabilityIndicator = + 'build.gradle(.kts) must set an explicit Java compatibility version.'; setUp(() { final GitDir gitDir; @@ -46,6 +48,9 @@ void main() { bool useDeprecatedCompileSdkVersion = false, bool usePropertyAssignment = true, String compileSdk = '36', + bool includeKotlinOptions = true, + bool commentKotlinOptions = false, + bool useDeprecatedJvmTarget = false, }) { final File buildGradle = package .platformDirectory(FlutterPlatform.android) @@ -69,11 +74,17 @@ java { '''; final String sourceCompat = - '${commentSourceLanguage ? '// ' : ''}sourceCompatibility = JavaVersion.VERSION_11'; + '${commentSourceLanguage ? '// ' : ''}sourceCompatibility = JavaVersion.VERSION_17'; final String targetCompat = - '${commentSourceLanguage ? '// ' : ''}targetCompatibility = JavaVersion.VERSION_11'; + '${commentSourceLanguage ? '// ' : ''}targetCompatibility = JavaVersion.VERSION_17'; final String namespace = " ${commentNamespace ? '// ' : ''}namespace = '$_defaultFakeNamespace'"; + final String jvmTarget = + useDeprecatedJvmTarget ? '17' : 'JavaVersion.VERSION_17.toString()'; + final String kotlinConfig = ''' + ${commentKotlinOptions ? '//' : ''}kotlinOptions { + ${commentKotlinOptions ? '//' : ''}jvmTarget = $jvmTarget + ${commentKotlinOptions ? '//' : ''}}'''; buildGradle.writeAsStringSync(''' group 'dev.flutter.plugins.fake' @@ -101,6 +112,7 @@ ${warningsConfigured ? warningConfig : ''} ${includeSourceCompat ? sourceCompat : ''} ${includeTargetCompat ? targetCompat : ''} } + ${includeKotlinOptions ? kotlinConfig : ''} testOptions { unitTests.includeAndroidResources = true } @@ -351,8 +363,7 @@ dependencies { expect( output, containsAllInOrder([ - contains( - 'build.gradle must set an explicit Java compatibility version.'), + contains(javaIncompatabilityIndicator), ]), ); }); @@ -375,8 +386,7 @@ dependencies { expect( output, containsAllInOrder([ - contains( - 'build.gradle must set an explicit Java compatibility version.'), + contains(javaIncompatabilityIndicator), ]), ); }); @@ -457,8 +467,7 @@ dependencies { expect( output, containsAllInOrder([ - contains( - 'build.gradle must set an explicit Java compatibility version.'), + contains(javaIncompatabilityIndicator), ]), ); }); @@ -480,8 +489,7 @@ dependencies { expect( output, containsAllInOrder([ - contains( - 'build.gradle must set an explicit Java compatibility version.'), + contains(javaIncompatabilityIndicator), ]), ); }); @@ -1162,4 +1170,96 @@ dependencies { ); }); }); + + group('kotlinOptions check', () { + test('passes when kotlin options are specified', () async { + final RepositoryPackage package = + createFakePlugin('a_plugin', packagesDir, examples: []); + writeFakePluginBuildGradle( + package, + includeLanguageVersion: true, + // ignore: avoid_redundant_argument_values ensure codepath is tested if defaults change. + includeKotlinOptions: true, + ); + writeFakeManifest(package); + + final List output = + await runCapturingPrint(runner, ['gradle-check']); + + expect( + output, + containsAllInOrder([ + contains('Validating android/build.gradle'), + ]), + ); + }); + + test('passes when kotlin options are not specified', () async { + final RepositoryPackage package = + createFakePlugin('a_plugin', packagesDir, examples: []); + writeFakePluginBuildGradle( + package, + includeLanguageVersion: true, + includeKotlinOptions: false, + ); + writeFakeManifest(package); + + final List output = + await runCapturingPrint(runner, ['gradle-check']); + + expect( + output, + containsAllInOrder([ + contains('Validating android/build.gradle'), + ]), + ); + }); + + test('passes when kotlin options commented out', () async { + final RepositoryPackage package = + createFakePlugin('a_plugin', packagesDir, examples: []); + writeFakePluginBuildGradle( + package, + includeLanguageVersion: true, + commentKotlinOptions: true, + ); + writeFakeManifest(package); + + final List output = + await runCapturingPrint(runner, ['gradle-check']); + + expect( + output, + containsAllInOrder([ + contains('Validating android/build.gradle'), + ]), + ); + }); + + test('fails when kotlin options uses string jvm version', () async { + final RepositoryPackage package = + createFakePlugin('a_plugin', packagesDir, examples: []); + writeFakePluginBuildGradle( + package, + includeLanguageVersion: true, + useDeprecatedJvmTarget: true, + ); + writeFakeManifest(package); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['gradle-check'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains( + 'build.gradle(.kts) sets jvmTarget then it must use JavaVersion syntax'), + ]), + ); + }); + }); } diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index a6e42f55cbf..38bc338c565 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.3.0 + +* Updates Java compatibility version to 17. +* If required, Updates minimum supported SDK version to Flutter 3.35/Dart 3.9. + ## 2.2.1 * Fixes message buffer access in SvgAssetLoader. diff --git a/third_party/packages/flutter_svg/README.md b/third_party/packages/flutter_svg/README.md index 15395077e6b..35400adefbf 100644 --- a/third_party/packages/flutter_svg/README.md +++ b/third_party/packages/flutter_svg/README.md @@ -98,11 +98,10 @@ final Widget svg = SvgPicture.asset(assetName); final Widget networkSvg = SvgPicture.network( 'https://site-that-takes-a-while.com/image.svg', semanticsLabel: 'A shark?!', - placeholderBuilder: - (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator(), - ), + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), ); ``` diff --git a/third_party/packages/flutter_svg/example/android/app/build.gradle b/third_party/packages/flutter_svg/example/android/app/build.gradle index 87f76b468c9..c553403648a 100644 --- a/third_party/packages/flutter_svg/example/android/app/build.gradle +++ b/third_party/packages/flutter_svg/example/android/app/build.gradle @@ -32,7 +32,7 @@ android { } kotlinOptions { - jvmTarget = '11' + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { diff --git a/third_party/packages/flutter_svg/example/lib/grid.dart b/third_party/packages/flutter_svg/example/lib/grid.dart index afaf6d4d879..e1aa81d9b0c 100644 --- a/third_party/packages/flutter_svg/example/lib/grid.dart +++ b/third_party/packages/flutter_svg/example/lib/grid.dart @@ -110,11 +110,10 @@ class _MyHomePageState extends State<_MyHomePage> { _painters.add( SvgPicture.network( uriName, - placeholderBuilder: - (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator(), - ), + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), ), ); } diff --git a/third_party/packages/flutter_svg/example/lib/readme_excerpts.dart b/third_party/packages/flutter_svg/example/lib/readme_excerpts.dart index eaca7ab8788..28d76f4845d 100644 --- a/third_party/packages/flutter_svg/example/lib/readme_excerpts.dart +++ b/third_party/packages/flutter_svg/example/lib/readme_excerpts.dart @@ -58,11 +58,10 @@ Widget loadNetworkAssetWithPlaceholder() { final Widget networkSvg = SvgPicture.network( 'https://site-that-takes-a-while.com/image.svg', semanticsLabel: 'A shark?!', - placeholderBuilder: - (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator(), - ), + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), ); // #enddocregion AssetWithPlaceholder return networkSvg; diff --git a/third_party/packages/flutter_svg/example/pubspec.yaml b/third_party/packages/flutter_svg/example/pubspec.yaml index ba5d03c85f0..ea17999d65a 100644 --- a/third_party/packages/flutter_svg/example/pubspec.yaml +++ b/third_party/packages/flutter_svg/example/pubspec.yaml @@ -3,8 +3,8 @@ description: An SVG samnple app. publish_to: none environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index 9c6ee191795..f7387471c61 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -162,10 +162,9 @@ abstract class SvgLoader extends BytesLoader { .encodeSvg( xml: provideSvg(message), theme: theme.toVgTheme(), - colorMapper: - colorMapper == null - ? null - : _DelegateVgColorMapper(colorMapper!), + colorMapper: colorMapper == null + ? null + : _DelegateVgColorMapper(colorMapper!), debugName: 'Svg loader', enableClippingOptimizer: false, enableMaskingOptimizer: false, diff --git a/third_party/packages/flutter_svg/lib/src/utilities/compute.dart b/third_party/packages/flutter_svg/lib/src/utilities/compute.dart index 67bd78d0b41..b701bc116ba 100644 --- a/third_party/packages/flutter_svg/lib/src/utilities/compute.dart +++ b/third_party/packages/flutter_svg/lib/src/utilities/compute.dart @@ -21,5 +21,5 @@ Future _testCompute( /// A compute implementation that does not spawn isolates in tests. const foundation.ComputeImpl compute = (foundation.kDebugMode || foundation.kIsWeb) - ? _testCompute - : foundation.compute; + ? _testCompute + : foundation.compute; diff --git a/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart b/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart index 5cad4594c6f..23e2b406124 100644 --- a/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart +++ b/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart @@ -10,14 +10,13 @@ double? parseDouble(String? rawDouble, {bool tryParse = false}) { return null; } - rawDouble = - rawDouble - .replaceFirst('rem', '') - .replaceFirst('em', '') - .replaceFirst('ex', '') - .replaceFirst('px', '') - .replaceFirst('pt', '') - .trim(); + rawDouble = rawDouble + .replaceFirst('rem', '') + .replaceFirst('em', '') + .replaceFirst('ex', '') + .replaceFirst('px', '') + .replaceFirst('pt', '') + .trim(); if (tryParse) { return double.tryParse(rawDouble); diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index 0e61acfe7d1..1aafcd51d79 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -453,8 +453,8 @@ class SvgPicture extends StatelessWidget { /// The default placeholder for a SVG that may take time to parse or /// retrieve, e.g. from a network location. - static WidgetBuilder defaultPlaceholderBuilder = - (BuildContext ctx) => const LimitedBox(); + static WidgetBuilder defaultPlaceholderBuilder = (BuildContext ctx) => + const LimitedBox(); /// If specified, the width to use for the SVG. If unspecified, the SVG /// will take the width of its parent. diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index 152ee9137ea..ab9c7470542 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,11 +2,11 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22 -version: 2.2.1 +version: 2.3.0 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" dependencies: flutter: diff --git a/third_party/packages/flutter_svg/test/cache_test.dart b/third_party/packages/flutter_svg/test/cache_test.dart index 8669633aa9c..30e9f6cacfd 100644 --- a/third_party/packages/flutter_svg/test/cache_test.dart +++ b/third_party/packages/flutter_svg/test/cache_test.dart @@ -32,12 +32,12 @@ void main() { test('LRU', () async { final Cache cache = Cache(); cache.maximumSize = 2; - final Completer completerA = - Completer()..complete(ByteData(1)); - final Completer completerB = - Completer()..complete(ByteData(2)); - final Completer completerC = - Completer()..complete(ByteData(3)); + final Completer completerA = Completer() + ..complete(ByteData(1)); + final Completer completerB = Completer() + ..complete(ByteData(2)); + final Completer completerC = Completer() + ..complete(ByteData(3)); expect(cache.count, 0); diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index 9cb5e1bba97..bc2d3fa2e59 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -941,7 +941,8 @@ void main() { // is used on each iteration. for (final String key in images.keys) { final String image = images[key]!; - final String svgStr = ''' + final String svgStr = + ''' @@ -990,16 +991,13 @@ void main() { data: mediaQueryData, child: SvgPicture.string( '', - errorBuilder: ( - BuildContext context, - Object error, - StackTrace stackTrace, - ) { - return const Directionality( - textDirection: TextDirection.ltr, - child: Text('image failed'), - ); - }, + errorBuilder: + (BuildContext context, Object error, StackTrace stackTrace) { + return const Directionality( + textDirection: TextDirection.ltr, + child: Text('image failed'), + ); + }, ), ), ); @@ -1016,16 +1014,13 @@ void main() { data: mediaQueryData, child: SvgPicture.memory( Uint8List.fromList(utf8.encode('')), - errorBuilder: ( - BuildContext context, - Object error, - StackTrace stackTrace, - ) { - return const Directionality( - textDirection: TextDirection.ltr, - child: Text('image failed'), - ); - }, + errorBuilder: + (BuildContext context, Object error, StackTrace stackTrace) { + return const Directionality( + textDirection: TextDirection.ltr, + child: Text('image failed'), + ); + }, ), ), ); @@ -1042,16 +1037,13 @@ void main() { data: mediaQueryData, child: SvgPicture.asset( '/wrong path', - errorBuilder: ( - BuildContext context, - Object error, - StackTrace stackTrace, - ) { - return const Directionality( - textDirection: TextDirection.ltr, - child: Text('image failed'), - ); - }, + errorBuilder: + (BuildContext context, Object error, StackTrace stackTrace) { + return const Directionality( + textDirection: TextDirection.ltr, + child: Text('image failed'), + ); + }, ), ), ); @@ -1066,16 +1058,13 @@ void main() { data: mediaQueryData, child: SvgPicture.file( File('nosuchfile'), - errorBuilder: ( - BuildContext context, - Object error, - StackTrace stackTrace, - ) { - return const Directionality( - textDirection: TextDirection.ltr, - child: Text('image failed'), - ); - }, + errorBuilder: + (BuildContext context, Object error, StackTrace stackTrace) { + return const Directionality( + textDirection: TextDirection.ltr, + child: Text('image failed'), + ); + }, ), ), );