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

Support Freezed classes extending another Freezed class. #907

Open
rrousselGit opened this issue May 13, 2023 · 5 comments
Open

Support Freezed classes extending another Freezed class. #907

rrousselGit opened this issue May 13, 2023 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@rrousselGit
Copy link
Owner

Cases to handle:

@freezed
sealed class A with _$A {
  factory A.one() = A1;
}

@freezed
class B extends A with _$B {
  factory B.one() = B1;
  factory B.two() = B2;
}

void main() {
  B b;
  switch (b){
    case B1(): print('b1');
    case B2(): print('b2');
  }
  
  A a;
  switch (a){
    case A1(): print('a1')
    case B1(): print('b1');
    case B2(): print('b2');
  }
}

with variants such as

@freezed
class B extends A1 with _$B {...}
@rrousselGit rrousselGit added enhancement New feature or request needs triage labels May 13, 2023
@rrousselGit rrousselGit self-assigned this May 13, 2023
@rrousselGit
Copy link
Owner Author

Probably would require disabling when generation. But we have pattern matching now :shrug;

@rrousselGit
Copy link
Owner Author

Currently we can do:

sealed class B implements A {
  int get moreCommonGround;
} 

@freezed
sealed class A with _$A {
  @Implements<B>();
  factory A.c(int commonGround, int moreCommonGround) = C;
  @Implements<B>();
  factory A.d(int commonGround, int moreCommonGround) = D;
  factory A.z(int commonGround) = Z;
}

The main genefit of this proposal is:

  • B could have a fromJson directly
  • B would have a custom copyWith with its shared properties.

@TimWhiting
Copy link
Contributor

Haha, I've actually been doing the implements workaround already for a few days with sealed classes. Would love to see this feature.

@jacobokoenig
Copy link

@TimWhiting can you share your workaround? Trying to extend a class that uses freezed and I would hate to have to remove the freezed implementation

@TimWhiting
Copy link
Contributor

TimWhiting commented Dec 1, 2023

Currently we can do:

sealed class B implements A {
  int get moreCommonGround;
} 

@freezed
sealed class A with _$A {
  @Implements<B>();
  factory A.c(int commonGround, int moreCommonGround) = C;
  @Implements<B>();
  factory A.d(int commonGround, int moreCommonGround) = D;
  factory A.z(int commonGround) = Z;
}

The main genefit of this proposal is:

  • B could have a fromJson directly
  • B would have a custom copyWith with its shared properties.

This is the workaround. You can't extend the freezed class. You have to use Implements annotation to share common ground between a subset of the cases.

Then just use pattern matching instead of when / map. If you want shared implementation details, then you can use the With annotation to share implementations based on the interface you Implements using a mixin on the interface. Or you can implement extension methods based on the interface you Implements. If you want exhaustive pattern matching on a subset of the constructors, then make the interface you implement an sealed class. Make all the definitions in the interface just getters or unimplemented methods since you won't actually inherit any implementations using Implements.

Here is a file that uses this approach. https://github.com/byu-static-analysis-lab/syntax/blob/main/lib/src/scheme/scheme_syntax.dart

Maybe you cna share your example to see if we have any more hints. Maybe inline the constructors for the freezed class you are trying to extend in the current freezed class you are creating and use this methodology to create shared implementation and relationships that was in your class you were trying to extend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants