It's safe to remove the unneeded `void`s from setters since the blocking issues in the
`always_declare_return_types` lint have been fixed (https://github.com/dart-lang/linter/). We can also safely flip the bit on `avoid_return_types_on_setters`.
Bindings now have a debugRegisterServiceExtensions() method that is
invoked in debug mode (only). (Once we have a profile mode, there'll be
a registerProfileServiceExtensions() method that gets called in that
mode only to register extensions that apply then.)
The BindingBase class provides convenience methods for registering
service extensions that do the equivalent of:
```dart
void extension() { ... }
bool extension([bool enabled]) { ... }
double extension([double extension]) { ... }
Map<String, String> extension([Map<String, String> parameters]) { ... }
```
The BindingBase class also itself registers ext.flutter.reassemble,
which it has call a function on the binding called
reassembleApplication().
The Scheduler binding now exposes the preexisting
ext.flutter.timeDilation.
The Renderer binding now exposes the preexisting ext.flutter.debugPaint.
The Renderer binding hooks reassembleApplication to trigger the
rendering tree to be reprocessed (in particular, to fix up the
optimisation closures).
All the logic from rendering/debug.dart about service extensions is
replaced by the above.
I moved basic_types to foundation.
The FlutterWidgets binding hooks reassembleApplication to trigger the
widget tree to be entirely rebuilt.
Flutter Driver now uses ext.flutter.driver instead of
ext.flutter_driver, and is hooked using the same binding mechanism.
Eventually we'll probably move the logic into the Flutter library so
that you just get it without having to invoke a special method first.
This adds an assert to verify that we have already got a binding when we
get a semantics listener. Otherwise we crash. (I mean, we still crash,
but now in checked mode we crash on an assert instead. Progress?)
The "leaf merge" feature was getting confused when we reset the
SemanticsNode. We now separately track whether the node itself is marked
as being merged vs whether we inherited that state, and we don't reset
the inherited state until you're reattached or reserialised. In the
latter case, we do a "just in time" clearing of the flag just like we
previously did a "just in time" setting of the flag, except now the flag
we're setting or clearing is the inherited flag not the actual flag.