From e231f1416250ad27471fca78828f6a736fb9b06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malo=20L=C3=A9on?= Date: Fri, 19 May 2023 18:46:59 +0200 Subject: [PATCH] feat(gen): add impl of proxy component generator --- .../component_multi_proxy_generator.dart | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 packages/wyatt_component_copy_with_gen/lib/src/generators/component_multi_proxy_generator.dart diff --git a/packages/wyatt_component_copy_with_gen/lib/src/generators/component_multi_proxy_generator.dart b/packages/wyatt_component_copy_with_gen/lib/src/generators/component_multi_proxy_generator.dart new file mode 100644 index 00000000..119e594f --- /dev/null +++ b/packages/wyatt_component_copy_with_gen/lib/src/generators/component_multi_proxy_generator.dart @@ -0,0 +1,101 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:async'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:build/build.dart'; +import 'package:source_gen/source_gen.dart'; +import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart'; + +class ComponentMultiProxyGenerator + extends GeneratorForAnnotation { + @override + FutureOr generateForAnnotatedElement( + Element element, + ConstantReader annotation, + BuildStep buildStep, + ) { + /// Check element type + if (element is! ClassElement) { + throw InvalidGenerationSourceError( + 'Only classes can be annotated with "CopyWith". "$element" is ' + 'not a ClassElement.', + element: element, + ); + } + + final classAnnotation = ComponentProxyExtension( + skipFields: annotation.peek('skipFields')?.boolValue ?? true, + ); + + final multiProxyClassName = + element.displayName.replaceAll('Component', 'MultiProxy'); + final generatedCode = StringBuffer() + ..write( + '@ComponentCopyWithExtension() class ' + '\$$multiProxyClassName extends ${element.displayName} with ' + '\$\$${multiProxyClassName}CWMixin {', + ) + ..write('final bool? freezed; ' + 'final ${element.displayName} Function(BuildContext context) select;') + ..write('\$$multiProxyClassName('); + + if (classAnnotation.skipFields ?? true) { + generatedCode.write('this.select,'); + for (final field in element.constructors.first.parameters + .where((element) => element.isNamed == false)) { + generatedCode.write('super.${field.displayName},'); + } + + generatedCode + ..write('{') + ..write('this.freezed,'); + for (final field in element.constructors.first.parameters + .where((element) => element.isNamed)) { + if (field.isRequiredNamed) { + generatedCode.write('required '); + } + generatedCode.write('super.${field.displayName},'); + } + generatedCode + ..write('});') + ..write(' factory \$$multiProxyClassName.multi( ' + ' ${element.displayName} Function(BuildContext context) test, ' + '{bool freezed = true}) => ' + '\$$multiProxyClassName( ' + 'test, ' + 'freezed: freezed,); ') + ..write( + ' ${element.displayName}? compo; ' + '@override ' + 'Widget build(BuildContext context) { final component = ' + '(compo ??= select(context)).copyWith.call(', + ); + for (final field in element.constructors.first.parameters) { + generatedCode.write('${field.displayName}:${field.displayName},'); + } + generatedCode + ..write(');') + ..write('if (!(freezed ?? true)) { ' + 'compo = null; } ' + 'return component; ' + '}} '); + } + + return generatedCode.toString(); + } +}