Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
990c293
implemented helpers for StatefulShellRoute
hannah-hyj Jun 16, 2023
4918014
Merge branch 'main' into statefulshellroute
hannah-hyj Jun 16, 2023
c6bde6d
lint
hannah-hyj Jun 16, 2023
52ce037
Update route_data.dart
hannah-hyj Jun 16, 2023
b9c8080
lint
hannah-hyj Jun 16, 2023
9005a8c
Update route_data.dart
hannah-hyj Jun 16, 2023
8cf69b6
update
hannah-hyj Jun 26, 2023
5963020
resolve comments
hannah-hyj Jun 28, 2023
4f60cd6
1
hannah-hyj Jun 16, 2023
e4fc526
Revert "1"
hannah-hyj Jun 16, 2023
d328021
update
hannah-hyj Jun 26, 2023
bc19f53
update tests
hannah-hyj Jun 28, 2023
f827680
Merge branch 'main' of https://github.com/flutter/packages into build…
hannah-hyj Jul 9, 2023
6a09020
update
hannah-hyj Jul 10, 2023
bb6064b
bump version
hannah-hyj Jul 10, 2023
441eb78
Update route_config.dart
hannah-hyj Jul 10, 2023
8b4e2de
Update stateful_shell_route_test.dart
hannah-hyj Jul 10, 2023
a2ef5d2
Merge branch 'main' of https://github.com/flutter/packages into build…
hannah-hyj Jul 12, 2023
13865ac
update route_config
hannah-hyj Jul 12, 2023
e3d109d
Update route_config.dart
hannah-hyj Jul 19, 2023
51ae0a0
Merge branch 'main' of https://github.com/flutter/packages into build…
hannah-hyj Jul 19, 2023
bfd36ef
merge
hannah-hyj Jul 20, 2023
03c069b
resolve comments
hannah-hyj Jul 25, 2023
0da2339
update
hannah-hyj Jul 25, 2023
06c7e67
Update route_config.dart
hannah-hyj Jul 25, 2023
ecbc5f5
update
hannah-hyj Jul 31, 2023
9808f62
Merge branch 'main' of https://github.com/flutter/packages into build…
hannah-hyj Jul 31, 2023
6044e32
Update pubspec.yaml
hannah-hyj Jul 31, 2023
3c2ed3b
lint
hannah-hyj Jul 31, 2023
1e78def
Update stateful_shell_route_example.dart
hannah-hyj Jul 31, 2023
eecb67e
Update pubspec.yaml
hannah-hyj Jul 31, 2023
2e63519
Update pubspec.yaml
hannah-hyj Jul 31, 2023
cfb1de8
Update stateful_shell_route_example.dart
hannah-hyj Jul 31, 2023
7fa8523
Merge branch 'main' into builder-stateful
hannah-hyj Aug 2, 2023
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
Prev Previous commit
Next Next commit
Merge branch 'main' of https://github.com/flutter/packages into build…
…er-stateful
  • Loading branch information
hannah-hyj committed Jul 12, 2023
commit a2ef5d2b535fa5278ba23a6a4dc0057b45eda8bf
4 changes: 4 additions & 0 deletions packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* Updates the documentation to go_router v9.0.3
* Bumps go_router version in example folder to v9.0.3

## 2.2.1

* Cleans up go_router_builder code.

## 2.2.0

* Adds replace methods to the generated routes.
Expand Down
269 changes: 62 additions & 207 deletions packages/go_router_builder/lib/src/route_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,174 +34,50 @@ class InfoIterable extends IterableBase<String> {
Iterator<String> get iterator => members.iterator;
}

