Skip to content

Commit 0ace57b

Browse files
FilledStackssebastianbuechlerferraraferEimen2018
authored
breaking: package updates to align with latest versions
* chore(deps): upgrade logger to 2.0.1 (#18) BREAKING CHANGE * upgrade logger to 2.0.1 * exchange pretty printer default values * adjust unit tests for logger * remove warnings --------- Co-authored-by: Fernando Ferrara <[email protected]> * fix: update SDK constraints * refactor: migrate to analyzer element2 API and update dependencies (#48) - Updated imports from `element.dart` to `element2.dart` across multiple files to utilize the new API. - Refactored parameter handling in various generator classes to accommodate changes in the element API. - Enhanced logging functionality with improved PrettyPrinter integration. - Removed redundant comments and improved code formatting for better readability. - Updated pubspec.yaml to reflect new dependency versions and SDK constraints. - Modified test cases to ensure compatibility with async operations. * Fix Unit Tests & Introduce AST Based Validation (#49) * Adds support for nested route naming with parent class context * refactor: update form view model extensions and improve validation logic * test: implement AST-based validation for router class generation * fix: remove unnecessary formatting fix command and ensure newline at end of file in tests --------- Co-authored-by: Sebastian Büchler <[email protected]> Co-authored-by: Fernando Ferrara <[email protected]> Co-authored-by: Aymen Nurhussen <[email protected]>
1 parent 178dc17 commit 0ace57b

File tree

51 files changed

+1365
-485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1365
-485
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
with:
1919
channel: 'stable'
2020
- run: dart pub get
21-
- run: dart format --fix .
21+
- run: dart format .
2222
- run: dart analyze
2323
- run: flutter test --coverage
2424
- name: Setup LCOV

lib/import_resolver.dart

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,50 @@
1-
import 'package:analyzer/dart/element/element.dart';
1+
import 'package:analyzer/dart/element/element2.dart';
22
import 'package:analyzer/dart/element/type.dart';
33
import 'package:path/path.dart' as p;
44

55
class ImportResolver {
6-
final List<LibraryElement> libs;
6+
final List<LibraryElement2> libs;
77
final String targetFilePath;
88

99
const ImportResolver(this.libs, this.targetFilePath);
1010

11-
String? resolve(Element? element) {
11+
String? resolve(Element2? element) {
1212
// return early if source is null or element is a core type
13-
if (element?.source == null || _isCoreDartType(element)) {
13+
if (element?.firstFragment.libraryFragment?.source == null ||
14+
_isCoreDartType(element)) {
1415
return null;
1516
}
1617

1718
for (var lib in libs) {
1819
if (_isCoreDartType(lib)) continue;
1920

20-
if (lib.exportNamespace.definedNames.keys.contains(element?.name)) {
21-
final package = lib.source.uri.pathSegments.first;
21+
if (lib.exportNamespace.definedNames2.keys
22+
.contains(element?.firstFragment.name2)) {
23+
final package =
24+
lib.firstFragment.libraryFragment?.source.uri.pathSegments.first;
2225
if (targetFilePath.startsWith(RegExp('^$package/'))) {
2326
return p.posix
24-
.relative(element?.source?.uri.path ?? '', from: targetFilePath)
27+
.relative(
28+
element?.firstFragment.libraryFragment?.source.uri.path ?? '',
29+
from: targetFilePath)
2530
.replaceFirst('../', '');
2631
} else {
27-
return element?.source?.uri.toString();
32+
return element?.firstFragment.libraryFragment?.source.uri.toString();
2833
}
2934
}
3035
}
3136

3237
return null;
3338
}
3439

35-
bool _isCoreDartType(Element? element) {
36-
return element?.source?.fullName == 'dart:core';
40+
bool _isCoreDartType(Element2? element) {
41+
return element?.firstFragment.libraryFragment?.source.fullName ==
42+
'dart:core';
3743
}
3844

3945
Set<String> resolveAll(DartType type) {
4046
final imports = <String>{};
41-
final resolvedValue = resolve(type.element);
47+
final resolvedValue = resolve(type.element3);
4248
if (resolvedValue != null) {
4349
imports.add(resolvedValue);
4450
}
@@ -50,7 +56,7 @@ class ImportResolver {
5056
final imports = <String>{};
5157
if (typeToCheck is ParameterizedType) {
5258
for (DartType type in typeToCheck.typeArguments) {
53-
final resolvedValue = resolve(type.element);
59+
final resolvedValue = resolve(type.element3);
5460
if (resolvedValue != null) {
5561
imports.add(resolvedValue);
5662
}

lib/src/generators/bottomsheets/resolve/bottomsheet_config_resolver.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:analyzer/dart/constant/value.dart';
2-
import 'package:analyzer/dart/element/element.dart';
2+
import 'package:analyzer/dart/element/element2.dart';
33
import 'package:source_gen/source_gen.dart';
44
import 'package:stacked_generator/import_resolver.dart';
55
import 'package:stacked_generator/src/generators/bottomsheets/bottomsheet_config.dart';
@@ -21,7 +21,7 @@ class BottomsheetConfigResolver {
2121
final bottomsheetClassType =
2222
bottomsheetReader.read('classType').typeValue;
2323

24-
final classElement = bottomsheetClassType.element as ClassElement?;
24+
final classElement = bottomsheetClassType.element3 as ClassElement2?;
2525

2626
// Get the import of the class type that's defined for the bottomSheet
2727
final import = importResolver.resolve(classElement!);

lib/src/generators/bottomsheets/resolve/stacked_bottomsheet_generator.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import 'dart:async';
22

3-
import 'package:analyzer/dart/element/element.dart';
3+
import 'package:analyzer/dart/element/element2.dart';
44
import 'package:build/build.dart';
55
import 'package:source_gen/source_gen.dart';
6-
import 'package:stacked_shared/stacked_shared.dart';
76
import 'package:stacked_generator/import_resolver.dart';
87
import 'package:stacked_generator/src/generators/bottomsheets/generate/bottomsheet_class_generator.dart';
8+
import 'package:stacked_shared/stacked_shared.dart';
99

1010
import 'bottomsheet_config_resolver.dart';
1111

1212
class StackedBottomsheetGenerator extends GeneratorForAnnotation<StackedApp> {
1313
@override
1414
FutureOr<String> generateForAnnotatedElement(
15-
Element element,
15+
Element2 element,
1616
ConstantReader annotation,
1717
BuildStep buildStep,
1818
) async {
1919
final bottomsheetResolver = BottomsheetConfigResolver();
2020
final libs = await buildStep.resolver.libraries.toList();
21-
final importResolver = ImportResolver(libs, element.source?.uri.path ?? '');
21+
final importResolver = ImportResolver(
22+
libs, element.firstFragment.libraryFragment?.source.uri.path ?? '');
2223

2324
/// If the bottomsheets parameter is not mentioned in the StackedApp
2425
/// return empty string

lib/src/generators/dialogs/resolve/dialog_config_resolver.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:analyzer/dart/constant/value.dart';
2-
import 'package:analyzer/dart/element/element.dart';
2+
import 'package:analyzer/dart/element/element2.dart';
33
import 'package:source_gen/source_gen.dart';
44
import 'package:stacked_generator/import_resolver.dart';
55
import 'package:stacked_generator/src/generators/dialogs/dialog_config.dart';
@@ -21,7 +21,7 @@ class DialogConfigResolver {
2121
// Get the type of the dialog that we want to register
2222
final dialogClassType = dialogReader.read('classType').typeValue;
2323

24-
final classElement = dialogClassType.element as ClassElement?;
24+
final classElement = dialogClassType.element3 as ClassElement2?;
2525

2626
// Get the import of the class type that's defined for the dialog
2727
final import = importResolver.resolve(classElement!);

lib/src/generators/dialogs/resolve/stacked_dialog_generator.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import 'dart:async';
22

3-
import 'package:analyzer/dart/element/element.dart';
3+
import 'package:analyzer/dart/element/element2.dart';
44
import 'package:build/build.dart';
55
import 'package:source_gen/source_gen.dart';
6-
import 'package:stacked_shared/stacked_shared.dart';
76
import 'package:stacked_generator/import_resolver.dart';
87
import 'package:stacked_generator/src/generators/dialogs/generate/dialog_class_generator.dart';
8+
import 'package:stacked_shared/stacked_shared.dart';
99

1010
import 'dialog_config_resolver.dart';
1111

1212
class StackedDialogGenerator extends GeneratorForAnnotation<StackedApp> {
1313
@override
1414
FutureOr<String> generateForAnnotatedElement(
15-
Element element,
15+
Element2 element,
1616
ConstantReader annotation,
1717
BuildStep buildStep,
1818
) async {
1919
final dialogResolver = DialogConfigResolver();
2020
final libs = await buildStep.resolver.libraries.toList();
21-
final importResolver = ImportResolver(libs, element.source?.uri.path ?? '');
21+
final importResolver = ImportResolver(
22+
libs, element.firstFragment.libraryFragment?.source.uri.path ?? '');
2223

2324
/// If the dialogs parameter is not mentioned in the StackedApp
2425
/// return empty string

lib/src/generators/exceptions/invalid_generator_input_exception.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import 'package:analyzer/dart/element/element.dart';
1+
import 'package:analyzer/dart/element/element2.dart';
22

33
class InvalidGeneratorInputException implements Exception {
44
final String message;
55
final String? todo;
6-
final Element? element;
6+
final Element2? element;
77
const InvalidGeneratorInputException(this.message, {this.todo, this.element});
88

99
@override

lib/src/generators/forms/field_config.dart

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ignore_for_file: unnecessary_this
22

3-
import 'package:analyzer/dart/element/element.dart';
3+
import 'package:analyzer/dart/element/element2.dart';
44

55
/// Described a single field to be generated.
66
///
@@ -17,21 +17,20 @@ class TextFieldConfig extends FieldConfig {
1717
final ExecutableElementData? validatorFunction;
1818
final ExecutableElementData? customTextEditingController;
1919
const TextFieldConfig({
20-
required String name,
20+
required super.name,
2121
this.initialValue,
2222
this.validatorFunction,
2323
this.customTextEditingController,
24-
}) : super(name: name);
24+
});
2525
}
2626

2727
class DateFieldConfig extends FieldConfig {
28-
const DateFieldConfig({required String name}) : super(name: name);
28+
const DateFieldConfig({required super.name});
2929
}
3030

3131
class DropdownFieldConfig extends FieldConfig {
3232
final List<DropdownFieldItem> items;
33-
const DropdownFieldConfig({required String name, required this.items})
34-
: super(name: name);
33+
const DropdownFieldConfig({required super.name, required this.items});
3534
}
3635

3736
class DropdownFieldItem {
@@ -56,13 +55,15 @@ class ExecutableElementData {
5655
});
5756

5857
factory ExecutableElementData.fromExecutableElement(
59-
ExecutableElement executableElement) {
58+
ExecutableElement2 executableElement) {
6059
return ExecutableElementData(
61-
returnType: executableElement.declaration.returnType.toString(),
62-
enclosingElementName: executableElement.enclosingElementName,
63-
hasEnclosingElementName: executableElement.hasEnclosingElementName,
64-
validatorName: executableElement.validatorName,
65-
validatorPath: executableElement.validatorPath);
60+
returnType: executableElement.firstFragment.element.returnType.toString(),
61+
enclosingElementName: executableElement.enclosingElement2?.name3,
62+
hasEnclosingElementName:
63+
executableElement.enclosingElement2?.name3 != null,
64+
validatorName: executableElement.validatorName,
65+
validatorPath: executableElement.validatorPath,
66+
);
6667
}
6768
}
6869

@@ -77,11 +78,12 @@ extension ListOfFieldConfigs on List<FieldConfig> {
7778
this.whereType<DropdownFieldConfig>().map((t) => t).toList();
7879
}
7980

80-
extension ExecutableElementDataExtension on ExecutableElement? {
81-
String? get validatorPath => this?.source.uri.toString();
81+
extension ExecutableElementDataExtension on ExecutableElement2? {
82+
String? get validatorPath =>
83+
this?.firstFragment.libraryFragment.source.uri.toString();
8284
String? get validatorName => hasEnclosingElementName
83-
? '$enclosingElementName.${this?.name}'
84-
: this?.name;
85+
? '$enclosingElementName.${this?.name3}'
86+
: this?.name3;
8587
bool get hasEnclosingElementName => enclosingElementName != null;
86-
String? get enclosingElementName => this?.enclosingElement.name;
88+
String? get enclosingElementName => this?.enclosingElement2?.name3;
8789
}

lib/src/generators/forms/form_builder.dart

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class FormBuilder with StringBufferUtils {
5656
}
5757

5858
FormBuilder addAnnotationOptions() {
59+
if (fields.onlyTextFieldConfigs.isEmpty) return this;
5960
newLine();
6061
writeLine(
6162
"const bool _autoTextFieldValidation = $autoTextFieldValidation;",
@@ -169,7 +170,7 @@ class FormBuilder with StringBufferUtils {
169170
FormBuilder addGetTextEditingController() {
170171
if (fields.onlyTextFieldConfigs.isEmpty) return this;
171172
newLine();
172-
writeLine('''
173+
writeLine('''
173174
TextEditingController _getFormTextEditingController(
174175
String key, {
175176
String? initialValue,
@@ -220,7 +221,7 @@ class FormBuilder with StringBufferUtils {
220221
if (fields.onlyTextFieldConfigs.isEmpty) return this;
221222

222223
newLine();
223-
writeLine('''
224+
writeLine('''
224225
FocusNode _getFormFocusNode(String key) {
225226
if (_${viewName}FocusNodes.containsKey(key)) {
226227
return _${viewName}FocusNodes[key]!;}
@@ -246,9 +247,11 @@ class FormBuilder with StringBufferUtils {
246247
}
247248

248249
newLine();
249-
writeLine(
250-
"_updateFormData(model, forceValidate: _autoTextFieldValidation);",
251-
);
250+
if (fields.onlyTextFieldConfigs.isNotEmpty) {
251+
writeLine(
252+
"_updateFormData(model, forceValidate: _autoTextFieldValidation);",
253+
);
254+
}
252255
writeLine('}');
253256
newLine();
254257

@@ -269,9 +272,11 @@ class FormBuilder with StringBufferUtils {
269272
}
270273

271274
newLine();
272-
writeLine(
273-
"_updateFormData(model, forceValidate: _autoTextFieldValidation);",
274-
);
275+
if (fields.onlyTextFieldConfigs.isNotEmpty) {
276+
writeLine(
277+
"_updateFormData(model, forceValidate: _autoTextFieldValidation);",
278+
);
279+
}
275280
writeLine('}');
276281
newLine();
277282
return this;
@@ -385,8 +390,13 @@ class FormBuilder with StringBufferUtils {
385390

386391
newLine();
387392
writeLine("""bool get isFormValid {
388-
if (!_autoTextFieldValidation) this.validateForm();
389-
393+
""");
394+
if (fields.onlyTextFieldConfigs.isNotEmpty) {
395+
writeLine("""
396+
if (!_autoTextFieldValidation) this.validateForm();
397+
""");
398+
}
399+
writeLine("""
390400
return !hasAnyValidationMessage;
391401
}""");
392402

@@ -482,12 +492,13 @@ class FormBuilder with StringBufferUtils {
482492
${_getFormKeyName(caseName)}: selectedDate}),
483493
);
484494
}
485-
486-
if (_autoTextFieldValidation) {
487-
this.validateForm();
488-
}
489-
}
490495
''');
496+
if (fields.onlyTextFieldConfigs.isNotEmpty) {
497+
writeLine(
498+
"if (_autoTextFieldValidation) this.validateForm();",
499+
);
500+
}
501+
writeLine('}');
491502
newLine();
492503
}
493504

@@ -499,12 +510,13 @@ class FormBuilder with StringBufferUtils {
499510
this.setData(
500511
this.formValueMap..addAll({${_getFormKeyName(caseName)}: ${caseName.camelCase}}),
501512
);
502-
503-
if (_autoTextFieldValidation) {
504-
this.validateForm();
505-
}
506-
}
507513
''');
514+
if (fields.onlyTextFieldConfigs.isNotEmpty) {
515+
writeLine(
516+
"if (_autoTextFieldValidation) this.validateForm();",
517+
);
518+
}
519+
writeLine('}');
508520
newLine();
509521
}
510522

@@ -513,7 +525,7 @@ class FormBuilder with StringBufferUtils {
513525
for (final field in fields) {
514526
final caseName = ReCase(field.name);
515527
writeLine(
516-
'set${caseName.pascalCase}ValidationMessage(String? validationMessage) => this.fieldsValidationMessages[${_getFormKeyName(caseName)}] = validationMessage;');
528+
'void set${caseName.pascalCase}ValidationMessage(String? validationMessage) => this.fieldsValidationMessages[${_getFormKeyName(caseName)}] = validationMessage;');
517529
}
518530

519531
// Write out the clearForm method

0 commit comments

Comments
 (0)