From 099a3cbe788ea1ff09d0aaa4e7c5728668294ddb Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Mon, 25 Nov 2019 22:49:32 +0100 Subject: [PATCH 1/5] Remove base class in favour of extensions --- example/lib/data_classes.dart | 6 +-- example/lib/sum_types.dart | 4 +- example/pubspec.yaml | 2 +- sum_data_types/pubspec.yaml | 2 +- sum_data_types_generator/lib/common.dart | 8 ++-- .../lib/data_classes.dart | 17 +++----- sum_data_types_generator/lib/sum_types.dart | 43 ++++++------------- sum_data_types_generator/pubspec.yaml | 4 +- 8 files changed, 33 insertions(+), 53 deletions(-) diff --git a/example/lib/data_classes.dart b/example/lib/data_classes.dart index df4c0aa..1bbea15 100644 --- a/example/lib/data_classes.dart +++ b/example/lib/data_classes.dart @@ -61,13 +61,13 @@ void main() { } @DataClass() -mixin Container on _ContainerBase { +mixin Container { String get id; T get payload; } @SumType() -mixin Either on _EitherBase { +mixin Either { A get _left; B get _right; } @@ -80,7 +80,7 @@ void foo(Either x) { } @DataClass() -mixin User on _UserBase { +mixin User { String get name; Optional get age; KtList get friends; diff --git a/example/lib/sum_types.dart b/example/lib/sum_types.dart index f7faae0..fb7c1fa 100644 --- a/example/lib/sum_types.dart +++ b/example/lib/sum_types.dart @@ -66,13 +66,13 @@ void main() { } @SumType() -mixin WithUnknown on _WithUnknownBase { +mixin WithUnknown { String get _known; dynamic get _unknown; } @SumType() -mixin Something implements _SomethingBase { +mixin Something { Unit get _nothing; User get _user; quiv.Optional get _address; diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ba13ce3..2a93911 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -5,7 +5,7 @@ author: Stefan Wehr (wehr@cp-med.com) homepage: https://github.com/factisresearch/sum_data_types environment: - sdk: ">=2.5.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" dependencies: quiver: '>=2.0.0 <3.0.0' diff --git a/sum_data_types/pubspec.yaml b/sum_data_types/pubspec.yaml index 623bd0d..c36ef6e 100644 --- a/sum_data_types/pubspec.yaml +++ b/sum_data_types/pubspec.yaml @@ -5,7 +5,7 @@ author: Stefan Wehr (wehr@cp-med.com) homepage: https://github.com/factisresearch/sum_data_types environment: - sdk: ">=2.5.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" dependencies: meta: ^1.1.7 diff --git a/sum_data_types_generator/lib/common.dart b/sum_data_types_generator/lib/common.dart index f7e35ea..fd55a19 100644 --- a/sum_data_types_generator/lib/common.dart +++ b/sum_data_types_generator/lib/common.dart @@ -153,7 +153,7 @@ typedef MkField = T Function(FieldElement f, ImportModel imports); class CommonClassModel { final String mixinName; final String className; - final String baseClassName; + final String extensionName; final List fields; final List typeArgs; @@ -164,7 +164,7 @@ class CommonClassModel { CommonClassModel.mk({ @required this.mixinName, @required this.className, - @required this.baseClassName, + @required this.extensionName, @required this.fields, @required this.typeArgs, }); @@ -181,7 +181,7 @@ class CommonClassModel { final mixinName = clazz.name; final List typeArgs = clazz.typeParameters.map((param) => param.name).toList(); final className = "_" + mixinName; - final baseName = className + "Base"; + final extensionName = mixinName + "Methods"; final fields = []; for (var field in clazz.fields) { @@ -197,7 +197,7 @@ class CommonClassModel { return CommonClassModel.mk( mixinName: mixinName, - baseClassName: baseName, + extensionName: extensionName, className: className, fields: fields, typeArgs: typeArgs, diff --git a/sum_data_types_generator/lib/data_classes.dart b/sum_data_types_generator/lib/data_classes.dart index ad24bc2..2056a40 100644 --- a/sum_data_types_generator/lib/data_classes.dart +++ b/sum_data_types_generator/lib/data_classes.dart @@ -95,7 +95,7 @@ class ClassModel { List get fields => _commonModel.fields; String get className => _commonModel.className; - String get baseClassName => _commonModel.baseClassName; + String get extensionName => _commonModel.extensionName; String get mixinName => _commonModel.mixinName; String get factoryName => _commonModel.factoryName; List get fieldNames => fields.map((f) => f.name).toList(); @@ -175,12 +175,15 @@ class DataClassGenerator extends GeneratorForAnnotation { ); } } - abstract class ${clazz.baseClassName}${clazz.typeArgsWithParens} { - ${clazz.copyWithSignature}; + extension ${clazz.extensionName}${clazz.typeArgsWithParens} on ${clazz.mixinName}${clazz.typeArgsWithParens} { + ${clazz.copyWithSignature} { + return ${clazz.className}.make( + ${clazz.copyWithArgs} + ); + } } @immutable class ${clazz.className}${clazz.typeArgsWithParens} - extends ${clazz.baseClassName}${clazz.typeArgsWithParens} with ${clazz.mixinName}${clazz.typeArgsWithParens} { ${clazz.fieldDeclarations} @@ -190,12 +193,6 @@ class DataClassGenerator extends GeneratorForAnnotation { ${clazz.constructorParams} ) ${clazz.constructorAsserts} - ${clazz.copyWithSignature} { - return ${clazz.className}.make( - ${clazz.copyWithArgs} - ); - } - ${eqImpl(clazz.className, clazz.fieldNames)} ${hashCodeImpl(clazz.fieldNames)} diff --git a/sum_data_types_generator/lib/sum_types.dart b/sum_data_types_generator/lib/sum_types.dart index 033df26..0649b8a 100644 --- a/sum_data_types_generator/lib/sum_types.dart +++ b/sum_data_types_generator/lib/sum_types.dart @@ -72,7 +72,7 @@ class FieldModel { String get getterImpl { final optional = _imports.lookupOptionalType(); - return '''@override + return ''' $getterDecl { return $optional<${type.typeRepr}>.fromNullable(this.$internalName); }'''; @@ -123,7 +123,7 @@ class ClassModel { List get fields => _commonModel.fields; String get className => _commonModel.className; - String get baseClassName => _commonModel.baseClassName; + String get extensionName => _commonModel.extensionName; String get mixinName => _commonModel.mixinName; String get factoryName => _commonModel.factoryName; List get typeArgs => _commonModel.typeArgs; @@ -139,10 +139,6 @@ class ClassModel { .join("\n"); } - String get getterDecls { - return this.fields.map((field) => field.getterDecl + ";").join("\n"); - } - String switchParams(String tyArg, SwitchMode mode) { return this.fields.map((field) => field.switchParam(tyArg, mode)).join(",\n"); } @@ -219,35 +215,13 @@ class SumTypeGenerator extends GeneratorForAnnotation { abstract class ${clazz.factoryName} { ${clazz.factoryMethods} } - abstract class ${clazz.baseClassName}${clazz.typeArgsWithParens} { - const ${clazz.baseClassName}(); - ${clazz.getterDecls} + extension ${clazz.extensionName}${clazz.typeArgsWithParens} on ${clazz.mixinName}${clazz.typeArgsWithParens} { $tyArg iswitch<$tyArg>({ - ${clazz.switchParams(tyArg, SwitchMode.Required)} - }); - $tyArg iswitcho<$tyArg>({ - ${clazz.switchParams(tyArg, SwitchMode.Optional)}, - @required $tyArg Function() $otherwise, - }); - } - class ${clazz.className}${clazz.typeArgsWithParens} - extends ${clazz.baseClassName}${clazz.typeArgsWithParens} - with ${clazz.mixinName}${clazz.typeArgsWithParens} - { - ${clazz.fieldDecls} - ${clazz.getterImpls} - ${clazz.className}({ - ${clazz.constructorParams} - }) : ${clazz.constructorInitializers}; - - @override - $tyArg iswitch<$tyArg>({ - ${clazz.switchParams(tyArg, SwitchMode.Required)} + ${clazz.switchParams(tyArg, SwitchMode.Required)}, }) { ${clazz.iswitchBody} } - @override $tyArg iswitcho<$tyArg>({ ${clazz.switchParams(tyArg, SwitchMode.Optional)}, @required $tyArg Function() $otherwise, @@ -256,6 +230,15 @@ class SumTypeGenerator extends GeneratorForAnnotation { ${clazz.iswitchArgsFromOtherwise(otherwise)} ); } + } + class ${clazz.className}${clazz.typeArgsWithParens} + with ${clazz.mixinName}${clazz.typeArgsWithParens} + { + ${clazz.fieldDecls} + ${clazz.getterImpls} + ${clazz.className}({ + ${clazz.constructorParams} + }) : ${clazz.constructorInitializers}; ${eqImpl(clazz.className, clazz.fieldNames)} diff --git a/sum_data_types_generator/pubspec.yaml b/sum_data_types_generator/pubspec.yaml index 6978465..7351a70 100644 --- a/sum_data_types_generator/pubspec.yaml +++ b/sum_data_types_generator/pubspec.yaml @@ -5,10 +5,10 @@ author: Stefan Wehr (wehr@cp-med.com) homepage: https://github.com/factisresearch/sum_data_types environment: - sdk: ">=2.5.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" dependencies: - analyzer: ^0.36.0 + analyzer: ^0.39.1 build: ^1.2.0 # sum_data_types: ^0.0.1 sum_data_types: From d3ffaf193473c54e54a51d1b8ccd21de95c11c66 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Mon, 25 Nov 2019 23:55:28 +0100 Subject: [PATCH 2/5] Generate more readable code --- sum_data_types_generator/lib/common.dart | 13 +++----- .../lib/data_classes.dart | 4 +-- sum_data_types_generator/lib/sum_types.dart | 31 ++++++++----------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/sum_data_types_generator/lib/common.dart b/sum_data_types_generator/lib/common.dart index fd55a19..6bfc222 100644 --- a/sum_data_types_generator/lib/common.dart +++ b/sum_data_types_generator/lib/common.dart @@ -229,21 +229,16 @@ String eqImpl(String className, List fieldNames) { } return '''@override bool operator ==(Object $other) { - if (identical(this, $other)) { - return true; - } - return ( - $other is $className && - this.runtimeType == $other.runtimeType && - $fieldsEq - ); + if (identical(this, $other)) return true; + if (this.runtimeType != $other.runtimeType) return false; + return $other is $className && $fieldsEq; }'''; } String hashCodeImpl(List fieldNames) { if (fieldNames.isEmpty) { return '''@override - int get hashCode { return 0; } + int get hashCode => 0; '''; } const result = r'__result$'; diff --git a/sum_data_types_generator/lib/data_classes.dart b/sum_data_types_generator/lib/data_classes.dart index 2056a40..2eda4be 100644 --- a/sum_data_types_generator/lib/data_classes.dart +++ b/sum_data_types_generator/lib/data_classes.dart @@ -86,7 +86,7 @@ class FieldModel { } String get copyWithParam { - return "${this.type.typeRepr} ${this.name}"; + return "${this.type.typeRepr} ${this.name},"; } } @@ -110,7 +110,7 @@ class ClassModel { String get copyWithSignature { final params = (this.fields.isNotEmpty) - ? "{" + this.fields.map((field) => field.copyWithParam).join(",") + "}" + ? "{" + this.fields.map((field) => field.copyWithParam).join("") + "}" : ""; return "${this.mixinType} copyWith($params)"; } diff --git a/sum_data_types_generator/lib/sum_types.dart b/sum_data_types_generator/lib/sum_types.dart index 0649b8a..bb3e290 100644 --- a/sum_data_types_generator/lib/sum_types.dart +++ b/sum_data_types_generator/lib/sum_types.dart @@ -42,9 +42,8 @@ class FieldModel { String factoryMethod(String resultType, String tyArgs, String constructor) { String mkFun(String arg, String result) { - return '''static $resultType $name$tyArgs($arg) { - return $constructor($name: $result); - }'''; + return '''static $resultType $name$tyArgs($arg) => + $constructor($name: $result);'''; } if (this.type.isUnit) { @@ -72,14 +71,11 @@ class FieldModel { String get getterImpl { final optional = _imports.lookupOptionalType(); - return ''' - $getterDecl { - return $optional<${type.typeRepr}>.fromNullable(this.$internalName); - }'''; + return "$getterDecl => $optional<${type.typeRepr}>.fromNullable(this.$internalName);"; } String get constructorParam { - return '${type.typeRepr} $name'; + return '${type.typeRepr} $name,'; } String get constructorAssignment { @@ -89,25 +85,22 @@ class FieldModel { String get iswitchIf { final funArg = this.type.isUnit ? '' : 'this.$internalName'; return '''if (this.$internalName != null) { - if ($name != null) { - return $name($funArg); - } else { - throw ArgumentError.notNull("$name"); - } + if ($name == null) throw ArgumentError.notNull("$name"); + return $name($funArg); } '''; } String iswitchArgFromOtherwise(String otherwise) { final _otherwise = this.type.isUnit ? otherwise : '(Object _) => $otherwise()'; - return '$name: $name ?? $_otherwise'; + return '$name: $name ?? $_otherwise,'; } String get toStringSwitch { if (type.isUnit) { return '$name: () => "$name"'; } else { - return '$name: (${type.typeRepr} __value\$) => "$name(" + __value\$.toString() + ")"'; + return '$name: (${type.typeRepr} __value\$) => "$name(\${__value\$})"'; } } } @@ -152,7 +145,7 @@ class ClassModel { } String get constructorParams { - return this.fields.map((field) => field.constructorParam).join(",\n"); + return this.fields.map((field) => field.constructorParam).join("\n"); } String get constructorInitializers { @@ -185,7 +178,7 @@ class ClassModel { } String iswitchArgsFromOtherwise(String otherwise) { - return this.fields.map((field) => field.iswitchArgFromOtherwise(otherwise)).join(",\n"); + return this.fields.map((field) => field.iswitchArgFromOtherwise(otherwise)).join("\n"); } String get toStringSwitch { @@ -235,7 +228,9 @@ class SumTypeGenerator extends GeneratorForAnnotation { with ${clazz.mixinName}${clazz.typeArgsWithParens} { ${clazz.fieldDecls} + ${clazz.getterImpls} + ${clazz.className}({ ${clazz.constructorParams} }) : ${clazz.constructorInitializers}; @@ -247,7 +242,7 @@ class SumTypeGenerator extends GeneratorForAnnotation { @override toString() { final __x\$ = iswitch(${clazz.toStringSwitch}); - return "${clazz.mixinName}." + __x\$; + return "${clazz.mixinName}.\${__x\$}"; } } '''; From 20358955dc94773ba46e7b36fb774590c7c3ae22 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Wed, 11 Dec 2019 19:04:14 +0100 Subject: [PATCH 3/5] Fix new examples after merge --- example/lib/data_classes.dart | 4 ++-- example/lib/sum_types.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/lib/data_classes.dart b/example/lib/data_classes.dart index ca7514a..f3131fd 100644 --- a/example/lib/data_classes.dart +++ b/example/lib/data_classes.dart @@ -106,7 +106,7 @@ mixin User { mixin NullaryType {} @DataClass(toString: false) -mixin CustomToString on _CustomToStringBase { +mixin CustomToString { String get foo; String get bar; @@ -116,7 +116,7 @@ mixin CustomToString on _CustomToStringBase { } @DataClass(eqHashCode: false) -mixin CustomEq on _CustomEqBase { +mixin CustomEq { String get foo; String get bar; diff --git a/example/lib/sum_types.dart b/example/lib/sum_types.dart index ec9b4b8..637c86e 100644 --- a/example/lib/sum_types.dart +++ b/example/lib/sum_types.dart @@ -93,7 +93,7 @@ mixin Something { } @SumType(toString: false) -mixin CustomToString on _CustomToStringBase { +mixin CustomToString { String get _foo; String toString() { @@ -102,7 +102,7 @@ mixin CustomToString on _CustomToStringBase { } @SumType(eqHashCode: false) -mixin CustomEq on _CustomEqBase { +mixin CustomEq { String get _foo; @override From 94a38010c0b908889966ad2470a59046df92ed0a Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Wed, 11 Dec 2019 19:07:18 +0100 Subject: [PATCH 4/5] Commit the generated code Why have the code in comments when there is a perfectly good place to put it? --- .gitignore | 1 - example/lib/data_classes.dart | 145 ------------ example/lib/data_classes.g.dart | 383 ++++++++++++++++++++++++++++++++ example/lib/sum_types.dart | 188 ---------------- example/lib/sum_types.g.dart | 327 +++++++++++++++++++++++++++ 5 files changed, 710 insertions(+), 334 deletions(-) create mode 100644 example/lib/data_classes.g.dart create mode 100644 example/lib/sum_types.g.dart diff --git a/.gitignore b/.gitignore index 23eb9bd..246deba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ *.lock .packages .dart_tool -example/lib/*.g.dart diff --git a/example/lib/data_classes.dart b/example/lib/data_classes.dart index f3131fd..4009a7c 100644 --- a/example/lib/data_classes.dart +++ b/example/lib/data_classes.dart @@ -129,148 +129,3 @@ mixin CustomEq { return 42; } } - -/* -// START generated code -abstract class UserFactory { - static User make({ - @required String name, - int age, - @required KtList friends, - @required ty.Address address, - ty.Address workAddress, - @required KtList friendsAddresses, - }) { - return _User.make( - name: name, - age: Optional.of(age), - friends: friends, - address: address, - workAddress: Optional.of(workAddress), - friendsAddresses: friendsAddresses, - ); - } -} - -abstract class _UserBase { - _User copyWith( - {String name, - Optional age, - KtList friends, - ty.Address address, - Optional workAddress, - KtList friendsAddresses}); -} - -@immutable -class _User extends _UserBase with User { - final String name; - final Optional age; - final KtList friends; - final ty.Address address; - final Optional workAddress; - final KtList friendsAddresses; - - // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 - _User.make({ - @required this.name, - @required this.age, - @required this.friends, - @required this.address, - @required this.workAddress, - @required this.friendsAddresses, - }) : assert(name != null), - assert(age != null), - assert(friends != null), - assert(address != null), - assert(workAddress != null), - assert(friendsAddresses != null); - - _User copyWith( - {String name, - Optional age, - KtList friends, - ty.Address address, - Optional workAddress, - KtList friendsAddresses}) { - return _User.make( - name: name ?? this.name, - age: age ?? this.age, - friends: friends ?? this.friends, - address: address ?? this.address, - workAddress: workAddress ?? this.workAddress, - friendsAddresses: friendsAddresses ?? this.friendsAddresses, - ); - } - - bool operator ==(Object other) { - if (identical(this, other)) { - return true; - } - return (other is _User && - this.runtimeType == other.runtimeType && - this.name == other.name && - this.age == other.age && - this.friends == other.friends && - this.address == other.address && - this.workAddress == other.workAddress && - this.friendsAddresses == other.friendsAddresses); - } - - int get hashCode { - var result = 17; - result = 37 * result + this.name.hashCode; - result = 37 * result + this.age.hashCode; - result = 37 * result + this.friends.hashCode; - result = 37 * result + this.address.hashCode; - result = 37 * result + this.workAddress.hashCode; - result = 37 * result + this.friendsAddresses.hashCode; - return result; - } - - String toString() { - return "User(name: ${this.name}, age: ${this.age}, friends: ${this.friends}, address: ${this.address}, workAddress: ${this.workAddress}, friendsAddresses: ${this.friendsAddresses})"; - } -} - -/// This data class has been generated from NullaryType -abstract class NullaryTypeFactory { - static NullaryType make() { - return _NullaryType.make(); - } -} - -abstract class _NullaryTypeBase { - _NullaryType copyWith(); -} - -@immutable -class _NullaryType extends _NullaryTypeBase with NullaryType { - // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 - _NullaryType.make(); - - _NullaryType copyWith() { - return _NullaryType.make(); - } - - bool operator ==(Object other) { - if (identical(this, other)) { - return true; - } - return (other is _NullaryType && - this.runtimeType == other.runtimeType && - true); - } - - int get hashCode { - var result = 17; - - return result; - } - - String toString() { - return "NullaryType()"; - } -} -// END generated code -*/ diff --git a/example/lib/data_classes.g.dart b/example/lib/data_classes.g.dart new file mode 100644 index 0000000..10b1459 --- /dev/null +++ b/example/lib/data_classes.g.dart @@ -0,0 +1,383 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'data_classes.dart'; + +// ************************************************************************** +// SumTypeGenerator +// ************************************************************************** + +/// This data class has been generated from Either +abstract class EitherFactory { + static Either left(A __x$) => _Either(left: __x$); + static Either right(B __x$) => _Either(right: __x$); +} + +extension EitherMethods on Either { + __T$ iswitch<__T$>({ + @required __T$ Function(A) left, + @required __T$ Function(B) right, + }) { + if (this._left != null) { + if (left == null) throw ArgumentError.notNull("left"); + return left(this._left); + } else if (this._right != null) { + if (right == null) throw ArgumentError.notNull("right"); + return right(this._right); + } else { + throw StateError("an instance of Either has no case selected"); + } + } + + __T$ iswitcho<__T$>({ + __T$ Function(A) left, + __T$ Function(B) right, + @required __T$ Function() otherwise, + }) { + return iswitch( + left: left ?? (Object _) => otherwise(), + right: right ?? (Object _) => otherwise(), + ); + } +} + +class _Either with Either { + final A _left; + final B _right; + + Optional get left => Optional.fromNullable(this._left); + Optional get right => Optional.fromNullable(this._right); + + _Either({ + A left, + B right, + }) : assert( + (left != null && right == null) || (left == null && right != null)), + this._left = left, + this._right = right; + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _Either && + this.left == __other$.left && + this.right == __other$.right; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.left.hashCode; + __result$ = 37 * __result$ + this.right.hashCode; + return __result$; + } + + @override + toString() { + final __x$ = iswitch( + left: (A __value$) => "left(${__value$})", + right: (B __value$) => "right(${__value$})"); + return "Either.${__x$}"; + } +} + +// ************************************************************************** +// DataClassGenerator +// ************************************************************************** + +/// This data class has been generated from Container +abstract class ContainerFactory { + static Container make({ + @required String id, + @required T payload, + }) { + return _Container.make( + id: id, + payload: payload, + ); + } +} + +extension ContainerMethods on Container { + Container copyWith({ + String id, + T payload, + }) { + return _Container.make( + id: id ?? this.id, + payload: payload ?? this.payload, + ); + } +} + +@immutable +class _Container with Container { + final String id; + final T payload; + + // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 + _Container.make({ + @required this.id, + @required this.payload, + }) : assert(id != null), + assert(payload != null); + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _Container && + this.id == __other$.id && + this.payload == __other$.payload; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.id.hashCode; + __result$ = 37 * __result$ + this.payload.hashCode; + return __result$; + } + + @override + String toString() { + return "Container(id: ${this.id}, payload: ${this.payload})"; + } +} + +/// This data class has been generated from User +abstract class UserFactory { + static User make({ + @required String name, + int age, + @required KtList friends, + @required ty.Address address, + ty.Address workAddress, + @required KtList friendsAddresses, + @required Either foo, + }) { + return _User.make( + name: name, + age: Optional.fromNullable(age), + friends: friends, + address: address, + workAddress: Optional.fromNullable(workAddress), + friendsAddresses: friendsAddresses, + foo: foo, + ); + } +} + +extension UserMethods on User { + User copyWith({ + String name, + Optional age, + KtList friends, + ty.Address address, + Optional workAddress, + KtList friendsAddresses, + Either foo, + }) { + return _User.make( + name: name ?? this.name, + age: age ?? this.age, + friends: friends ?? this.friends, + address: address ?? this.address, + workAddress: workAddress ?? this.workAddress, + friendsAddresses: friendsAddresses ?? this.friendsAddresses, + foo: foo ?? this.foo, + ); + } +} + +@immutable +class _User with User { + final String name; + final Optional age; + final KtList friends; + final ty.Address address; + final Optional workAddress; + final KtList friendsAddresses; + final Either foo; + + // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 + _User.make({ + @required this.name, + @required this.age, + @required this.friends, + @required this.address, + @required this.workAddress, + @required this.friendsAddresses, + @required this.foo, + }) : assert(name != null), + assert(age != null), + assert(friends != null), + assert(address != null), + assert(workAddress != null), + assert(friendsAddresses != null), + assert(foo != null); + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _User && + this.name == __other$.name && + this.age == __other$.age && + this.friends == __other$.friends && + this.address == __other$.address && + this.workAddress == __other$.workAddress && + this.friendsAddresses == __other$.friendsAddresses && + this.foo == __other$.foo; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.name.hashCode; + __result$ = 37 * __result$ + this.age.hashCode; + __result$ = 37 * __result$ + this.friends.hashCode; + __result$ = 37 * __result$ + this.address.hashCode; + __result$ = 37 * __result$ + this.workAddress.hashCode; + __result$ = 37 * __result$ + this.friendsAddresses.hashCode; + __result$ = 37 * __result$ + this.foo.hashCode; + return __result$; + } + + @override + String toString() { + return "User(name: ${this.name}, age: ${this.age}, friends: ${this.friends}, address: ${this.address}, workAddress: ${this.workAddress}, friendsAddresses: ${this.friendsAddresses}, foo: ${this.foo})"; + } +} + +/// This data class has been generated from NullaryType +abstract class NullaryTypeFactory { + static NullaryType make() { + return _NullaryType.make(); + } +} + +extension NullaryTypeMethods on NullaryType { + NullaryType copyWith() { + return _NullaryType.make(); + } +} + +@immutable +class _NullaryType with NullaryType { + // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 + _NullaryType.make(); + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _NullaryType && true; + } + + @override + int get hashCode => 0; + + @override + String toString() { + return "NullaryType()"; + } +} + +/// This data class has been generated from CustomToString +abstract class CustomToStringFactory { + static CustomToString make({ + @required String foo, + @required String bar, + }) { + return _CustomToString.make( + foo: foo, + bar: bar, + ); + } +} + +extension CustomToStringMethods on CustomToString { + CustomToString copyWith({ + String foo, + String bar, + }) { + return _CustomToString.make( + foo: foo ?? this.foo, + bar: bar ?? this.bar, + ); + } +} + +@immutable +class _CustomToString with CustomToString { + final String foo; + final String bar; + + // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 + _CustomToString.make({ + @required this.foo, + @required this.bar, + }) : assert(foo != null), + assert(bar != null); + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _CustomToString && + this.foo == __other$.foo && + this.bar == __other$.bar; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.foo.hashCode; + __result$ = 37 * __result$ + this.bar.hashCode; + return __result$; + } +} + +/// This data class has been generated from CustomEq +abstract class CustomEqFactory { + static CustomEq make({ + @required String foo, + @required String bar, + }) { + return _CustomEq.make( + foo: foo, + bar: bar, + ); + } +} + +extension CustomEqMethods on CustomEq { + CustomEq copyWith({ + String foo, + String bar, + }) { + return _CustomEq.make( + foo: foo ?? this.foo, + bar: bar ?? this.bar, + ); + } +} + +@immutable +class _CustomEq with CustomEq { + final String foo; + final String bar; + + // We cannot have a const constructor because of https://github.com/dart-lang/sdk/issues/37810 + _CustomEq.make({ + @required this.foo, + @required this.bar, + }) : assert(foo != null), + assert(bar != null); + + @override + String toString() { + return "CustomEq(foo: ${this.foo}, bar: ${this.bar})"; + } +} diff --git a/example/lib/sum_types.dart b/example/lib/sum_types.dart index 637c86e..2b55880 100644 --- a/example/lib/sum_types.dart +++ b/example/lib/sum_types.dart @@ -114,191 +114,3 @@ mixin CustomEq { return 42; } } - -/* -// generated code -abstract class SomethingFactory { - static Something nothing() { - return _Something(nothing: const Unit()); - } - static Something user(User x) { - return _Something(user: x); - } - static Something address(Optional x) { - return _Something(address: x); - } - static Something something(Something x) { - return _Something(something: x); - } - static Something param(T x) { - return _Something(param: x); - } -} - -abstract class _SomethingBase { - Optional get nothing; - Optional get user; - Optional> get address; - Optional get something; - Optional get param; - - __T iswitch<__T>({ - @required __T Function() nothing, - @required __T Function(User) user, - @required __T Function(Optional) address, - @required __T Function(Something) something, - @required __T Function(T) param, - }); - __T iswitcho<__T>({ - __T Function() nothing, - __T Function(User) user, - __T Function(Optional) address, - __T Function(Something) something, - __T Function(T) param, - @required __T Function() otherwise, - }); - - const _SomethingBase(); -} - -class _Something extends _SomethingBase with Something { - - final Unit _nothing; - final User _user; - final Optional _address; - final Something _something; - final T _param; - - Optional get nothing { - return Optional.fromNullable(this._nothing); - } - - Optional get user { - return Optional.fromNullable(this._user); - } - - Optional> get address { - return Optional.fromNullable(this._address); - } - Optional get something { - return Optional.fromNullable(this._something); - } - Optional get param { - return Optional.fromNullable(this._param); - } - - _Something({ - Unit nothing, - User user, - Optional address, - Something something, - T param, - }) : assert( - (nothing != null && user == null && address == null && something == null) || - (nothing == null && user != null && address == null && something == null) || - (nothing == null && user == null && address != null && something == null) || - (nothing == null && user == null && address == null && something != null) - ), - this._nothing = nothing, - this._user = user, - this._address = address, - this._something = something, - this._param = param; - - @override - __T iswitch<__T>({ - @required __T Function() nothing, - @required __T Function(User) user, - @required __T Function(Optional) address, - @required __T Function(Something) something, - @required __T Function(T) param, - }) { - if (this._nothing != null) { - if (nothing != null) { - return nothing(); - } else { - throw ArgumentError.notNull("nothing"); - } - } else if (this._user != null) { - if (user != null) { - return user(this._user); - } else { - throw ArgumentError.notNull("user"); - } - } else if (this._address != null) { - if (address != null) { - return address(this._address); - } else { - throw ArgumentError.notNull("address"); - } - } else if (this._something != null) { - if (something != null) { - return something(this._something); - } else { - throw ArgumentError.notNull("something"); - } - } else if (this._param != null) { - if (param != null) { - return param(this._param); - } else { - throw ArgumentError.notNull("something"); - } - } else { - throw StateError("an instance of Something has no case selected"); - } - } - - @override - __T iswitcho<__T>({ - __T Function() nothing, - __T Function(User) user, - __T Function(Optional) address, - __T Function(Something) something, - __T Function(T) param, - @required __T Function() otherwise, - }) { - return iswitch( - nothing: nothing ?? otherwise, - user: user ?? (Object _) => otherwise(), - address: address ?? (Object _) => otherwise(), - something: something ?? (Object _) => otherwise(), - param: param ?? (Object _) => otherwise(), - ); - } - - @override - bool operator ==( - dynamic other, - ) { - return other.runtimeType == runtimeType && - other._nothing == this._nothing && - other._user == this._user && - other._address == this._address && - other._something == this._something && - other._param == this._param; - } - - @override - int get hashCode { - var result = 17; - result = 37 * result + this._nothing.hashCode; - result = 37 * result + this._user.hashCode; - result = 37 * result + this._address.hashCode; - result = 37 * result + this._something.hashCode; - result = 37 * result + this._param.hashCode; - return result; - } - - @override - String toString() { - final ctor = iswitch( - nothing: () => "nothing", - user: (value) => "user($value)", - address: (value) => "address($value)", - something: (value) => "something($value)", - param: (value) => "param($value)", - ); - return "Something.$ctor"; - } -} -*/ diff --git a/example/lib/sum_types.g.dart b/example/lib/sum_types.g.dart new file mode 100644 index 0000000..432ba98 --- /dev/null +++ b/example/lib/sum_types.g.dart @@ -0,0 +1,327 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'sum_types.dart'; + +// ************************************************************************** +// SumTypeGenerator +// ************************************************************************** + +/// This data class has been generated from WithUnknown +abstract class WithUnknownFactory { + static WithUnknown known(String __x$) => _WithUnknown(known: __x$); + static WithUnknown unknown(dynamic __x$) => _WithUnknown(unknown: __x$); +} + +extension WithUnknownMethods on WithUnknown { + __T$ iswitch<__T$>({ + @required __T$ Function(String) known, + @required __T$ Function(dynamic) unknown, + }) { + if (this._known != null) { + if (known == null) throw ArgumentError.notNull("known"); + return known(this._known); + } else if (this._unknown != null) { + if (unknown == null) throw ArgumentError.notNull("unknown"); + return unknown(this._unknown); + } else { + throw StateError("an instance of WithUnknown has no case selected"); + } + } + + __T$ iswitcho<__T$>({ + __T$ Function(String) known, + __T$ Function(dynamic) unknown, + @required __T$ Function() otherwise, + }) { + return iswitch( + known: known ?? (Object _) => otherwise(), + unknown: unknown ?? (Object _) => otherwise(), + ); + } +} + +class _WithUnknown with WithUnknown { + final String _known; + final dynamic _unknown; + + quiv.Optional get known => + quiv.Optional.fromNullable(this._known); + quiv.Optional get unknown => + quiv.Optional.fromNullable(this._unknown); + + _WithUnknown({ + String known, + dynamic unknown, + }) : assert((known != null && unknown == null) || + (known == null && unknown != null)), + this._known = known, + this._unknown = unknown; + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _WithUnknown && + this.known == __other$.known && + this.unknown == __other$.unknown; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.known.hashCode; + __result$ = 37 * __result$ + this.unknown.hashCode; + return __result$; + } + + @override + toString() { + final __x$ = iswitch( + known: (String __value$) => "known(${__value$})", + unknown: (dynamic __value$) => "unknown(${__value$})"); + return "WithUnknown.${__x$}"; + } +} + +/// This data class has been generated from Something +abstract class SomethingFactory { + static Something nothing() => _Something(nothing: const Unit()); + static Something user(User __x$) => _Something(user: __x$); + static Something address(quiv.Optional __x$) => + _Something(address: __x$); + static Something something(Something __x$) => + _Something(something: __x$); + static Something param(T __x$) => _Something(param: __x$); +} + +extension SomethingMethods on Something { + __T$ iswitch<__T$>({ + @required __T$ Function() nothing, + @required __T$ Function(User) user, + @required __T$ Function(quiv.Optional) address, + @required __T$ Function(Something) something, + @required __T$ Function(T) param, + }) { + if (this._nothing != null) { + if (nothing == null) throw ArgumentError.notNull("nothing"); + return nothing(); + } else if (this._user != null) { + if (user == null) throw ArgumentError.notNull("user"); + return user(this._user); + } else if (this._address != null) { + if (address == null) throw ArgumentError.notNull("address"); + return address(this._address); + } else if (this._something != null) { + if (something == null) throw ArgumentError.notNull("something"); + return something(this._something); + } else if (this._param != null) { + if (param == null) throw ArgumentError.notNull("param"); + return param(this._param); + } else { + throw StateError("an instance of Something has no case selected"); + } + } + + __T$ iswitcho<__T$>({ + __T$ Function() nothing, + __T$ Function(User) user, + __T$ Function(quiv.Optional) address, + __T$ Function(Something) something, + __T$ Function(T) param, + @required __T$ Function() otherwise, + }) { + return iswitch( + nothing: nothing ?? otherwise, + user: user ?? (Object _) => otherwise(), + address: address ?? (Object _) => otherwise(), + something: something ?? (Object _) => otherwise(), + param: param ?? (Object _) => otherwise(), + ); + } +} + +class _Something with Something { + final Unit _nothing; + final User _user; + final quiv.Optional _address; + final Something _something; + final T _param; + + quiv.Optional get nothing => + quiv.Optional.fromNullable(this._nothing); + quiv.Optional get user => quiv.Optional.fromNullable(this._user); + quiv.Optional> get address => + quiv.Optional>.fromNullable(this._address); + quiv.Optional> get something => + quiv.Optional>.fromNullable(this._something); + quiv.Optional get param => quiv.Optional.fromNullable(this._param); + + _Something({ + Unit nothing, + User user, + quiv.Optional address, + Something something, + T param, + }) : assert((nothing != null && + user == null && + address == null && + something == null && + param == null) || + (nothing == null && + user != null && + address == null && + something == null && + param == null) || + (nothing == null && + user == null && + address != null && + something == null && + param == null) || + (nothing == null && + user == null && + address == null && + something != null && + param == null) || + (nothing == null && + user == null && + address == null && + something == null && + param != null)), + this._nothing = nothing, + this._user = user, + this._address = address, + this._something = something, + this._param = param; + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _Something && + this.nothing == __other$.nothing && + this.user == __other$.user && + this.address == __other$.address && + this.something == __other$.something && + this.param == __other$.param; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.nothing.hashCode; + __result$ = 37 * __result$ + this.user.hashCode; + __result$ = 37 * __result$ + this.address.hashCode; + __result$ = 37 * __result$ + this.something.hashCode; + __result$ = 37 * __result$ + this.param.hashCode; + return __result$; + } + + @override + toString() { + final __x$ = iswitch( + nothing: () => "nothing", + user: (User __value$) => "user(${__value$})", + address: (quiv.Optional __value$) => "address(${__value$})", + something: (Something __value$) => "something(${__value$})", + param: (T __value$) => "param(${__value$})"); + return "Something.${__x$}"; + } +} + +/// This data class has been generated from CustomToString +abstract class CustomToStringFactory { + static CustomToString foo(String __x$) => _CustomToString(foo: __x$); +} + +extension CustomToStringMethods on CustomToString { + __T$ iswitch<__T$>({ + @required __T$ Function(String) foo, + }) { + if (this._foo != null) { + if (foo == null) throw ArgumentError.notNull("foo"); + return foo(this._foo); + } else { + throw StateError("an instance of CustomToString has no case selected"); + } + } + + __T$ iswitcho<__T$>({ + __T$ Function(String) foo, + @required __T$ Function() otherwise, + }) { + return iswitch( + foo: foo ?? (Object _) => otherwise(), + ); + } +} + +class _CustomToString with CustomToString { + final String _foo; + + quiv.Optional get foo => + quiv.Optional.fromNullable(this._foo); + + _CustomToString({ + String foo, + }) : assert((foo != null)), + this._foo = foo; + + @override + bool operator ==(Object __other$) { + if (identical(this, __other$)) return true; + if (this.runtimeType != __other$.runtimeType) return false; + return __other$ is _CustomToString && this.foo == __other$.foo; + } + + @override + int get hashCode { + var __result$ = 17; + __result$ = 37 * __result$ + this.foo.hashCode; + return __result$; + } +} + +/// This data class has been generated from CustomEq +abstract class CustomEqFactory { + static CustomEq foo(String __x$) => _CustomEq(foo: __x$); +} + +extension CustomEqMethods on CustomEq { + __T$ iswitch<__T$>({ + @required __T$ Function(String) foo, + }) { + if (this._foo != null) { + if (foo == null) throw ArgumentError.notNull("foo"); + return foo(this._foo); + } else { + throw StateError("an instance of CustomEq has no case selected"); + } + } + + __T$ iswitcho<__T$>({ + __T$ Function(String) foo, + @required __T$ Function() otherwise, + }) { + return iswitch( + foo: foo ?? (Object _) => otherwise(), + ); + } +} + +class _CustomEq with CustomEq { + final String _foo; + + quiv.Optional get foo => + quiv.Optional.fromNullable(this._foo); + + _CustomEq({ + String foo, + }) : assert((foo != null)), + this._foo = foo; + + @override + toString() { + final __x$ = iswitch(foo: (String __value$) => "foo(${__value$})"); + return "CustomEq.${__x$}"; + } +} From 1ad52fc70100b43618cd0bd2a5fa8dc0599a008d Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Wed, 11 Dec 2019 19:09:15 +0100 Subject: [PATCH 5/5] Update travis config to use new dart version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 39e296c..6481fd8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: dart dart: - stable -- 2.5.2 +- 2.7.0 script: ${TRAVIS_BUILD_DIR}/scripts/check-all --prepare