Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT
## 3.0.2

- Restricts `build` to versions less than 2.5.0.
- Support `extension type`.

## 3.0.1

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router_builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ class RedirectRoute extends GoRouteData {

## Type conversions

The code generator can convert simple types like `int` and `enum` to/from the
The code generator can convert simple types like `int`, `enum`, and `extension type` to/from the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a new example in example/ folder

`String` type of the underlying pathParameters:

<?code-excerpt "example/lib/readme_excerpts.dart (BookKind)"?>
Expand Down
44 changes: 44 additions & 0 deletions packages/go_router_builder/lib/src/type_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const List<_TypeHelper> _helpers = <_TypeHelper>[
_TypeHelperDateTime(),
_TypeHelperDouble(),
_TypeHelperEnum(),
_TypeHelperExtensionType(),
_TypeHelperInt(),
_TypeHelperNum(),
_TypeHelperString(),
Expand Down Expand Up @@ -263,6 +264,49 @@ class _TypeHelperEnum extends _TypeHelperWithHelper {
bool _matchesType(DartType type) => type.isEnum;
}

/// A type helper for extension types.
class _TypeHelperExtensionType extends _TypeHelper {
const _TypeHelperExtensionType();

@override
String _decode(
ParameterElement parameterElement, Set<String> pathParameters) {
final DartType paramType = parameterElement.type;
if (paramType.isNullableType && parameterElement.hasDefaultValue) {
throw NullableDefaultValueError(parameterElement);
}

final String stateValue =
'state.${_stateValueAccess(parameterElement, pathParameters)}';
final String castType;
if (paramType.isNullableType || parameterElement.hasDefaultValue) {
castType = '$paramType${paramType.isNullableType ? '' : '?'}';
} else {
castType = '$paramType';
}

final DartType extensionTypeErasure = paramType.extensionTypeErasure;
if (extensionTypeErasure.isDartCoreString) {
return '$stateValue as $castType';
}

final String parseTypeName =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we guard against no primitive type? since this is following by a hardcode tryParse, may as well only allow certain numeric types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right in pointing this out. I restricted the type and handled it correctly. 61901a3

withoutNullability(extensionTypeErasure.getDisplayString());
if (paramType.isNullableType || parameterElement.hasDefaultValue) {
return "$parseTypeName.tryParse($stateValue ?? '') as $castType";
} else {
return '$parseTypeName.parse($stateValue) as $castType';
}
}

@override
String _encode(String fieldName, DartType type) =>
'$fieldName${type.ensureNotNull}.toString()';

@override
bool _matchesType(DartType type) => type != type.extensionTypeErasure;
}

class _TypeHelperInt extends _TypeHelperWithHelper {
const _TypeHelperInt();

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router_builder/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
149 changes: 149 additions & 0 deletions packages/go_router_builder/test_inputs/extension_type_parameter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// 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 _$ExtenstionTypeParam {}
mixin _$ExtenstionTypeStringParam {}
mixin _$ExtenstionTypeStringDefaultParam {}
mixin _$ExtenstionTypeIntParam {}
mixin _$ExtenstionTypeIntDefaultParam {}
mixin _$ExtenstionTypeDoubleParam {}
mixin _$ExtenstionTypeNumParam {}
mixin _$ExtenstionTypeBoolParam {}
mixin _$ExtenstionTypeBigIntParam {}
mixin _$ExtenstionTypeDateTimeParam {}

@TypedGoRoute<ExtenstionTypeParam>(path: '/', routes: <TypedRoute<RouteData>>[
TypedGoRoute<ExtenstionTypeStringParam>(path: 'string/:s'),
TypedGoRoute<ExtenstionTypeStringDefaultParam>(path: 'string_default/:s'),
TypedGoRoute<ExtenstionTypeIntParam>(path: 'int/:x'),
TypedGoRoute<ExtenstionTypeIntDefaultParam>(path: 'int_default/:x'),
TypedGoRoute<ExtenstionTypeDoubleParam>(path: 'double/:d'),
TypedGoRoute<ExtenstionTypeNumParam>(path: 'num/:n'),
TypedGoRoute<ExtenstionTypeBoolParam>(path: 'bool/:b'),
TypedGoRoute<ExtenstionTypeBigIntParam>(path: 'bigint/:bi'),
TypedGoRoute<ExtenstionTypeDateTimeParam>(path: 'datetime/:dt'),
])
class ExtenstionTypeParam extends GoRouteData with _$ExtenstionTypeParam {
ExtenstionTypeParam();
}

class ExtenstionTypeStringParam extends GoRouteData
with _$ExtenstionTypeStringParam {
ExtenstionTypeStringParam({
required this.s,
required this.requiredValue,
this.optionalNullableValue,
this.optionalDefaultValue = const StringExtensionType('default'),
});
final StringExtensionType s;
final StringExtensionType requiredValue;
final StringExtensionType? optionalNullableValue;
final StringExtensionType optionalDefaultValue;
}

class ExtenstionTypeStringDefaultParam extends GoRouteData
with _$ExtenstionTypeStringDefaultParam {
ExtenstionTypeStringDefaultParam({
this.s = const StringExtensionType('default'),
});
final StringExtensionType s;
}

class ExtenstionTypeIntParam extends GoRouteData with _$ExtenstionTypeIntParam {
ExtenstionTypeIntParam({
required this.x,
required this.requiredValue,
this.optionalNullableValue,
this.optionalDefaultValue = const IntExtensionType(42),
});
final IntExtensionType x;
final IntExtensionType requiredValue;
final IntExtensionType? optionalNullableValue;
final IntExtensionType optionalDefaultValue;
}

class ExtenstionTypeIntDefaultParam extends GoRouteData
with _$ExtenstionTypeIntDefaultParam {
ExtenstionTypeIntDefaultParam({
this.x = const IntExtensionType(42),
});
final IntExtensionType x;
}

class ExtenstionTypeDoubleParam extends GoRouteData
with _$ExtenstionTypeDoubleParam {
ExtenstionTypeDoubleParam({
required this.d,
required this.requiredValue,
this.optionalNullableValue,
this.optionalDefaultValue = const DoubleExtensionType(3.14),
});
final DoubleExtensionType d;
final DoubleExtensionType requiredValue;
final DoubleExtensionType? optionalNullableValue;
final DoubleExtensionType optionalDefaultValue;
}

class ExtenstionTypeNumParam extends GoRouteData with _$ExtenstionTypeNumParam {
ExtenstionTypeNumParam({
required this.n,
required this.requiredValue,
this.optionalNullableValue,
this.optionalDefaultValue = const NumExtensionType(3.14),
});
final NumExtensionType n;
final NumExtensionType requiredValue;
final NumExtensionType? optionalNullableValue;
final NumExtensionType optionalDefaultValue;
}

class ExtenstionTypeBoolParam extends GoRouteData
with _$ExtenstionTypeBoolParam {
ExtenstionTypeBoolParam({
required this.b,
required this.requiredValue,
this.optionalNullableValue,
this.optionalDefaultValue = const BoolExtensionType(true),
});
final BoolExtensionType b;
final BoolExtensionType requiredValue;
final BoolExtensionType? optionalNullableValue;
final BoolExtensionType optionalDefaultValue;
}

class ExtenstionTypeBigIntParam extends GoRouteData
with _$ExtenstionTypeBigIntParam {
ExtenstionTypeBigIntParam({
required this.bi,
required this.requiredValue,
this.optionalValue,
this.optionalNullableValue,
});
final BigIntExtensionType bi;
final BigIntExtensionType requiredValue;
final BigIntExtensionType? optionalValue;
final BigIntExtensionType? optionalNullableValue;
}

class ExtenstionTypeDateTimeParam extends GoRouteData
with _$ExtenstionTypeDateTimeParam {
ExtenstionTypeDateTimeParam({
required this.dt,
required this.optionalValue,
this.optionalNullableValue,
});
final DateTimeExtensionType dt;
final DateTimeExtensionType optionalValue;
final DateTimeExtensionType? optionalNullableValue;
}

extension type const StringExtensionType(String value) {}
extension type const IntExtensionType(int value) {}
extension type const DoubleExtensionType(double value) {}
extension type const NumExtensionType(num value) {}
extension type const BoolExtensionType(bool value) {}
extension type const BigIntExtensionType(BigInt value) {}
extension type const DateTimeExtensionType(DateTime value) {}
Loading