-
Notifications
You must be signed in to change notification settings - Fork 209
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
Getting Workiva/OverReact on Build Runner #897
Comments
Started some working documents here: |
Hey @greglittlefield-wf, have you had any time to consider options here? |
Hey @matanlurey, I've been thinking about it in the back of my mind, but haven't had a chance to dig in to the code yet, sorry! I'll try to do that this week and get back to you |
Hey @matanlurey, sorry for the delayed response! I've taken a look, and a large portion of OverReact's code generation (basically all of the steps listed here) plays nicely with or can easily be adapted to work with the restrictions of the However, there's a case of inline code transformation that doesn't seem to have a super clear path forward using I've split the concerns around this transformation into two parts:
If you have any ideas for these, or thoughts on my thoughts, I'm all ears! Also, I realize that some of the restrictions in Apologies for the strikethroughs and stream-of-connsciousness-eque format of the following sections; I thought it would be a good idea to ensure I've shared all of my thoughts/ideas, even the bad ones! Leaving behind fieldsWe are currently using field syntax to declare props, which the transformer replaces with getters/setters that proxy Map key-value pairs. // Current, with transformer
@Props()
class FooProps extends UiProps {
- String foo;
+ String get foo => props['foo'];
+ set foo(String value) => props['foo'] = value;
} Something similar is possible using build, but it leaves behind those fields in the superclass. // Using build package
@Props()
class FooProps extends UiProps {
String foo;
}
+// .g.dart
+class $FooPropsImpl extends FooProps {
+ @override String get foo => props['foo'];
+ @override set foo(String value) => props['foo'] = value;
+} The same thing could be accomplished by stubbing props with abstract getters/setters instead of fields, but that would increase the boilerplate of declaring props significantly, which would be quite unfortunate. Syntactic sugar for "abstract fields" could potentially help here, but that's a long shot.
We already have runtime checks in place that preventing instantiation of non-generated There's still the concern of users calling It also looks like while these fields get tree-shaken in dartjs, they still show up in JS constructor initializer lists, which isn't ideal (see dart-lang/sdk#11558). InheritanceSeparate from how those props are declared, however, are concerns around how things would work with inheritance. With the transformer, everything gets transformed in-place. Thus, extending from and mixing in classes that declare props works pretty well: @Props()
class FooProps extends UiProps {
String foo;
}
@PropsMixin()
abstract class BarPropsMixin {
int bar;
}
@Props()
class BazProps extends FooProps with BarPropsMixin {
List baz;
} With
|
Hey @greglittlefield-wf thanks for the writeup! One idea, if you used redirecting factory constructors it could work: @Props()
abstract class FooProps extends UiProps {
factory PooProps() = _$FooProps;
String foo;
}
// .g.dart
class _$FooProps implements FooProps {
// ...
} /cc @natebosch |
Another thing that you can do, which is a bit of an anti-pattern according to some but might help the mixin case, is actually generate the public @Props()
abstract class _$FooProps implements UiProps {
String foo;
}
// .g.dart
class FooProps extends UiProps implements _$FooProps {
// ...
} That requires less boilerplate for the user (no mention of generated classes, no redirecting factory constructor), but they do have to follow a specific naming convention. For consumers I believe it means they can just mixin/extend the |
@matanlurey Yeah, those are definitely on the table! With out current setup, though, we probably wouldn't need to add redirecting factory constructors, since we only allow instantiation of those classes under the hood. UiFactory<FooProps> Foo = $Foo;
@Props()
abstract class FooProps extends UiProps {
String foo;
}
// .g.dart
FooProps $Foo() => new $FooPropsImpl();
// usage
render() {
FooProps builder = Foo();
new FooProps(); // this was never allowed, and threw a runtime exception
} |
@jakemac53 Ooh, interesting, I hadn't thought about doing it "backwards" like that... I'll definitely explore that idea, thanks! That |
Ah I like that too. re: dart-lang/sdk#14729... no idea. |
Update: we haven't spent much time recently on this problem, but we are starting to think about this more, and are hoping to get to it in Q3. Thanks again for all of the help! |
@matanlurey OverReact 2.0.0 has been released which converts the previous transformer functionality to a builder and is Dart 2 compatible. This issue can now be closed. Many thanks from all of us at Workiva for the help! |
Happy to hear its working! |
We spoke to @greglittlefield-wf at DartConf, and we wanted to start this working issue.
Things to cover:
OverReact
uses transformers today.OverReact
relies on same-file transformationspackage:build
andbuild_runner
, instead./cc @natebosch @jakemac53.
The text was updated successfully, but these errors were encountered: