diff --git a/CHANGELOG.md b/CHANGELOG.md index 6065403..0099280 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.6.0-wip + +* Add support for named arguments in `enum` classes + ## 4.5.0 * Require Dart 2.19 diff --git a/lib/src/emitter.dart b/lib/src/emitter.dart index 21f680d..972381e 100644 --- a/lib/src/emitter.dart +++ b/lib/src/emitter.dart @@ -800,8 +800,9 @@ class DartEmitter extends Object out.write('.${v.constructorName}'); } visitTypeParameters(v.types.map((r) => r.type), out); - final takesArguments = - v.constructorName != null || v.arguments.isNotEmpty; + final takesArguments = v.constructorName != null || + v.arguments.isNotEmpty || + v.namedArguments.isNotEmpty; if (takesArguments) { out.write('('); } @@ -809,6 +810,15 @@ class DartEmitter extends Object out.writeAll( v.arguments.map((arg) => arg.accept(this)), ', '); } + if (v.arguments.isNotEmpty && v.namedArguments.isNotEmpty) { + out.write(', '); + } + visitAll(v.namedArguments.keys, out, (name) { + out + ..write(name) + ..write(': '); + v.namedArguments[name]!.accept(this, out); + }); if (takesArguments) { out.write(')'); } diff --git a/lib/src/specs/enum.dart b/lib/src/specs/enum.dart index 632eb8f..c58f92c 100644 --- a/lib/src/specs/enum.dart +++ b/lib/src/specs/enum.dart @@ -105,6 +105,9 @@ abstract class EnumValue extends Object /// Arguments to the constructor. BuiltList get arguments; + + /// Named arguments to the constructor. + BuiltMap get namedArguments; } abstract class EnumValueBuilder extends Object @@ -130,4 +133,7 @@ abstract class EnumValueBuilder extends Object /// Arguments to the constructor. ListBuilder arguments = ListBuilder(); + + /// Named arguments to the constructor. + MapBuilder namedArguments = MapBuilder(); } diff --git a/lib/src/specs/enum.g.dart b/lib/src/specs/enum.g.dart index 050885b..651cc61 100644 --- a/lib/src/specs/enum.g.dart +++ b/lib/src/specs/enum.g.dart @@ -331,6 +331,8 @@ class _$EnumValue extends EnumValue { final BuiltList types; @override final BuiltList arguments; + @override + final BuiltMap namedArguments; factory _$EnumValue([void Function(EnumValueBuilder)? updates]) => (new EnumValueBuilder()..update(updates)).build() as _$EnumValue; @@ -341,7 +343,8 @@ class _$EnumValue extends EnumValue { required this.docs, this.constructorName, required this.types, - required this.arguments}) + required this.arguments, + required this.namedArguments}) : super._() { BuiltValueNullFieldError.checkNotNull(name, r'EnumValue', 'name'); BuiltValueNullFieldError.checkNotNull( @@ -349,6 +352,8 @@ class _$EnumValue extends EnumValue { BuiltValueNullFieldError.checkNotNull(docs, r'EnumValue', 'docs'); BuiltValueNullFieldError.checkNotNull(types, r'EnumValue', 'types'); BuiltValueNullFieldError.checkNotNull(arguments, r'EnumValue', 'arguments'); + BuiltValueNullFieldError.checkNotNull( + namedArguments, r'EnumValue', 'namedArguments'); } @override @@ -367,7 +372,8 @@ class _$EnumValue extends EnumValue { docs == other.docs && constructorName == other.constructorName && types == other.types && - arguments == other.arguments; + arguments == other.arguments && + namedArguments == other.namedArguments; } @override @@ -379,6 +385,7 @@ class _$EnumValue extends EnumValue { _$hash = $jc(_$hash, constructorName.hashCode); _$hash = $jc(_$hash, types.hashCode); _$hash = $jc(_$hash, arguments.hashCode); + _$hash = $jc(_$hash, namedArguments.hashCode); _$hash = $jf(_$hash); return _$hash; } @@ -391,7 +398,8 @@ class _$EnumValue extends EnumValue { ..add('docs', docs) ..add('constructorName', constructorName) ..add('types', types) - ..add('arguments', arguments)) + ..add('arguments', arguments) + ..add('namedArguments', namedArguments)) .toString(); } } @@ -471,6 +479,18 @@ class _$EnumValueBuilder extends EnumValueBuilder { super.arguments = arguments; } + @override + MapBuilder get namedArguments { + _$this; + return super.namedArguments; + } + + @override + set namedArguments(MapBuilder namedArguments) { + _$this; + super.namedArguments = namedArguments; + } + _$EnumValueBuilder() : super._(); EnumValueBuilder get _$this { @@ -482,6 +502,7 @@ class _$EnumValueBuilder extends EnumValueBuilder { super.constructorName = $v.constructorName; super.types = $v.types.toBuilder(); super.arguments = $v.arguments.toBuilder(); + super.namedArguments = $v.namedArguments.toBuilder(); _$v = null; } return this; @@ -512,7 +533,8 @@ class _$EnumValueBuilder extends EnumValueBuilder { docs: docs.build(), constructorName: constructorName, types: types.build(), - arguments: arguments.build()); + arguments: arguments.build(), + namedArguments: namedArguments.build()); } catch (_) { late String _$failedField; try { @@ -525,6 +547,8 @@ class _$EnumValueBuilder extends EnumValueBuilder { types.build(); _$failedField = 'arguments'; arguments.build(); + _$failedField = 'namedArguments'; + namedArguments.build(); } catch (e) { throw new BuiltValueNestedFieldError( r'EnumValue', _$failedField, e.toString()); diff --git a/pubspec.yaml b/pubspec.yaml index c199431..9ddf190 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: code_builder -version: 4.5.0 +version: 4.6.0-wip description: >- A fluent, builder-based library for generating valid Dart code repository: https://github.com/dart-lang/code_builder diff --git a/test/specs/enum_test.dart b/test/specs/enum_test.dart index 1025e66..5a0b19a 100644 --- a/test/specs/enum_test.dart +++ b/test/specs/enum_test.dart @@ -381,4 +381,62 @@ void main() { } ''')); }); + + test('should create an enum which named and unnamed constructor parameters', + () { + final myEnum = Enum((b) => b + ..name = 'MyEnum' + ..constructors.add(Constructor((c) => c + ..constant = true + ..requiredParameters.addAll([ + Parameter((p) => p + ..toThis = true + ..name = 'myInt') + ]) + ..optionalParameters.addAll([ + Parameter((p) => p + ..toThis = true + ..named = true + ..required = true + ..name = 'myString') + ]))) + ..fields.addAll([ + Field((f) => f + ..modifier = FieldModifier.final$ + ..type = refer('int?') + ..name = 'myInt'), + Field((f) => f + ..modifier = FieldModifier.final$ + ..type = refer('String?') + ..name = 'myString') + ]) + ..values.addAll([ + EnumValue((v) => v..name = 'a'), + EnumValue((v) => v + ..name = 'b' + ..arguments.addAll([ + literalNum(1), + ]) + ..namedArguments.addAll({ + 'myString': literalString('abc'), + })), + EnumValue((v) => v..name = 'c'), + ])); + expect(myEnum, equalsDart(''' + enum MyEnum { + a, + b(1, myString: 'abc'), + c; + + const MyEnum( + this.myInt, + {required this.myString, } + ); + + final int? myInt; + + final String? myString; + } + ''')); + }); }