Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diverged #1

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
29c6a8a
1.3.0 see CHANGELOG.md for changes
atreeon Aug 22, 2024
5267788
fixed naming
arrrrny Dec 3, 2024
92fab97
updated readme and changelog
arrrrny Dec 3, 2024
1c2270f
updated readme
arrrrny Dec 3, 2024
e5724ed
Merge branch 'master' into master
arrrrny Dec 3, 2024
bb94af5
change method name toJson_2 to toKsonCustom
arrrrny Dec 3, 2024
d017331
changed version to 2.0.0 to avoid confusions
arrrrny Dec 3, 2024
afa33eb
added back the throwing error if class type is not supported
arrrrny Dec 3, 2024
09eed66
dependency override to reference from git
arrrrny Dec 3, 2024
df83497
git referencing
arrrrny Dec 3, 2024
c19d178
git madness
arrrrny Dec 3, 2024
044325f
git refe
arrrrny Dec 3, 2024
116c7cf
we need the default FromJson
arrrrny Dec 3, 2024
ebd55ef
added toJsonClean to easily extract data to be used outside
arrrrny Dec 3, 2024
0ac3997
added toJsonLean and fromJsonLean to better intregrate to external sy…
arrrrny Dec 3, 2024
a4a99c4
updated version
arrrrny Dec 3, 2024
7b0b35a
refactored to support subtypes from different files
arrrrny Dec 4, 2024
b425fb0
better layout
arrrrny Dec 4, 2024
1721f5a
Merge pull request #1 from arrrrny/git-ref
arrrrny Dec 4, 2024
8ca52f9
checkpoint
arrrrny Dec 4, 2024
6b2a24a
throw error for neccessary imports
arrrrny Dec 4, 2024
411751c
version to 2.0.0
arrrrny Dec 4, 2024
bb244eb
Merge pull request #2 from arrrrny/git-ref
arrrrny Dec 4, 2024
2708261
added compareTo jsonHeader as default to true to set compareTo method
arrrrny Dec 5, 2024
7e5bdd4
fixed wron jsonserializable annotation
arrrrny Dec 5, 2024
542a5cf
Merge pull request #3 from arrrrny/git-ref
arrrrny Dec 5, 2024
acb2653
added non null for nullable but not null field
arrrrny Dec 5, 2024
1c2acd6
annotations update
arrrrny Dec 5, 2024
c92e151
Merge pull request #4 from arrrrny/git-ref
arrrrny Dec 5, 2024
4400780
added Patch type definition
arrrrny Dec 5, 2024
e3be723
Merge pull request #5 from arrrrny/git-ref
arrrrny Dec 5, 2024
52fbb8a
added more types to primitive compare
arrrrny Dec 5, 2024
c8c6227
Merge pull request #6 from arrrrny/git-ref
arrrrny Dec 5, 2024
d23be1b
supporting nested compareToEnum nested name
arrrrny Dec 6, 2024
54d0e37
Merge pull request #7 from arrrrny/git-ref
arrrrny Dec 6, 2024
b5d1141
implemented comprehensive non primitive type comparisons and enum com…
arrrrny Dec 6, 2024
0035dc2
Merge pull request #8 from arrrrny/git-ref
arrrrny Dec 6, 2024
7339c12
all tests pass with changes for ability to reference from external fi…
arrrrny Dec 8, 2024
ed426bf
added tests for toJsonLean
arrrrny Dec 8, 2024
daeb832
Merge pull request #9 from arrrrny/git-ref
arrrrny Dec 8, 2024
91369c2
type safe entity patch
arrrrny Dec 14, 2024
5bbcff0
Merge pull request #10 from arrrrny/git-ref
arrrrny Dec 14, 2024
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
7 changes: 4 additions & 3 deletions example/test/ex11_generic_subclass_manual_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import 'package:test/test.dart';

