deriveAutoRoute function
Leitet Screens aus @RoutePage()-Klassen ab; AutoRoute(page:, path:)-
Einträge liefern die Pfad-Zuordnung.
Implementation
AutoRouteDerivation deriveAutoRoute(
List<ScannedFile> files,
void Function(String) warn,
) {
final result = AutoRouteDerivation();
for (final file in files) {
for (final decl in file.unit.declarations) {
if (decl is! ClassDeclaration) continue;
final hasRoutePage = decl.metadata.any((a) {
final name = a.name;
final simple = name is PrefixedIdentifier ? name.identifier.name : name.name;
return simple == 'RoutePage';
});
if (!hasRoutePage) continue;
final className = decl.namePart.typeName.lexeme;
final id = screenIdFromClassName(className);
result.nodes.add(GraphNode(
id: id,
type: 'screen',
title: humanize(id),
source: SourceKind.derived,
sourceRef: file.refAt(decl.namePart.typeName.offset, symbol: className),
));
result.classToScreen.putIfAbsent(className, () => id);
}
}
// AutoRoute(page: LoginRoute.page, path: '/login') — der generierte
// Routenname entsteht aus dem Klassennamen ohne Screen/Page-Suffix + 'Route'.
for (final file in files) {
final collector = _AutoRouteEntryCollector();
file.unit.accept(collector);
for (final entry in collector.entries) {
Expression? pageExpr;
String? path;
for (final arg in entry.arguments) {
if (arg is! NamedArgument) continue;
switch (arg.name.lexeme) {
case 'page':
pageExpr = arg.argumentExpression;
case 'path':
final expr = arg.argumentExpression;
if (expr is StringLiteral) path = expr.stringValue;
}
}
if (pageExpr == null || path == null) continue;
final routeClass = _routeClassOfPageExpr(pageExpr);
if (routeClass == null) continue;
final base = routeClass.endsWith('Route')
? routeClass.substring(0, routeClass.length - 'Route'.length)
: routeClass;
final id = _kebabCase(base);
// Nur zuordnen, wenn der Screen tatsächlich existiert (kein Dangling).
if (result.nodes.any((n) => n.id == id)) {
result.pathToScreen.putIfAbsent(path, () => id);
}
}
}
return result;
}