Skip to content

Commit

Permalink
Merge pull request #20 from IO-Design-Team/feature/constructor-defaul…
Browse files Browse the repository at this point in the history
…t-values

Support constructor parameter default values
  • Loading branch information
Rexios80 authored Sep 3, 2024
2 parents 67e33c2 + 45f96ff commit 139cdae
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 77 deletions.
4 changes: 4 additions & 0 deletions hive/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.5.0+1

- Documentation updates for `HiveField` in support of `hive_ce_generator` changes

## 2.5.0

- Adds `Target` annotations to `HiveField` and `HiveType` to prevent invalid usage
Expand Down
2 changes: 2 additions & 0 deletions hive/lib/src/annotations/hive_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class HiveField {

/// The default value of this field for class hive types.
///
/// This value takes precedence over constructor parameter default values.
///
/// In enum hive types set `true` to use this enum value as default value
/// instead of null in null-safety.
///
Expand Down
2 changes: 1 addition & 1 deletion hive/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: hive_ce
description: Hive Community Edition - A spiritual continuation of Hive v2
version: 2.5.0
version: 2.5.0+1
homepage: https://github.com/IO-Design-Team/hive_ce/tree/main/hive
documentation: https://docs.hivedb.dev/

Expand Down
7 changes: 7 additions & 0 deletions hive_generator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.5.0

- Supports constructor parameter default values
- No longer generates the `HiveRegistrar` if there are no adapters
- Removes unnecessary print statement in `HiveRegistrar` generator
- Bumps `analyzer` to `^6.5.0` to deal with deprecations

## 1.4.0

- Adds a generator to create a `HiveRegistrar` extension that allows registration of all generated `TypeAdapters` in one call
Expand Down
2 changes: 2 additions & 0 deletions hive_generator/example/lib/hive_registrar.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ extension HiveRegistrar on HiveInterface {
registerAdapter(Class2Adapter());
registerAdapter(EmptyClassAdapter());
registerAdapter(IterableClassAdapter());
registerAdapter(ConstructorDefaultsAdapter());
registerAdapter(NullableTypesAdapter());
registerAdapter(Enum1Adapter());
}
}
36 changes: 36 additions & 0 deletions hive_generator/example/lib/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,39 @@ class IterableClass {
@HiveField(3)
final Set<List<String>> nestedSet;
}

@HiveType(typeId: 6)
class ConstructorDefaults {
ConstructorDefaults({
this.a = 42,
this.b = '42',
this.c = true,
DateTime? d,
}) : d = d ?? DateTime.now();

@HiveField(0)
final int a;

@HiveField(1, defaultValue: '6 * 7')
final String b;

@HiveField(2)
final bool c;

@HiveField(3)
final DateTime d;
}

@HiveType(typeId: 7)
class NullableTypes {
NullableTypes({this.a, this.b, this.c});

@HiveField(0)
final int? a;

@HiveField(1)
final String? b;

@HiveField(2)
final bool? c;
}
83 changes: 83 additions & 0 deletions hive_generator/example/lib/types.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 19 additions & 8 deletions hive_generator/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@ import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

/// TODO: Document this!
/// Metadata about a field in a class adapter
class AdapterField {
/// TODO: Document this!
/// The index of the field
///
/// Determines the order fields are read and written
final int index;

/// TODO: Document this!
/// The name of the field
final String name;

/// TODO: Document this!
/// The type of the field
final DartType type;

/// TODO: Document this!
final DartObject? defaultValue;
/// A default value provided by the field annotation
final DartObject? annotationDefault;

/// TODO: Document this!
AdapterField(this.index, this.name, this.type, this.defaultValue);
/// A default value provided by the constructor
final String? constructorDefault;

/// Constructor
AdapterField(
this.index,
this.name,
this.type,
this.annotationDefault,
this.constructorDefault,
);
}

/// TODO: Document this!
Expand Down
62 changes: 28 additions & 34 deletions hive_generator/lib/src/class_builder.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:typed_data';

