diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index b4f32dc31ed..cffa4b727e8 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,7 @@ +## 16.0.1 + +- Adds `TypedRelativeGoRoute` + ## 16.0.0 - **BREAKING CHANGE** diff --git a/packages/go_router/lib/src/route_data.dart b/packages/go_router/lib/src/route_data.dart index 24afed52740..8c6ec6adc30 100644 --- a/packages/go_router/lib/src/route_data.dart +++ b/packages/go_router/lib/src/route_data.dart @@ -133,30 +133,6 @@ abstract class GoRouteData extends RouteData { static final Expando _stateObjectExpando = Expando( 'GoRouteState to GoRouteData expando', ); - - /// The location of this route. - String get location => throw _shouldBeGeneratedError; - - /// Navigate to the route. - void go(BuildContext context) => throw _shouldBeGeneratedError; - - /// Push the route onto the page stack. - Future push(BuildContext context) => throw _shouldBeGeneratedError; - - /// Replaces the top-most page of the page stack with the route. - void pushReplacement(BuildContext context) => throw _shouldBeGeneratedError; - - /// Replaces the top-most page of the page stack with the route but treats - /// it as the same page. - /// - /// The page key will be reused. This will preserve the state and not run any - /// page animation. - /// - void replace(BuildContext context) => throw _shouldBeGeneratedError; - - static UnimplementedError get _shouldBeGeneratedError => UnimplementedError( - 'Should be generated using [Type-safe routing](https://pub.dev/documentation/go_router/latest/topics/Type-safe%20routes-topic.html).', - ); } /// A class to represent a [ShellRoute] in @@ -430,6 +406,40 @@ class TypedGoRoute extends TypedRoute { final bool caseSensitive; } +/// A superclass for each typed go route descendant +@Target({TargetKind.library, TargetKind.classType}) +class TypedRelativeGoRoute extends TypedRoute { + /// Default const constructor + const TypedRelativeGoRoute({ + required this.path, + this.routes = const >[], + this.caseSensitive = true, + }); + + /// The relative path that corresponds to this route. + /// + /// See [GoRoute.path]. + /// + /// + final String path; + + /// Child route definitions. + /// + /// See [RouteBase.routes]. + final List> routes; + + /// Determines whether the route matching is case sensitive. + /// + /// When `true`, the path must match the specified case. For example, + /// a route with `path: '/family/:fid'` will not match `/FaMiLy/f2`. + /// + /// When `false`, the path matching is case insensitive. The route + /// with `path: '/family/:fid'` will match `/FaMiLy/f2`. + /// + /// Defaults to `true`. + final bool caseSensitive; +} + /// A superclass for each typed shell route descendant @Target({TargetKind.library, TargetKind.classType}) class TypedShellRoute extends TypedRoute { diff --git a/packages/go_router/test/route_data_test.dart b/packages/go_router/test/route_data_test.dart index 218caef690d..bb721c9ad0a 100644 --- a/packages/go_router/test/route_data_test.dart +++ b/packages/go_router/test/route_data_test.dart @@ -280,76 +280,6 @@ void main() { expect(routeWithDefaultCaseSensitivity.caseSensitive, false); }, ); - - testWidgets( - 'It should throw beacuase there is no code generated', - (WidgetTester tester) async { - final List errors = []; - - FlutterError.onError = - (FlutterErrorDetails details) => errors.add(details); - - const String errorText = 'Should be generated'; - - Widget buildWidget(void Function(BuildContext) onTap) { - return MaterialApp( - home: Builder( - builder: (BuildContext context) => GestureDetector( - child: const Text('Tap'), - onTap: () => onTap(context), - ), - ), - ); - } - - final Widget pushThrower = buildWidget((BuildContext context) { - const _GoRouteDataBuild().push(context); - }); - await tester.pumpWidget(pushThrower); - await tester.tap(find.text('Tap')); - - expect(errors.first.exception, isA()); - expect(errors.first.exception.toString(), contains(errorText)); - - errors.clear(); - - final Widget goThrower = buildWidget((BuildContext context) { - const _GoRouteDataBuild().go(context); - }); - await tester.pumpWidget(goThrower); - await tester.tap(find.text('Tap')); - - expect(errors.first.exception, isA()); - expect(errors.first.exception.toString(), contains(errorText)); - - errors.clear(); - - final Widget pushReplacementThrower = - buildWidget((BuildContext context) { - const _GoRouteDataBuild().pushReplacement(context); - }); - await tester.pumpWidget(pushReplacementThrower); - await tester.tap(find.text('Tap')); - - expect(errors.first.exception, isA()); - expect(errors.first.exception.toString(), contains(errorText)); - - errors.clear(); - - final Widget replaceThrower = buildWidget((BuildContext context) { - const _GoRouteDataBuild().pushReplacement(context); - }); - await tester.pumpWidget(replaceThrower); - await tester.tap(find.text('Tap')); - - expect(errors.first.exception, isA()); - expect(errors.first.exception.toString(), contains(errorText)); - - errors.clear(); - - FlutterError.onError = FlutterError.dumpErrorToConsole; - }, - ); }); group('ShellRouteData', () { diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md index b9ef60077e8..723beabd902 100644 --- a/packages/go_router_builder/CHANGELOG.md +++ b/packages/go_router_builder/CHANGELOG.md @@ -2,6 +2,10 @@ - Restricts `build` to versions less than 2.5.0. +## 3.0.2 + +- Adds `TypedRelativeGoRoute` annotation which supports relative routes. + ## 3.0.1 - Updates README.md to use the mixin `with _$RouteName`. diff --git a/packages/go_router_builder/example/lib/all_types.g.dart b/packages/go_router_builder/example/lib/all_types.g.dart index 6af36b14ee6..4086fc1db1b 100644 --- a/packages/go_router_builder/example/lib/all_types.g.dart +++ b/packages/go_router_builder/example/lib/all_types.g.dart @@ -75,22 +75,17 @@ mixin _$AllTypesBaseRoute on GoRouteData { static AllTypesBaseRoute _fromState(GoRouterState state) => const AllTypesBaseRoute(); - @override String get location => GoRouteData.$location( '/', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -104,7 +99,6 @@ mixin _$BigIntRoute on GoRouteData { BigIntRoute get _self => this as BigIntRoute; - @override String get location => GoRouteData.$location( '/big-int-route/${Uri.encodeComponent(_self.requiredBigIntField.toString())}', queryParams: { @@ -113,17 +107,13 @@ mixin _$BigIntRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -142,7 +132,6 @@ mixin _$BoolRoute on GoRouteData { BoolRoute get _self => this as BoolRoute; - @override String get location => GoRouteData.$location( '/bool-route/${Uri.encodeComponent(_self.requiredBoolField.toString())}', queryParams: { @@ -154,17 +143,13 @@ mixin _$BoolRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -178,7 +163,6 @@ mixin _$DateTimeRoute on GoRouteData { DateTimeRoute get _self => this as DateTimeRoute; - @override String get location => GoRouteData.$location( '/date-time-route/${Uri.encodeComponent(_self.requiredDateTimeField.toString())}', queryParams: { @@ -187,17 +171,13 @@ mixin _$DateTimeRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -216,7 +196,6 @@ mixin _$DoubleRoute on GoRouteData { DoubleRoute get _self => this as DoubleRoute; - @override String get location => GoRouteData.$location( '/double-route/${Uri.encodeComponent(_self.requiredDoubleField.toString())}', queryParams: { @@ -228,17 +207,13 @@ mixin _$DoubleRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -256,7 +231,6 @@ mixin _$IntRoute on GoRouteData { IntRoute get _self => this as IntRoute; - @override String get location => GoRouteData.$location( '/int-route/${Uri.encodeComponent(_self.requiredIntField.toString())}', queryParams: { @@ -267,17 +241,13 @@ mixin _$IntRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -295,7 +265,6 @@ mixin _$NumRoute on GoRouteData { NumRoute get _self => this as NumRoute; - @override String get location => GoRouteData.$location( '/num-route/${Uri.encodeComponent(_self.requiredNumField.toString())}', queryParams: { @@ -306,17 +275,13 @@ mixin _$NumRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -335,7 +300,6 @@ mixin _$EnumRoute on GoRouteData { EnumRoute get _self => this as EnumRoute; - @override String get location => GoRouteData.$location( '/enum-route/${Uri.encodeComponent(_$PersonDetailsEnumMap[_self.requiredEnumField]!)}', queryParams: { @@ -347,17 +311,13 @@ mixin _$EnumRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -382,7 +342,6 @@ mixin _$EnhancedEnumRoute on GoRouteData { EnhancedEnumRoute get _self => this as EnhancedEnumRoute; - @override String get location => GoRouteData.$location( '/enhanced-enum-route/${Uri.encodeComponent(_$SportDetailsEnumMap[_self.requiredEnumField]!)}', queryParams: { @@ -394,17 +353,13 @@ mixin _$EnhancedEnumRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -426,7 +381,6 @@ mixin _$StringRoute on GoRouteData { StringRoute get _self => this as StringRoute; - @override String get location => GoRouteData.$location( '/string-route/${Uri.encodeComponent(_self.requiredStringField)}', queryParams: { @@ -437,17 +391,13 @@ mixin _$StringRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -460,7 +410,6 @@ mixin _$UriRoute on GoRouteData { UriRoute get _self => this as UriRoute; - @override String get location => GoRouteData.$location( '/uri-route/${Uri.encodeComponent(_self.requiredUriField.toString())}', queryParams: { @@ -468,17 +417,13 @@ mixin _$UriRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -564,7 +509,6 @@ mixin _$IterableRoute on GoRouteData { IterableRoute get _self => this as IterableRoute; - @override String get location => GoRouteData.$location( '/iterable-route', queryParams: { @@ -629,17 +573,13 @@ mixin _$IterableRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -732,7 +672,6 @@ mixin _$IterableRouteWithDefaultValues on GoRouteData { IterableRouteWithDefaultValues get _self => this as IterableRouteWithDefaultValues; - @override String get location => GoRouteData.$location( '/iterable-route-with-default-values', queryParams: { @@ -792,17 +731,13 @@ mixin _$IterableRouteWithDefaultValues on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/case_sensitive_example.g.dart b/packages/go_router_builder/example/lib/case_sensitive_example.g.dart index 3c6a5b84e31..0144a91d8ae 100644 --- a/packages/go_router_builder/example/lib/case_sensitive_example.g.dart +++ b/packages/go_router_builder/example/lib/case_sensitive_example.g.dart @@ -22,22 +22,17 @@ mixin _$CaseSensitiveRoute on GoRouteData { static CaseSensitiveRoute _fromState(GoRouterState state) => const CaseSensitiveRoute(); - @override String get location => GoRouteData.$location( '/case-sensitive', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -51,21 +46,16 @@ mixin _$NotCaseSensitiveRoute on GoRouteData { static NotCaseSensitiveRoute _fromState(GoRouterState state) => const NotCaseSensitiveRoute(); - @override String get location => GoRouteData.$location( '/not-case-sensitive', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/extra_example.g.dart b/packages/go_router_builder/example/lib/extra_example.g.dart index 1161326b103..9a812562eb9 100644 --- a/packages/go_router_builder/example/lib/extra_example.g.dart +++ b/packages/go_router_builder/example/lib/extra_example.g.dart @@ -27,23 +27,18 @@ mixin _$RequiredExtraRoute on GoRouteData { RequiredExtraRoute get _self => this as RequiredExtraRoute; - @override String get location => GoRouteData.$location( '/requiredExtra', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } @@ -61,23 +56,18 @@ mixin _$OptionalExtraRoute on GoRouteData { OptionalExtraRoute get _self => this as OptionalExtraRoute; - @override String get location => GoRouteData.$location( '/optionalExtra', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } @@ -90,21 +80,16 @@ RouteBase get $splashRoute => GoRouteData.$route( mixin _$SplashRoute on GoRouteData { static SplashRoute _fromState(GoRouterState state) => const SplashRoute(); - @override String get location => GoRouteData.$location( '/splash', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/go_relative.dart b/packages/go_router_builder/example/lib/go_relative.dart new file mode 100644 index 00000000000..a431245fafe --- /dev/null +++ b/packages/go_router_builder/example/lib/go_relative.dart @@ -0,0 +1,198 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs, unreachable_from_main + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +part 'go_relative.g.dart'; + +void main() => runApp(const MyApp()); + +/// The main app. +class MyApp extends StatelessWidget { + /// Constructs a [MyApp] + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + routerConfig: _router, + ); + } +} + +/// The route configuration. +final GoRouter _router = GoRouter( + routes: $appRoutes, +); +const TypedRelativeGoRoute detailRoute = + TypedRelativeGoRoute( + path: 'details/:detailId', + routes: >[ + TypedRelativeGoRoute(path: 'settings/:settingId'), + ], +); + +@TypedGoRoute( + path: '/', + routes: >[ + TypedGoRoute( + path: '/dashboard', + routes: >[detailRoute], + ), + detailRoute, + ], +) +class HomeRoute extends GoRouteData with _$HomeRoute { + @override + Widget build(BuildContext context, GoRouterState state) { + return const HomeScreen(); + } +} + +class DashboardRoute extends GoRouteData with _$DashboardRoute { + @override + Widget build(BuildContext context, GoRouterState state) { + return const DashboardScreen(); + } +} + +class DetailsRoute extends GoRouteData with _$DetailsRoute { + const DetailsRoute({required this.detailId}); + final String detailId; + + @override + Widget build(BuildContext context, GoRouterState state) { + return DetailsScreen(id: detailId); + } +} + +class SettingsRoute extends GoRouteData with _$SettingsRoute { + const SettingsRoute({ + required this.settingId, + }); + final String settingId; + + @override + Widget build(BuildContext context, GoRouterState state) { + return SettingsScreen(id: settingId); + } +} + +/// The home screen +class HomeScreen extends StatelessWidget { + /// Constructs a [HomeScreen] + const HomeScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Home Screen')), + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + const DetailsRoute(detailId: 'DetailsId').goRelative(context); + }, + child: const Text('Go to the Details screen'), + ), + ElevatedButton( + onPressed: () { + DashboardRoute().go(context); + }, + child: const Text('Go to the Dashboard screen'), + ), + ], + ), + ); + } +} + +/// The home screen +class DashboardScreen extends StatelessWidget { + /// Constructs a [DashboardScreen] + const DashboardScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Dashboard Screen')), + body: Column( + children: [ + ElevatedButton( + onPressed: () { + const DetailsRoute(detailId: 'DetailsId').goRelative(context); + }, + child: const Text('Go to the Details screen'), + ), + ElevatedButton( + onPressed: () => context.pop(), + child: const Text('Go back'), + ), + ], + ), + ); + } +} + +/// The details screen +class DetailsScreen extends StatelessWidget { + /// Constructs a [DetailsScreen] + const DetailsScreen({ + super.key, + required this.id, + }); + + final String id; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Details Screen $id')), + body: Center( + child: Column( + children: [ + ElevatedButton( + onPressed: () => context.pop(), + child: const Text('Go back'), + ), + ElevatedButton( + onPressed: () => const SettingsRoute( + settingId: 'SettingsId', + ).goRelative(context), + child: const Text('Go to the Settings screen'), + ), + ], + ), + ), + ); + } +} + +/// The details screen +class SettingsScreen extends StatelessWidget { + /// Constructs a [SettingsScreen] + const SettingsScreen({ + super.key, + required this.id, + }); + + final String id; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Settings Screen $id')), + body: Center( + child: TextButton( + onPressed: () => context.pop(), + child: const Text('Go back'), + ), + ), + ); + } +} diff --git a/packages/go_router_builder/example/lib/go_relative.g.dart b/packages/go_router_builder/example/lib/go_relative.g.dart new file mode 100644 index 00000000000..c88a2fe7ffb --- /dev/null +++ b/packages/go_router_builder/example/lib/go_relative.g.dart @@ -0,0 +1,130 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: always_specify_types, public_member_api_docs + +part of 'go_relative.dart'; + +// ************************************************************************** +// GoRouterGenerator +// ************************************************************************** + +List get $appRoutes => [ + $homeRoute, + ]; + +RouteBase get $homeRoute => GoRouteData.$route( + path: '/', + factory: _$HomeRoute._fromState, + routes: [ + GoRouteData.$route( + path: '/dashboard', + factory: _$DashboardRoute._fromState, + routes: [ + GoRouteData.$route( + path: 'details/:detailId', + factory: _$DetailsRoute._fromState, + routes: [ + GoRouteData.$route( + path: 'settings/:settingId', + factory: _$SettingsRoute._fromState, + ), + ], + ), + ], + ), + GoRouteData.$route( + path: 'details/:detailId', + factory: _$DetailsRoute._fromState, + routes: [ + GoRouteData.$route( + path: 'settings/:settingId', + factory: _$SettingsRoute._fromState, + ), + ], + ), + ], + ); + +mixin _$HomeRoute on GoRouteData { + static HomeRoute _fromState(GoRouterState state) => HomeRoute(); + + String get location => GoRouteData.$location( + '/', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} + +mixin _$DashboardRoute on GoRouteData { + static DashboardRoute _fromState(GoRouterState state) => DashboardRoute(); + + String get location => GoRouteData.$location( + '/dashboard', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} + +mixin _$DetailsRoute on GoRouteData { + static DetailsRoute _fromState(GoRouterState state) => DetailsRoute( + detailId: state.pathParameters['detailId']!, + ); + + DetailsRoute get _self => this as DetailsRoute; + + String get location => GoRouteData.$location( + 'details/${Uri.encodeComponent(_self.detailId)}', + ); + + String get relativeLocation => './$location'; + + void goRelative(BuildContext context) => context.go(relativeLocation); + + Future pushRelative(BuildContext context) => + context.push(relativeLocation); + + void pushReplacementRelative(BuildContext context) => + context.pushReplacement(relativeLocation); + + void replaceRelative(BuildContext context) => + context.replace(relativeLocation); +} + +mixin _$SettingsRoute on GoRouteData { + static SettingsRoute _fromState(GoRouterState state) => SettingsRoute( + settingId: state.pathParameters['settingId']!, + ); + + SettingsRoute get _self => this as SettingsRoute; + + String get location => GoRouteData.$location( + 'settings/${Uri.encodeComponent(_self.settingId)}', + ); + + String get relativeLocation => './$location'; + + void goRelative(BuildContext context) => context.go(relativeLocation); + + Future pushRelative(BuildContext context) => + context.push(relativeLocation); + + void pushReplacementRelative(BuildContext context) => + context.pushReplacement(relativeLocation); + + void replaceRelative(BuildContext context) => + context.replace(relativeLocation); +} diff --git a/packages/go_router_builder/example/lib/main.g.dart b/packages/go_router_builder/example/lib/main.g.dart index f631d241cc0..cc8a9fc9ca8 100644 --- a/packages/go_router_builder/example/lib/main.g.dart +++ b/packages/go_router_builder/example/lib/main.g.dart @@ -43,22 +43,17 @@ RouteBase get $homeRoute => GoRouteData.$route( mixin _$HomeRoute on GoRouteData { static HomeRoute _fromState(GoRouterState state) => const HomeRoute(); - @override String get location => GoRouteData.$location( '/', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -69,22 +64,17 @@ mixin _$FamilyRoute on GoRouteData { FamilyRoute get _self => this as FamilyRoute; - @override String get location => GoRouteData.$location( '/family/${Uri.encodeComponent(_self.fid)}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -96,22 +86,17 @@ mixin _$PersonRoute on GoRouteData { PersonRoute get _self => this as PersonRoute; - @override String get location => GoRouteData.$location( '/family/${Uri.encodeComponent(_self.fid)}/person/${Uri.encodeComponent(_self.pid.toString())}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -126,23 +111,18 @@ mixin _$PersonDetailsRoute on GoRouteData { PersonDetailsRoute get _self => this as PersonDetailsRoute; - @override String get location => GoRouteData.$location( '/family/${Uri.encodeComponent(_self.fid)}/person/${Uri.encodeComponent(_self.pid.toString())}/details/${Uri.encodeComponent(_$PersonDetailsEnumMap[_self.details]!)}', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } @@ -160,22 +140,17 @@ mixin _$FamilyCountRoute on GoRouteData { FamilyCountRoute get _self => this as FamilyCountRoute; - @override String get location => GoRouteData.$location( '/family-count/${Uri.encodeComponent(_self.count.toString())}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -196,7 +171,6 @@ mixin _$LoginRoute on GoRouteData { LoginRoute get _self => this as LoginRoute; - @override String get location => GoRouteData.$location( '/login', queryParams: { @@ -204,16 +178,12 @@ mixin _$LoginRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/on_exit_example.g.dart b/packages/go_router_builder/example/lib/on_exit_example.g.dart index 458ccc0371b..96adc67f02e 100644 --- a/packages/go_router_builder/example/lib/on_exit_example.g.dart +++ b/packages/go_router_builder/example/lib/on_exit_example.g.dart @@ -26,43 +26,33 @@ RouteBase get $homeRoute => GoRouteData.$route( mixin _$HomeRoute on GoRouteData { static HomeRoute _fromState(GoRouterState state) => const HomeRoute(); - @override String get location => GoRouteData.$location( '/', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } mixin _$SubRoute on GoRouteData { static SubRoute _fromState(GoRouterState state) => const SubRoute(); - @override String get location => GoRouteData.$location( '/sub-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/readme_excerpts.g.dart b/packages/go_router_builder/example/lib/readme_excerpts.g.dart index 6a6ff0c69b6..435b665571a 100644 --- a/packages/go_router_builder/example/lib/readme_excerpts.g.dart +++ b/packages/go_router_builder/example/lib/readme_excerpts.g.dart @@ -34,22 +34,17 @@ RouteBase get $homeRoute => GoRouteData.$route( mixin _$HomeRoute on GoRouteData { static HomeRoute _fromState(GoRouterState state) => const HomeRoute(); - @override String get location => GoRouteData.$location( '/', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -60,22 +55,17 @@ mixin _$FamilyRoute on GoRouteData { FamilyRoute get _self => this as FamilyRoute; - @override String get location => GoRouteData.$location( '/family/${Uri.encodeComponent(_self.fid ?? '')}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -91,7 +81,6 @@ mixin _$LoginRoute on GoRouteData { LoginRoute get _self => this as LoginRoute; - @override String get location => GoRouteData.$location( '/login', queryParams: { @@ -99,17 +88,13 @@ mixin _$LoginRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -126,7 +111,6 @@ mixin _$MyRoute on GoRouteData { MyRoute get _self => this as MyRoute; - @override String get location => GoRouteData.$location( '/my-route', queryParams: { @@ -135,17 +119,13 @@ mixin _$MyRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -162,23 +142,18 @@ mixin _$PersonRouteWithExtra on GoRouteData { PersonRouteWithExtra get _self => this as PersonRouteWithExtra; - @override String get location => GoRouteData.$location( '/person', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } @@ -198,7 +173,6 @@ mixin _$HotdogRouteWithEverything on GoRouteData { HotdogRouteWithEverything get _self => this as HotdogRouteWithEverything; - @override String get location => GoRouteData.$location( '/${Uri.encodeComponent(_self.ketchup.toString())}', queryParams: { @@ -206,18 +180,14 @@ mixin _$HotdogRouteWithEverything on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } @@ -247,7 +217,6 @@ mixin _$BooksRoute on GoRouteData { BooksRoute get _self => this as BooksRoute; - @override String get location => GoRouteData.$location( '/books', queryParams: { @@ -256,17 +225,13 @@ mixin _$BooksRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -299,22 +264,17 @@ mixin _$MyMaterialRouteWithKey on GoRouteData { static MyMaterialRouteWithKey _fromState(GoRouterState state) => const MyMaterialRouteWithKey(); - @override String get location => GoRouteData.$location( '/my-material-route-with-key', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -326,22 +286,17 @@ RouteBase get $fancyRoute => GoRouteData.$route( mixin _$FancyRoute on GoRouteData { static FancyRoute _fromState(GoRouterState state) => const FancyRoute(); - @override String get location => GoRouteData.$location( '/fancy', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -365,21 +320,16 @@ extension $MyShellRouteDataExtension on MyShellRouteData { mixin _$MyGoRouteData on GoRouteData { static MyGoRouteData _fromState(GoRouterState state) => const MyGoRouteData(); - @override String get location => GoRouteData.$location( 'my-go-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/shell_route_example.g.dart b/packages/go_router_builder/example/lib/shell_route_example.g.dart index 0b2e61ebee3..0c578ced16e 100644 --- a/packages/go_router_builder/example/lib/shell_route_example.g.dart +++ b/packages/go_router_builder/example/lib/shell_route_example.g.dart @@ -35,44 +35,34 @@ extension $MyShellRouteDataExtension on MyShellRouteData { mixin _$FooRouteData on GoRouteData { static FooRouteData _fromState(GoRouterState state) => const FooRouteData(); - @override String get location => GoRouteData.$location( '/foo', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } mixin _$BarRouteData on GoRouteData { static BarRouteData _fromState(GoRouterState state) => const BarRouteData(); - @override String get location => GoRouteData.$location( '/bar', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -84,21 +74,16 @@ RouteBase get $loginRoute => GoRouteData.$route( mixin _$LoginRoute on GoRouteData { static LoginRoute _fromState(GoRouterState state) => const LoginRoute(); - @override String get location => GoRouteData.$location( '/login', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/shell_route_with_keys_example.g.dart b/packages/go_router_builder/example/lib/shell_route_with_keys_example.g.dart index 759588b2d28..b29ef63d13b 100644 --- a/packages/go_router_builder/example/lib/shell_route_with_keys_example.g.dart +++ b/packages/go_router_builder/example/lib/shell_route_with_keys_example.g.dart @@ -42,22 +42,17 @@ extension $MyShellRouteDataExtension on MyShellRouteData { mixin _$HomeRouteData on GoRouteData { static HomeRouteData _fromState(GoRouterState state) => const HomeRouteData(); - @override String get location => GoRouteData.$location( '/home', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -65,22 +60,17 @@ mixin _$UsersRouteData on GoRouteData { static UsersRouteData _fromState(GoRouterState state) => const UsersRouteData(); - @override String get location => GoRouteData.$location( '/users', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -91,21 +81,16 @@ mixin _$UserRouteData on GoRouteData { UserRouteData get _self => this as UserRouteData; - @override String get location => GoRouteData.$location( '/users/${Uri.encodeComponent(_self.id.toString())}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/shell_route_with_observers_example.g.dart b/packages/go_router_builder/example/lib/shell_route_with_observers_example.g.dart index e510a5f3a80..c5e6afd6a1c 100644 --- a/packages/go_router_builder/example/lib/shell_route_with_observers_example.g.dart +++ b/packages/go_router_builder/example/lib/shell_route_with_observers_example.g.dart @@ -41,22 +41,17 @@ extension $MyShellRouteDataExtension on MyShellRouteData { mixin _$HomeRouteData on GoRouteData { static HomeRouteData _fromState(GoRouterState state) => const HomeRouteData(); - @override String get location => GoRouteData.$location( '/home', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -64,22 +59,17 @@ mixin _$UsersRouteData on GoRouteData { static UsersRouteData _fromState(GoRouterState state) => const UsersRouteData(); - @override String get location => GoRouteData.$location( '/users', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -90,21 +80,16 @@ mixin _$UserRouteData on GoRouteData { UserRouteData get _self => this as UserRouteData; - @override String get location => GoRouteData.$location( '/users/${Uri.encodeComponent(_self.id.toString())}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/simple_example.g.dart b/packages/go_router_builder/example/lib/simple_example.g.dart index 4ecd74e3cbf..02ccb6e1c23 100644 --- a/packages/go_router_builder/example/lib/simple_example.g.dart +++ b/packages/go_router_builder/example/lib/simple_example.g.dart @@ -27,22 +27,17 @@ RouteBase get $homeRoute => GoRouteData.$route( mixin _$HomeRoute on GoRouteData { static HomeRoute _fromState(GoRouterState state) => const HomeRoute(); - @override String get location => GoRouteData.$location( '/', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -53,21 +48,16 @@ mixin _$FamilyRoute on GoRouteData { FamilyRoute get _self => this as FamilyRoute; - @override String get location => GoRouteData.$location( '/family/${Uri.encodeComponent(_self.familyId)}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/stateful_shell_route_example.g.dart b/packages/go_router_builder/example/lib/stateful_shell_route_example.g.dart index d0eaa8ddf6a..d0a5ea2f26e 100644 --- a/packages/go_router_builder/example/lib/stateful_shell_route_example.g.dart +++ b/packages/go_router_builder/example/lib/stateful_shell_route_example.g.dart @@ -47,22 +47,17 @@ mixin _$DetailsARouteData on GoRouteData { static DetailsARouteData _fromState(GoRouterState state) => const DetailsARouteData(); - @override String get location => GoRouteData.$location( '/detailsA', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -70,21 +65,16 @@ mixin _$DetailsBRouteData on GoRouteData { static DetailsBRouteData _fromState(GoRouterState state) => const DetailsBRouteData(); - @override String get location => GoRouteData.$location( '/detailsB', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/lib/stateful_shell_route_initial_location_example.g.dart b/packages/go_router_builder/example/lib/stateful_shell_route_initial_location_example.g.dart index c7e63a1fc7f..7093db69b54 100644 --- a/packages/go_router_builder/example/lib/stateful_shell_route_initial_location_example.g.dart +++ b/packages/go_router_builder/example/lib/stateful_shell_route_initial_location_example.g.dart @@ -51,22 +51,17 @@ extension $MainShellRouteDataExtension on MainShellRouteData { mixin _$HomeRouteData on GoRouteData { static HomeRouteData _fromState(GoRouterState state) => const HomeRouteData(); - @override String get location => GoRouteData.$location( '/home', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -79,22 +74,17 @@ mixin _$NotificationsRouteData on GoRouteData { NotificationsRouteData get _self => this as NotificationsRouteData; - @override String get location => GoRouteData.$location( '/notifications/${Uri.encodeComponent(_$NotificationsPageSectionEnumMap[_self.section]!)}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -108,22 +98,17 @@ mixin _$OrdersRouteData on GoRouteData { static OrdersRouteData _fromState(GoRouterState state) => const OrdersRouteData(); - @override String get location => GoRouteData.$location( '/orders', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/example/pubspec.yaml b/packages/go_router_builder/example/pubspec.yaml index a98b4537a8e..6f7dab11e3a 100644 --- a/packages/go_router_builder/example/pubspec.yaml +++ b/packages/go_router_builder/example/pubspec.yaml @@ -21,5 +21,9 @@ dev_dependencies: path: .. test: ^1.17.0 +dependency_overrides: + go_router: + path: ../../go_router + flutter: uses-material-design: true diff --git a/packages/go_router_builder/example/test/go_relative_test.dart b/packages/go_router_builder/example/test/go_relative_test.dart new file mode 100644 index 00000000000..3efd323e8c2 --- /dev/null +++ b/packages/go_router_builder/example/test/go_relative_test.dart @@ -0,0 +1,55 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:go_router_builder_example/go_relative.dart' as example; + +void main() { + testWidgets('example works', (WidgetTester tester) async { + await tester.pumpWidget(const example.MyApp()); + expect(find.byType(example.HomeScreen), findsOneWidget); + + // From Home screen, go to Details screen + await tester.tap(find.text('Go to the Details screen')); + await tester.pumpAndSettle(); + expect(find.byType(example.DetailsScreen), findsOneWidget); + + await tester.tap(find.text('Go to the Settings screen')); + await tester.pumpAndSettle(); + expect(find.byType(example.SettingsScreen), findsOneWidget); + + await tester.tap(find.text('Go back')); + await tester.pumpAndSettle(); + expect(find.byType(example.DetailsScreen), findsOneWidget); + + await tester.tap(find.text('Go back')); + await tester.pumpAndSettle(); + expect(find.byType(example.HomeScreen), findsOneWidget); + + await tester.tap(find.text('Go to the Dashboard screen')); + await tester.pumpAndSettle(); + expect(find.byType(example.DashboardScreen), findsOneWidget); + + // From Dashboard screen, go to Details screen + await tester.tap(find.text('Go to the Details screen')); + await tester.pumpAndSettle(); + expect(find.byType(example.DetailsScreen), findsOneWidget); + + await tester.tap(find.text('Go to the Settings screen')); + await tester.pumpAndSettle(); + expect(find.byType(example.SettingsScreen), findsOneWidget); + + await tester.tap(find.text('Go back')); + await tester.pumpAndSettle(); + expect(find.byType(example.DetailsScreen), findsOneWidget); + + await tester.tap(find.text('Go back')); + await tester.pumpAndSettle(); + expect(find.byType(example.DashboardScreen), findsOneWidget); + + await tester.tap(find.text('Go back')); + await tester.pumpAndSettle(); + expect(find.byType(example.HomeScreen), findsOneWidget); + }); +} diff --git a/packages/go_router_builder/lib/src/go_router_generator.dart b/packages/go_router_builder/lib/src/go_router_generator.dart index 88803b29e5c..f28fa387918 100644 --- a/packages/go_router_builder/lib/src/go_router_generator.dart +++ b/packages/go_router_builder/lib/src/go_router_generator.dart @@ -16,6 +16,7 @@ const String _routeDataUrl = 'package:go_router/src/route_data.dart'; const Map _annotations = { 'TypedGoRoute': 'GoRouteData', + 'TypedRelativeGoRoute': 'GoRouteData', 'TypedShellRoute': 'ShellRouteData', 'TypedStatefulShellBranch': 'StatefulShellBranchData', 'TypedStatefulShellRoute': 'StatefulShellRouteData', diff --git a/packages/go_router_builder/lib/src/route_config.dart b/packages/go_router_builder/lib/src/route_config.dart index d95663d15ac..3f7aa762c3d 100644 --- a/packages/go_router_builder/lib/src/route_config.dart +++ b/packages/go_router_builder/lib/src/route_config.dart @@ -220,8 +220,10 @@ class GoRouteConfig extends RouteBaseConfig { RouteBaseConfig? config = this; while (config != null) { - if (config is GoRouteConfig) { - pathSegments.add(config.path); + if (config + case GoRouteConfig(:final String path) || + GoRelativeRouteConfig(:final String path)) { + pathSegments.add(path); } config = config.parent; } @@ -416,22 +418,17 @@ class GoRouteConfig extends RouteBaseConfig { mixin $_mixinName on GoRouteData { static $_className _fromState(GoRouterState state) $_fromStateConstructor $_castedSelf - @override String get location => GoRouteData.\$location($_locationArgs,$_locationQueryParams); - @override void go(BuildContext context) => context.go(location${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); - @override Future push(BuildContext context) => context.push(location${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); - @override void replace(BuildContext context) => context.replace(location${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); } @@ -479,6 +476,271 @@ mixin $_mixinName on GoRouteData { String get dataConvertionFunctionName => r'$route'; } +/// The configuration to generate class declarations for a GoRouteData. +class GoRelativeRouteConfig extends RouteBaseConfig { + GoRelativeRouteConfig._({ + required this.path, + required this.caseSensitive, + required this.parentNavigatorKey, + required super.routeDataClass, + required super.parent, + }) : super._(); + + /// The path of the GoRoute to be created by this configuration. + final String path; + + /// The case sensitivity of the GoRelativeRoute to be created by this configuration. + final bool caseSensitive; + + /// The parent navigator key. + final String? parentNavigatorKey; + + late final Set _pathParams = pathParametersFromPattern(path); + + // construct path bits using parent bits + // if there are any queryParam objects, add in the `queryParam` bits + String get _locationArgs { + final Map pathParameters = Map.fromEntries( + _pathParams.map((String pathParameter) { + // Enum types are encoded using a map, so we need a nullability check + // here to ensure it matches Uri.encodeComponent nullability + final DartType? type = _field(pathParameter)?.returnType; + + final StringBuffer valueBuffer = StringBuffer(); + + valueBuffer.write(r'${Uri.encodeComponent('); + valueBuffer.write(_encodeFor(pathParameter)); + + if (type?.isEnum ?? false) { + valueBuffer.write('!'); + } else if (type?.isNullableType ?? false) { + valueBuffer.write("?? ''"); + } + + valueBuffer.write(')}'); + + return MapEntry(pathParameter, valueBuffer.toString()); + }), + ); + final String location = patternToPath(path, pathParameters); + return "'$location'"; + } + + ParameterElement? get _extraParam => _ctor.parameters + .singleWhereOrNull((ParameterElement element) => element.isExtraField); + + String get _fromStateConstructor { + final StringBuffer buffer = StringBuffer('=>'); + if (_ctor.isConst && + _ctorParams.isEmpty && + _ctorQueryParams.isEmpty && + _extraParam == null) { + buffer.writeln('const '); + } + + buffer.writeln('$_className('); + for (final ParameterElement param in [ + ..._ctorParams, + ..._ctorQueryParams, + if (_extraParam != null) _extraParam!, + ]) { + buffer.write(_decodeFor(param)); + } + buffer.writeln(');'); + + return buffer.toString(); + } + + String get _castedSelf { + if (_pathParams.isEmpty && + _ctorQueryParams.isEmpty && + _extraParam == null) { + return ''; + } + + return '\n$_className get $selfFieldName => this as $_className;\n'; + } + + String _decodeFor(ParameterElement element) { + if (element.isRequired) { + if (element.type.nullabilitySuffix == NullabilitySuffix.question && + _pathParams.contains(element.name)) { + throw InvalidGenerationSourceError( + 'Required parameters in the path cannot be nullable.', + element: element, + ); + } + } + final String fromStateExpression = decodeParameter(element, _pathParams); + + if (element.isPositional) { + return '$fromStateExpression,'; + } + + if (element.isNamed) { + return '${element.name}: $fromStateExpression,'; + } + + throw InvalidGenerationSourceError( + '$likelyIssueMessage (param not named or positional)', + element: element, + ); + } + + String _encodeFor(String fieldName) { + final PropertyAccessorElement? field = _field(fieldName); + if (field == null) { + throw InvalidGenerationSourceError( + 'Could not find a field for the path parameter "$fieldName".', + element: routeDataClass, + ); + } + + return encodeField(field); + } + + String get _locationQueryParams { + if (_ctorQueryParams.isEmpty) { + return ''; + } + + final StringBuffer buffer = StringBuffer('queryParams: {\n'); + + for (final ParameterElement param in _ctorQueryParams) { + final String parameterName = param.name; + + final List conditions = []; + if (param.hasDefaultValue) { + if (param.type.isNullableType) { + throw NullableDefaultValueError(param); + } + conditions.add( + compareField(param, parameterName, param.defaultValueCode!), + ); + } else if (param.type.isNullableType) { + conditions.add('$selfFieldName.$parameterName != null'); + } + String line = ''; + if (conditions.isNotEmpty) { + line = 'if (${conditions.join(' && ')}) '; + } + line += '${escapeDartString(parameterName.kebab)}: ' + '${_encodeFor(parameterName)},'; + + buffer.writeln(line); + } + + buffer.writeln('},'); + + return buffer.toString(); + } + + late final List _ctorParams = + _ctor.parameters.where((ParameterElement element) { + if (_pathParams.contains(element.name)) { + return true; + } + return false; + }).toList(); + + late final List _ctorQueryParams = _ctor.parameters + .where((ParameterElement element) => + !_pathParams.contains(element.name) && !element.isExtraField) + .toList(); + + ConstructorElement get _ctor { + final ConstructorElement? ctor = routeDataClass.unnamedConstructor; + + if (ctor == null) { + throw InvalidGenerationSourceError( + 'Missing default constructor', + element: routeDataClass, + ); + } + return ctor; + } + + @override + Iterable classDeclarations() => [ + _mixinDefinition, + ..._enumDeclarations(), + ]; + + String get _mixinDefinition { + final bool hasMixin = getNodeDeclaration(routeDataClass) + ?.withClause + ?.mixinTypes + .any((NamedType e) => e.name2.toString() == _mixinName) ?? + false; + + if (!hasMixin) { + throw InvalidGenerationSourceError( + 'Missing mixin clause `with $_mixinName`', + element: routeDataClass, + ); + } + return ''' +mixin $_mixinName on GoRouteData { + static $_className _fromState(GoRouterState state) $_fromStateConstructor + $_castedSelf + String get location => GoRouteData.\$location($_locationArgs,$_locationQueryParams); + + String get relativeLocation => './\$location'; + + void goRelative(BuildContext context) => + context.go(relativeLocation${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); + + Future pushRelative(BuildContext context) => + context.push(relativeLocation${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); + + void pushReplacementRelative(BuildContext context) => + context.pushReplacement(relativeLocation${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); + + void replaceRelative(BuildContext context) => + context.replace(relativeLocation${_extraParam != null ? ', extra: $selfFieldName.$extraFieldName' : ''}); +} +'''; + } + + /// Returns code representing the constant maps that contain the `enum` to + /// [String] mapping for each referenced enum. + Iterable _enumDeclarations() { + final Set enumParamTypes = {}; + + for (final ParameterElement ctorParam in [ + ..._ctorParams, + ..._ctorQueryParams, + ]) { + DartType potentialEnumType = ctorParam.type; + if (potentialEnumType is ParameterizedType && + (ctorParam.type as ParameterizedType).typeArguments.isNotEmpty) { + potentialEnumType = + (ctorParam.type as ParameterizedType).typeArguments.first; + } + + if (potentialEnumType.isEnum) { + enumParamTypes.add(potentialEnumType as InterfaceType); + } + } + return enumParamTypes.map(_enumMapConst); + } + + @override + String get factorConstructorParameters => 'factory: $_mixinName._fromState,'; + + @override + String get routeConstructorParameters => ''' + path: ${escapeDartString(path)}, + ${parentNavigatorKey == null ? '' : 'parentNavigatorKey: $parentNavigatorKey,'} +'''; + + @override + String get routeDataClassName => 'GoRouteData'; + + @override + String get dataConvertionFunctionName => r'$route'; +} + /// Represents a `TypedGoRoute` annotation to the builder. abstract class RouteBaseConfig { RouteBaseConfig._({ @@ -611,6 +873,25 @@ abstract class RouteBaseConfig { parameterName: r'$parentNavigatorKey', ), ); + case 'TypedRelativeGoRoute': + final ConstantReader pathValue = reader.read('path'); + if (pathValue.isNull) { + throw InvalidGenerationSourceError( + 'Missing `path` value on annotation.', + element: element, + ); + } + final ConstantReader caseSensitiveValue = reader.read('caseSensitive'); + value = GoRelativeRouteConfig._( + path: pathValue.stringValue, + caseSensitive: caseSensitiveValue.boolValue, + routeDataClass: classElement, + parent: parent, + parentNavigatorKey: _generateParameterGetterCode( + classElement, + parameterName: r'$parentNavigatorKey', + ), + ); default: throw UnsupportedError('Unrecognized type $typeName'); } diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml index 7d7dde0c893..ce26cb65cc1 100644 --- a/packages/go_router_builder/pubspec.yaml +++ b/packages/go_router_builder/pubspec.yaml @@ -2,7 +2,7 @@ name: go_router_builder description: >- A builder that supports generated strongly-typed route helpers for package:go_router -version: 3.0.1 +version: 3.0.2 repository: https://github.com/flutter/packages/tree/main/packages/go_router_builder issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22 @@ -29,12 +29,16 @@ dev_dependencies: dart_style: '>=2.3.7 <4.0.0' flutter: sdk: flutter - go_router: ^15.1.0 + go_router: ^15.1.3 leak_tracker_flutter_testing: ">=3.0.0" package_config: ^2.1.1 pub_semver: ^2.1.5 test: ^1.20.0 +dependency_overrides: + go_router: + path: ../go_router + topics: - codegen - deep-linking diff --git a/packages/go_router_builder/test_inputs/case_sensitivity.dart.expect b/packages/go_router_builder/test_inputs/case_sensitivity.dart.expect index acbc044d5bf..bf577320bad 100644 --- a/packages/go_router_builder/test_inputs/case_sensitivity.dart.expect +++ b/packages/go_router_builder/test_inputs/case_sensitivity.dart.expect @@ -7,22 +7,17 @@ mixin _$CaseSensitiveRoute on GoRouteData { static CaseSensitiveRoute _fromState(GoRouterState state) => CaseSensitiveRoute(); - @override String get location => GoRouteData.$location( '/case-sensitive-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } @@ -36,21 +31,16 @@ mixin _$NotCaseSensitiveRoute on GoRouteData { static NotCaseSensitiveRoute _fromState(GoRouterState state) => NotCaseSensitiveRoute(); - @override String get location => GoRouteData.$location( '/not-case-sensitive-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/default_value.dart.expect b/packages/go_router_builder/test_inputs/default_value.dart.expect index 9302c4b2346..49468768b5e 100644 --- a/packages/go_router_builder/test_inputs/default_value.dart.expect +++ b/packages/go_router_builder/test_inputs/default_value.dart.expect @@ -12,7 +12,6 @@ mixin _$DefaultValueRoute on GoRouteData { DefaultValueRoute get _self => this as DefaultValueRoute; - @override String get location => GoRouteData.$location( '/default-value-route', queryParams: { @@ -20,17 +19,13 @@ mixin _$DefaultValueRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/enum_parameter.dart.expect b/packages/go_router_builder/test_inputs/enum_parameter.dart.expect index 341e1bab282..029203dfe4d 100644 --- a/packages/go_router_builder/test_inputs/enum_parameter.dart.expect +++ b/packages/go_router_builder/test_inputs/enum_parameter.dart.expect @@ -10,22 +10,17 @@ mixin _$EnumParam on GoRouteData { EnumParam get _self => this as EnumParam; - @override String get location => GoRouteData.$location( '/${Uri.encodeComponent(_$EnumTestEnumMap[_self.y]!)}', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/extra_value.dart.expect b/packages/go_router_builder/test_inputs/extra_value.dart.expect index 944b8a4b25c..d86f0587dad 100644 --- a/packages/go_router_builder/test_inputs/extra_value.dart.expect +++ b/packages/go_router_builder/test_inputs/extra_value.dart.expect @@ -13,7 +13,6 @@ mixin _$ExtraValueRoute on GoRouteData { ExtraValueRoute get _self => this as ExtraValueRoute; - @override String get location => GoRouteData.$location( '/default-value-route', queryParams: { @@ -21,18 +20,14 @@ mixin _$ExtraValueRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } diff --git a/packages/go_router_builder/test_inputs/go_relative.dart b/packages/go_router_builder/test_inputs/go_relative.dart new file mode 100644 index 00000000000..aaa53fee17e --- /dev/null +++ b/packages/go_router_builder/test_inputs/go_relative.dart @@ -0,0 +1,42 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:go_router/go_router.dart'; + +mixin _$Route1 {} +mixin _$Route2 {} +mixin _$RelativeRoute {} +mixin _$InnerRelativeRoute {} + +const TypedRelativeGoRoute relativeRoute = + TypedRelativeGoRoute( + path: 'relative-route', + routes: >[ + TypedRelativeGoRoute(path: 'inner-relative-route') + ], +); + +@TypedGoRoute( + path: 'route-1', + routes: >[relativeRoute], +) +class Route1 extends GoRouteData with _$Route1 { + const Route1(); +} + +@TypedGoRoute( + path: 'route-2', + routes: >[relativeRoute], +) +class Route2 extends GoRouteData with _$Route2 { + const Route2(); +} + +class RelativeRoute extends GoRouteData with _$RelativeRoute { + const RelativeRoute(); +} + +class InnerRelativeRoute extends GoRouteData with _$InnerRelativeRoute { + const InnerRelativeRoute(); +} diff --git a/packages/go_router_builder/test_inputs/go_relative.dart.expect b/packages/go_router_builder/test_inputs/go_relative.dart.expect new file mode 100644 index 00000000000..6d877058682 --- /dev/null +++ b/packages/go_router_builder/test_inputs/go_relative.dart.expect @@ -0,0 +1,110 @@ +RouteBase get $route1 => GoRouteData.$route( + path: 'route-1', + factory: _$Route1._fromState, + routes: [ + GoRouteData.$route( + path: 'relative-route', + factory: _$RelativeRoute._fromState, + routes: [ + GoRouteData.$route( + path: 'inner-relative-route', + factory: _$InnerRelativeRoute._fromState, + ), + ], + ), + ], + ); + +mixin _$Route1 on GoRouteData { + static Route1 _fromState(GoRouterState state) => const Route1(); + + String get location => GoRouteData.$location( + 'route-1', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} + +mixin _$RelativeRoute on GoRouteData { + static RelativeRoute _fromState(GoRouterState state) => const RelativeRoute(); + + String get location => GoRouteData.$location( + 'relative-route', + ); + + String get relativeLocation => './$location'; + + void goRelative(BuildContext context) => context.go(relativeLocation); + + Future pushRelative(BuildContext context) => + context.push(relativeLocation); + + void pushReplacementRelative(BuildContext context) => + context.pushReplacement(relativeLocation); + + void replaceRelative(BuildContext context) => + context.replace(relativeLocation); +} + +mixin _$InnerRelativeRoute on GoRouteData { + static InnerRelativeRoute _fromState(GoRouterState state) => + const InnerRelativeRoute(); + + String get location => GoRouteData.$location( + 'inner-relative-route', + ); + + String get relativeLocation => './$location'; + + void goRelative(BuildContext context) => context.go(relativeLocation); + + Future pushRelative(BuildContext context) => + context.push(relativeLocation); + + void pushReplacementRelative(BuildContext context) => + context.pushReplacement(relativeLocation); + + void replaceRelative(BuildContext context) => + context.replace(relativeLocation); +} + +RouteBase get $route2 => GoRouteData.$route( + path: 'route-2', + factory: _$Route2._fromState, + routes: [ + GoRouteData.$route( + path: 'relative-route', + factory: _$RelativeRoute._fromState, + routes: [ + GoRouteData.$route( + path: 'inner-relative-route', + factory: _$InnerRelativeRoute._fromState, + ), + ], + ), + ], + ); + +mixin _$Route2 on GoRouteData { + static Route2 _fromState(GoRouterState state) => const Route2(); + + String get location => GoRouteData.$location( + 'route-2', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} diff --git a/packages/go_router_builder/test_inputs/iterable_with_default_value.dart.expect b/packages/go_router_builder/test_inputs/iterable_with_default_value.dart.expect index 35e4cb75fb5..fc3a553e15e 100644 --- a/packages/go_router_builder/test_inputs/iterable_with_default_value.dart.expect +++ b/packages/go_router_builder/test_inputs/iterable_with_default_value.dart.expect @@ -14,7 +14,6 @@ mixin _$IterableDefaultValueRoute on GoRouteData { IterableDefaultValueRoute get _self => this as IterableDefaultValueRoute; - @override String get location => GoRouteData.$location( '/iterable-default-value-route', queryParams: { @@ -23,17 +22,13 @@ mixin _$IterableDefaultValueRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/iterable_with_enum.dart.expect b/packages/go_router_builder/test_inputs/iterable_with_enum.dart.expect index ef7fd9fec7c..b39e6a4f6a3 100644 --- a/packages/go_router_builder/test_inputs/iterable_with_enum.dart.expect +++ b/packages/go_router_builder/test_inputs/iterable_with_enum.dart.expect @@ -14,7 +14,6 @@ mixin _$IterableWithEnumRoute on GoRouteData { IterableWithEnumRoute get _self => this as IterableWithEnumRoute; - @override String get location => GoRouteData.$location( '/iterable-with-enum', queryParams: { @@ -25,17 +24,13 @@ mixin _$IterableWithEnumRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/list.dart.expect b/packages/go_router_builder/test_inputs/list.dart.expect index abe23c4c4f1..f8b4caf03c9 100644 --- a/packages/go_router_builder/test_inputs/list.dart.expect +++ b/packages/go_router_builder/test_inputs/list.dart.expect @@ -27,7 +27,6 @@ mixin _$ListRoute on GoRouteData { ListRoute get _self => this as ListRoute; - @override String get location => GoRouteData.$location( '/list-route', queryParams: { @@ -41,17 +40,13 @@ mixin _$ListRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/named_escaped_route.dart.expect b/packages/go_router_builder/test_inputs/named_escaped_route.dart.expect index df9ab5f52d5..b5574b9159c 100644 --- a/packages/go_router_builder/test_inputs/named_escaped_route.dart.expect +++ b/packages/go_router_builder/test_inputs/named_escaped_route.dart.expect @@ -8,21 +8,16 @@ mixin _$NamedEscapedRoute on GoRouteData { static NamedEscapedRoute _fromState(GoRouterState state) => NamedEscapedRoute(); - @override String get location => GoRouteData.$location( '/named-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/named_route.dart.expect b/packages/go_router_builder/test_inputs/named_route.dart.expect index b3cf1c42c42..5d6f00509f1 100644 --- a/packages/go_router_builder/test_inputs/named_route.dart.expect +++ b/packages/go_router_builder/test_inputs/named_route.dart.expect @@ -7,21 +7,16 @@ RouteBase get $namedRoute => GoRouteData.$route( mixin _$NamedRoute on GoRouteData { static NamedRoute _fromState(GoRouterState state) => NamedRoute(); - @override String get location => GoRouteData.$location( '/named-route', ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/no_mixin_relative.dart b/packages/go_router_builder/test_inputs/no_mixin_relative.dart new file mode 100644 index 00000000000..871d45830c3 --- /dev/null +++ b/packages/go_router_builder/test_inputs/no_mixin_relative.dart @@ -0,0 +1,8 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:go_router/go_router.dart'; + +@TypedRelativeGoRoute(path: '/') +class HomeRoute extends GoRouteData {} diff --git a/packages/go_router_builder/test_inputs/no_mixin_relative.dart.expect b/packages/go_router_builder/test_inputs/no_mixin_relative.dart.expect new file mode 100644 index 00000000000..dc98f351c1f --- /dev/null +++ b/packages/go_router_builder/test_inputs/no_mixin_relative.dart.expect @@ -0,0 +1 @@ +Missing mixin clause `with _$HomeRoute` diff --git a/packages/go_router_builder/test_inputs/required_extra_value.dart.expect b/packages/go_router_builder/test_inputs/required_extra_value.dart.expect index 662c55b6758..3eb6990b6c2 100644 --- a/packages/go_router_builder/test_inputs/required_extra_value.dart.expect +++ b/packages/go_router_builder/test_inputs/required_extra_value.dart.expect @@ -11,23 +11,18 @@ mixin _$RequiredExtraValueRoute on GoRouteData { RequiredExtraValueRoute get _self => this as RequiredExtraValueRoute; - @override String get location => GoRouteData.$location( '/default-value-route', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } diff --git a/packages/go_router_builder/test_inputs/required_nullable_type_arguments_extra_value.dart.expect b/packages/go_router_builder/test_inputs/required_nullable_type_arguments_extra_value.dart.expect index 2a181ac8576..dadb4da739f 100644 --- a/packages/go_router_builder/test_inputs/required_nullable_type_arguments_extra_value.dart.expect +++ b/packages/go_router_builder/test_inputs/required_nullable_type_arguments_extra_value.dart.expect @@ -14,23 +14,18 @@ mixin _$RequiredNullableTypeArgumentsExtraValueRoute on GoRouteData { RequiredNullableTypeArgumentsExtraValueRoute get _self => this as RequiredNullableTypeArgumentsExtraValueRoute; - @override String get location => GoRouteData.$location( '/default-value-route', ); - @override void go(BuildContext context) => context.go(location, extra: _self.$extra); - @override Future push(BuildContext context) => context.push(location, extra: _self.$extra); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location, extra: _self.$extra); - @override void replace(BuildContext context) => context.replace(location, extra: _self.$extra); } diff --git a/packages/go_router_builder/test_inputs/required_parameters_not_in_path_can_be_null.dart.expect b/packages/go_router_builder/test_inputs/required_parameters_not_in_path_can_be_null.dart.expect index 60c1c0f6a25..64a7518ee75 100644 --- a/packages/go_router_builder/test_inputs/required_parameters_not_in_path_can_be_null.dart.expect +++ b/packages/go_router_builder/test_inputs/required_parameters_not_in_path_can_be_null.dart.expect @@ -12,7 +12,6 @@ mixin _$NullableRequiredParamNotInPath on GoRouteData { NullableRequiredParamNotInPath get _self => this as NullableRequiredParamNotInPath; - @override String get location => GoRouteData.$location( 'bob', queryParams: { @@ -20,17 +19,13 @@ mixin _$NullableRequiredParamNotInPath on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/required_query_parameter.dart.expect b/packages/go_router_builder/test_inputs/required_query_parameter.dart.expect index 23487d96d6e..99e48d0a5c6 100644 --- a/packages/go_router_builder/test_inputs/required_query_parameter.dart.expect +++ b/packages/go_router_builder/test_inputs/required_query_parameter.dart.expect @@ -12,7 +12,6 @@ mixin _$NonNullableRequiredParamNotInPath on GoRouteData { NonNullableRequiredParamNotInPath get _self => this as NonNullableRequiredParamNotInPath; - @override String get location => GoRouteData.$location( 'bob', queryParams: { @@ -20,16 +19,12 @@ mixin _$NonNullableRequiredParamNotInPath on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); } diff --git a/packages/go_router_builder/test_inputs/set.dart.expect b/packages/go_router_builder/test_inputs/set.dart.expect index 69d25393d59..632395241e9 100644 --- a/packages/go_router_builder/test_inputs/set.dart.expect +++ b/packages/go_router_builder/test_inputs/set.dart.expect @@ -27,7 +27,6 @@ mixin _$SetRoute on GoRouteData { SetRoute get _self => this as SetRoute; - @override String get location => GoRouteData.$location( '/set-route', queryParams: { @@ -41,17 +40,13 @@ mixin _$SetRoute on GoRouteData { }, ); - @override void go(BuildContext context) => context.go(location); - @override Future push(BuildContext context) => context.push(location); - @override void pushReplacement(BuildContext context) => context.pushReplacement(location); - @override void replace(BuildContext context) => context.replace(location); }