router_generator.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import 'package:analyzer/dart/element/element.dart';
  2. import 'package:build/build.dart';
  3. import 'package:router_gen/annotation/router_page.dart';
  4. import 'package:router_gen/annotation/router_param.dart';
  5. import 'package:router_gen/model/router.dart';
  6. import 'package:router_gen/util/utils.dart';
  7. import 'package:source_gen/source_gen.dart';
  8. import 'package:path/path.dart' as Path;
  9. /// save router annotation
  10. class RouterGenerator extends GeneratorForAnnotation<RouterPage> {
  11. final _paramChecker = const TypeChecker.fromRuntime(RouterParam);
  12. @override
  13. generateForAnnotatedElement(
  14. Element element, ConstantReader annotation, BuildStep buildStep) async {
  15. if (element.kind == ElementKind.CLASS) {
  16. router.imports.add(getImportStr(buildStep));
  17. String path = buildStep.inputId.path; // lib/xxx.dart
  18. String basename = Path.basename(buildStep.inputId.path); // xxx.dart
  19. // router name
  20. String className = element.name;
  21. String aptPath = annotation.peek("path")?.stringValue;
  22. String routerName =
  23. toCamelCase(aptPath == null || aptPath.isEmpty ? className : aptPath);
  24. var page = Page();
  25. page.name = className;
  26. page.path = routerName.startsWith("/")
  27. ? routerName
  28. : Path.join(path.replaceFirst("lib", "").replaceFirst(basename, ""),
  29. routerName);
  30. page.arguments = [];
  31. for (FieldElement e in (element as ClassElement).fields) {
  32. if (_paramChecker.hasAnnotationOf(e)) {
  33. String type = e.type.getDisplayString(withNullability: false);
  34. try {
  35. Set<String> types = getType(type);
  36. for (String importType in types) {
  37. // not container all type
  38. if (isSpeciousType(importType) == false) {
  39. continue;
  40. }
  41. print("specious type ${importType}");
  42. // 添加到imports
  43. for (LibraryElement element
  44. in (await buildStep.inputLibrary).importedLibraries) {
  45. if (element.name == "dart.core") {
  46. continue;
  47. }
  48. ClassElement importUri = element.getType(importType);
  49. if (importUri != null) {
  50. router.imports.add(element.source?.uri.toString());
  51. break;
  52. } else {
  53. // 查找exports
  54. Set<LibraryElement> exports = allExportedElements(element);
  55. bool exported = false;
  56. for (LibraryElement exportElement in exports) {
  57. if (exportElement.getType(importType) != null) {
  58. exported = true;
  59. break;
  60. }
  61. }
  62. if (exported) {
  63. router.imports.add(element.source?.uri?.toString());
  64. break;
  65. }
  66. }
  67. }
  68. }
  69. } catch (e) {
  70. print(e);
  71. }
  72. bool required =
  73. e.computeConstantValue()?.getField("required")?.toBoolValue();
  74. page.arguments.add(Argument(
  75. e.name,
  76. type,
  77. required ?? true,
  78. ));
  79. }
  80. }
  81. router.routerMap[Path.basename(routerName)] = page;
  82. }
  83. return null;
  84. }
  85. Set<LibraryElement> allExportedElements(LibraryElement element) {
  86. Set<LibraryElement> allElements = Set();
  87. if (element.exports.isEmpty) {
  88. return Set()..add(element);
  89. }
  90. allElements.addAll(element.exportedLibraries);
  91. // 查找exports
  92. for (LibraryElement exportElement in element.exportedLibraries) {
  93. allElements.addAll(allExportedElements(exportElement));
  94. }
  95. return allElements;
  96. }
  97. }