feat: add generators for components proxy and mixins to enable copywith methods
continuous-integration/drone/push Build is failing

This commit was merged in pull request #114.
This commit is contained in:
AN12345
2023-02-06 18:42:34 +01:00
parent b025247002
commit 46c51525e8
20 changed files with 662 additions and 0 deletions
@@ -0,0 +1,21 @@
// 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 <https://www.gnu.org/licenses/>.
/// Generator for copywith method for components
library component_copy_with_gen;
export 'src/builder.dart';
export 'src/generators/component_copy_with_generator.dart';
@@ -0,0 +1,28 @@
// 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 <https://www.gnu.org/licenses/>.
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'package:wyatt_component_copy_with_gen/src/generators/component_copy_with_generator.dart';
import 'package:wyatt_component_copy_with_gen/src/generators/component_proxy_generator.dart';
Builder componentCopyWithReporter(BuilderOptions options) => SharedPartBuilder(
[
ComponentProxyGenerator(),
ComponentCopyWithGenerator(),
],
'component_copy_with',
);
@@ -0,0 +1,97 @@
// 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 <https://www.gnu.org/licenses/>.
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/component_copy_with_extension.dart';
class ComponentCopyWithGenerator
extends GeneratorForAnnotation<ComponentCopyWithExtension> {
@override
FutureOr<String> 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 = ComponentCopyWithExtension(
skipFields: annotation.peek('skipFields')?.boolValue ?? true,
);
final generatedCode = StringBuffer()
// Generate CopyWith Proxy implementation.
..write('class \$${element.displayName}CWProxyImpl implements '
'\$${element.supertype?.getDisplayString(
withNullability: false,
)}CWProxy { '
'const \$${element.displayName}CWProxyImpl '
'(this._value); '
'final ${element.displayName} _value;');
if (classAnnotation.skipFields ?? true) {
for (final superField
in element.supertype!.element.constructors.first.parameters) {
final superFieldDisplayName = superField.displayName;
generatedCode.write('@override ${element.displayName} '
'$superFieldDisplayName(${superField.type.getDisplayString(
withNullability: false,
)}? '
' $superFieldDisplayName)'
' => this($superFieldDisplayName : $superFieldDisplayName); ');
}
}
generatedCode.write('@override ${element.displayName} call ({');
for (final superField
in element.supertype!.element.constructors.first.parameters) {
final superFieldDisplayName = superField.displayName;
generatedCode.write('${superField.type.getDisplayString(
withNullability: false,
)}? $superFieldDisplayName,');
}
generatedCode.write('})=>${element.displayName}(');
for (final superField in element.constructors.first.parameters) {
final superFieldDisplayName = superField.displayName;
generatedCode.write('$superFieldDisplayName:$superFieldDisplayName?? '
'_value.$superFieldDisplayName,');
}
generatedCode
..write(');}')
..write(
'mixin \$${element.displayName}CWMixin on Component { '
'\$${element.supertype?.element.displayName}CWProxy get copyWith => '
'\$${element.displayName}CWProxyImpl(this as ${element.displayName});}',
);
return generatedCode.toString();
}
}
@@ -0,0 +1,75 @@
// 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 <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'package:wyatt_component_copy_with_extension/component_copy_with_extension.dart';
class ComponentProxyGenerator
extends GeneratorForAnnotation<ComponentProxyExtension> {
@override
FutureOr<String> 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 generatedCode = StringBuffer()
..write('abstract class \$${element.displayName}CWProxy {');
if (classAnnotation.skipFields ?? true) {
for (final field in element.constructors.first.parameters) {
generatedCode.write(
'${element.displayName} '
'${field.displayName}(${field.type.getDisplayString(
withNullability: false,
)}? '
'${field.displayName});',
);
}
}
generatedCode.write('${element.displayName} call({');
for (final field in element.constructors.first.parameters) {
if (field.type.nullabilitySuffix == NullabilitySuffix.question) {
generatedCode.write('${field.type.getDisplayString(
withNullability: false,
)}? ${field.displayName}, ');
}
}
generatedCode.write('});}');
return generatedCode.toString();
}
}