Unverified Commit a1070e4f authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Revert "Remove duplicate code in Element.rebuild() and BuildOwner.buildScope() (#71940)" (#72120)

This reverts commit c8f07aad.
parent 8df56056
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment