import 'package:analyzer/dart/element/element.dart'; import 'package:build/build.dart'; import 'package:router_gen/annotation/router_page.dart'; import 'package:router_gen/annotation/router_param.dart'; import 'package:router_gen/model/router.dart'; import 'package:router_gen/util/utils.dart'; import 'package:source_gen/source_gen.dart'; import 'package:path/path.dart' as Path; /// save router annotation class RouterGenerator extends GeneratorForAnnotation { final _paramChecker = const TypeChecker.fromRuntime(RouterParam); @override generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) async { if (element.kind == ElementKind.CLASS) { router.imports.add(getImportStr(buildStep)); String path = buildStep.inputId.path; // lib/xxx.dart String basename = Path.basename(buildStep.inputId.path); // xxx.dart // router name String className = element.name; String aptPath = annotation.peek("path")?.stringValue; String routerName = toCamelCase(aptPath == null || aptPath.isEmpty ? className : aptPath); var page = Page(); page.name = className; page.path = routerName.startsWith("/") ? routerName : Path.join(path.replaceFirst("lib", "").replaceFirst(basename, ""), routerName); page.arguments = []; for (FieldElement e in (element as ClassElement).fields) { if (_paramChecker.hasAnnotationOf(e)) { String type = e.type.getDisplayString(withNullability: false); try { Set types = getType(type); for (String importType in types) { // not container all type if (isSpeciousType(importType) == false) { continue; } print("specious type ${importType}"); // 添加到imports for (LibraryElement element in (await buildStep.inputLibrary).importedLibraries) { if (element.name == "dart.core") { continue; } ClassElement importUri = element.getType(importType); if (importUri != null) { router.imports.add(element.source?.uri.toString()); break; } else { // 查找exports Set exports = allExportedElements(element); bool exported = false; for (LibraryElement exportElement in exports) { if (exportElement.getType(importType) != null) { exported = true; break; } } if (exported) { router.imports.add(element.source?.uri?.toString()); break; } } } } } catch (e) { print(e); } bool required = e.computeConstantValue()?.getField("required")?.toBoolValue(); page.arguments.add(Argument( e.name, type, required ?? true, )); } } router.routerMap[Path.basename(routerName)] = page; } return null; } Set allExportedElements(LibraryElement element) { Set allElements = Set(); if (element.exports.isEmpty) { return Set()..add(element); } allElements.addAll(element.exportedLibraries); // 查找exports for (LibraryElement exportElement in element.exportedLibraries) { allElements.addAll(allExportedElements(exportElement)); } return allElements; } }