@@ -28,6 +28,7 @@ import 'package:over_react/over_react.dart' show
2828 PropError;
2929
3030import 'package:over_react/src/component_declaration/component_type_checking.dart' ;
31+ import 'package:over_react/src/util/ddc_emulated_function_name_bug.dart' as ddc_emulated_function_name_bug;
3132import 'package:react/react.dart' as react;
3233import 'package:react/react_client.dart' ;
3334
@@ -257,7 +258,31 @@ abstract class UiStatefulComponent<TProps extends UiProps, TState extends UiStat
257258///
258259/// Note: Implements MapViewMixin instead of extending it so that the abstract [State] declarations
259260/// don't need a constructor. The generated implementations can mix that functionality in.
260- abstract class UiState extends Object with MapViewMixin , StateMapViewMixin implements Map {}
261+ abstract class UiState extends Object implements StateMapViewMixin , MapViewMixin , Map {
262+ // Manually implement members from `StateMapViewMixin`,
263+ // since mixing that class in doesn't play well with the DDC.
264+ // TODO find out root cause and reduced test case.
265+ @override Map get _map => this .state;
266+ @override String toString () => '$runtimeType : ${prettyPrintMap (_map )}' ;
267+
268+ // Manually implement members from `MapViewMixin`,
269+ // since mixing that class in doesn't play well with the DDC.
270+ // TODO find out root cause and reduced test case.
271+ @override operator [](Object key) => _map[key];
272+ @override void operator []= (key, value) { _map[key] = value; }
273+ @override void addAll (other) { _map.addAll (other); }
274+ @override void clear () { _map.clear (); }
275+ @override putIfAbsent (key, ifAbsent ()) => _map.putIfAbsent (key, ifAbsent);
276+ @override bool containsKey (Object key) => _map.containsKey (key);
277+ @override bool containsValue (Object value) => _map.containsValue (value);
278+ @override void forEach (void action (key, value)) { _map.forEach (action); }
279+ @override bool get isEmpty => _map.isEmpty;
280+ @override bool get isNotEmpty => _map.isNotEmpty;
281+ @override int get length => _map.length;
282+ @override Iterable get keys => _map.keys;
283+ @override remove (Object key) => _map.remove (key);
284+ @override Iterable get values => _map.values;
285+ }
261286
262287/// The string used by default for the key of the attribute added by [UiProps.addTestId] .
263288const defaultTestIdKey = 'data-test-id' ;
@@ -275,9 +300,41 @@ typedef PropsModifier(Map props);
275300///
276301/// Note: Implements MapViewMixin instead of extending it so that the abstract [Props] declarations
277302/// don't need a constructor. The generated implementations can mix that functionality in.
278- abstract class UiProps
279- extends Object with MapViewMixin , PropsMapViewMixin , ReactPropsMixin , UbiquitousDomPropsMixin , CssClassPropsMixin
280- implements Map {
303+ abstract class UiProps extends Object
304+ with ReactPropsMixin , UbiquitousDomPropsMixin , CssClassPropsMixin
305+ implements PropsMapViewMixin , MapViewMixin , Map {
306+
307+ UiProps () {
308+ // Work around https://github.com/dart-lang/sdk/issues/27647 for all UiProps instances
309+ if (ddc_emulated_function_name_bug.isBugPresent) {
310+ ddc_emulated_function_name_bug.patchName (this );
311+ }
312+ }
313+
314+ // Manually implement members from `MapViewMixin`,
315+ // since mixing that class in doesn't play well with the DDC.
316+ // TODO find out root cause and reduced test case.
317+ @override operator [](Object key) => _map[key];
318+ @override void operator []= (key, value) { _map[key] = value; }
319+ @override void addAll (other) { _map.addAll (other); }
320+ @override void clear () { _map.clear (); }
321+ @override putIfAbsent (key, ifAbsent ()) => _map.putIfAbsent (key, ifAbsent);
322+ @override bool containsKey (Object key) => _map.containsKey (key);
323+ @override bool containsValue (Object value) => _map.containsValue (value);
324+ @override void forEach (void action (key, value)) { _map.forEach (action); }
325+ @override bool get isEmpty => _map.isEmpty;
326+ @override bool get isNotEmpty => _map.isNotEmpty;
327+ @override int get length => _map.length;
328+ @override Iterable get keys => _map.keys;
329+ @override remove (Object key) => _map.remove (key);
330+ @override Iterable get values => _map.values;
331+
332+ // Manually implement members from `StateMapViewMixin`,
333+ // since mixing that class in doesn't play well with the DDC.
334+ // TODO find out root cause and reduced test case.
335+ @override Map get _map => this .props;
336+ @override String toString () => '$runtimeType : ${prettyPrintMap (_map )}' ;
337+
281338 /// Adds an arbitrary prop key-value pair if [shouldAdd] is true, otherwise, does nothing.
282339 void addProp (propKey, value, [bool shouldAdd = true ]) {
283340 if (! shouldAdd) return ;
@@ -362,10 +419,6 @@ abstract class UiProps
362419 @override
363420 dynamic noSuchMethod (Invocation invocation) {
364421 if (invocation.memberName == #call && invocation.isMethod) {
365- var parameters = []
366- ..add (props)
367- ..addAll (invocation.positionalArguments);
368-
369422 assert (() {
370423 // These checks are within the assert so they are not done in production.
371424 var children = invocation.positionalArguments;
@@ -377,7 +430,18 @@ abstract class UiProps
377430 return _validateChildren (children);
378431 });
379432
380- return Function .apply (componentFactory, parameters);
433+ final factory = componentFactory;
434+ if (factory is ReactComponentFactoryProxy ) {
435+ // Use `build` instead of using emulated function behavior to work around DDC issue
436+ // https://github.com/dart-lang/sdk/issues/29904
437+ // Should have the benefit of better performance; TODO optimize type check?
438+ return factory .build (props, invocation.positionalArguments);
439+ } else {
440+ var parameters = []
441+ ..add (props)
442+ ..addAll (invocation.positionalArguments);
443+ return Function .apply (factory , parameters);
444+ }
381445 }
382446
383447 return super .noSuchMethod (invocation);
0 commit comments