Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions lib/import_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,41 @@ class ImportResolver {

String? resolve(Element2? element) {
// return early if source is null or element is a core type
if (element?.firstFragment.libraryFragment?.source == null ||
_isCoreDartType(element)) {
final elementSourceUri = _sourceUriOfElement(element);
if (elementSourceUri == null || _isCoreDartType(element)) {
return null;
}

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

if (lib.exportNamespace.definedNames2.keys
.contains(element?.firstFragment.name2)) {
final package =
lib.firstFragment.libraryFragment?.source.uri.pathSegments.first;
if (lib.exportNamespace.definedNames2.values.contains(element)) {
final packageSourceUri = lib.firstFragment.source.uri;
final package = packageSourceUri.pathSegments.first;
if (targetFilePath.startsWith(RegExp('^$package/'))) {
return p.posix
.relative(
element?.firstFragment.libraryFragment?.source.uri.path ?? '',
from: targetFilePath)
.relative(elementSourceUri.path, from: targetFilePath)
.replaceFirst('../', '');
} else {
return element?.firstFragment.libraryFragment?.source.uri.toString();
return elementSourceUri.toString();
}
}
}

return null;
}

bool _isCoreDartType(Element2? element) {
return element?.firstFragment.libraryFragment?.source.fullName ==
'dart:core';
bool _isCoreDartType(Element? element) {
if (element == null) {
return false;
}
return element is LibraryElement
? element.isDartCore
: element.library?.isDartCore ?? false;
}

Uri? _sourceUriOfElement(Element? element) {
return element?.firstFragment.libraryFragment?.source.uri;
}

Set<String> resolveAll(DartType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class StackedBottomsheetGenerator extends GeneratorForAnnotation<StackedApp> {
final bottomsheetResolver = BottomsheetConfigResolver();
final libs = await buildStep.resolver.libraries.toList();
final importResolver = ImportResolver(
libs, element.firstFragment.libraryFragment?.source.uri.path ?? '');
libs,
element.firstFragment.libraryFragment?.source.uri.path ?? '',
);

/// If the bottomsheets parameter is not mentioned in the StackedApp
/// return empty string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class StackedDialogGenerator extends GeneratorForAnnotation<StackedApp> {
final dialogResolver = DialogConfigResolver();
final libs = await buildStep.resolver.libraries.toList();
final importResolver = ImportResolver(
libs, element.firstFragment.libraryFragment?.source.uri.path ?? '');
libs,
element.firstFragment.libraryFragment?.source.uri.path ?? '',
);

/// If the dialogs parameter is not mentioned in the StackedApp
/// return empty string
Expand Down
27 changes: 17 additions & 10 deletions lib/src/generators/forms/field_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ class ExecutableElementData {
});

factory ExecutableElementData.fromExecutableElement(
ExecutableElement2 executableElement) {
ExecutableElement executableElement) {
final enclosingElementName = executableElement.enclosingElement?.name;
return ExecutableElementData(
returnType: executableElement.firstFragment.element.returnType.toString(),
enclosingElementName: executableElement.enclosingElement2?.name3,
returnType: executableElement.returnType.toString(),
enclosingElementName: enclosingElementName,
hasEnclosingElementName:
executableElement.enclosingElement2?.name3 != null,
enclosingElementName != null && enclosingElementName.isNotEmpty,
validatorName: executableElement.validatorName,
validatorPath: executableElement.validatorPath,
);
Expand All @@ -78,12 +79,18 @@ extension ListOfFieldConfigs on List<FieldConfig> {
this.whereType<DropdownFieldConfig>().map((t) => t).toList();
}

extension ExecutableElementDataExtension on ExecutableElement2? {
extension ExecutableElementDataExtension on ExecutableElement? {
String? get validatorPath =>
this?.firstFragment.libraryFragment.source.uri.toString();
String? get validatorName => hasEnclosingElementName
? '$enclosingElementName.${this?.name3}'
: this?.name3;
bool get hasEnclosingElementName => enclosingElementName != null;
String? get enclosingElementName => this?.enclosingElement2?.name3;
String? get validatorName {
final enclosingName = enclosingElementName;
if (enclosingName != null && enclosingName.isNotEmpty) {
return '$enclosingName.${this?.name}';
}
return this?.name;
}

bool get hasEnclosingElementName =>
enclosingElementName != null && enclosingElementName!.isNotEmpty;
String? get enclosingElementName => this?.enclosingElement?.name;
}
38 changes: 35 additions & 3 deletions lib/src/generators/forms/form_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ class FormBuilder with StringBufferUtils {
);
for (var field in fields.onlyTextFieldConfigs) {
final caseName = ReCase(field.name);
final validatorName =
_sanitizeExecutableReference(field.validatorFunction?.validatorName);
writeLine(
"${_getFormKeyName(caseName)}: ${field.validatorFunction?.validatorName},",
);
"${_getFormKeyName(caseName)}: ${validatorName ?? 'null'},");
}
writeLine("};");
newLine();
Expand Down Expand Up @@ -187,6 +188,14 @@ class FormBuilder with StringBufferUtils {
return this;
}

@Deprecated(
'Use addGetTextEditingController instead. '
'This alias exists for backwards compatibility.',
)
FormBuilder addGetTextEditinController() {
return addGetTextEditingController();
}

FormBuilder addGetCustomTextEditingController() {
final textFieldsConfigs = fields.onlyTextFieldConfigs
.where((element) => element.customTextEditingController != null);
Expand All @@ -197,7 +206,11 @@ class FormBuilder with StringBufferUtils {

for (var tf in textFieldsConfigs) {
final customTextEditingClassNameAndCallingFunction =
tf.customTextEditingController!.validatorName;
_sanitizeExecutableReference(
tf.customTextEditingController!.validatorName,
) ??
tf.customTextEditingController!.validatorName ??
'';
final customTextEditingClassName =
tf.customTextEditingController!.returnType;
newLine();
Expand Down Expand Up @@ -233,6 +246,14 @@ class FormBuilder with StringBufferUtils {
return this;
}

@Deprecated(
'Use addGetFocusNode instead. '
'This alias exists for backwards compatibility.',
)
FormBuilder addGetFocuNode() {
return addGetFocusNode();
}

FormBuilder addListenerRegistrationsForTextFields() {
writeLine('''
/// Registers a listener on every generated controller that calls [model.setData()]
Expand Down Expand Up @@ -594,4 +615,15 @@ class FormBuilder with StringBufferUtils {
String _getControllerName(FieldConfig field) =>
'${field.name.camelCase}Controller';
String _getFormKeyName(ReCase caseName) => '${caseName.pascalCase}ValueKey';

String? _sanitizeExecutableReference(String? reference) {
if (reference == null) return null;

var sanitized = reference.trim();
while (sanitized.startsWith('.')) {
sanitized = sanitized.substring(1);
}

return sanitized.isEmpty ? null : sanitized;
}
}
24 changes: 14 additions & 10 deletions lib/src/generators/forms/stacked_form_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ class StackedFormGenerator extends GeneratorForAnnotation<FormView> {
BuildStep buildStep,
) async {
var libs = await buildStep.resolver.libraries.toList();
var importResolver = ImportResolver(
libs,
classForAnnotation.firstFragment.libraryFragment?.source.uri.path ??
'');
var importResolver =
ImportResolver(libs, classForAnnotation.firstFragment.libraryFragment?.source.uri.path ?? '');

final viewName = classForAnnotation.displayName;

Expand Down Expand Up @@ -57,12 +55,18 @@ FieldConfig _readFieldConfig({
}) {
var fieldReader = ConstantReader(fieldConfig);

bool isTextField =
fieldReader.instanceOf(const TypeChecker.fromRuntime(FormTextField));
bool isDateField =
fieldReader.instanceOf(const TypeChecker.fromRuntime(FormDateField));
bool isDropdownField =
fieldReader.instanceOf(const TypeChecker.fromRuntime(FormDropdownField));
bool isTextField = fieldReader.instanceOf(const TypeChecker.typeNamed(
FormTextField,
inPackage: 'stacked_shared',
));
bool isDateField = fieldReader.instanceOf(const TypeChecker.typeNamed(
FormDateField,
inPackage: 'stacked_shared',
));
bool isDropdownField = fieldReader.instanceOf(const TypeChecker.typeNamed(
FormDropdownField,
inPackage: 'stacked_shared',
));

if (isTextField) {
return _readTextFieldConfig(
Expand Down
39 changes: 27 additions & 12 deletions lib/src/generators/getit/dependency_config_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ import 'dependency_config/factory_param_dependency.dart';
import 'dependency_config/initializable_singleton_dependency.dart';
import 'dependency_config/lazy_singleton.dart';

const _initializableSingletonChecker = TypeChecker.typeNamed(
InitializableSingleton,
inPackage: 'stacked_shared',
);
const _factoryWithParamChecker = TypeChecker.typeNamed(
FactoryWithParam,
inPackage: 'stacked_shared',
);

class DependencyConfigFactory {
static DependencyConfig fromResolver({
required DartObject dependencyConfig,
Expand Down Expand Up @@ -64,7 +73,10 @@ class DependencyConfigFactory {
// NOTE: This can be used for actual dependency inject. We do service location instead.
final constructor = classElement.unnamedConstructor2;

if (dependencyReader.instanceOf(const TypeChecker.fromRuntime(Factory))) {
if (dependencyReader.instanceOf(const TypeChecker.typeNamed(
Factory,
inPackage: 'stacked_shared',
))) {
return FactoryDependency(
instanceName: instanceName,
import: import!,
Expand All @@ -73,8 +85,10 @@ class DependencyConfigFactory {
abstractedImport: abstractedImport,
environments: environments,
);
} else if (dependencyReader
.instanceOf(const TypeChecker.fromRuntime(Singleton))) {
} else if (dependencyReader.instanceOf(const TypeChecker.typeNamed(
Singleton,
inPackage: 'stacked_shared',
))) {
final ConstantReader? resolveUsing =
dependencyReader.peek('resolveUsing');
final resolveObject = resolveUsing?.objectValue.toFunctionValue2();
Expand All @@ -87,8 +101,10 @@ class DependencyConfigFactory {
abstractedImport: abstractedImport,
environments: environments,
resolveFunction: resolveObject?.displayName);
} else if (dependencyReader
.instanceOf(const TypeChecker.fromRuntime(LazySingleton))) {
} else if (dependencyReader.instanceOf(const TypeChecker.typeNamed(
LazySingleton,
inPackage: 'stacked_shared',
))) {
final ConstantReader? resolveUsing =
dependencyReader.peek('resolveUsing');
final resolveObject = resolveUsing?.objectValue.toFunctionValue2();
Expand All @@ -101,9 +117,10 @@ class DependencyConfigFactory {
abstractedImport: abstractedImport,
environments: environments,
resolveFunction: resolveObject?.displayName);
} else if (dependencyReader
// ignore: deprecated_member_use
.instanceOf(const TypeChecker.fromRuntime(Presolve))) {
} else if (dependencyReader.instanceOf(const TypeChecker.typeNamed(
Presolve,
inPackage: 'stacked_shared',
))) {
final ConstantReader? presolveUsing =
dependencyReader.peek('presolveUsing');
final presolveObject = presolveUsing?.objectValue.toFunctionValue2();
Expand All @@ -115,8 +132,7 @@ class DependencyConfigFactory {
abstractedImport: abstractedImport,
environments: environments,
presolveFunction: presolveObject?.displayName);
} else if (dependencyReader
.instanceOf(const TypeChecker.fromRuntime(InitializableSingleton))) {
} else if (dependencyReader.instanceOf(_initializableSingletonChecker)) {
return InitializableSingletonDependency(
instanceName: instanceName,
import: import!,
Expand All @@ -125,8 +141,7 @@ class DependencyConfigFactory {
abstractedImport: abstractedImport,
environments: environments,
);
} else if (dependencyReader
.instanceOf(const TypeChecker.fromRuntime(FactoryWithParam))) {
} else if (dependencyReader.instanceOf(_factoryWithParamChecker)) {
final Set<FactoryParameter> clazzParams = {};
var params = constructor?.formalParameters;
if (params?.isNotEmpty == true && constructor != null) {
Expand Down
25 changes: 16 additions & 9 deletions lib/src/generators/getit/stacked_locator_content_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ class StackedLocatorContentGenerator
});
@override
String generate() {
final hasRouterService = dependencies
.any((depdenency) => depdenency.className == 'RouterService');
final hasRouterService = dependencies.any(
(depdenency) => depdenency.className == 'RouterService',
);
writeLine(
"// ignore_for_file: public_member_api_docs, implementation_imports, depend_on_referenced_packages");
"// ignore_for_file: public_member_api_docs, implementation_imports, depend_on_referenced_packages",
);

_generateImports(dependencies);
if (hasRouterService) {
Expand All @@ -31,23 +33,28 @@ class StackedLocatorContentGenerator
writeLine('final $locatorName = StackedLocator.instance;');
newLine();

writeLine(
'Future<void> $locatorSetupName ({String? environment , EnvironmentFilter? environmentFilter,${hasRouterService ? ' StackedRouterWeb? stackedRouter,' : ''}}) async {',
);
final setupParameters = <String>[
'String? environment',
'EnvironmentFilter? environmentFilter',
if (hasRouterService) 'StackedRouterWeb? stackedRouter',
].join(' , ');
writeLine('Future<void> $locatorSetupName ({$setupParameters}) async {');

newLine();
writeLine('// Register environments');

writeLine(
'$locatorName.registerEnvironment(environment: environment, environmentFilter: environmentFilter);');
'$locatorName.registerEnvironment(environment: environment, environmentFilter: environmentFilter);',
);

newLine();
writeLine('// Register dependencies');

// Loop through all service definitions and generate the code for it
for (final dependency in dependencies) {
final registerDependenciesCode =
dependency.registerDependencies(locatorName);
final registerDependenciesCode = dependency.registerDependencies(
locatorName,
);
writeLine(registerDependenciesCode);
}

Expand Down
4 changes: 3 additions & 1 deletion lib/src/generators/getit/stacked_locator_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class StackedLocatorGenerator extends GeneratorForAnnotation<StackedApp> {
) async {
final libs = await buildStep.resolver.libraries.toList();
final importResolver = ImportResolver(
libs, element.firstFragment.libraryFragment?.source.uri.path ?? '');
libs,
element.firstFragment.libraryFragment?.source.uri.path ?? '',
);

final String locatorName =
stackedApplication.peek('locatorName')!.stringValue;
Expand Down
Loading