Skip to content

Commit

Permalink
nested form groups
Browse files Browse the repository at this point in the history
  • Loading branch information
vasilich6107 committed Jun 8, 2024
1 parent 61c6bb1 commit 1d44eed
Show file tree
Hide file tree
Showing 14 changed files with 853 additions and 132 deletions.
4 changes: 2 additions & 2 deletions packages/generator_tests/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -436,14 +436,14 @@ packages:
path: "../reactive_forms_annotations"
relative: true
source: path
version: "5.0.0"
version: "6.0.0-beta.1"
reactive_forms_generator:
dependency: "direct dev"
description:
path: "../reactive_forms_generator"
relative: true
source: path
version: "5.0.1"
version: "6.0.0-beta.3"
recase:
dependency: "direct main"
description:
Expand Down
52 changes: 52 additions & 0 deletions packages/generator_tests/test/doc/animated_url_list_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@Timeout(Duration(seconds: 145))
import 'package:test/test.dart';

import '../helpers.dart';

const fileName = 'animated_url_list';

void main() {
group('reactive_forms_generator', () {
test(
'Animated URL list',
() async {
return testGenerator(
fileName: fileName,
model: '''
import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
@Rf()
class UrlO {
final List<UrlEntityO> urlList;
UrlO({@RfArray() this.urlList = const []});
}
@RfGroup()
class UrlEntityO {
final String? label;
final String? url;
UrlEntityO({
@RfControl(validators: [
RequiredValidator(),
])
this.label,
@RfControl(validators: [
RequiredValidator(),
])
this.url,
});
}
''',
generatedFile: generatedFile,
);
},
);
});
}

const generatedFile = r'''
''';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';

part 'url_output.gform.dart';

@Rf()
class UrlO {
final List<UrlEntityO> urlList;

UrlO({@RfArray() this.urlList = const []});
}

@RfGroup()
class UrlEntityO {
final String? label;
final String? url;

UrlEntityO({
@RfControl(validators: [
RequiredValidator(),
])
this.label,
@RfControl(validators: [
RequiredValidator(),
])
this.url,
});
}
35 changes: 17 additions & 18 deletions packages/reactive_forms_generator/lib/reactive_forms_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ library reactive_forms_generator;

import 'dart:async';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:code_builder/code_builder.dart';
Expand Down Expand Up @@ -41,49 +40,49 @@ class ReactiveFormsGenerator extends Generator {
}

final lib = Library(
(b) => b
(b) =>
b
..body.addAll(specList.mergeDuplicatesBy(
(i) => i is Class ? i.name : i,
(a, b) => a,
(i) => i is Class ? i.name : i,
(a, b) => a,
)),
);

// final x = lib.accept(emitter).toString();

final generatedValue =
DartFormatter().format(lib.accept(emitter).toString());
DartFormatter().format(lib.accept(emitter).toString());

final values = <String>[];
await for (var value in normalizeGeneratorOutput(generatedValue)) {
assert(value.length == value.trim().length);
assert(value.length == value
.trim()
.length);
values.add(value);
}

return values.join('\n\n');
}

