feat: add generators for components proxy and mixins to enable copywith methods
continuous-integration/drone/push Build is failing
continuous-integration/drone/push Build is failing
This commit was merged in pull request #114.
This commit is contained in:
@@ -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',
|
||||
);
|
||||
+97
@@ -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();
|
||||
}
|
||||
}
|
||||
+75
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user