import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:hive_ce/hive.dart';
Expand Down Expand Up @@ -68,13 +67,7 @@ class ClassBuilder extends Builder {
if (param.isNamed) {
code.write('${param.name}: ');
}
code.write(
_value(
param.type,
'fields[${field.index}]',
field.defaultValue,
),
);
code.write(_value(param.type, field));
code.writeln(',');
fields.remove(field);
}
Expand All @@ -86,24 +79,33 @@ class ClassBuilder extends Builder {
// as initializing formals. We do so using cascades.
for (final field in fields) {
code.write('..${field.name} = ');
code.writeln(
_value(
field.type,
'fields[${field.index}]',
field.defaultValue,
),
);
code.writeln(_value(field.type, field));
}

code.writeln(';');

return code.toString();
}

String _value(DartType type, String variable, DartObject? defaultValue) {
String _value(DartType type, AdapterField field) {
final variable = 'fields[${field.index}]';
final value = _cast(type, variable);
if (defaultValue?.isNull != false) return value;
return '$variable == null ? ${constantToString(defaultValue!)} : $value';

final annotationDefaultIsNull = field.annotationDefault?.isNull ?? true;
final constructorDefaultIsNull = field.constructorDefault == null;

final String? defaultValue;
if (!annotationDefaultIsNull) {
defaultValue = constantToString(field.annotationDefault);
} else if (!constructorDefaultIsNull) {
defaultValue = field.constructorDefault;
} else {
defaultValue = null;
}

if (defaultValue == null) return value;

return '$variable == null ? $defaultValue : $value';
}

String _cast(DartType type, String variable) {
Expand All @@ -121,7 +123,7 @@ class ClassBuilder extends Builder {
} else if (type.isDartCoreDouble) {
return '($variable as num$suffix)$suffix.toDouble()';
} else {
return '$variable as ${_displayString(type)}';
return '$variable as ${type.getDisplayString()}';
}
}

Expand Down Expand Up @@ -152,7 +154,7 @@ class ClassBuilder extends Builder {

return '$suffix.map((e) => ${_cast(arg, 'e')})$cast';
} else {
return '$suffix.cast<${_displayString(arg)}>()';
return '$suffix.cast<${arg.getDisplayString()}>()';
}
}

Expand All @@ -165,8 +167,8 @@ class ClassBuilder extends Builder {
return '$suffix.map((dynamic k, dynamic v)=>'
'MapEntry(${_cast(arg1, 'k')},${_cast(arg2, 'v')}))';
} else {
return '$suffix.cast<${_displayString(arg1)}, '
'${_displayString(arg2)}>()';
return '$suffix.cast<${arg1.getDisplayString()}, '
'${arg2.getDisplayString()}>()';
}
}

Expand Down Expand Up @@ -212,16 +214,8 @@ String _accessorSuffixFromType(DartType type) {
/// Suffix to use when casting a value to [type].
/// $variable as $type$suffix
String _suffixFromType(DartType type) {
if (type.nullabilitySuffix == NullabilitySuffix.star) {
return '';
}
if (type.nullabilitySuffix == NullabilitySuffix.question) {
return '?';
}
return '';
}

String _displayString(DartType e) {
final suffix = _suffixFromType(e);
return '${e.getDisplayString()}$suffix';
return switch (type.nullabilitySuffix) {
NullabilitySuffix.question => '?',
_ => '',
};
}
2 changes: 1 addition & 1 deletion hive_generator/lib/src/enum_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class EnumBuilder extends Builder {
}

final defaultField = getters.firstWhere(
(it) => it.defaultValue?.toBoolValue() == true,
(it) => it.annotationDefault?.toBoolValue() == true,
orElse: () => getters.first,
);
code.writeln('''
Expand Down
7 changes: 5 additions & 2 deletions hive_generator/lib/src/registrar_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class RegistrarBuilder implements Builder {

@override
Future<void> build(BuildStep buildStep) async {
final buffer = StringBuffer("import 'package:hive_ce/hive.dart';\n");

final uris = <String>[];
final adapters = <String>[];
await for (final input
Expand All @@ -26,6 +24,11 @@ class RegistrarBuilder implements Builder {
adapters.addAll((data['adapters'] as List).cast<String>());
}

// Do not create the registrar if there are no adapters
if (adapters.isEmpty) return;

final buffer = StringBuffer("import 'package:hive_ce/hive.dart';\n");

for (final uri in uris) {
buffer.writeln("import '$uri';");
}
Expand Down
Loading

0 comments on commit 139cdae

Please sign in to comment.