adding packages
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import 'setting_impl.dart';
|
||||
|
||||
class BoolSettingTemplate implements SettingsImpl {
|
||||
bool defaultValue;
|
||||
String name;
|
||||
bool isPrivate;
|
||||
bool addStream = true;
|
||||
bool addValueNotifier = true;
|
||||
|
||||
@override
|
||||
String preInit() {
|
||||
return '${name}Notify($defaultValue);';
|
||||
}
|
||||
|
||||
@override
|
||||
String postInit() {
|
||||
return '${name}Notify($name);';
|
||||
}
|
||||
|
||||
@override
|
||||
String dispose() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.close();');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(
|
||||
'final _${name}Controller = StreamController<bool>.broadcast();');
|
||||
sb.writeln(
|
||||
'Stream<bool> get ${name}Stream => _${name}Controller.stream;');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('final _${name}Notifier = ValueNotifier<bool>($defaultValue);');
|
||||
sb.writeln('ValueListenable<bool> get ${name}Notifier => _${name}Notifier;');
|
||||
}
|
||||
|
||||
sb.writeln("""
|
||||
|
||||
@override
|
||||
bool get $name {
|
||||
return prefs?.getBool('$name') ?? $defaultValue;
|
||||
}
|
||||
|
||||
@override
|
||||
set $name(bool value) {
|
||||
${name}Async(value);
|
||||
}
|
||||
|
||||
Future<bool> ${name}Async(bool value) async {
|
||||
final success = await prefs.setBool('$name', value);
|
||||
if (success) {
|
||||
${name}Notify(value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln('void ${name}Notify(bool value) {');
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.add(value);');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('_${name}Notifier.value = value;');
|
||||
}
|
||||
sb.writeln('_controller.add(this);');
|
||||
sb.writeln('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:settings_gen/src/template/util.dart';
|
||||
|
||||
class CommaList<T> {
|
||||
CommaList(this.templates) : assert(templates != null);
|
||||
|
||||
final List<T> templates;
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
templates.map((t) => t.toString()).where((s) => s.isNotEmpty).join(', ');
|
||||
}
|
||||
|
||||
class SurroundedCommaList<T> {
|
||||
SurroundedCommaList(this.prefix, this.suffix, this.templates)
|
||||
: assert(prefix != null),
|
||||
assert(suffix != null),
|
||||
assert(templates != null);
|
||||
|
||||
final String prefix;
|
||||
final String suffix;
|
||||
final List<T> templates;
|
||||
|
||||
@override
|
||||
String toString() => surroundNonEmpty(prefix, suffix, CommaList(templates));
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import 'setting_impl.dart';
|
||||
|
||||
class DoubleSettingTemplate implements SettingsImpl {
|
||||
double defaultValue;
|
||||
String name;
|
||||
bool isPrivate;
|
||||
bool addStream = true;
|
||||
bool addValueNotifier = true;
|
||||
|
||||
@override
|
||||
String preInit() {
|
||||
return '${name}Notify($defaultValue);';
|
||||
}
|
||||
|
||||
@override
|
||||
String postInit() {
|
||||
return '${name}Notify($name);';
|
||||
}
|
||||
|
||||
@override
|
||||
String dispose() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.close();');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(
|
||||
'final _${name}Controller = StreamController<double>.broadcast();');
|
||||
sb.writeln(
|
||||
'Stream<double> get ${name}Stream => _${name}Controller.stream;');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('final _${name}Notifier = ValueNotifier<double>($defaultValue);');
|
||||
sb.writeln(
|
||||
'ValueListenable<double> get ${name}Notifier => _${name}Notifier;');
|
||||
}
|
||||
|
||||
sb.writeln("""
|
||||
|
||||
@override
|
||||
double get $name {
|
||||
return prefs?.getDouble('$name') ?? $defaultValue;
|
||||
}
|
||||
|
||||
@override
|
||||
set $name(double value) {
|
||||
${name}Async(value);
|
||||
}
|
||||
|
||||
Future<bool> ${name}Async(double value) async {
|
||||
final success = await prefs.setDouble('$name', value);
|
||||
if (success) {
|
||||
${name}Notify(value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln('void ${name}Notify(double value) {');
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.add(value);');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('_${name}Notifier.value = value;');
|
||||
}
|
||||
sb.writeln('_controller.add(this);');
|
||||
sb.writeln('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import 'setting_impl.dart';
|
||||
|
||||
class IntSettingTemplate implements SettingsImpl {
|
||||
int defaultValue;
|
||||
String name;
|
||||
bool isPrivate;
|
||||
bool addStream = true;
|
||||
bool addValueNotifier = true;
|
||||
|
||||
@override
|
||||
String preInit() {
|
||||
return '${name}Notify($defaultValue);';
|
||||
}
|
||||
|
||||
@override
|
||||
String postInit() {
|
||||
return '${name}Notify($name);';
|
||||
}
|
||||
|
||||
@override
|
||||
String dispose() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.close();');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(
|
||||
'final _${name}Controller = StreamController<int>.broadcast();');
|
||||
sb.writeln('Stream<int> get ${name}Stream => _${name}Controller.stream;');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('final _${name}Notifier = ValueNotifier<int>($defaultValue);');
|
||||
sb.writeln('ValueListenable<int> get ${name}Notifier => _${name}Notifier;');
|
||||
}
|
||||
|
||||
sb.writeln("""
|
||||
|
||||
@override
|
||||
int get $name {
|
||||
return prefs?.getInt('$name') ?? $defaultValue;
|
||||
}
|
||||
|
||||
@override
|
||||
set $name(int value) {
|
||||
${name}Async(value);
|
||||
}
|
||||
|
||||
Future<bool> ${name}Async(int value) async {
|
||||
final success = await prefs.setInt('$name', value);
|
||||
if (success) {
|
||||
${name}Notify(value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln('void ${name}Notify(int value) {');
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.add(value);');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('_${name}Notifier.value = value;');
|
||||
}
|
||||
sb.writeln('_controller.add(this);');
|
||||
sb.writeln('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
class ParamTemplate {
|
||||
String name;
|
||||
String type;
|
||||
String defaultValue;
|
||||
bool hasRequiredAnnotation = false;
|
||||
|
||||
String get asArgument => name;
|
||||
|
||||
NamedArgTemplate get asNamedArgument => NamedArgTemplate()..name = name;
|
||||
|
||||
String get metadata => hasRequiredAnnotation ? '@required ' : '';
|
||||
|
||||
@override
|
||||
String toString() => defaultValue == null
|
||||
? '$metadata$type $name'
|
||||
: '$type $name = $defaultValue';
|
||||
}
|
||||
|
||||
class TypeParamTemplate {
|
||||
String name;
|
||||
String bound;
|
||||
|
||||
String get asArgument => name;
|
||||
|
||||
@override
|
||||
String toString() => bound == null ? name : '$name extends $bound';
|
||||
}
|
||||
|
||||
class NamedArgTemplate {
|
||||
String name;
|
||||
|
||||
@override
|
||||
String toString() => '$name: $name';
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class Rows<T> {
|
||||
final List<T> _templates = [];
|
||||
|
||||
void add(T template) => _templates.add(template);
|
||||
|
||||
bool get isEmpty => _templates.isEmpty;
|
||||
List get templates => _templates;
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
_templates.map((t) => t.toString()).where((s) => s.isNotEmpty).join('\n');
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
abstract class SettingsImpl {
|
||||
String preInit();
|
||||
String postInit();
|
||||
String dispose();
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import 'bool_setting.dart';
|
||||
import 'comma_list.dart';
|
||||
import 'double_setting.dart';
|
||||
import 'int_setting.dart';
|
||||
import 'params.dart';
|
||||
import 'rows.dart';
|
||||
import 'setting_impl.dart';
|
||||
import 'string_list_setting.dart';
|
||||
import 'string_setting.dart';
|
||||
|
||||
class MixinStoreTemplate extends StoreTemplate {
|
||||
String get typeName => '_\$$publicTypeName';
|
||||
|
||||
@override
|
||||
String toString() => '''
|
||||
|
||||
mixin $typeName$typeParams on $parentTypeName$typeArgs, SettingsStore {
|
||||
$storeBody
|
||||
}''';
|
||||
}
|
||||
|
||||
abstract class StoreTemplate {
|
||||
final SurroundedCommaList<TypeParamTemplate> typeParams =
|
||||
SurroundedCommaList('<', '>', []);
|
||||
final SurroundedCommaList<String> typeArgs =
|
||||
SurroundedCommaList('<', '>', []);
|
||||
String publicTypeName;
|
||||
String parentTypeName;
|
||||
|
||||
final Rows<BoolSettingTemplate> boolSettings = Rows();
|
||||
final Rows<StringSettingTemplate> stringSettings = Rows();
|
||||
final Rows<IntSettingTemplate> intSettings = Rows();
|
||||
final Rows<DoubleSettingTemplate> doubleSettings = Rows();
|
||||
final Rows<StringListSettingTemplate> stringListSettings = Rows();
|
||||
final List<String> toStringList = [];
|
||||
|
||||
bool generateToString = false;
|
||||
String _actionControllerName;
|
||||
String get actionControllerName =>
|
||||
_actionControllerName ??= '_\$${parentTypeName}ActionController';
|
||||
|
||||
String get storeBody {
|
||||
var toStringMethod = '';
|
||||
|
||||
final sb = StringBuffer();
|
||||
|
||||
sb.writeln('SharedPreferences prefs;');
|
||||
sb.writeln(
|
||||
'final _controller = StreamController<$publicTypeName>.broadcast();');
|
||||
sb.writeln('Stream<$publicTypeName> get stream => _controller.stream;');
|
||||
sb.writeln();
|
||||
List<SettingsImpl> _settingsImpl = [];
|
||||
_settingsImpl.addAll(
|
||||
boolSettings.templates.whereType<SettingsImpl>().map((t) => t).toList(),
|
||||
);
|
||||
_settingsImpl.addAll(
|
||||
stringSettings.templates.whereType<SettingsImpl>().map((t) => t).toList(),
|
||||
);
|
||||
_settingsImpl.addAll(
|
||||
intSettings.templates.whereType<SettingsImpl>().map((t) => t).toList(),
|
||||
);
|
||||
_settingsImpl.addAll(
|
||||
doubleSettings.templates.whereType<SettingsImpl>().map((t) => t).toList(),
|
||||
);
|
||||
_settingsImpl.addAll(
|
||||
stringListSettings.templates
|
||||
.whereType<SettingsImpl>()
|
||||
.map((t) => t)
|
||||
.toList(),
|
||||
);
|
||||
sb.writeln(' Future<bool> init() async {');
|
||||
for (final setting in _settingsImpl) {
|
||||
sb.writeln(setting.preInit());
|
||||
}
|
||||
sb.writeln(' prefs = await SharedPreferences.getInstance();');
|
||||
for (final setting in _settingsImpl) {
|
||||
sb.writeln(setting.postInit());
|
||||
}
|
||||
sb.writeln(' return prefs != null;');
|
||||
sb.writeln(' }');
|
||||
sb.writeln();
|
||||
sb.writeln('$boolSettings');
|
||||
sb.writeln();
|
||||
sb.writeln('$stringSettings');
|
||||
sb.writeln();
|
||||
sb.writeln('$intSettings');
|
||||
sb.writeln();
|
||||
sb.writeln('$doubleSettings');
|
||||
sb.writeln();
|
||||
sb.writeln('$stringListSettings');
|
||||
sb.writeln();
|
||||
sb.writeln(' void dispose() {');
|
||||
for (final setting in _settingsImpl) {
|
||||
sb.writeln(setting.dispose());
|
||||
}
|
||||
sb.writeln('_controller.close();');
|
||||
sb.writeln(' }');
|
||||
sb.writeln();
|
||||
|
||||
final baseBody = sb.toString();
|
||||
|
||||
if (generateToString) {
|
||||
final publicBoolSettings = boolSettings.templates
|
||||
..removeWhere((element) => element.isPrivate);
|
||||
final publicStringSettings = stringSettings.templates
|
||||
..removeWhere((element) => element.isPrivate);
|
||||
final publicIntSettings = intSettings.templates
|
||||
..removeWhere((element) => element.isPrivate);
|
||||
final publicDoubleSettings = doubleSettings.templates
|
||||
..removeWhere((element) => element.isPrivate);
|
||||
final publicStringListSettings = doubleSettings.templates
|
||||
..removeWhere((element) => element.isPrivate);
|
||||
|
||||
toStringList
|
||||
..addAll(publicBoolSettings.map(
|
||||
(current) => '${current.name}: \${${current.name}.toString()}'))
|
||||
..addAll(publicStringSettings.map(
|
||||
(current) => '${current.name}: \${${current.name}.toString()}'))
|
||||
..addAll(publicIntSettings.map(
|
||||
(current) => '${current.name}: \${${current.name}.toString()}'))
|
||||
..addAll(publicDoubleSettings.map(
|
||||
(current) => '${current.name}: \${${current.name}.toString()}'))
|
||||
..addAll(publicStringListSettings.map(
|
||||
(current) => '${current.name}: \${${current.name}.toString()}'));
|
||||
|
||||
toStringMethod = '''
|
||||
@override
|
||||
String toString() {
|
||||
final string = \'${toStringList.join(',')}\';
|
||||
return '{\$string}';
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
return baseBody + toStringMethod;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
const _analyzerIgnores =
|
||||
'// ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic';
|
||||
|
||||
class StoreFileTemplate {
|
||||
Iterable<String> storeSources;
|
||||
|
||||
@override
|
||||
String toString() => storeSources.isEmpty
|
||||
? ''
|
||||
: '''
|
||||
$_analyzerIgnores
|
||||
|
||||
${storeSources.join('\n\n')}
|
||||
''';
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import 'setting_impl.dart';
|
||||
|
||||
class StringListSettingTemplate implements SettingsImpl {
|
||||
List<String> defaultValue;
|
||||
String name;
|
||||
bool isPrivate;
|
||||
bool addStream = true;
|
||||
bool addValueNotifier = true;
|
||||
|
||||
@override
|
||||
String preInit() {
|
||||
return "${name}Notify($defaultValue);";
|
||||
}
|
||||
|
||||
@override
|
||||
String postInit() {
|
||||
return '${name}Notify($name);';
|
||||
}
|
||||
|
||||
@override
|
||||
String dispose() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.close();');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(
|
||||
'final _${name}Controller = StreamController<List<String>>.broadcast();');
|
||||
sb.writeln(
|
||||
'Stream<List<String>> get ${name}Stream => _${name}Controller.stream;');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('final _${name}Notifier = ValueNotifier<List<String>>($defaultValue);');
|
||||
sb.writeln('ValueListenable<List<String>> get ${name}Notifier => _${name}Notifier;');
|
||||
}
|
||||
|
||||
sb.writeln("""
|
||||
|
||||
@override
|
||||
List<String> get $name {
|
||||
return prefs?.getStringList('$name') ?? $defaultValue;
|
||||
}
|
||||
|
||||
@override
|
||||
set $name(List<String> value) {
|
||||
${name}Async(value);
|
||||
}
|
||||
|
||||
Future<bool> ${name}Async(List<String> value) async {
|
||||
final success = await prefs.setStringList('$name', value);
|
||||
if (success) {
|
||||
${name}Notify(value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln('void ${name}Notify(List<String> value) {');
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.add(value);');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('_${name}Notifier.value = value;');
|
||||
}
|
||||
sb.writeln('_controller.add(this);');
|
||||
sb.writeln('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import 'setting_impl.dart';
|
||||
|
||||
class StringSettingTemplate implements SettingsImpl {
|
||||
String defaultValue;
|
||||
String name;
|
||||
bool isPrivate;
|
||||
bool addStream = true;
|
||||
bool addValueNotifier = true;
|
||||
|
||||
@override
|
||||
String preInit() {
|
||||
return "${name}Notify('$defaultValue');";
|
||||
}
|
||||
|
||||
@override
|
||||
String postInit() {
|
||||
return '${name}Notify($name);';
|
||||
}
|
||||
|
||||
@override
|
||||
String dispose() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.close();');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final sb = StringBuffer();
|
||||
if (addStream) {
|
||||
sb.writeln(
|
||||
'final _${name}Controller = StreamController<String>.broadcast();');
|
||||
sb.writeln(
|
||||
'Stream<String> get ${name}Stream => _${name}Controller.stream;');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln("final _${name}Notifier = ValueNotifier<String>('$defaultValue');");
|
||||
sb.writeln('ValueListenable<String> get ${name}Notifier => _${name}Notifier;');
|
||||
}
|
||||
|
||||
sb.writeln("""
|
||||
|
||||
@override
|
||||
String get $name {
|
||||
return prefs?.getString('$name') ?? '$defaultValue';
|
||||
}
|
||||
|
||||
@override
|
||||
set $name(String value) {
|
||||
${name}Async(value);
|
||||
}
|
||||
|
||||
Future<bool> ${name}Async(String value) async {
|
||||
final success = await prefs.setString('$name', value);
|
||||
if (success) {
|
||||
${name}Notify(value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln('void ${name}Notify(String value) {');
|
||||
if (addStream) {
|
||||
sb.writeln(' _${name}Controller.add(value);');
|
||||
}
|
||||
if (addValueNotifier) {
|
||||
sb.writeln('_${name}Notifier.value = value;');
|
||||
}
|
||||
sb.writeln('_controller.add(this);');
|
||||
sb.writeln('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:settings_gen/src/template/params.dart';
|
||||
import 'package:settings_gen/src/type_names.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
// ignore: avoid_annotating_with_dynamic
|
||||
String surroundNonEmpty(String prefix, String suffix, dynamic content) {
|
||||
final contentStr = content.toString();
|
||||
return contentStr.isEmpty ? '' : '$prefix$contentStr$suffix';
|
||||
}
|
||||
|
||||
const _streamChecker = TypeChecker.fromRuntime(Stream);
|
||||
|
||||
class AsyncMethodChecker {
|
||||
AsyncMethodChecker([TypeChecker checkStream]) {
|
||||
_checkStream = checkStream ?? _streamChecker;
|
||||
}
|
||||
|
||||
TypeChecker _checkStream;
|
||||
|
||||
bool returnsFuture(MethodElement method) =>
|
||||
method.returnType.isDartAsyncFuture ||
|
||||
(method.isAsynchronous &&
|
||||
!method.isGenerator &&
|
||||
method.returnType.isDynamic);
|
||||
|
||||
bool returnsStream(MethodElement method) =>
|
||||
_checkStream.isAssignableFromType(method.returnType) ||
|
||||
(method.isAsynchronous &&
|
||||
method.isGenerator &&
|
||||
method.returnType.isDynamic);
|
||||
}
|
||||
|
||||
TypeParamTemplate typeParamTemplate(
|
||||
TypeParameterElement param,
|
||||
LibraryScopedNameFinder typeNameFinder,
|
||||
) =>
|
||||
TypeParamTemplate()
|
||||
..name = param.name
|
||||
..bound = param.bound != null
|
||||
? typeNameFinder.findTypeParameterBoundsTypeName(param)
|
||||
: null;
|
||||
Reference in New Issue
Block a user