abstract class A<T1, T2> {
T1 get x;

T2 get y;

A copyWith_A<T1, T2>({
A<T1, T2> copyWith_A<T1, T2>({
Opt<T1>? x,
Opt<T2>? y,
});
Expand All @@ -26,15 +27,15 @@ class B implements A<int, String> {

String toString() => "(B-x:$x|y:$y|z:$z)";

B copyWith_A<T1, T2>({
A<T1, T2> copyWith_A<T1, T2>({
Opt<T1>? x,
Opt<T2>? y,
}) {
return B(
x: x == null ? this.x as int : x.value as int,
y: y == null ? this.y as String : y.value as String,
z: (this as B).z,
);
) as A<T1, T2>;
}

B copyWith_B({
Expand Down
2 changes: 1 addition & 1 deletion example/test/ex29_copywith_subclasses_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ main() {

test("db", () {
D db = D(b: 5, a: "A");
var db_copy = db.copyWith_B(a: () => "a", b: () => 6);
var db_copy = db.copyWith_B(a: () => "a", b: () => 6) as D;
expect(db_copy.toString(), "(D-a:a|b:6)");
});

Expand Down
12 changes: 4 additions & 8 deletions example/test/ex60_copywith_generic_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ part 'ex60_copywith_generic_test.morphy.dart';

main() {
test("1", () {
// var a = A<int>(x:1, y:2);
//
// var aAsInt = a.copyWith_A<int>(x: () => 2);
//
// expect(aAsInt.runtimeType, A<int>);
var a = A<int>(x:1, y:2);

// var aAsDouble = a.copyWith_A(x: () => 2.1);
//
// expect(aAsDouble.runtimeType, 2.1);
var aAsInt = a.copyWith_A<int>(x: () => 2);

expect(aAsInt.runtimeType, A<int>);
});
}

Expand Down
30 changes: 30 additions & 0 deletions example/test/ex63_class_with_no_members_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:morphy_annotation/morphy_annotation.dart';
import 'package:test/test.dart';

part 'ex63_class_with_no_members_test.morphy.dart';

@Morphy(
explicitSubTypes: [
$AgreedEulaState,
]
)
abstract class $EulaState
{
// lack of members
}

@Morphy()
abstract class $AgreedEulaState implements $EulaState
{
bool get test;
}

main() {
test("1", () {
var a = EulaState();
var b = AgreedEulaState(test: true);

expect(a == null, false);
expect(b.test, true);
});
}
19 changes: 17 additions & 2 deletions morphy/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
## 2.0.0
- BREAKING CHANGES! copyWith_A is now copyWithA and changeTo_A is now changeToA
- This is to make the naming more consistent with dart conventions
- merged the PRs that allow to set explicitToJson false
- Call the class fromJson if _className_ isn't specified
- Support property name shadowing global types such as Type, String, In…
- thanks to @miklcct for the PRs.

## 1.3.0
- bug fixes, subclass with no members now works, generic copy with bug now fixed where type is incorrect
- in order to fix the above problem the type returned from the copywith is now the type of the named copywith function, eg b.copyWith_A now returns an A type
- this is a BREAKING change.
- if you specify D newD = d.copyWith_A(); then newD will be of type D not A and you'll receive an error
- the thing is that if you know it is a d type you'd more likely do a d.copyWith_D() so this should not be a problem

## 1.2.0
- New functionality - private getters are now allowed!

## 1.1.0
- Breaking change! copywith / change to, the Opt class has been removed and now we favour the () => syntax for optional parameters
- Breaking change! copywith / change to, the Opt class has been removed and now we favour the () => syntax for optional parameters

## 1.0.8
- change_to added for a subclass to change the type back to a superclass
Expand Down Expand Up @@ -33,4 +48,4 @@
- Updated documentation

## 1.0.0
- First published version
- First published version
70 changes: 35 additions & 35 deletions morphy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ We need a way to simplify our Dart classes, support polymorphism and allow copyi

### Why Not Freezed or Built Value?
Well the main reason; I actually wrote this before Freezed was released.
Freezed is really good, established and well used.
However if you want to use both inheritance and polymorphism use Morphy.
Freezed is really good, established and well used.
However if you want to use both inheritance and polymorphism use Morphy.

### Solution: use morphy

Expand All @@ -24,7 +24,7 @@ To create a new class.
```
import 'package:morphy_annotation/morphy_annotation.dart';
part 'Pet.morphy.dart';

@morphy
abstract class $Pet {
String get type;
Expand Down Expand Up @@ -77,13 +77,13 @@ var cat1 = Pet(type: "cat");

### CopyWith

A simple copy with implementation comes with every class.
We pass a function to the copyWith_Pet method that returns a new value to set the property.
A simple copy with implementation comes with every class.
We pass a function to the copyWithPet method that returns a new value to set the property.
You can pass any value you like, including null if the property is nullable.

```
var flossy = Pet(name: "Flossy", age: 5);
var plossy = flossy.copyWith_Pet(name: () => "Plossy");
var plossy = flossy.copyWithPet(name: () => "Plossy");

expect(flossy.age, plossy.age);
```
Expand All @@ -107,9 +107,9 @@ All properties will be inherited by default.
abstract class $Cat implements $Pet {
int get whiskerLength;
}

var bagpussCat = Cat(whiskerLength: 13.75, name: "Bagpuss", age: 4);

expect(bagpussCat.whiskerLength, 13.75);

### CopyWith Polymorphic
Expand All @@ -122,14 +122,14 @@ then the copyWith still works whilst preserving the underlying type.
Cat(whiskerLength: 13.75, name: "Bagpuss", age: 4),
Dog(woofSound: "rowf", name: "Colin", age: 4),
];

var petsOlder = pets //
.map((e) => e.copyWith_Pet(age: () => e.age + 1))
.map((e) => e.copyWithPet(age: () => e.age + 1))
.toList();

expect(petsOlder[0].age, 5);
expect(petsOlder[1].age, 5);

Importantly the type remains the same, it is not converted to a Pet class.

expect(petsOlder[0].runtimeType, Cat);
Expand All @@ -147,7 +147,7 @@ Importantly the type remains the same, it is not converted to a Pet class.

### Generics are allowed

Specify the class definition if you want to constrain your generic type (use the dollar)
Specify the class definition if you want to constrain your generic type (use the dollar)

@morphy
abstract class $PetOwner<TPet extends $Pet> {
Expand All @@ -157,7 +157,7 @@ Specify the class definition if you want to constrain your generic type (use the

var cathy = PetOwner<Cat>(ownerName: "Cathy", pet: bagpussCat);
var dougie = PetOwner<Dog>(ownerName: "Dougie", pet: colin);

expect(cathy.pet.whiskerLength, 13.75);
expect(dougie.pet.woofSound, "rowf");

Expand All @@ -167,7 +167,7 @@ Sometimes you might want to turn a super class into a subclass (Pet into a Cat)

var flossy = Pet(name: "Flossy", age: 5);

var bagpussCat = flossy.changeTo_Cat(whiskerLength: 13.75);
var bagpussCat = flossy.changeToCat(whiskerLength: 13.75);

expect(bagpussCat.whiskerLength, 13.75);
expect(bagpussCat.runtimeType, Cat);
Expand All @@ -176,23 +176,23 @@ Sometimes you might want to turn a super class into a subclass (Pet into a Cat)

### Convert object to Json

In order to convert the object to Json specify the `generateJson`.
In order to convert the object to Json specify the `generateJson`.

@Morphy(generateJson: true)
abstract class $Pet {

Add the dev dependency to the json_serializable package

dart pub add json_serializable --dev

Add the part file, .g is required by the json_serializable package used internally by `morphy`

part 'Pets.g.dart';
part 'Pets.morphy.dart';

Build the generated files then use the toJson_2 method to generate the JSON
Build the generated files then use the toJsonCustom method to generate the JSON

var json = flossy.toJson_2({});
var json = flossy.toJsonCustom({});
expect(json, {'name': 'Flossy', 'age': 5, '_className_': 'Pet'});

### Convert Json to Object
Expand All @@ -209,19 +209,19 @@ Use the factory method `Pet.fromJson()` to create the new object.
### Json to Object Polymorphism

Unlike other json conversions you can convert subtypes using the super types toJson and fromJson functions.

The subtypes must be specified in the explicitSubTypes and in the correct order for this to work.

@Morphy(generateJson: true, explicitSubTypes: [$Z, $Y])
abstract class $X {
String get val;
}

@Morphy(generateJson: true, explicitSubTypes: [$Z])
abstract class $Y implements $X {
int get valY;
}

@Morphy(generateJson: true)
abstract class $Z implements $Y {
double get valZ;
Expand All @@ -235,7 +235,7 @@ The subtypes must be specified in the explicitSubTypes and in the correct order

We can then just convert our list of X objects to JSON preserving their original type.

var resultInJsonFormat = xObjects.map((e) => e.toJson_2({})).toList();
var resultInJsonFormat = xObjects.map((e) => e.toJsonCustom({})).toList();

var expectedJson = [
{'val': 'x', '_className_': 'X'},
Expand Down Expand Up @@ -267,10 +267,10 @@ We also allow multiple inheritance.

### Custom Constructors

To allow custom constructors you can simply create a publicly accessible factory function that calls the constructor (ie just a method that calls the default constructor).
To allow custom constructors you can simply create a publicly accessible factory function that calls the constructor (ie just a method that calls the default constructor).
If you'd like to hide the automatic constructor set the `hidePublicConstructor` on the Morphy annotation to true.
If you do hide the default constructor,
then in order for the custom factory function (A_FactoryFunction in the example below) to be able to call the hidden (or private) default constructor,
If you do hide the default constructor,
then in order for the custom factory function (A_FactoryFunction in the example below) to be able to call the hidden (or private) default constructor,
your factory function should live in the same file you defined your class.

@Morphy(hidePublicConstructor: true)
Expand Down Expand Up @@ -304,7 +304,7 @@ Optional parameters can be specified using the ? keyword on the getter property.
### Comments

Comments are copied from the class definition to the generated class
and for ease of use copied to the constructor too.
and for ease of use copied to the constructor too.

### Constant Constructor

Expand All @@ -313,7 +313,7 @@ Just define a blank const constructor in your class definition file
const $A();

Then call the const constructor using the named constructor ```constant``

var a = A.constant();

### Private Getters
Expand All @@ -324,17 +324,17 @@ If we start our property with an underscore then we make the getter private but
@morphy
abstract class $$Pet {
int get _ageInYears;

String get name;
}

@morphy
abstract class $Cat implements $$Pet {}

@morphy
abstract class $Dog implements $$Pet {}
abstract class $Dog implements $$Pet {}

extension Pet_E on Pet {
extension PetE on Pet {
int age() => switch (this) {
Cat() => _ageInYears * 7,
Dog() => _ageInYears * 5,
Expand All @@ -343,7 +343,7 @@ If we start our property with an underscore then we make the getter private but

var cat = Cat(name: "Tom", ageInYears: 3);
var dog = Dog(name: "Rex", ageInYears: 3);

expect(cat.age(), 21);
expect(dog.age(), 15);

Expand All @@ -358,4 +358,4 @@ a kind of two step route back. You must go to the generated and then you can cl
$ version of the class which will be next to it.

Sometimes one class needs to be built before another.
In that scenario use morphy2 as the annotation in one class and morphy in the other.
In that scenario use morphy2 as the annotation in one class and morphy in the other.
18 changes: 14 additions & 4 deletions morphy/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,25 @@ builders:
target: ":morphy"
import: "package:morphy/morphyBuilder.dart"
builder_factories: ["morphyBuilder"]
build_extensions: {".dart": [".morphy.part"]}
build_extensions: { ".dart": [".morphy.dart"] }
auto_apply: dependents
build_to: source
runs_before: ["json_serializable:json_serializable", "typedef_for_fn_generator:typedef_for_fn","mock_creator_generator:mock_creator","copy_with_e_generator:copy_with_e", "copy_with_e_generator:copy_with_e","memoizer_generator:memoizer_generator"]
applies_builders: ["source_gen|combining_builder"]
runs_before: ["json_serializable:json_serializable"]
morphy2:
target: ":morphy2_generator"
import: "package:morphy/morphy2Builder.dart"
builder_factories: ["morphy2Builder"]
build_extensions: {".dart": [".morphy2.part"]}
build_extensions: { ".dart": [".morphy2.dart"] }
auto_apply: dependents
build_to: source
runs_before: ["json_serializable|json_serializable", "morphy:morphy", "typedef_for_fn_generator:typedef_for_fn","mock_creator_generator:mock_creator","copy_with_e_generator:copy_with_e", "copy_with_e_generator:copy_with_e","memoizer_generator:memoizer_generator"]
runs_before:
[
"json_serializable|json_serializable",
"morphy:morphy",
"typedef_for_fn_generator:typedef_for_fn",
"mock_creator_generator:mock_creator",
"copy_with_e_generator:copy_with_e",
"copy_with_e_generator:copy_with_e",
"memoizer_generator:memoizer_generator",
]
3 changes: 2 additions & 1 deletion morphy/lib/morphy2Builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import 'package:source_gen/source_gen.dart';
import 'package:morphy_annotation/morphy_annotation.dart';

Builder morphy2Builder(BuilderOptions options) => //
PartBuilder([MorphyGenerator<Morphy2>()], '.morphy2.dart',
PartBuilder(
[MorphyGenerator<Morphy2>()], '.morphy2.dart', // Keep as .morphy2.dart
header: '''
// ignore_for_file: UNNECESSARY_CAST
// ignore_for_file: type=lint
Expand Down
2 changes: 1 addition & 1 deletion morphy/lib/morphyBuilder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Builder morphyBuilder(BuilderOptions options) => //
header: '''
// ignore_for_file: UNNECESSARY_CAST
// ignore_for_file: type=lint
''');
''');
Loading