diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md index 36a87c8a75e2..687d9210f05f 100644 --- a/packages/go_router_builder/CHANGELOG.md +++ b/packages/go_router_builder/CHANGELOG.md @@ -1,3 +1,8 @@ + +## 2.7.3 + +- Fixes an issue when using a not null List or Set param. + ## 2.7.2 - Supports the latest `package:analyzer` and `package:source_gen`. diff --git a/packages/go_router_builder/lib/src/type_helpers.dart b/packages/go_router_builder/lib/src/type_helpers.dart index 94ddcd0a6e7c..d375c013e20d 100644 --- a/packages/go_router_builder/lib/src/type_helpers.dart +++ b/packages/go_router_builder/lib/src/type_helpers.dart @@ -273,18 +273,27 @@ class _TypeHelperIterable extends _TypeHelper { // get correct type for iterable String iterableCaster = ''; + String fallBack = ''; if (const TypeChecker.fromRuntime(List) .isAssignableFromType(parameterElement.type)) { iterableCaster = '.toList()'; + if (!parameterElement.type.isNullableType && + !parameterElement.hasDefaultValue) { + fallBack = '?? const []'; + } } else if (const TypeChecker.fromRuntime(Set) .isAssignableFromType(parameterElement.type)) { iterableCaster = '.toSet()'; + if (!parameterElement.type.isNullableType && + !parameterElement.hasDefaultValue) { + fallBack = '?? const {}'; + } } return ''' state.uri.queryParametersAll[ ${escapeDartString(parameterElement.name.kebab)}] - ?.map($entriesTypeDecoder)$iterableCaster'''; + ?.map($entriesTypeDecoder)$iterableCaster$fallBack'''; } return ''' state.uri.queryParametersAll[${escapeDartString(parameterElement.name.kebab)}]'''; diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml index e27dfc8e7f38..692b81f07967 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: 2.7.2 +version: 2.7.3 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 diff --git a/packages/go_router_builder/test_inputs/list.dart b/packages/go_router_builder/test_inputs/list.dart new file mode 100644 index 000000000000..e7b3e3d975dd --- /dev/null +++ b/packages/go_router_builder/test_inputs/list.dart @@ -0,0 +1,17 @@ +// 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'; + +@TypedGoRoute(path: '/list-route') +class ListRoute extends GoRouteData { + ListRoute({ + required this.ids, + this.nullableIds, + this.idsWithDefaultValue = const [0], + }); + final List ids; + final List? nullableIds; + final List idsWithDefaultValue; +} diff --git a/packages/go_router_builder/test_inputs/list.dart.expect b/packages/go_router_builder/test_inputs/list.dart.expect new file mode 100644 index 000000000000..2fbf6eef07bc --- /dev/null +++ b/packages/go_router_builder/test_inputs/list.dart.expect @@ -0,0 +1,40 @@ +RouteBase get $listRoute => GoRouteData.$route( + path: '/list-route', + factory: $ListRouteExtension._fromState, + ); + +extension $ListRouteExtension on ListRoute { + static ListRoute _fromState(GoRouterState state) => ListRoute( + ids: state.uri.queryParametersAll['ids']?.map(int.parse).toList() ?? + const [], + nullableIds: state.uri.queryParametersAll['nullable-ids'] + ?.map(int.parse) + .toList(), + idsWithDefaultValue: state + .uri.queryParametersAll['ids-with-default-value'] + ?.map(int.parse) + .toList() ?? + const [0], + ); + + String get location => GoRouteData.$location( + '/list-route', + queryParams: { + 'ids': ids.map((e) => e.toString()).toList(), + if (nullableIds != null) + 'nullable-ids': nullableIds?.map((e) => e.toString()).toList(), + if (idsWithDefaultValue != const [0]) + 'ids-with-default-value': + idsWithDefaultValue.map((e) => e.toString()).toList(), + }, + ); + + 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/set.dart b/packages/go_router_builder/test_inputs/set.dart new file mode 100644 index 000000000000..286fd6b236f4 --- /dev/null +++ b/packages/go_router_builder/test_inputs/set.dart @@ -0,0 +1,17 @@ +// 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'; + +@TypedGoRoute(path: '/set-route') +class SetRoute extends GoRouteData { + SetRoute({ + required this.ids, + this.nullableIds, + this.idsWithDefaultValue = const {0}, + }); + final Set ids; + final Set? nullableIds; + final Set idsWithDefaultValue; +} diff --git a/packages/go_router_builder/test_inputs/set.dart.expect b/packages/go_router_builder/test_inputs/set.dart.expect new file mode 100644 index 000000000000..6a8c150b54c5 --- /dev/null +++ b/packages/go_router_builder/test_inputs/set.dart.expect @@ -0,0 +1,40 @@ +RouteBase get $setRoute => GoRouteData.$route( + path: '/set-route', + factory: $SetRouteExtension._fromState, + ); + +extension $SetRouteExtension on SetRoute { + static SetRoute _fromState(GoRouterState state) => SetRoute( + ids: state.uri.queryParametersAll['ids']?.map(int.parse).toSet() ?? + const {}, + nullableIds: state.uri.queryParametersAll['nullable-ids'] + ?.map(int.parse) + .toSet(), + idsWithDefaultValue: state + .uri.queryParametersAll['ids-with-default-value'] + ?.map(int.parse) + .toSet() ?? + const {0}, + ); + + String get location => GoRouteData.$location( + '/set-route', + queryParams: { + 'ids': ids.map((e) => e.toString()).toList(), + if (nullableIds != null) + 'nullable-ids': nullableIds?.map((e) => e.toString()).toList(), + if (idsWithDefaultValue != const {0}) + 'ids-with-default-value': + idsWithDefaultValue.map((e) => e.toString()).toList(), + }, + ); + + 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); +}