[go_router_builder] Support `ShellRouteData` without `const` constructor  (#4627)

Fixes https://github.com/flutter/flutter/issues/131211
diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md
index cb3433f..11aeb62 100644
--- a/packages/go_router_builder/CHANGELOG.md
+++ b/packages/go_router_builder/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.2.5
+
+* Fixes a bug where shell routes without const constructor were not generated correctly.
+
 ## 2.2.4
 
 * Bumps example go_router version to v10.0.0 and migrate example code.
diff --git a/packages/go_router_builder/lib/src/route_config.dart b/packages/go_router_builder/lib/src/route_config.dart
index ef3b82e..1d60776 100644
--- a/packages/go_router_builder/lib/src/route_config.dart
+++ b/packages/go_router_builder/lib/src/route_config.dart
@@ -47,13 +47,24 @@
   final String? navigatorKey;
 
   @override
-  Iterable<String> classDeclarations() => <String>[
-        '''
-extension $_extensionName on $_className {
-  static $_className _fromState(GoRouterState state) => const $_className();
-}
-'''
-      ];
+  Iterable<String> classDeclarations() {
+    if (routeDataClass.unnamedConstructor == null) {
+      throw InvalidGenerationSourceError(
+        'The ShellRouteData "$_className" class must have an unnamed constructor.',
+        element: routeDataClass,
+      );
+    }
+
+    final bool isConst = routeDataClass.unnamedConstructor!.isConst;
+
+    return <String>[
+      '''
+  extension $_extensionName on $_className {
+  static $_className _fromState(GoRouterState state) =>${isConst ? ' const' : ''} $_className();
+  }
+  '''
+    ];
+  }
 
   @override
   String get routeConstructorParameters =>
diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml
index 1bd454a..dac268f 100644
--- a/packages/go_router_builder/pubspec.yaml
+++ b/packages/go_router_builder/pubspec.yaml
@@ -2,7 +2,7 @@
 description: >-
   A builder that supports generated strongly-typed route helpers for
   package:go_router
-version: 2.2.4
+version: 2.2.5
 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/shell_route_data.dart b/packages/go_router_builder/test_inputs/shell_route_data.dart
new file mode 100644
index 0000000..43f2b28
--- /dev/null
+++ b/packages/go_router_builder/test_inputs/shell_route_data.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';
+
+@TypedShellRoute<ShellRouteNoConstConstructor>(
+  routes: <TypedRoute<RouteData>>[],
+)
+class ShellRouteNoConstConstructor extends ShellRouteData {}
+
+@TypedShellRoute<ShellRouteWithConstConstructor>(
+  routes: <TypedRoute<RouteData>>[],
+)
+class ShellRouteWithConstConstructor extends ShellRouteData {
+  const ShellRouteWithConstConstructor();
+}
diff --git a/packages/go_router_builder/test_inputs/shell_route_data.dart.expect b/packages/go_router_builder/test_inputs/shell_route_data.dart.expect
new file mode 100644
index 0000000..b99dd51
--- /dev/null
+++ b/packages/go_router_builder/test_inputs/shell_route_data.dart.expect
@@ -0,0 +1,19 @@
+RouteBase get $shellRouteNoConstConstructor => ShellRouteData.$route(
+      factory: $ShellRouteNoConstConstructorExtension._fromState,
+    );
+
+extension $ShellRouteNoConstConstructorExtension
+    on ShellRouteNoConstConstructor {
+  static ShellRouteNoConstConstructor _fromState(GoRouterState state) =>
+      ShellRouteNoConstConstructor();
+}
+
+RouteBase get $shellRouteWithConstConstructor => ShellRouteData.$route(
+      factory: $ShellRouteWithConstConstructorExtension._fromState,
+    );
+
+extension $ShellRouteWithConstConstructorExtension
+    on ShellRouteWithConstConstructor {
+  static ShellRouteWithConstConstructor _fromState(GoRouterState state) =>
+      const ShellRouteWithConstConstructor();
+}
diff --git a/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart b/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart
new file mode 100644
index 0000000..24e97bf
--- /dev/null
+++ b/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart
@@ -0,0 +1,12 @@
+// 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';
+
+@TypedShellRoute<ShellRouteWithoutUnnamedConstructor>(
+  routes: <TypedRoute<RouteData>>[],
+)
+class ShellRouteWithoutUnnamedConstructor extends ShellRouteData {
+  const ShellRouteWithoutUnnamedConstructor.namedConstructor();
+}
diff --git a/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart.expect b/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart.expect
new file mode 100644
index 0000000..c3d6e57
--- /dev/null
+++ b/packages/go_router_builder/test_inputs/shell_route_data_without_unnamed_constructor.dart.expect
@@ -0,0 +1 @@
+The ShellRouteData "ShellRouteWithoutUnnamedConstructor" class must have an unnamed constructor.