Future<List<Spec>> generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) async {
Future<List<Spec>> generateForAnnotatedElement(Element element,
ConstantReader annotation,
BuildStep buildStep,) async {
throwIf(
element is! ClassElement,
'${element.name} is not a class element',
element: element,
);

final ast = await buildStep.resolver.astNodeFor(element, resolve: true);
final astElement = element.enclosingElement;

final ast = await buildStep.resolver.astNodeFor(
astElement ?? element,
resolve: true,
);

if (ast == null) {
throw InvalidGenerationSourceError('Ast not found', element: element);
}
if (ast is! Declaration) {
throw InvalidGenerationSourceError(
'Ast is not a Declaration',
element: element,
);
}

return generateLibrary(element as ClassElement, ast);
}
Expand Down
35 changes: 18 additions & 17 deletions packages/reactive_forms_generator/lib/src/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import 'package:recase/recase.dart';
import '../utils.dart';

extension ConstructorElementExt on ConstructorElement {
bool get hasReactiveFormAnnotatedParameters => parameters.any(
(e) => true,
bool get hasReactiveFormAnnotatedParameters =>
parameters.any(
(e) => true,
);
}

extension ClassElementExt on ClassElement {
String get fullTypeName => thisType.toString();

String get fullTypeNameOutput =>
'${thisType.toString()}${output ? 'Output' : ''}';
// String get fullTypeNameOutput =>
// '${thisType.toString()}${output ? 'Output' : ''}';

String get generics {
final generics = genericTypes.map((e) => e.symbol).join(', ');
Expand All @@ -36,19 +37,19 @@ extension ClassElementExt on ClassElement {

Iterable<Reference> get genericTypes {
return thisType.typeArguments.map(
(e) => Reference(e.getDisplayString(withNullability: false)),
(e) => Reference(e.getDisplayString(withNullability: false)),
);
}

Iterable<Reference> get fullGenericTypes {
return thisType.typeArguments.map(
(e) => Reference(e.element?.getDisplayString(withNullability: false)),
(e) => Reference(e.element?.getDisplayString(withNullability: false)),
);
}

List<ParameterElement> get annotatedParameters {
final annotatedConstructors =
constructors.where((e) => e.hasReactiveFormAnnotatedParameters);
constructors.where((e) => e.hasReactiveFormAnnotatedParameters);

if (annotatedConstructors.isNotEmpty) {
return annotatedConstructors.first.parameters;
Expand Down Expand Up @@ -146,7 +147,7 @@ extension ParameterElementExt on ParameterElement {

final type = this.type;
final typeArguments =
type is ParameterizedType ? type.typeArguments : const <DartType>[];
type is ParameterizedType ? type.typeArguments : const <DartType>[];

final typeParameter = typeArguments.first;

Expand All @@ -161,13 +162,13 @@ extension ParameterElementExt on ParameterElement {

final type = this.type;
final typeArguments =
type is ParameterizedType ? type.typeArguments : const <DartType>[];
type is ParameterizedType ? type.typeArguments : const <DartType>[];

final typeParameter = typeArguments.first;

return (typeParameter.element is ClassElement ||
typeParameter.element is EnumElement ||
typeParameter.element is TypeDefiningElement) &&
typeParameter.element is EnumElement ||
typeParameter.element is TypeDefiningElement) &&
!typeParameter.element!.hasRfGroupAnnotation;
}

Expand Down Expand Up @@ -211,8 +212,8 @@ extension FieldElementExt on FieldElement {
typedef IterableFunction<T, U> = U Function(T i);
typedef MergeableFunction<T> = T Function(T oldT, T newT);

Iterable<T> _mergeDuplicatesBy<T, U>(
Iterable<T> list, IterableFunction<T, U> fn, MergeableFunction<T> mergeFn) {
Iterable<T> _mergeDuplicatesBy<T, U>(Iterable<T> list,
IterableFunction<T, U> fn, MergeableFunction<T> mergeFn) {
final values = <U, T>{};
for (var i in list) {
final value = fn(i);
Expand All @@ -221,8 +222,8 @@ Iterable<T> _mergeDuplicatesBy<T, U>(
return values.values.toList();
}

Iterable<T> _removeDuplicatedBy<T, U>(
Iterable<T> list, IterableFunction<T, U> fn) {
Iterable<T> _removeDuplicatedBy<T, U>(Iterable<T> list,
IterableFunction<T, U> fn) {
final values = <U, bool>{};
return list.where((i) {
final value = fn(i);
Expand All @@ -235,8 +236,8 @@ Iterable<T> _removeDuplicatedBy<T, U>(
extension ExtensionsOnIterable<T, U> on Iterable<T> {
/// Merge multiple values from an iterable given a predicate without modifying
/// the original iterable.
Iterable<T> mergeDuplicatesBy(
IterableFunction<T, U> fn, MergeableFunction<T> mergeFn) =>
Iterable<T> mergeDuplicatesBy(IterableFunction<T, U> fn,
MergeableFunction<T> mergeFn) =>
_mergeDuplicatesBy(this, fn, mergeFn);

/// Remove duplicated values from an iterable given a predicate without
Expand Down
Loading

0 comments on commit 1d44eed

Please sign in to comment.