Skip to content

Commit 2101010

Browse files
authored
Merge pull request Workiva#34 from davidmarne/fix_thunk_and_repatch_generic_generation
Fix thunk and repatch generic generation
2 parents bb9c1d2 + 4470d5b commit 2101010

File tree

5 files changed

+76
-20
lines changed

5 files changed

+76
-20
lines changed

lib/generator.dart

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ String _generateActions(ClassElement element) {
3939
var initializerCode = '''
4040
class _\$${element.name} extends ${element.name}{
4141
factory _\$${element.name}() => new _\$${element.name}._();
42-
42+
4343
_\$${element.name}._() : super._();
44-
44+
4545
$defaultFunctionDeclaration;
4646
}''';
4747

@@ -105,7 +105,44 @@ String _getActionDispatcherGenericType(FieldElement e) {
105105
typeArgument.typeArguments.every((ta) => ta.name == 'dynamic')) {
106106
return typeArgument.name;
107107
}
108-
return '${typeArgument.name}<${typeArgument.typeArguments.join(',')}>';
108+
109+
final typeArguments =
110+
typeArgument.typeArguments.map((ta) => ta.toString()).toList();
111+
112+
// hack for thunks/repatches or any other type argument list where
113+
// any given argument is a Built and the proceding is a Builder
114+
// and the builder is dynamic in the typeArguments list becauses it is
115+
// yet to be generated. This is complex and a bit awkward but
116+
// it is written this way to be very careful not to make any unintended
117+
// changes the the typeArguments list.
118+
final boundParams = typeArgument.typeParameters.map((e) => e.bound);
119+
for (int i = 0; i < boundParams.length; i++) {
120+
// get the bound param at this spot
121+
final b = boundParams.elementAt(i);
122+
123+
// if it is a Built and there is another argument after it
124+
// check if it is supposed to be a Builder
125+
if (b != null &&
126+
b.name.startsWith('Built') &&
127+
i != boundParams.length - 1) {
128+
final next = boundParams.elementAt(i + 1);
129+
if (next != null &&
130+
next.name.startsWith('Builder') &&
131+
typeArguments.elementAt(i + 1) == 'dynamic') {
132+
log.info(
133+
"replacing unresolved builder name ${typeArguments.elementAt(i)}Builder");
134+
// if it is a builder replace typeArguments at this location as
135+
// the Built's name + Builder
136+
typeArguments.replaceRange(
137+
i + 1,
138+
i + 2,
139+
['${typeArguments.elementAt(i)}Builder'],
140+
);
141+
}
142+
}
143+
}
144+
145+
return '${typeArgument.name}<${typeArguments.join(',')}>';
109146
}
110147

111148
String _appendCode(String before, String newCode) =>

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: built_redux
2-
version: 6.1.0
2+
version: 6.1.1
33
description:
44
A state management library written in dart that enforces immutability
55
authors:

test/unit/redux_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ main() {
208208

209209
test('ActionDispatcher<SomeTypeDef>', () async {
210210
setup();
211-
store.actions.foo((MiddlewareApi api) {
212-
(api.actions as BaseCounterActions).incrementOne();
211+
store.actions.thunkDispatcher(
212+
(MiddlewareApi<BaseCounter, BaseCounterBuilder, BaseCounterActions>
213+
api) {
214+
api.actions.incrementOne();
213215
});
214216
var stateChange = await store.stream.first;
215217
expect(stateChange.prev.count, 1);

test/unit/test_counter.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ part 'test_counter.g.dart';
1010

1111
/// Used to test code generation when the generic type of an action is a
1212
/// `typedef`
13-
typedef dynamic FooTypedef(MiddlewareApi api);
13+
typedef dynamic ThunkTypedef<V extends Built<V, B>, B extends Builder<V, B>,
14+
A extends ReduxActions>(MiddlewareApi<V, B, A> api);
1415

1516
// BaseCounter
1617

1718
abstract class BaseCounterActions extends ReduxActions {
1819
ActionDispatcher<int> increment;
1920
ActionDispatcher<int> decrement;
2021
ActionDispatcher<Null> incrementOne;
21-
ActionDispatcher<FooTypedef> foo;
22+
ActionDispatcher<
23+
ThunkTypedef<BaseCounter, BaseCounterBuilder, BaseCounterActions>>
24+
thunkDispatcher;
2225
ActionDispatcher<List<int>> genericAction1;
2326
ActionDispatcher<Map<String, List<int>>> genericAction2;
2427
ActionDispatcher<int> appendToNestedList;
@@ -86,7 +89,9 @@ abstract class NestedCounterActions extends ReduxActions {
8689
ActionDispatcher<int> increment;
8790
ActionDispatcher<int> decrement;
8891
ActionDispatcher<Null> incrementOne;
89-
ActionDispatcher<FooTypedef> fooTypedef;
92+
ActionDispatcher<
93+
ThunkTypedef<BaseCounter, BaseCounterBuilder, BaseCounterActions>>
94+
thunkDispatcher;
9095

9196
NestedCounterActions._();
9297
factory NestedCounterActions() => new _$NestedCounterActions();
@@ -148,7 +153,7 @@ NextActionHandler fooTypedefMiddleware(
148153
MiddlewareApi<BaseCounter, BaseCounterBuilder, BaseCounterActions>
149154
api) =>
150155
(ActionHandler next) => (Action a) {
151-
if (a.payload is FooTypedef) {
156+
if (a.payload is ThunkTypedef) {
152157
a.payload(api);
153158
}
154159

test/unit/test_counter.g.dart

Lines changed: 22 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)