/// Represents a `TypedGoRoute` annotation to the builder.
class RouteConfig {
RouteConfig._(
this._path,
this._name,
this._routeDataClass,
this._parent,
this._key,
this._typeName,
);
/// The configuration to generate class declarations for a ShellRouteData.
class ShellRouteConfig extends RouteBaseConfig {
ShellRouteConfig._({
required this.navigatorKey,
required super.routeDataClass,
required super.parent,
required super.parentNavigatorKey,
}) : super._();

/// The command for calling the navigator key getter from the ShellRouteData.
final String? navigatorKey;

if (element != definition._routeDataClass) {
throw InvalidGenerationSourceError(
'The @TypedGoRoute annotation must have a type parameter that matches '
'the annotated element.',
element: element,
);
}

return definition;
}

factory RouteConfig._fromAnnotation(
ConstantReader reader,
InterfaceElement element,
RouteConfig? parent,
) {
assert(!reader.isNull, 'reader should not be null');
final InterfaceType type = reader.objectValue.type! as InterfaceType;
// TODO(stuartmorgan): Remove this ignore once 'analyze' can be set to
// 5.2+ (when Flutter 3.4+ is on stable).
// ignore: deprecated_member_use
final String typeName = type.element.name;

String? path;
String? name;

if (!typeName.contains('Shell')) {
final ConstantReader pathValue = reader.read('path');
if (pathValue.isNull) {
throw InvalidGenerationSourceError(
'Missing `path` value on annotation.',
element: element,
);
}
path = pathValue.stringValue;

final ConstantReader nameValue = reader.read('name');
name = nameValue.isNull ? null : nameValue.stringValue;
}

final DartType typeParamType = type.typeArguments.single;
if (typeParamType is! InterfaceType) {
throw InvalidGenerationSourceError(
'The type parameter on one of the @TypedGoRoute declarations could not '
'be parsed.',
element: element,
);
}

// TODO(kevmoo): validate that this MUST be a subtype of `GoRouteData`
// TODO(stuartmorgan): Remove this ignore once 'analyze' can be set to
// 5.2+ (when Flutter 3.4+ is on stable).
// ignore: deprecated_member_use
final InterfaceElement classElement = typeParamType.element;

final RouteConfig value = RouteConfig._(
path ?? '',
name,
classElement,
parent,
_generateNavigatorKeyGetterCode(
classElement,
keyName: typeName.contains('Shell')
? r'$navigatorKey'
: r'$parentNavigatorKey',
),
typeName,
);
if (typeName == 'TypedStatefulShellRoute') {
value._children.addAll(reader.read('branches').listValue.map(
(DartObject e) =>
RouteConfig._fromAnnotation(ConstantReader(e), element, value)));
} else {
value._children.addAll(reader.read('routes').listValue.map(
(DartObject e) =>
RouteConfig._fromAnnotation(ConstantReader(e), element, value)));
}

return value;
}

final List<RouteConfig> _children = <RouteConfig>[];
final String _path;
final String? _name;
final InterfaceElement _routeDataClass;
final RouteConfig? _parent;
final String? _key;
final String _typeName;

static String? _generateNavigatorKeyGetterCode(
InterfaceElement classElement, {
required String keyName,
}) {
final String? fieldDisplayName = classElement.fields
.where((FieldElement element) {
final DartType type = element.type;
if (!element.isStatic ||
element.name != keyName ||
type is! ParameterizedType) {
return false;
}
final List<DartType> typeArguments = type.typeArguments;
if (typeArguments.length != 1) {
return false;
}
final DartType typeArgument = typeArguments.single;
if (typeArgument.getDisplayString(withNullability: false) ==
'NavigatorState') {
return true;
}
return false;
})
.map<String>((FieldElement e) => e.displayName)
.firstOrNull;

if (fieldDisplayName == null) {
return null;
}
return '${classElement.name}.$fieldDisplayName';
}

/// Generates all of the members that correspond to `this`.
InfoIterable generateMembers() => InfoIterable._(
members: _generateMembers().toList(),
routeGetterName: _routeGetterName,
);

Iterable<String> _generateMembers() sync* {
final List<String> items = <String>[
_rootDefinition(),
];
@override
Iterable<String> classDeclarations() => <String>[
'''
extension $_extensionName on $_className {
static $_className _fromState(GoRouterState state) => const $_className();
}
'''
];

for (final RouteConfig def in _flatten()) {
items.add(def._extensionDefinition());
}
@override
String get routeConstructorParameters =>
navigatorKey == null ? '' : 'navigatorKey: $navigatorKey,';

_enumDefinitions().forEach(items.add);
@override
String get routeDataClassName => 'ShellRouteData';
}

yield* items;
/// The configuration to generate class declarations for a ShellRouteData.
class StatefulShellRouteConfig extends RouteBaseConfig {
StatefulShellRouteConfig._({
required this.navigatorKey,
required super.routeDataClass,
required super.parent,
Copy link
Contributor

Choose a reason for hiding this comment

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

parent navigator key?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

required super.parentNavigatorKey,
}) : super._();

yield* items
.expand(
(String e) => helperNames.entries
.where(
(MapEntry<String, String> element) => e.contains(element.key))
.map((MapEntry<String, String> e) => e.value),
)
.toSet();
}
/// The command for calling the navigator key getter from the ShellRouteData.
final String? navigatorKey;

/// Returns `extension` code.
String _extensionDefinition() {
if (_typeName.contains('Shell')) {
return '''
@override
Iterable<String> classDeclarations() => <String>[
'''
extension $_extensionName on $_className {
static $_className _fromState(GoRouterState state) => const $_className();
}
Expand All @@ -213,7 +89,7 @@ extension $_extensionName on $_className {
navigatorKey == null ? '' : 'navigatorKey: $navigatorKey,';
Copy link
Contributor

Choose a reason for hiding this comment

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

no navigator key, but we need to have a way to pass in
navigatorContainerBuilder and restorationScopeId

Copy link
Member Author

Choose a reason for hiding this comment

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

done


@override
String get routeDataClassName => 'ShellRouteData';
String get routeDataClassName => 'StatefulShellRouteData';
}

/// The configuration to generate class declarations for a GoRouteData.
Expand Down Expand Up @@ -286,49 +162,13 @@ class GoRouteConfig extends RouteBaseConfig {
buffer.writeln('const ');
}

return p.url.joinAll(pathSegments.reversed);
}

String get _className => _routeDataClass.name;

String get _extensionName => '\$${_className}Extension';

String _routeDefinition() {
final String routesBit = _children.isEmpty
? ''
: '''
${_typeName == 'TypedStatefulShellRoute' ? "branches:" : "routes:"} [${_children.map((RouteConfig e) => '${e._routeDefinition()},').join()}],
''';
final String navigatorKeyParameterName =
_typeName.contains('Shell') ? 'navigatorKey' : 'parentNavigatorKey';
final String navigatorKey = _key == null || _key!.isEmpty
? ''
: '$navigatorKeyParameterName: $_key,';
if (_typeName == 'TypedStatefulShellRoute') {
return '''
StatefulShellRouteData.\$route(
factory: $_extensionName._fromState,
$navigatorKey
$routesBit
)
''';
}
if (_typeName == 'TypedStatefulShellBranch') {
return '''
StatefulShellBranchData.\$branch(
$navigatorKey
$routesBit
)
''';
}
if (_typeName == 'TypedShellRoute') {
return '''
ShellRouteData.\$route(
factory: $_extensionName._fromState,
$navigatorKey
$routesBit
)
''';
buffer.writeln('$_className(');
for (final ParameterElement param in <ParameterElement>[
..._ctorParams,
..._ctorQueryParams,
if (_extraParam != null) _extraParam!,
]) {
buffer.write(_decodeFor(param));
}
buffer.writeln(');');

Expand Down Expand Up @@ -528,7 +368,7 @@ abstract class RouteBaseConfig {
// TODO(stuartmorgan): Remove this ignore once 'analyze' can be set to
// 5.2+ (when Flutter 3.4+ is on stable).
// ignore: deprecated_member_use
final bool isShellRoute = type.element.name == 'TypedShellRoute';
final String typeName = type.element.name;
final DartType typeParamType = type.typeArguments.single;
if (typeParamType is! InterfaceType) {
throw InvalidGenerationSourceError(
Expand All @@ -545,7 +385,7 @@ abstract class RouteBaseConfig {
final InterfaceElement classElement = typeParamType.element;

final RouteBaseConfig value;
if (isShellRoute) {
if (typeName =='TypedShellRoute') {
value = ShellRouteConfig._(
routeDataClass: classElement,
parent: parent,
Expand All @@ -558,7 +398,22 @@ abstract class RouteBaseConfig {
keyName: r'$parentNavigatorKey',
),
);
} else {
}
else if(typeName=='TypedStatefulShellRoute'){
value = StatefulShellRouteConfig._(
routeDataClass: classElement,
parent: parent,
navigatorKey: _generateNavigatorKeyGetterCode(
classElement,
keyName: r'$navigatorKey',
),
parentNavigatorKey: _generateNavigatorKeyGetterCode(
classElement,
keyName: r'$parentNavigatorKey',
),
);
}
else {
final ConstantReader pathValue = reader.read('path');
if (pathValue.isNull) {
throw InvalidGenerationSourceError(
Expand Down Expand Up @@ -773,4 +628,4 @@ const String _enumConverterHelper = '''
extension<T extends Enum> on Map<T, String> {
T $enumExtensionHelperName(String value) =>
entries.singleWhere((element) => element.value == value).key;
}''';
}''';
4 changes: 3 additions & 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: 2.2.1
version: 2.3.0
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 All @@ -25,4 +25,6 @@ dev_dependencies:
build_runner: ^2.0.0
go_router: ^9.0.3
source_gen_test: ^1.0.0
build_test: ^2.1.7
dart_style: 2.3.2
test: ^1.20.0
You are viewing a condensed version of this merge commit. You can view the full changes here.