This reverts commit c8f07aad563d9460eac0074be0a24a38158239af.
This commit is contained in:
parent
8df56056b4
commit
a1070e4f4c
@ -75,7 +75,6 @@ class PointerRouter {
|
||||
///
|
||||
/// This is valid in debug builds only. In release builds, this will throw an
|
||||
/// [UnsupportedError].
|
||||
@visibleForTesting
|
||||
int get debugGlobalRouteCount {
|
||||
int? count;
|
||||
assert(() {
|
||||
|
@ -2651,26 +2651,6 @@ class BuildOwner {
|
||||
/// Only valid when asserts are enabled.
|
||||
bool get debugBuilding => _debugBuilding;
|
||||
bool _debugBuilding = false;
|
||||
|
||||
/// The element currently being built, or null if no element is actively
|
||||
/// being built.
|
||||
///
|
||||
/// This is valid in debug builds only. In release builds, this will throw an
|
||||
/// [UnsupportedError].
|
||||
@visibleForTesting
|
||||
Element? get debugCurrentBuildTarget {
|
||||
Element? result;
|
||||
bool isSupportedOperation = false;
|
||||
assert(() {
|
||||
result = _debugCurrentBuildTarget;
|
||||
isSupportedOperation = true;
|
||||
return true;
|
||||
}());
|
||||
if (isSupportedOperation) {
|
||||
return result;
|
||||
}
|
||||
throw UnsupportedError('debugCurrentBuildTarget is not supported in release builds');
|
||||
}
|
||||
Element? _debugCurrentBuildTarget;
|
||||
|
||||
/// Establishes a scope in which calls to [State.setState] are forbidden, and
|
||||
@ -2696,25 +2676,6 @@ class BuildOwner {
|
||||
assert(_debugStateLockLevel >= 0);
|
||||
}
|
||||
|
||||
void _runWithCurrentBuildTarget(Element element, VoidCallback callback) {
|
||||
assert(_debugStateLocked);
|
||||
Element? debugPreviousBuildTarget;
|
||||
assert(() {
|
||||
debugPreviousBuildTarget = _debugCurrentBuildTarget;
|
||||
_debugCurrentBuildTarget = element;
|
||||
return true;
|
||||
}());
|
||||
try {
|
||||
callback();
|
||||
} finally {
|
||||
assert(() {
|
||||
assert(_debugCurrentBuildTarget == element);
|
||||
_debugCurrentBuildTarget = debugPreviousBuildTarget;
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
}
|
||||
|
||||
/// Establishes a scope for updating the widget tree, and calls the given
|
||||
/// `callback`, if any. Then, builds all the elements that were marked as
|
||||
/// dirty using [scheduleBuildFor], in depth order.
|
||||
@ -2757,22 +2718,26 @@ class BuildOwner {
|
||||
try {
|
||||
_scheduledFlushDirtyElements = true;
|
||||
if (callback != null) {
|
||||
_runWithCurrentBuildTarget(context, () {
|
||||
assert(_debugStateLocked);
|
||||
Element? debugPreviousBuildTarget;
|
||||
assert(() {
|
||||
context._debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
|
||||
debugPreviousBuildTarget = _debugCurrentBuildTarget;
|
||||
_debugCurrentBuildTarget = context;
|
||||
return true;
|
||||
}());
|
||||
_dirtyElementsNeedsResorting = false;
|
||||
try {
|
||||
callback();
|
||||
} finally {
|
||||
assert(() {
|
||||
context._debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
|
||||
context._debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
|
||||
assert(_debugCurrentBuildTarget == context);
|
||||
_debugCurrentBuildTarget = debugPreviousBuildTarget;
|
||||
_debugElementWasRebuilt(context);
|
||||
return true;
|
||||
}());
|
||||
_dirtyElementsNeedsResorting = false;
|
||||
try {
|
||||
callback();
|
||||
} finally {
|
||||
assert(() {
|
||||
context._debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
|
||||
_debugElementWasRebuilt(context);
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_dirtyElements.sort(Element._sort);
|
||||
_dirtyElementsNeedsResorting = false;
|
||||
@ -4404,7 +4369,19 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
|
||||
return true;
|
||||
}());
|
||||
assert(_lifecycleState == _ElementLifecycle.active);
|
||||
owner!._runWithCurrentBuildTarget(this, performRebuild);
|
||||
assert(owner!._debugStateLocked);
|
||||
Element? debugPreviousBuildTarget;
|
||||
assert(() {
|
||||
debugPreviousBuildTarget = owner!._debugCurrentBuildTarget;
|
||||
owner!._debugCurrentBuildTarget = this;
|
||||
return true;
|
||||
}());
|
||||
performRebuild();
|
||||
assert(() {
|
||||
assert(owner!._debugCurrentBuildTarget == this);
|
||||
owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
|
||||
return true;
|
||||
}());
|
||||
assert(!_dirty);
|
||||
}
|
||||
|
||||
@ -5609,7 +5586,6 @@ abstract class RenderObjectElement extends Element {
|
||||
}
|
||||
|
||||
@override
|
||||
@mustCallSuper
|
||||
void performRebuild() {
|
||||
assert(() {
|
||||
_debugDoingBuild = true;
|
||||
|
@ -1494,44 +1494,6 @@ void main() {
|
||||
expect(GestureBinding.instance!.pointerRouter.debugGlobalRouteCount, pointerRouterCount);
|
||||
expect(RawKeyboard.instance.keyEventHandler, same(rawKeyEventHandler));
|
||||
});
|
||||
|
||||
testWidgets('Errors in build', (WidgetTester tester) async {
|
||||
final ErrorWidgetBuilder oldErrorBuilder = ErrorWidget.builder;
|
||||
ErrorWidget.builder = (FlutterErrorDetails detail) => throw AssertionError();
|
||||
try {
|
||||
final FlutterExceptionHandler? oldErrorHandler = FlutterError.onError;
|
||||
FlutterError.onError = (FlutterErrorDetails detail) {};
|
||||
try {
|
||||
int buildCount = 0;
|
||||
void handleBuild() => buildCount++;
|
||||
expect(tester.binding.buildOwner!.debugCurrentBuildTarget, isNull);
|
||||
await tester.pumpWidget(_WidgetThatCanThrowInBuild(onBuild: handleBuild));
|
||||
expect(buildCount, 1);
|
||||
await tester.pumpWidget(_WidgetThatCanThrowInBuild(onBuild: handleBuild, shouldThrow: true));
|
||||
tester.takeException();
|
||||
expect(buildCount, 2);
|
||||
expect(tester.binding.buildOwner!.debugCurrentBuildTarget, isNull);
|
||||
} finally {
|
||||
FlutterError.onError = oldErrorHandler;
|
||||
}
|
||||
} finally {
|
||||
ErrorWidget.builder = oldErrorBuilder;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class _WidgetThatCanThrowInBuild extends StatelessWidget {
|
||||
const _WidgetThatCanThrowInBuild({required this.onBuild, this.shouldThrow = false});
|
||||
|
||||
final VoidCallback onBuild;
|
||||
final bool shouldThrow;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
onBuild();
|
||||
assert(!shouldThrow);
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
class _FakeFocusManager implements FocusManager {
|
||||
|
Loading…
x
Reference in New Issue
Block a user