• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:collection';
7import 'dart:developer';
8
9import 'package:flutter/foundation.dart';
10import 'package:flutter/rendering.dart';
11
12import 'debug.dart';
13import 'focus_manager.dart';
14
15export 'dart:ui' show hashValues, hashList;
16
17export 'package:flutter/foundation.dart' show
18  immutable,
19  mustCallSuper,
20  optionalTypeArgs,
21  protected,
22  required,
23  visibleForTesting;
24export 'package:flutter/foundation.dart' show FlutterError, ErrorSummary, ErrorDescription, ErrorHint, debugPrint, debugPrintStack;
25export 'package:flutter/foundation.dart' show VoidCallback, ValueChanged, ValueGetter, ValueSetter;
26export 'package:flutter/foundation.dart' show DiagnosticsNode, DiagnosticLevel;
27export 'package:flutter/foundation.dart' show Key, LocalKey, ValueKey;
28export 'package:flutter/rendering.dart' show RenderObject, RenderBox, debugDumpRenderTree, debugDumpLayerTree;
29
30// Examples can assume:
31// BuildContext context;
32// void setState(VoidCallback fn) { }
33
34// Examples can assume:
35// abstract class RenderFrogJar extends RenderObject { }
36// abstract class FrogJar extends RenderObjectWidget { }
37// abstract class FrogJarParentData extends ParentData { Size size; }
38
39// KEYS
40
41/// A key that is only equal to itself.
42class UniqueKey extends LocalKey {
43  /// Creates a key that is equal only to itself.
44  // ignore: prefer_const_constructors_in_immutables , never use const for this class
45  UniqueKey();
46
47  @override
48  String toString() => '[#${shortHash(this)}]';
49}
50
51/// A key that takes its identity from the object used as its value.
52///
53/// Used to tie the identity of a widget to the identity of an object used to
54/// generate that widget.
55///
56/// See also the discussions at [Key] and [Widget.key].
57class ObjectKey extends LocalKey {
58  /// Creates a key that uses [identical] on [value] for its [operator==].
59  const ObjectKey(this.value);
60
61  /// The object whose identity is used by this key's [operator==].
62  final Object value;
63
64  @override
65  bool operator ==(dynamic other) {
66    if (other.runtimeType != runtimeType)
67      return false;
68    final ObjectKey typedOther = other;
69    return identical(value, typedOther.value);
70  }
71
72  @override
73  int get hashCode => hashValues(runtimeType, identityHashCode(value));
74
75  @override
76  String toString() {
77    if (runtimeType == ObjectKey)
78      return '[${describeIdentity(value)}]';
79    return '[$runtimeType ${describeIdentity(value)}]';
80  }
81}
82
83/// A key that is unique across the entire app.
84///
85/// Global keys uniquely identify elements. Global keys provide access to other
86/// objects that are associated with those elements, such as [BuildContext].
87/// For [StatefulWidget]s, global keys also provide access to [State].
88///
89/// Widgets that have global keys reparent their subtrees when they are moved
90/// from one location in the tree to another location in the tree. In order to
91/// reparent its subtree, a widget must arrive at its new location in the tree
92/// in the same animation frame in which it was removed from its old location in
93/// the tree.
94///
95/// Global keys are relatively expensive. If you don't need any of the features
96/// listed above, consider using a [Key], [ValueKey], [ObjectKey], or
97/// [UniqueKey] instead.
98///
99/// You cannot simultaneously include two widgets in the tree with the same
100/// global key. Attempting to do so will assert at runtime.
101///
102/// See also the discussion at [Widget.key].
103@optionalTypeArgs
104abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
105  /// Creates a [LabeledGlobalKey], which is a [GlobalKey] with a label used for
106  /// debugging.
107  ///
108  /// The label is purely for debugging and not used for comparing the identity
109  /// of the key.
110  factory GlobalKey({ String debugLabel }) => LabeledGlobalKey<T>(debugLabel);
111
112  /// Creates a global key without a label.
113  ///
114  /// Used by subclasses because the factory constructor shadows the implicit
115  /// constructor.
116  const GlobalKey.constructor() : super.empty();
117
118  static final Map<GlobalKey, Element> _registry = <GlobalKey, Element>{};
119  static final Set<Element> _debugIllFatedElements = HashSet<Element>();
120  static final Map<GlobalKey, Element> _debugReservations = <GlobalKey, Element>{};
121
122  void _register(Element element) {
123    assert(() {
124      if (_registry.containsKey(this)) {
125        assert(element.widget != null);
126        assert(_registry[this].widget != null);
127        assert(element.widget.runtimeType != _registry[this].widget.runtimeType);
128        _debugIllFatedElements.add(_registry[this]);
129      }
130      return true;
131    }());
132    _registry[this] = element;
133  }
134
135  void _unregister(Element element) {
136    assert(() {
137      if (_registry.containsKey(this) && _registry[this] != element) {
138        assert(element.widget != null);
139        assert(_registry[this].widget != null);
140        assert(element.widget.runtimeType != _registry[this].widget.runtimeType);
141      }
142      return true;
143    }());
144    if (_registry[this] == element)
145      _registry.remove(this);
146  }
147
148  void _debugReserveFor(Element parent) {
149    assert(() {
150      assert(parent != null);
151      if (_debugReservations.containsKey(this) && _debugReservations[this] != parent) {
152        // Reserving a new parent while the old parent is not attached is ok.
153        // This can happen when a renderObject detaches and re-attaches to rendering
154        // tree multiple times.
155        if (_debugReservations[this].renderObject?.attached == false) {
156          _debugReservations[this] = parent;
157          return true;
158        }
159        // It's possible for an element to get built multiple times in one
160        // frame, in which case it'll reserve the same child's key multiple
161        // times. We catch multiple children of one widget having the same key
162        // by verifying that an element never steals elements from itself, so we
163        // don't care to verify that here as well.
164        final String older = _debugReservations[this].toString();
165        final String newer = parent.toString();
166        if (older != newer) {
167          throw FlutterError.fromParts(<DiagnosticsNode>[
168            ErrorSummary('Multiple widgets used the same GlobalKey.'),
169            ErrorDescription(
170              'The key $this was used by multiple widgets. The parents of those widgets were:\n'
171              '- $older\n'
172              '- $newer\n'
173              'A GlobalKey can only be specified on one widget at a time in the widget tree.'
174            )
175          ]);
176        }
177        throw FlutterError.fromParts(<DiagnosticsNode>[
178          ErrorSummary('Multiple widgets used the same GlobalKey.'),
179          ErrorDescription(
180            'The key $this was used by multiple widgets. The parents of those widgets were '
181            'different widgets that both had the following description:\n'
182            '  $parent\n'
183            'A GlobalKey can only be specified on one widget at a time in the widget tree.'
184          ),
185        ]);
186      }
187      _debugReservations[this] = parent;
188      return true;
189    }());
190  }
191
192  static void _debugVerifyIllFatedPopulation() {
193    assert(() {
194      Map<GlobalKey, Set<Element>> duplicates;
195      for (Element element in _debugIllFatedElements) {
196        if (element._debugLifecycleState != _ElementLifecycle.defunct) {
197          assert(element != null);
198          assert(element.widget != null);
199          assert(element.widget.key != null);
200          final GlobalKey key = element.widget.key;
201          assert(_registry.containsKey(key));
202          duplicates ??= <GlobalKey, Set<Element>>{};
203          final Set<Element> elements = duplicates.putIfAbsent(key, () => HashSet<Element>());
204          elements.add(element);
205          elements.add(_registry[key]);
206        }
207      }
208      _debugIllFatedElements.clear();
209      _debugReservations.clear();
210      if (duplicates != null) {
211        final List<DiagnosticsNode> information = <DiagnosticsNode>[];
212        information.add(ErrorSummary('Multiple widgets used the same GlobalKey.'));
213        for (GlobalKey key in duplicates.keys) {
214          final Set<Element> elements = duplicates[key];
215          // TODO(jacobr): this will omit the '- ' before each widget name and
216          // use the more standard whitespace style instead. Please let me know
217          // if the '- ' style is a feature we want to maintain and we can add
218          // another tree style that supports it. I also see '* ' in some places
219          // so it would be nice to unify and normalize.
220          information.add(Element.describeElements('The key $key was used by ${elements.length} widgets', elements));
221        }
222        information.add(ErrorDescription('A GlobalKey can only be specified on one widget at a time in the widget tree.'));
223        throw FlutterError.fromParts(information);
224      }
225      return true;
226    }());
227  }
228
229  Element get _currentElement => _registry[this];
230
231  /// The build context in which the widget with this key builds.
232  ///
233  /// The current context is null if there is no widget in the tree that matches
234  /// this global key.
235  BuildContext get currentContext => _currentElement;
236
237  /// The widget in the tree that currently has this global key.
238  ///
239  /// The current widget is null if there is no widget in the tree that matches
240  /// this global key.
241  Widget get currentWidget => _currentElement?.widget;
242
243  /// The [State] for the widget in the tree that currently has this global key.
244  ///
245  /// The current state is null if (1) there is no widget in the tree that
246  /// matches this global key, (2) that widget is not a [StatefulWidget], or the
247  /// associated [State] object is not a subtype of `T`.
248  T get currentState {
249    final Element element = _currentElement;
250    if (element is StatefulElement) {
251      final StatefulElement statefulElement = element;
252      final State state = statefulElement.state;
253      if (state is T)
254        return state;
255    }
256    return null;
257  }
258}
259
260/// A global key with a debugging label.
261///
262/// The debug label is useful for documentation and for debugging. The label
263/// does not affect the key's identity.
264@optionalTypeArgs
265class LabeledGlobalKey<T extends State<StatefulWidget>> extends GlobalKey<T> {
266  /// Creates a global key with a debugging label.
267  ///
268  /// The label does not affect the key's identity.
269  // ignore: prefer_const_constructors_in_immutables , never use const for this class
270  LabeledGlobalKey(this._debugLabel) : super.constructor();
271
272  final String _debugLabel;
273
274  @override
275  String toString() {
276    final String label = _debugLabel != null ? ' $_debugLabel' : '';
277    if (runtimeType == LabeledGlobalKey)
278      return '[GlobalKey#${shortHash(this)}$label]';
279    return '[${describeIdentity(this)}$label]';
280  }
281}
282
283/// A global key that takes its identity from the object used as its value.
284///
285/// Used to tie the identity of a widget to the identity of an object used to
286/// generate that widget.
287///
288/// If the object is not private, then it is possible that collisions will occur
289/// where independent widgets will reuse the same object as their
290/// [GlobalObjectKey] value in a different part of the tree, leading to a global
291/// key conflict. To avoid this problem, create a private [GlobalObjectKey]
292/// subclass, as in:
293///
294/// ```dart
295/// class _MyKey extends GlobalObjectKey {
296///   const _MyKey(Object value) : super(value);
297/// }
298/// ```
299///
300/// Since the [runtimeType] of the key is part of its identity, this will
301/// prevent clashes with other [GlobalObjectKey]s even if they have the same
302/// value.
303///
304/// Any [GlobalObjectKey] created for the same value will match.
305@optionalTypeArgs
306class GlobalObjectKey<T extends State<StatefulWidget>> extends GlobalKey<T> {
307  /// Creates a global key that uses [identical] on [value] for its [operator==].
308  const GlobalObjectKey(this.value) : super.constructor();
309
310  /// The object whose identity is used by this key's [operator==].
311  final Object value;
312
313  @override
314  bool operator ==(dynamic other) {
315    if (other.runtimeType != runtimeType)
316      return false;
317    final GlobalObjectKey<T> typedOther = other;
318    return identical(value, typedOther.value);
319  }
320
321  @override
322  int get hashCode => identityHashCode(value);
323
324  @override
325  String toString() {
326    String selfType = runtimeType.toString();
327    // const GlobalObjectKey().runtimeType.toString() returns 'GlobalObjectKey<State<StatefulWidget>>'
328    // because GlobalObjectKey is instantiated to its bounds. To avoid cluttering the output
329    // we remove the suffix.
330    const String suffix = '<State<StatefulWidget>>';
331    if (selfType.endsWith(suffix)) {
332      selfType = selfType.substring(0, selfType.length - suffix.length);
333    }
334    return '[$selfType ${describeIdentity(value)}]';
335  }
336}
337
338/// This class is a work-around for the "is" operator not accepting a variable value as its right operand
339@optionalTypeArgs
340class TypeMatcher<T> {
341  /// Creates a type matcher for the given type parameter.
342  const TypeMatcher();
343
344  /// Returns true if the given object is of type `T`.
345  bool check(dynamic object) => object is T;
346}
347
348/// Describes the configuration for an [Element].
349///
350/// Widgets are the central class hierarchy in the Flutter framework. A widget
351/// is an immutable description of part of a user interface. Widgets can be
352/// inflated into elements, which manage the underlying render tree.
353///
354/// Widgets themselves have no mutable state (all their fields must be final).
355/// If you wish to associate mutable state with a widget, consider using a
356/// [StatefulWidget], which creates a [State] object (via
357/// [StatefulWidget.createState]) whenever it is inflated into an element and
358/// incorporated into the tree.
359///
360/// A given widget can be included in the tree zero or more times. In particular
361/// a given widget can be placed in the tree multiple times. Each time a widget
362/// is placed in the tree, it is inflated into an [Element], which means a
363/// widget that is incorporated into the tree multiple times will be inflated
364/// multiple times.
365///
366/// The [key] property controls how one widget replaces another widget in the
367/// tree. If the [runtimeType] and [key] properties of the two widgets are
368/// [operator==], respectively, then the new widget replaces the old widget by
369/// updating the underlying element (i.e., by calling [Element.update] with the
370/// new widget). Otherwise, the old element is removed from the tree, the new
371/// widget is inflated into an element, and the new element is inserted into the
372/// tree.
373///
374/// See also:
375///
376///  * [StatefulWidget] and [State], for widgets that can build differently
377///    several times over their lifetime.
378///  * [InheritedWidget], for widgets that introduce ambient state that can
379///    be read by descendant widgets.
380///  * [StatelessWidget], for widgets that always build the same way given a
381///    particular configuration and ambient state.
382@immutable
383abstract class Widget extends DiagnosticableTree {
384  /// Initializes [key] for subclasses.
385  const Widget({ this.key });
386
387  /// Controls how one widget replaces another widget in the tree.
388  ///
389  /// If the [runtimeType] and [key] properties of the two widgets are
390  /// [operator==], respectively, then the new widget replaces the old widget by
391  /// updating the underlying element (i.e., by calling [Element.update] with the
392  /// new widget). Otherwise, the old element is removed from the tree, the new
393  /// widget is inflated into an element, and the new element is inserted into the
394  /// tree.
395  ///
396  /// In addition, using a [GlobalKey] as the widget's [key] allows the element
397  /// to be moved around the tree (changing parent) without losing state. When a
398  /// new widget is found (its key and type do not match a previous widget in
399  /// the same location), but there was a widget with that same global key
400  /// elsewhere in the tree in the previous frame, then that widget's element is
401  /// moved to the new location.
402  ///
403  /// Generally, a widget that is the only child of another widget does not need
404  /// an explicit key.
405  ///
406  /// See also the discussions at [Key] and [GlobalKey].
407  final Key key;
408
409  /// Inflates this configuration to a concrete instance.
410  ///
411  /// A given widget can be included in the tree zero or more times. In particular
412  /// a given widget can be placed in the tree multiple times. Each time a widget
413  /// is placed in the tree, it is inflated into an [Element], which means a
414  /// widget that is incorporated into the tree multiple times will be inflated
415  /// multiple times.
416  @protected
417  Element createElement();
418
419  /// A short, textual description of this widget.
420  @override
421  String toStringShort() {
422    return key == null ? '$runtimeType' : '$runtimeType-$key';
423  }
424
425  @override
426  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
427    super.debugFillProperties(properties);
428    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
429  }
430
431
432  /// Whether the `newWidget` can be used to update an [Element] that currently
433  /// has the `oldWidget` as its configuration.
434  ///
435  /// An element that uses a given widget as its configuration can be updated to
436  /// use another widget as its configuration if, and only if, the two widgets
437  /// have [runtimeType] and [key] properties that are [operator==].
438  ///
439  /// If the widgets have no key (their key is null), then they are considered a
440  /// match if they have the same type, even if their children are completely
441  /// different.
442  static bool canUpdate(Widget oldWidget, Widget newWidget) {
443    return oldWidget.runtimeType == newWidget.runtimeType
444        && oldWidget.key == newWidget.key;
445  }
446}
447
448/// A widget that does not require mutable state.
449///
450/// A stateless widget is a widget that describes part of the user interface by
451/// building a constellation of other widgets that describe the user interface
452/// more concretely. The building process continues recursively until the
453/// description of the user interface is fully concrete (e.g., consists
454/// entirely of [RenderObjectWidget]s, which describe concrete [RenderObject]s).
455///
456/// {@youtube 560 315 https://www.youtube.com/watch?v=wE7khGHVkYY}
457///
458/// Stateless widget are useful when the part of the user interface you are
459/// describing does not depend on anything other than the configuration
460/// information in the object itself and the [BuildContext] in which the widget
461/// is inflated. For compositions that can change dynamically, e.g. due to
462/// having an internal clock-driven state, or depending on some system state,
463/// consider using [StatefulWidget].
464///
465/// ## Performance considerations
466///
467/// The [build] method of a stateless widget is typically only called in three
468/// situations: the first time the widget is inserted in the tree, when the
469/// widget's parent changes its configuration, and when an [InheritedWidget] it
470/// depends on changes.
471///
472/// If a widget's parent will regularly change the widget's configuration, or if
473/// it depends on inherited widgets that frequently change, then it is important
474/// to optimize the performance of the [build] method to maintain a fluid
475/// rendering performance.
476///
477/// There are several techniques one can use to minimize the impact of
478/// rebuilding a stateless widget:
479///
480///  * Minimize the number of nodes transitively created by the build method and
481///    any widgets it creates. For example, instead of an elaborate arrangement
482///    of [Row]s, [Column]s, [Padding]s, and [SizedBox]es to position a single
483///    child in a particularly fancy manner, consider using just an [Align] or a
484///    [CustomSingleChildLayout]. Instead of an intricate layering of multiple
485///    [Container]s and with [Decoration]s to draw just the right graphical
486///    effect, consider a single [CustomPaint] widget.
487///
488///  * Use `const` widgets where possible, and provide a `const` constructor for
489///    the widget so that users of the widget can also do so.
490///
491///  * Consider refactoring the stateless widget into a stateful widget so that
492///    it can use some of the techniques described at [StatefulWidget], such as
493///    caching common parts of subtrees and using [GlobalKey]s when changing the
494///    tree structure.
495///
496///  * If the widget is likely to get rebuilt frequently due to the use of
497///    [InheritedWidget]s, consider refactoring the stateless widget into
498///    multiple widgets, with the parts of the tree that change being pushed to
499///    the leaves. For example instead of building a tree with four widgets, the
500///    inner-most widget depending on the [Theme], consider factoring out the
501///    part of the build function that builds the inner-most widget into its own
502///    widget, so that only the inner-most widget needs to be rebuilt when the
503///    theme changes.
504///
505/// {@tool sample}
506///
507/// The following is a skeleton of a stateless widget subclass called `GreenFrog`.
508///
509/// Normally, widgets have more constructor arguments, each of which corresponds
510/// to a `final` property.
511///
512/// ```dart
513/// class GreenFrog extends StatelessWidget {
514///   const GreenFrog({ Key key }) : super(key: key);
515///
516///   @override
517///   Widget build(BuildContext context) {
518///     return Container(color: const Color(0xFF2DBD3A));
519///   }
520/// }
521/// ```
522/// {@end-tool}
523///
524/// {@tool sample}
525///
526/// This next example shows the more generic widget `Frog` which can be given
527/// a color and a child:
528///
529/// ```dart
530/// class Frog extends StatelessWidget {
531///   const Frog({
532///     Key key,
533///     this.color = const Color(0xFF2DBD3A),
534///     this.child,
535///   }) : super(key: key);
536///
537///   final Color color;
538///   final Widget child;
539///
540///   @override
541///   Widget build(BuildContext context) {
542///     return Container(color: color, child: child);
543///   }
544/// }
545/// ```
546/// {@end-tool}
547///
548/// By convention, widget constructors only use named arguments. Named arguments
549/// can be marked as required using [@required]. Also by convention, the first
550/// argument is [key], and the last argument is `child`, `children`, or the
551/// equivalent.
552///
553/// See also:
554///
555///  * [StatefulWidget] and [State], for widgets that can build differently
556///    several times over their lifetime.
557///  * [InheritedWidget], for widgets that introduce ambient state that can
558///    be read by descendant widgets.
559abstract class StatelessWidget extends Widget {
560  /// Initializes [key] for subclasses.
561  const StatelessWidget({ Key key }) : super(key: key);
562
563  /// Creates a [StatelessElement] to manage this widget's location in the tree.
564  ///
565  /// It is uncommon for subclasses to override this method.
566  @override
567  StatelessElement createElement() => StatelessElement(this);
568
569  /// Describes the part of the user interface represented by this widget.
570  ///
571  /// The framework calls this method when this widget is inserted into the
572  /// tree in a given [BuildContext] and when the dependencies of this widget
573  /// change (e.g., an [InheritedWidget] referenced by this widget changes).
574  ///
575  /// The framework replaces the subtree below this widget with the widget
576  /// returned by this method, either by updating the existing subtree or by
577  /// removing the subtree and inflating a new subtree, depending on whether the
578  /// widget returned by this method can update the root of the existing
579  /// subtree, as determined by calling [Widget.canUpdate].
580  ///
581  /// Typically implementations return a newly created constellation of widgets
582  /// that are configured with information from this widget's constructor and
583  /// from the given [BuildContext].
584  ///
585  /// The given [BuildContext] contains information about the location in the
586  /// tree at which this widget is being built. For example, the context
587  /// provides the set of inherited widgets for this location in the tree. A
588  /// given widget might be built with multiple different [BuildContext]
589  /// arguments over time if the widget is moved around the tree or if the
590  /// widget is inserted into the tree in multiple places at once.
591  ///
592  /// The implementation of this method must only depend on:
593  ///
594  /// * the fields of the widget, which themselves must not change over time,
595  ///   and
596  /// * any ambient state obtained from the `context` using
597  ///   [BuildContext.inheritFromWidgetOfExactType].
598  ///
599  /// If a widget's [build] method is to depend on anything else, use a
600  /// [StatefulWidget] instead.
601  ///
602  /// See also:
603  ///
604  ///  * [StatelessWidget], which contains the discussion on performance considerations.
605  @protected
606  Widget build(BuildContext context);
607}
608
609/// A widget that has mutable state.
610///
611/// State is information that (1) can be read synchronously when the widget is
612/// built and (2) might change during the lifetime of the widget. It is the
613/// responsibility of the widget implementer to ensure that the [State] is
614/// promptly notified when such state changes, using [State.setState].
615///
616/// A stateful widget is a widget that describes part of the user interface by
617/// building a constellation of other widgets that describe the user interface
618/// more concretely. The building process continues recursively until the
619/// description of the user interface is fully concrete (e.g., consists
620/// entirely of [RenderObjectWidget]s, which describe concrete [RenderObject]s).
621///
622/// Stateful widgets are useful when the part of the user interface you are
623/// describing can change dynamically, e.g. due to having an internal
624/// clock-driven state, or depending on some system state. For compositions that
625/// depend only on the configuration information in the object itself and the
626/// [BuildContext] in which the widget is inflated, consider using
627/// [StatelessWidget].
628///
629/// {@youtube 560 315 https://www.youtube.com/watch?v=AqCMFXEmf3w}
630///
631/// [StatefulWidget] instances themselves are immutable and store their mutable
632/// state either in separate [State] objects that are created by the
633/// [createState] method, or in objects to which that [State] subscribes, for
634/// example [Stream] or [ChangeNotifier] objects, to which references are stored
635/// in final fields on the [StatefulWidget] itself.
636///
637/// The framework calls [createState] whenever it inflates a
638/// [StatefulWidget], which means that multiple [State] objects might be
639/// associated with the same [StatefulWidget] if that widget has been inserted
640/// into the tree in multiple places. Similarly, if a [StatefulWidget] is
641/// removed from the tree and later inserted in to the tree again, the framework
642/// will call [createState] again to create a fresh [State] object, simplifying
643/// the lifecycle of [State] objects.
644///
645/// A [StatefulWidget] keeps the same [State] object when moving from one
646/// location in the tree to another if its creator used a [GlobalKey] for its
647/// [key]. Because a widget with a [GlobalKey] can be used in at most one
648/// location in the tree, a widget that uses a [GlobalKey] has at most one
649/// associated element. The framework takes advantage of this property when
650/// moving a widget with a global key from one location in the tree to another
651/// by grafting the (unique) subtree associated with that widget from the old
652/// location to the new location (instead of recreating the subtree at the new
653/// location). The [State] objects associated with [StatefulWidget] are grafted
654/// along with the rest of the subtree, which means the [State] object is reused
655/// (instead of being recreated) in the new location. However, in order to be
656/// eligible for grafting, the widget must be inserted into the new location in
657/// the same animation frame in which it was removed from the old location.
658///
659/// ## Performance considerations
660///
661/// There are two primary categories of [StatefulWidget]s.
662///
663/// The first is one which allocates resources in [State.initState] and disposes
664/// of them in [State.dispose], but which does not depend on [InheritedWidget]s
665/// or call [State.setState]. Such widgets are commonly used at the root of an
666/// application or page, and communicate with subwidgets via [ChangeNotifier]s,
667/// [Stream]s, or other such objects. Stateful widgets following such a pattern
668/// are relatively cheap (in terms of CPU and GPU cycles), because they are
669/// built once then never update. They can, therefore, have somewhat complicated
670/// and deep build methods.
671///
672/// The second category is widgets that use [State.setState] or depend on
673/// [InheritedWidget]s. These will typically rebuild many times during the
674/// application's lifetime, and it is therefore important to minimize the impact
675/// of rebuilding such a widget. (They may also use [State.initState] or
676/// [State.didChangeDependencies] and allocate resources, but the important part
677/// is that they rebuild.)
678///
679/// There are several techniques one can use to minimize the impact of
680/// rebuilding a stateful widget:
681///
682///  * Push the state to the leaves. For example, if your page has a ticking
683///    clock, rather than putting the state at the top of the page and
684///    rebuilding the entire page each time the clock ticks, create a dedicated
685///    clock widget that only updates itself.
686///
687///  * Minimize the number of nodes transitively created by the build method and
688///    any widgets it creates. Ideally, a stateful widget would only create a
689///    single widget, and that widget would be a [RenderObjectWidget].
690///    (Obviously this isn't always practical, but the closer a widget gets to
691///    this ideal, the more efficient it will be.)
692///
693///  * If a subtree does not change, cache the widget that represents that
694///    subtree and re-use it each time it can be used. It is massively more
695///    efficient for a widget to be re-used than for a new (but
696///    identically-configured) widget to be created. Factoring out the stateful
697///    part into a widget that takes a child argument is a common way of doing
698///    this.
699///
700///  * Use `const` widgets where possible. (This is equivalent to caching a
701///    widget and re-using it.)
702///
703///  * Avoid changing the depth of any created subtrees or changing the type of
704///    any widgets in the subtree. For example, rather than returning either the
705///    child or the child wrapped in an [IgnorePointer], always wrap the child
706///    widget in an [IgnorePointer] and control the [IgnorePointer.ignoring]
707///    property. This is because changing the depth of the subtree requires
708///    rebuilding, laying out, and painting the entire subtree, whereas just
709///    changing the property will require the least possible change to the
710///    render tree (in the case of [IgnorePointer], for example, no layout or
711///    repaint is necessary at all).
712///
713///  * If the depth must be changed for some reason, consider wrapping the
714///    common parts of the subtrees in widgets that have a [GlobalKey] that
715///    remains consistent for the life of the stateful widget. (The
716///    [KeyedSubtree] widget may be useful for this purpose if no other widget
717///    can conveniently be assigned the key.)
718///
719/// {@tool sample}
720///
721/// This is a skeleton of a stateful widget subclass called `YellowBird`.
722///
723/// In this example. the [State] has no actual state. State is normally
724/// represented as private member fields. Also, normally widgets have more
725/// constructor arguments, each of which corresponds to a `final` property.
726///
727/// ```dart
728/// class YellowBird extends StatefulWidget {
729///   const YellowBird({ Key key }) : super(key: key);
730///
731///   @override
732///   _YellowBirdState createState() => _YellowBirdState();
733/// }
734///
735/// class _YellowBirdState extends State<YellowBird> {
736///   @override
737///   Widget build(BuildContext context) {
738///     return Container(color: const Color(0xFFFFE306));
739///   }
740/// }
741/// ```
742/// {@end-tool}
743/// {@tool sample}
744///
745/// This example shows the more generic widget `Bird` which can be given a
746/// color and a child, and which has some internal state with a method that
747/// can be called to mutate it:
748///
749/// ```dart
750/// class Bird extends StatefulWidget {
751///   const Bird({
752///     Key key,
753///     this.color = const Color(0xFFFFE306),
754///     this.child,
755///   }) : super(key: key);
756///
757///   final Color color;
758///   final Widget child;
759///
760///   _BirdState createState() => _BirdState();
761/// }
762///
763/// class _BirdState extends State<Bird> {
764///   double _size = 1.0;
765///
766///   void grow() {
767///     setState(() { _size += 0.1; });
768///   }
769///
770///   @override
771///   Widget build(BuildContext context) {
772///     return Container(
773///       color: widget.color,
774///       transform: Matrix4.diagonal3Values(_size, _size, 1.0),
775///       child: widget.child,
776///     );
777///   }
778/// }
779/// ```
780/// {@end-tool}
781///
782/// By convention, widget constructors only use named arguments. Named arguments
783/// can be marked as required using [@required]. Also by convention, the first
784/// argument is [key], and the last argument is `child`, `children`, or the
785/// equivalent.
786///
787/// See also:
788///
789///  * [State], where the logic behind a [StatefulWidget] is hosted.
790///  * [StatelessWidget], for widgets that always build the same way given a
791///    particular configuration and ambient state.
792///  * [InheritedWidget], for widgets that introduce ambient state that can
793///    be read by descendant widgets.
794abstract class StatefulWidget extends Widget {
795  /// Initializes [key] for subclasses.
796  const StatefulWidget({ Key key }) : super(key: key);
797
798  /// Creates a [StatefulElement] to manage this widget's location in the tree.
799  ///
800  /// It is uncommon for subclasses to override this method.
801  @override
802  StatefulElement createElement() => StatefulElement(this);
803
804  /// Creates the mutable state for this widget at a given location in the tree.
805  ///
806  /// Subclasses should override this method to return a newly created
807  /// instance of their associated [State] subclass:
808  ///
809  /// ```dart
810  /// @override
811  /// _MyState createState() => _MyState();
812  /// ```
813  ///
814  /// The framework can call this method multiple times over the lifetime of
815  /// a [StatefulWidget]. For example, if the widget is inserted into the tree
816  /// in multiple locations, the framework will create a separate [State] object
817  /// for each location. Similarly, if the widget is removed from the tree and
818  /// later inserted into the tree again, the framework will call [createState]
819  /// again to create a fresh [State] object, simplifying the lifecycle of
820  /// [State] objects.
821  @protected
822  State createState();
823}
824
825/// Tracks the lifecycle of [State] objects when asserts are enabled.
826enum _StateLifecycle {
827  /// The [State] object has been created. [State.initState] is called at this
828  /// time.
829  created,
830
831  /// The [State.initState] method has been called but the [State] object is
832  /// not yet ready to build. [State.didChangeDependencies] is called at this time.
833  initialized,
834
835  /// The [State] object is ready to build and [State.dispose] has not yet been
836  /// called.
837  ready,
838
839  /// The [State.dispose] method has been called and the [State] object is
840  /// no longer able to build.
841  defunct,
842}
843
844/// The signature of [State.setState] functions.
845typedef StateSetter = void Function(VoidCallback fn);
846
847/// The logic and internal state for a [StatefulWidget].
848///
849/// State is information that (1) can be read synchronously when the widget is
850/// built and (2) might change during the lifetime of the widget. It is the
851/// responsibility of the widget implementer to ensure that the [State] is
852/// promptly notified when such state changes, using [State.setState].
853///
854/// [State] objects are created by the framework by calling the
855/// [StatefulWidget.createState] method when inflating a [StatefulWidget] to
856/// insert it into the tree. Because a given [StatefulWidget] instance can be
857/// inflated multiple times (e.g., the widget is incorporated into the tree in
858/// multiple places at once), there might be more than one [State] object
859/// associated with a given [StatefulWidget] instance. Similarly, if a
860/// [StatefulWidget] is removed from the tree and later inserted in to the tree
861/// again, the framework will call [StatefulWidget.createState] again to create
862/// a fresh [State] object, simplifying the lifecycle of [State] objects.
863///
864/// [State] objects have the following lifecycle:
865///
866///  * The framework creates a [State] object by calling
867///    [StatefulWidget.createState].
868///  * The newly created [State] object is associated with a [BuildContext].
869///    This association is permanent: the [State] object will never change its
870///    [BuildContext]. However, the [BuildContext] itself can be moved around
871///    the tree along with its subtree. At this point, the [State] object is
872///    considered [mounted].
873///  * The framework calls [initState]. Subclasses of [State] should override
874///    [initState] to perform one-time initialization that depends on the
875///    [BuildContext] or the widget, which are available as the [context] and
876///    [widget] properties, respectively, when the [initState] method is
877///    called.
878///  * The framework calls [didChangeDependencies]. Subclasses of [State] should
879///    override [didChangeDependencies] to perform initialization involving
880///    [InheritedWidget]s. If [BuildContext.inheritFromWidgetOfExactType] is
881///    called, the [didChangeDependencies] method will be called again if the
882///    inherited widgets subsequently change or if the widget moves in the tree.
883///  * At this point, the [State] object is fully initialized and the framework
884///    might call its [build] method any number of times to obtain a
885///    description of the user interface for this subtree. [State] objects can
886///    spontaneously request to rebuild their subtree by callings their
887///    [setState] method, which indicates that some of their internal state
888///    has changed in a way that might impact the user interface in this
889///    subtree.
890///  * During this time, a parent widget might rebuild and request that this
891///    location in the tree update to display a new widget with the same
892///    [runtimeType] and [Widget.key]. When this happens, the framework will
893///    update the [widget] property to refer to the new widget and then call the
894///    [didUpdateWidget] method with the previous widget as an argument. [State]
895///    objects should override [didUpdateWidget] to respond to changes in their
896///    associated widget (e.g., to start implicit animations). The framework
897///    always calls [build] after calling [didUpdateWidget], which means any
898///    calls to [setState] in [didUpdateWidget] are redundant.
899///  * During development, if a hot reload occurs (whether initiated from the
900///    command line `flutter` tool by pressing `r`, or from an IDE), the
901///    [reassemble] method is called. This provides an opportunity to
902///    reinitialize any data that was prepared in the [initState] method.
903///  * If the subtree containing the [State] object is removed from the tree
904///    (e.g., because the parent built a widget with a different [runtimeType]
905///    or [Widget.key]), the framework calls the [deactivate] method. Subclasses
906///    should override this method to clean up any links between this object
907///    and other elements in the tree (e.g. if you have provided an ancestor
908///    with a pointer to a descendant's [RenderObject]).
909///  * At this point, the framework might reinsert this subtree into another
910///    part of the tree. If that happens, the framework will ensure that it
911///    calls [build] to give the [State] object a chance to adapt to its new
912///    location in the tree. If the framework does reinsert this subtree, it
913///    will do so before the end of the animation frame in which the subtree was
914///    removed from the tree. For this reason, [State] objects can defer
915///    releasing most resources until the framework calls their [dispose]
916///    method.
917///  * If the framework does not reinsert this subtree by the end of the current
918///    animation frame, the framework will call [dispose], which indicates that
919///    this [State] object will never build again. Subclasses should override
920///    this method to release any resources retained by this object (e.g.,
921///    stop any active animations).
922///  * After the framework calls [dispose], the [State] object is considered
923///    unmounted and the [mounted] property is false. It is an error to call
924///    [setState] at this point. This stage of the lifecycle is terminal: there
925///    is no way to remount a [State] object that has been disposed.
926///
927/// See also:
928///
929///  * [StatefulWidget], where the current configuration of a [State] is hosted,
930///    and whose documentation has sample code for [State].
931///  * [StatelessWidget], for widgets that always build the same way given a
932///    particular configuration and ambient state.
933///  * [InheritedWidget], for widgets that introduce ambient state that can
934///    be read by descendant widgets.
935///  * [Widget], for an overview of widgets in general.
936@optionalTypeArgs
937abstract class State<T extends StatefulWidget> extends Diagnosticable {
938  /// The current configuration.
939  ///
940  /// A [State] object's configuration is the corresponding [StatefulWidget]
941  /// instance. This property is initialized by the framework before calling
942  /// [initState]. If the parent updates this location in the tree to a new
943  /// widget with the same [runtimeType] and [Widget.key] as the current
944  /// configuration, the framework will update this property to refer to the new
945  /// widget and then call [didUpdateWidget], passing the old configuration as
946  /// an argument.
947  T get widget => _widget;
948  T _widget;
949
950  /// The current stage in the lifecycle for this state object.
951  ///
952  /// This field is used by the framework when asserts are enabled to verify
953  /// that [State] objects move through their lifecycle in an orderly fashion.
954  _StateLifecycle _debugLifecycleState = _StateLifecycle.created;
955
956  /// Verifies that the [State] that was created is one that expects to be
957  /// created for that particular [Widget].
958  bool _debugTypesAreRight(Widget widget) => widget is T;
959
960  /// The location in the tree where this widget builds.
961  ///
962  /// The framework associates [State] objects with a [BuildContext] after
963  /// creating them with [StatefulWidget.createState] and before calling
964  /// [initState]. The association is permanent: the [State] object will never
965  /// change its [BuildContext]. However, the [BuildContext] itself can be moved
966  /// around the tree.
967  ///
968  /// After calling [dispose], the framework severs the [State] object's
969  /// connection with the [BuildContext].
970  BuildContext get context => _element;
971  StatefulElement _element;
972
973  /// Whether this [State] object is currently in a tree.
974  ///
975  /// After creating a [State] object and before calling [initState], the
976  /// framework "mounts" the [State] object by associating it with a
977  /// [BuildContext]. The [State] object remains mounted until the framework
978  /// calls [dispose], after which time the framework will never ask the [State]
979  /// object to [build] again.
980  ///
981  /// It is an error to call [setState] unless [mounted] is true.
982  bool get mounted => _element != null;
983
984  /// Called when this object is inserted into the tree.
985  ///
986  /// The framework will call this method exactly once for each [State] object
987  /// it creates.
988  ///
989  /// Override this method to perform initialization that depends on the
990  /// location at which this object was inserted into the tree (i.e., [context])
991  /// or on the widget used to configure this object (i.e., [widget]).
992  ///
993  /// {@template flutter.widgets.subscriptions}
994  /// If a [State]'s [build] method depends on an object that can itself
995  /// change state, for example a [ChangeNotifier] or [Stream], or some
996  /// other object to which one can subscribe to receive notifications, then
997  /// be sure to subscribe and unsubscribe properly in [initState],
998  /// [didUpdateWidget], and [dispose]:
999  ///
1000  ///  * In [initState], subscribe to the object.
1001  ///  * In [didUpdateWidget] unsubscribe from the old object and subscribe
1002  ///    to the new one if the updated widget configuration requires
1003  ///    replacing the object.
1004  ///  * In [dispose], unsubscribe from the object.
1005  ///
1006  /// {@endtemplate}
1007  ///
1008  /// You cannot use [BuildContext.inheritFromWidgetOfExactType] from this
1009  /// method. However, [didChangeDependencies] will be called immediately
1010  /// following this method, and [BuildContext.inheritFromWidgetOfExactType] can
1011  /// be used there.
1012  ///
1013  /// If you override this, make sure your method starts with a call to
1014  /// super.initState().
1015  @protected
1016  @mustCallSuper
1017  void initState() {
1018    assert(_debugLifecycleState == _StateLifecycle.created);
1019  }
1020
1021  /// Called whenever the widget configuration changes.
1022  ///
1023  /// If the parent widget rebuilds and request that this location in the tree
1024  /// update to display a new widget with the same [runtimeType] and
1025  /// [Widget.key], the framework will update the [widget] property of this
1026  /// [State] object to refer to the new widget and then call this method
1027  /// with the previous widget as an argument.
1028  ///
1029  /// Override this method to respond when the [widget] changes (e.g., to start
1030  /// implicit animations).
1031  ///
1032  /// The framework always calls [build] after calling [didUpdateWidget], which
1033  /// means any calls to [setState] in [didUpdateWidget] are redundant.
1034  ///
1035  /// {@macro flutter.widgets.subscriptions}
1036  ///
1037  /// If you override this, make sure your method starts with a call to
1038  /// super.didUpdateWidget(oldWidget).
1039  @mustCallSuper
1040  @protected
1041  void didUpdateWidget(covariant T oldWidget) { }
1042
1043  /// {@macro flutter.widgets.reassemble}
1044  ///
1045  /// In addition to this method being invoked, it is guaranteed that the
1046  /// [build] method will be invoked when a reassemble is signaled. Most
1047  /// widgets therefore do not need to do anything in the [reassemble] method.
1048  ///
1049  /// See also:
1050  ///
1051  ///  * [Element.reassemble]
1052  ///  * [BindingBase.reassembleApplication]
1053  ///  * [Image], which uses this to reload images.
1054  @protected
1055  @mustCallSuper
1056  void reassemble() { }
1057
1058  /// Notify the framework that the internal state of this object has changed.
1059  ///
1060  /// Whenever you change the internal state of a [State] object, make the
1061  /// change in a function that you pass to [setState]:
1062  ///
1063  /// ```dart
1064  /// setState(() { _myState = newValue });
1065  /// ```
1066  ///
1067  /// The provided callback is immediately called synchronously. It must not
1068  /// return a future (the callback cannot be `async`), since then it would be
1069  /// unclear when the state was actually being set.
1070  ///
1071  /// Calling [setState] notifies the framework that the internal state of this
1072  /// object has changed in a way that might impact the user interface in this
1073  /// subtree, which causes the framework to schedule a [build] for this [State]
1074  /// object.
1075  ///
1076  /// If you just change the state directly without calling [setState], the
1077  /// framework might not schedule a [build] and the user interface for this
1078  /// subtree might not be updated to reflect the new state.
1079  ///
1080  /// Generally it is recommended that the `setState` method only be used to
1081  /// wrap the actual changes to the state, not any computation that might be
1082  /// associated with the change. For example, here a value used by the [build]
1083  /// function is incremented, and then the change is written to disk, but only
1084  /// the increment is wrapped in the `setState`:
1085  ///
1086  /// ```dart
1087  /// Future<void> _incrementCounter() async {
1088  ///   setState(() {
1089  ///     _counter++;
1090  ///   });
1091  ///   Directory directory = await getApplicationDocumentsDirectory();
1092  ///   final String dirName = directory.path;
1093  ///   await File('$dir/counter.txt').writeAsString('$_counter');
1094  /// }
1095  /// ```
1096  ///
1097  /// It is an error to call this method after the framework calls [dispose].
1098  /// You can determine whether it is legal to call this method by checking
1099  /// whether the [mounted] property is true.
1100  @protected
1101  void setState(VoidCallback fn) {
1102    assert(fn != null);
1103    assert(() {
1104      if (_debugLifecycleState == _StateLifecycle.defunct) {
1105        throw FlutterError.fromParts(<DiagnosticsNode>[
1106          ErrorSummary('setState() called after dispose(): $this'),
1107          ErrorDescription(
1108            'This error happens if you call setState() on a State object for a widget that '
1109            'no longer appears in the widget tree (e.g., whose parent widget no longer '
1110            'includes the widget in its build). This error can occur when code calls '
1111            'setState() from a timer or an animation callback.'
1112          ),
1113          ErrorHint(
1114            'The preferred solution is '
1115            'to cancel the timer or stop listening to the animation in the dispose() '
1116            'callback. Another solution is to check the "mounted" property of this '
1117            'object before calling setState() to ensure the object is still in the '
1118            'tree.'
1119          ),
1120          ErrorHint(
1121            'This error might indicate a memory leak if setState() is being called '
1122            'because another object is retaining a reference to this State object '
1123            'after it has been removed from the tree. To avoid memory leaks, '
1124            'consider breaking the reference to this object during dispose().'
1125          ),
1126        ]);
1127      }
1128      if (_debugLifecycleState == _StateLifecycle.created && !mounted) {
1129        throw FlutterError.fromParts(<DiagnosticsNode>[
1130          ErrorSummary('setState() called in constructor: $this'),
1131          ErrorHint(
1132            'This happens when you call setState() on a State object for a widget that '
1133            'hasn\'t been inserted into the widget tree yet. It is not necessary to call '
1134            'setState() in the constructor, since the state is already assumed to be dirty '
1135            'when it is initially created.'
1136          )
1137        ]);
1138      }
1139      return true;
1140    }());
1141    final dynamic result = fn() as dynamic;
1142    assert(() {
1143      if (result is Future) {
1144        throw FlutterError.fromParts(<DiagnosticsNode>[
1145          ErrorSummary('setState() callback argument returned a Future.'),
1146          ErrorDescription(
1147            'The setState() method on $this was called with a closure or method that '
1148            'returned a Future. Maybe it is marked as "async".'
1149          ),
1150          ErrorHint(
1151            'Instead of performing asynchronous work inside a call to setState(), first '
1152            'execute the work (without updating the widget state), and then synchronously '
1153           'update the state inside a call to setState().'
1154          )
1155        ]);
1156      }
1157      // We ignore other types of return values so that you can do things like:
1158      //   setState(() => x = 3);
1159      return true;
1160    }());
1161    _element.markNeedsBuild();
1162  }
1163
1164  /// Called when this object is removed from the tree.
1165  ///
1166  /// The framework calls this method whenever it removes this [State] object
1167  /// from the tree. In some cases, the framework will reinsert the [State]
1168  /// object into another part of the tree (e.g., if the subtree containing this
1169  /// [State] object is grafted from one location in the tree to another). If
1170  /// that happens, the framework will ensure that it calls [build] to give the
1171  /// [State] object a chance to adapt to its new location in the tree. If
1172  /// the framework does reinsert this subtree, it will do so before the end of
1173  /// the animation frame in which the subtree was removed from the tree. For
1174  /// this reason, [State] objects can defer releasing most resources until the
1175  /// framework calls their [dispose] method.
1176  ///
1177  /// Subclasses should override this method to clean up any links between
1178  /// this object and other elements in the tree (e.g. if you have provided an
1179  /// ancestor with a pointer to a descendant's [RenderObject]).
1180  ///
1181  /// If you override this, make sure to end your method with a call to
1182  /// super.deactivate().
1183  ///
1184  /// See also [dispose], which is called after [deactivate] if the widget is
1185  /// removed from the tree permanently.
1186  @protected
1187  @mustCallSuper
1188  void deactivate() { }
1189
1190  /// Called when this object is removed from the tree permanently.
1191  ///
1192  /// The framework calls this method when this [State] object will never
1193  /// build again. After the framework calls [dispose], the [State] object is
1194  /// considered unmounted and the [mounted] property is false. It is an error
1195  /// to call [setState] at this point. This stage of the lifecycle is terminal:
1196  /// there is no way to remount a [State] object that has been disposed.
1197  ///
1198  /// Subclasses should override this method to release any resources retained
1199  /// by this object (e.g., stop any active animations).
1200  ///
1201  /// {@macro flutter.widgets.subscriptions}
1202  ///
1203  /// If you override this, make sure to end your method with a call to
1204  /// super.dispose().
1205  ///
1206  /// See also [deactivate], which is called prior to [dispose].
1207  @protected
1208  @mustCallSuper
1209  void dispose() {
1210    assert(_debugLifecycleState == _StateLifecycle.ready);
1211    assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; }());
1212  }
1213
1214  /// Describes the part of the user interface represented by this widget.
1215  ///
1216  /// The framework calls this method in a number of different situations:
1217  ///
1218  ///  * After calling [initState].
1219  ///  * After calling [didUpdateWidget].
1220  ///  * After receiving a call to [setState].
1221  ///  * After a dependency of this [State] object changes (e.g., an
1222  ///    [InheritedWidget] referenced by the previous [build] changes).
1223  ///  * After calling [deactivate] and then reinserting the [State] object into
1224  ///    the tree at another location.
1225  ///
1226  /// The framework replaces the subtree below this widget with the widget
1227  /// returned by this method, either by updating the existing subtree or by
1228  /// removing the subtree and inflating a new subtree, depending on whether the
1229  /// widget returned by this method can update the root of the existing
1230  /// subtree, as determined by calling [Widget.canUpdate].
1231  ///
1232  /// Typically implementations return a newly created constellation of widgets
1233  /// that are configured with information from this widget's constructor, the
1234  /// given [BuildContext], and the internal state of this [State] object.
1235  ///
1236  /// The given [BuildContext] contains information about the location in the
1237  /// tree at which this widget is being built. For example, the context
1238  /// provides the set of inherited widgets for this location in the tree. The
1239  /// [BuildContext] argument is always the same as the [context] property of
1240  /// this [State] object and will remain the same for the lifetime of this
1241  /// object. The [BuildContext] argument is provided redundantly here so that
1242  /// this method matches the signature for a [WidgetBuilder].
1243  ///
1244  /// ## Design discussion
1245  ///
1246  /// ### Why is the [build] method on [State], and not [StatefulWidget]?
1247  ///
1248  /// Putting a `Widget build(BuildContext context)` method on [State] rather
1249  /// than putting a `Widget build(BuildContext context, State state)` method
1250  /// on [StatefulWidget] gives developers more flexibility when subclassing
1251  /// [StatefulWidget].
1252  ///
1253  /// For example, [AnimatedWidget] is a subclass of [StatefulWidget] that
1254  /// introduces an abstract `Widget build(BuildContext context)` method for its
1255  /// subclasses to implement. If [StatefulWidget] already had a [build] method
1256  /// that took a [State] argument, [AnimatedWidget] would be forced to provide
1257  /// its [State] object to subclasses even though its [State] object is an
1258  /// internal implementation detail of [AnimatedWidget].
1259  ///
1260  /// Conceptually, [StatelessWidget] could also be implemented as a subclass of
1261  /// [StatefulWidget] in a similar manner. If the [build] method were on
1262  /// [StatefulWidget] rather than [State], that would not be possible anymore.
1263  ///
1264  /// Putting the [build] function on [State] rather than [StatefulWidget] also
1265  /// helps avoid a category of bugs related to closures implicitly capturing
1266  /// `this`. If you defined a closure in a [build] function on a
1267  /// [StatefulWidget], that closure would implicitly capture `this`, which is
1268  /// the current widget instance, and would have the (immutable) fields of that
1269  /// instance in scope:
1270  ///
1271  /// ```dart
1272  /// class MyButton extends StatefulWidget {
1273  ///   ...
1274  ///   final Color color;
1275  ///
1276  ///   @override
1277  ///   Widget build(BuildContext context, MyButtonState state) {
1278  ///     ... () { print("color: $color"); } ...
1279  ///   }
1280  /// }
1281  /// ```
1282  ///
1283  /// For example, suppose the parent builds `MyButton` with `color` being blue,
1284  /// the `$color` in the print function refers to blue, as expected. Now,
1285  /// suppose the parent rebuilds `MyButton` with green. The closure created by
1286  /// the first build still implicitly refers to the original widget and the
1287  /// `$color` still prints blue even through the widget has been updated to
1288  /// green.
1289  ///
1290  /// In contrast, with the [build] function on the [State] object, closures
1291  /// created during [build] implicitly capture the [State] instance instead of
1292  /// the widget instance:
1293  ///
1294  /// ```dart
1295  /// class MyButtonState extends State<MyButton> {
1296  ///   ...
1297  ///   @override
1298  ///   Widget build(BuildContext context) {
1299  ///     ... () { print("color: ${widget.color}"); } ...
1300  ///   }
1301  /// }
1302  /// ```
1303  ///
1304  /// Now when the parent rebuilds `MyButton` with green, the closure created by
1305  /// the first build still refers to [State] object, which is preserved across
1306  /// rebuilds, but the framework has updated that [State] object's [widget]
1307  /// property to refer to the new `MyButton` instance and `${widget.color}`
1308  /// prints green, as expected.
1309  ///
1310  /// See also:
1311  ///
1312  ///  * [StatefulWidget], which contains the discussion on performance considerations.
1313  @protected
1314  Widget build(BuildContext context);
1315
1316  /// Called when a dependency of this [State] object changes.
1317  ///
1318  /// For example, if the previous call to [build] referenced an
1319  /// [InheritedWidget] that later changed, the framework would call this
1320  /// method to notify this object about the change.
1321  ///
1322  /// This method is also called immediately after [initState]. It is safe to
1323  /// call [BuildContext.inheritFromWidgetOfExactType] from this method.
1324  ///
1325  /// Subclasses rarely override this method because the framework always
1326  /// calls [build] after a dependency changes. Some subclasses do override
1327  /// this method because they need to do some expensive work (e.g., network
1328  /// fetches) when their dependencies change, and that work would be too
1329  /// expensive to do for every build.
1330  @protected
1331  @mustCallSuper
1332  void didChangeDependencies() { }
1333
1334  @override
1335  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
1336    super.debugFillProperties(properties);
1337    assert(() {
1338      properties.add(EnumProperty<_StateLifecycle>('lifecycle state', _debugLifecycleState, defaultValue: _StateLifecycle.ready));
1339      return true;
1340    }());
1341    properties.add(ObjectFlagProperty<T>('_widget', _widget, ifNull: 'no widget'));
1342    properties.add(ObjectFlagProperty<StatefulElement>('_element', _element, ifNull: 'not mounted'));
1343  }
1344}
1345
1346/// A widget that has a child widget provided to it, instead of building a new
1347/// widget.
1348///
1349/// Useful as a base class for other widgets, such as [InheritedWidget] and
1350/// [ParentDataWidget].
1351///
1352/// See also:
1353///
1354///  * [InheritedWidget], for widgets that introduce ambient state that can
1355///    be read by descendant widgets.
1356///  * [ParentDataWidget], for widgets that populate the
1357///    [RenderObject.parentData] slot of their child's [RenderObject] to
1358///    configure the parent widget's layout.
1359///  * [StatefulWidget] and [State], for widgets that can build differently
1360///    several times over their lifetime.
1361///  * [StatelessWidget], for widgets that always build the same way given a
1362///    particular configuration and ambient state.
1363///  * [Widget], for an overview of widgets in general.
1364abstract class ProxyWidget extends Widget {
1365  /// Creates a widget that has exactly one child widget.
1366  const ProxyWidget({ Key key, @required this.child }) : super(key: key);
1367
1368  /// The widget below this widget in the tree.
1369  ///
1370  /// {@template flutter.widgets.child}
1371  /// This widget can only have one child. To lay out multiple children, let this
1372  /// widget's child be a widget such as [Row], [Column], or [Stack], which have a
1373  /// `children` property, and then provide the children to that widget.
1374  /// {@endtemplate}
1375  final Widget child;
1376}
1377
1378/// Base class for widgets that hook [ParentData] information to children of
1379/// [RenderObjectWidget]s.
1380///
1381/// This can be used to provide per-child configuration for
1382/// [RenderObjectWidget]s with more than one child. For example, [Stack] uses
1383/// the [Positioned] parent data widget to position each child.
1384///
1385/// A [ParentDataWidget] is specific to a particular kind of [RenderObject], and
1386/// thus also to a particular [RenderObjectWidget] class. That class is `T`, the
1387/// [ParentDataWidget] type argument.
1388///
1389/// {@tool sample}
1390///
1391/// This example shows how you would build a [ParentDataWidget] to configure a
1392/// `FrogJar` widget's children by specifying a [Size] for each one.
1393///
1394/// ```dart
1395/// class FrogSize extends ParentDataWidget<FrogJar> {
1396///   FrogSize({
1397///     Key key,
1398///     @required this.size,
1399///     @required Widget child,
1400///   }) : assert(child != null),
1401///        assert(size != null),
1402///        super(key: key, child: child);
1403///
1404///   final Size size;
1405///
1406///   @override
1407///   void applyParentData(RenderObject renderObject) {
1408///     final FrogJarParentData parentData = renderObject.parentData;
1409///     if (parentData.size != size) {
1410///       parentData.size = size;
1411///       final RenderFrogJar targetParent = renderObject.parent;
1412///       targetParent.markNeedsLayout();
1413///     }
1414///   }
1415/// }
1416/// ```
1417/// {@end-tool}
1418///
1419/// See also:
1420///
1421///  * [RenderObject], the superclass for layout algorithms.
1422///  * [RenderObject.parentData], the slot that this class configures.
1423///  * [ParentData], the superclass of the data that will be placed in
1424///    [RenderObject.parentData] slots.
1425///  * [RenderObjectWidget], the class for widgets that wrap [RenderObject]s.
1426///    The `T` type parameter for [ParentDataWidget] is a [RenderObjectWidget].
1427///  * [StatefulWidget] and [State], for widgets that can build differently
1428///    several times over their lifetime.
1429abstract class ParentDataWidget<T extends RenderObjectWidget> extends ProxyWidget {
1430  /// Abstract const constructor. This constructor enables subclasses to provide
1431  /// const constructors so that they can be used in const expressions.
1432  const ParentDataWidget({ Key key, Widget child })
1433    : super(key: key, child: child);
1434
1435  @override
1436  ParentDataElement<T> createElement() => ParentDataElement<T>(this);
1437
1438  /// Subclasses should override this method to return true if the given
1439  /// ancestor is a RenderObjectWidget that wraps a RenderObject that can handle
1440  /// the kind of ParentData widget that the ParentDataWidget subclass handles.
1441  ///
1442  /// The default implementation uses the type argument.
1443  bool debugIsValidAncestor(RenderObjectWidget ancestor) {
1444    assert(T != dynamic);
1445    assert(T != RenderObjectWidget);
1446    return ancestor is T;
1447  }
1448
1449  /// Subclasses should override this to describe the requirements for using the
1450  /// ParentDataWidget subclass. It is called when debugIsValidAncestor()
1451  /// returned false for an ancestor, or when there are extraneous
1452  /// [ParentDataWidget]s in the ancestor chain.
1453  Iterable<DiagnosticsNode> debugDescribeInvalidAncestorChain({ String description, DiagnosticsNode ownershipChain, bool foundValidAncestor, Iterable<Widget> badAncestors }) sync* {
1454    assert(T != dynamic);
1455    assert(T != RenderObjectWidget);
1456    if (!foundValidAncestor) {
1457      yield ErrorDescription(
1458        '$runtimeType widgets must be placed inside $T widgets.\n'
1459        '$description has no $T ancestor at all.'
1460      );
1461    } else {
1462      assert(badAncestors.isNotEmpty);
1463      yield ErrorDescription(
1464        '$runtimeType widgets must be placed directly inside $T widgets.\n'
1465        '$description has a $T ancestor, but there are other widgets between them:'
1466      );
1467      for (Widget ancestor in badAncestors) {
1468        if (ancestor.runtimeType == runtimeType) {
1469          yield ErrorDescription('- $ancestor (this is a different $runtimeType than the one with the problem)');
1470        } else {
1471          yield ErrorDescription('- $ancestor');
1472        }
1473      }
1474      yield ErrorDescription('These widgets cannot come between a $runtimeType and its $T.');
1475    }
1476    yield ErrorDescription('The ownership chain for the parent of the offending $runtimeType was:\n  $ownershipChain');
1477  }
1478
1479  /// Write the data from this widget into the given render object's parent data.
1480  ///
1481  /// The framework calls this function whenever it detects that the
1482  /// [RenderObject] associated with the [child] has outdated
1483  /// [RenderObject.parentData]. For example, if the render object was recently
1484  /// inserted into the render tree, the render object's parent data might not
1485  /// match the data in this widget.
1486  ///
1487  /// Subclasses are expected to override this function to copy data from their
1488  /// fields into the [RenderObject.parentData] field of the given render
1489  /// object. The render object's parent is guaranteed to have been created by a
1490  /// widget of type `T`, which usually means that this function can assume that
1491  /// the render object's parent data object inherits from a particular class.
1492  ///
1493  /// If this function modifies data that can change the parent's layout or
1494  /// painting, this function is responsible for calling
1495  /// [RenderObject.markNeedsLayout] or [RenderObject.markNeedsPaint] on the
1496  /// parent, as appropriate.
1497  @protected
1498  void applyParentData(RenderObject renderObject);
1499
1500  /// Whether the [ParentDataElement.applyWidgetOutOfTurn] method is allowed
1501  /// with this widget.
1502  ///
1503  /// This should only return true if this widget represents a [ParentData]
1504  /// configuration that will have no impact on the layout or paint phase.
1505  ///
1506  /// See also:
1507  ///
1508  ///  * [ParentDataElement.applyWidgetOutOfTurn], which verifies this in debug
1509  ///    mode.
1510  @protected
1511  bool debugCanApplyOutOfTurn() => false;
1512}
1513
1514/// Base class for widgets that efficiently propagate information down the tree.
1515///
1516/// To obtain the nearest instance of a particular type of inherited widget from
1517/// a build context, use [BuildContext.inheritFromWidgetOfExactType].
1518///
1519/// Inherited widgets, when referenced in this way, will cause the consumer to
1520/// rebuild when the inherited widget itself changes state.
1521///
1522/// {@youtube 560 315 https://www.youtube.com/watch?v=Zbm3hjPjQMk}
1523///
1524/// {@tool sample}
1525///
1526/// The following is a skeleton of an inherited widget called `FrogColor`:
1527///
1528/// ```dart
1529/// class FrogColor extends InheritedWidget {
1530///   const FrogColor({
1531///     Key key,
1532///     @required this.color,
1533///     @required Widget child,
1534///   }) : assert(color != null),
1535///        assert(child != null),
1536///        super(key: key, child: child);
1537///
1538///   final Color color;
1539///
1540///   static FrogColor of(BuildContext context) {
1541///     return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor;
1542///   }
1543///
1544///   @override
1545///   bool updateShouldNotify(FrogColor old) => color != old.color;
1546/// }
1547/// ```
1548/// {@end-tool}
1549///
1550/// The convention is to provide a static method `of` on the [InheritedWidget]
1551/// which does the call to [BuildContext.inheritFromWidgetOfExactType]. This
1552/// allows the class to define its own fallback logic in case there isn't
1553/// a widget in scope. In the example above, the value returned will be
1554/// null in that case, but it could also have defaulted to a value.
1555///
1556/// Sometimes, the `of` method returns the data rather than the inherited
1557/// widget; for example, in this case it could have returned a [Color] instead
1558/// of the `FrogColor` widget.
1559///
1560/// Occasionally, the inherited widget is an implementation detail of another
1561/// class, and is therefore private. The `of` method in that case is typically
1562/// put on the public class instead. For example, [Theme] is implemented as a
1563/// [StatelessWidget] that builds a private inherited widget; [Theme.of] looks
1564/// for that inherited widget using [BuildContext.inheritFromWidgetOfExactType]
1565/// and then returns the [ThemeData].
1566///
1567/// {@youtube 560 315 https://www.youtube.com/watch?v=1t-8rBCGBYw}
1568///
1569/// See also:
1570///
1571///  * [StatefulWidget] and [State], for widgets that can build differently
1572///    several times over their lifetime.
1573///  * [StatelessWidget], for widgets that always build the same way given a
1574///    particular configuration and ambient state.
1575///  * [Widget], for an overview of widgets in general.
1576///  * [InheritedNotifier], an inherited widget whose value can be a
1577///    [Listenable], and which will notify dependents whenever the value
1578///    sends notifications.
1579///  * [InheritedModel], an inherited widget that allows clients to subscribe
1580///    to changes for subparts of the value.
1581abstract class InheritedWidget extends ProxyWidget {
1582  /// Abstract const constructor. This constructor enables subclasses to provide
1583  /// const constructors so that they can be used in const expressions.
1584  const InheritedWidget({ Key key, Widget child })
1585    : super(key: key, child: child);
1586
1587  @override
1588  InheritedElement createElement() => InheritedElement(this);
1589
1590  /// Whether the framework should notify widgets that inherit from this widget.
1591  ///
1592  /// When this widget is rebuilt, sometimes we need to rebuild the widgets that
1593  /// inherit from this widget but sometimes we do not. For example, if the data
1594  /// held by this widget is the same as the data held by `oldWidget`, then we
1595  /// do not need to rebuild the widgets that inherited the data held by
1596  /// `oldWidget`.
1597  ///
1598  /// The framework distinguishes these cases by calling this function with the
1599  /// widget that previously occupied this location in the tree as an argument.
1600  /// The given widget is guaranteed to have the same [runtimeType] as this
1601  /// object.
1602  @protected
1603  bool updateShouldNotify(covariant InheritedWidget oldWidget);
1604}
1605
1606/// RenderObjectWidgets provide the configuration for [RenderObjectElement]s,
1607/// which wrap [RenderObject]s, which provide the actual rendering of the
1608/// application.
1609abstract class RenderObjectWidget extends Widget {
1610  /// Abstract const constructor. This constructor enables subclasses to provide
1611  /// const constructors so that they can be used in const expressions.
1612  const RenderObjectWidget({ Key key }) : super(key: key);
1613
1614  /// RenderObjectWidgets always inflate to a [RenderObjectElement] subclass.
1615  @override
1616  RenderObjectElement createElement();
1617
1618  /// Creates an instance of the [RenderObject] class that this
1619  /// [RenderObjectWidget] represents, using the configuration described by this
1620  /// [RenderObjectWidget].
1621  ///
1622  /// This method should not do anything with the children of the render object.
1623  /// That should instead be handled by the method that overrides
1624  /// [RenderObjectElement.mount] in the object rendered by this object's
1625  /// [createElement] method. See, for example,
1626  /// [SingleChildRenderObjectElement.mount].
1627  @protected
1628  RenderObject createRenderObject(BuildContext context);
1629
1630  /// Copies the configuration described by this [RenderObjectWidget] to the
1631  /// given [RenderObject], which will be of the same type as returned by this
1632  /// object's [createRenderObject].
1633  ///
1634  /// This method should not do anything to update the children of the render
1635  /// object. That should instead be handled by the method that overrides
1636  /// [RenderObjectElement.update] in the object rendered by this object's
1637  /// [createElement] method. See, for example,
1638  /// [SingleChildRenderObjectElement.update].
1639  @protected
1640  void updateRenderObject(BuildContext context, covariant RenderObject renderObject) { }
1641
1642  /// A render object previously associated with this widget has been removed
1643  /// from the tree. The given [RenderObject] will be of the same type as
1644  /// returned by this object's [createRenderObject].
1645  @protected
1646  void didUnmountRenderObject(covariant RenderObject renderObject) { }
1647}
1648
1649/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
1650/// that have no children.
1651abstract class LeafRenderObjectWidget extends RenderObjectWidget {
1652  /// Abstract const constructor. This constructor enables subclasses to provide
1653  /// const constructors so that they can be used in const expressions.
1654  const LeafRenderObjectWidget({ Key key }) : super(key: key);
1655
1656  @override
1657  LeafRenderObjectElement createElement() => LeafRenderObjectElement(this);
1658}
1659
1660/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
1661/// that have a single child slot. (This superclass only provides the storage
1662/// for that child, it doesn't actually provide the updating logic.)
1663abstract class SingleChildRenderObjectWidget extends RenderObjectWidget {
1664  /// Abstract const constructor. This constructor enables subclasses to provide
1665  /// const constructors so that they can be used in const expressions.
1666  const SingleChildRenderObjectWidget({ Key key, this.child }) : super(key: key);
1667
1668  /// The widget below this widget in the tree.
1669  ///
1670  /// {@macro flutter.widgets.child}
1671  final Widget child;
1672
1673  @override
1674  SingleChildRenderObjectElement createElement() => SingleChildRenderObjectElement(this);
1675}
1676
1677/// A superclass for RenderObjectWidgets that configure RenderObject subclasses
1678/// that have a single list of children. (This superclass only provides the
1679/// storage for that child list, it doesn't actually provide the updating
1680/// logic.)
1681abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {
1682  /// Initializes fields for subclasses.
1683  ///
1684  /// The [children] argument must not be null and must not contain any null
1685  /// objects.
1686  MultiChildRenderObjectWidget({ Key key, this.children = const <Widget>[] })
1687    : assert(children != null),
1688      assert(() {
1689        final int index = children.indexOf(null);
1690        if (index >= 0) {
1691          throw FlutterError(
1692            "$runtimeType's children must not contain any null values, "
1693            'but a null value was found at index $index'
1694          );
1695        }
1696        return true;
1697      }()), // https://github.com/dart-lang/sdk/issues/29276
1698      super(key: key);
1699
1700  /// The widgets below this widget in the tree.
1701  ///
1702  /// If this list is going to be mutated, it is usually wise to put [Key]s on
1703  /// the widgets, so that the framework can match old configurations to new
1704  /// configurations and maintain the underlying render objects.
1705  final List<Widget> children;
1706
1707  @override
1708  MultiChildRenderObjectElement createElement() => MultiChildRenderObjectElement(this);
1709}
1710
1711
1712// ELEMENTS
1713
1714enum _ElementLifecycle {
1715  initial,
1716  active,
1717  inactive,
1718  defunct,
1719}
1720
1721class _InactiveElements {
1722  bool _locked = false;
1723  final Set<Element> _elements = HashSet<Element>();
1724
1725  void _unmount(Element element) {
1726    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
1727    assert(() {
1728      if (debugPrintGlobalKeyedWidgetLifecycle) {
1729        if (element.widget.key is GlobalKey)
1730          debugPrint('Discarding $element from inactive elements list.');
1731      }
1732      return true;
1733    }());
1734    element.visitChildren((Element child) {
1735      assert(child._parent == element);
1736      _unmount(child);
1737    });
1738    element.unmount();
1739    assert(element._debugLifecycleState == _ElementLifecycle.defunct);
1740  }
1741
1742  void _unmountAll() {
1743    _locked = true;
1744    final List<Element> elements = _elements.toList()..sort(Element._sort);
1745    _elements.clear();
1746    try {
1747      elements.reversed.forEach(_unmount);
1748    } finally {
1749      assert(_elements.isEmpty);
1750      _locked = false;
1751    }
1752  }
1753
1754  static void _deactivateRecursively(Element element) {
1755    assert(element._debugLifecycleState == _ElementLifecycle.active);
1756    element.deactivate();
1757    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
1758    element.visitChildren(_deactivateRecursively);
1759    assert(() { element.debugDeactivated(); return true; }());
1760  }
1761
1762  void add(Element element) {
1763    assert(!_locked);
1764    assert(!_elements.contains(element));
1765    assert(element._parent == null);
1766    if (element._active)
1767      _deactivateRecursively(element);
1768    _elements.add(element);
1769  }
1770
1771  void remove(Element element) {
1772    assert(!_locked);
1773    assert(_elements.contains(element));
1774    assert(element._parent == null);
1775    _elements.remove(element);
1776    assert(!element._active);
1777  }
1778
1779  bool debugContains(Element element) {
1780    bool result;
1781    assert(() {
1782      result = _elements.contains(element);
1783      return true;
1784    }());
1785    return result;
1786  }
1787}
1788
1789/// Signature for the callback to [BuildContext.visitChildElements].
1790///
1791/// The argument is the child being visited.
1792///
1793/// It is safe to call `element.visitChildElements` reentrantly within
1794/// this callback.
1795typedef ElementVisitor = void Function(Element element);
1796
1797/// A handle to the location of a widget in the widget tree.
1798///
1799/// This class presents a set of methods that can be used from
1800/// [StatelessWidget.build] methods and from methods on [State] objects.
1801///
1802/// [BuildContext] objects are passed to [WidgetBuilder] functions (such as
1803/// [StatelessWidget.build]), and are available from the [State.context] member.
1804/// Some static functions (e.g. [showDialog], [Theme.of], and so forth) also
1805/// take build contexts so that they can act on behalf of the calling widget, or
1806/// obtain data specifically for the given context.
1807///
1808/// Each widget has its own [BuildContext], which becomes the parent of the
1809/// widget returned by the [StatelessWidget.build] or [State.build] function.
1810/// (And similarly, the parent of any children for [RenderObjectWidget]s.)
1811///
1812/// In particular, this means that within a build method, the build context of
1813/// the widget of the build method is not the same as the build context of the
1814/// widgets returned by that build method. This can lead to some tricky cases.
1815/// For example, [Theme.of(context)] looks for the nearest enclosing [Theme] of
1816/// the given build context. If a build method for a widget Q includes a [Theme]
1817/// within its returned widget tree, and attempts to use [Theme.of] passing its
1818/// own context, the build method for Q will not find that [Theme] object. It
1819/// will instead find whatever [Theme] was an ancestor to the widget Q. If the
1820/// build context for a subpart of the returned tree is needed, a [Builder]
1821/// widget can be used: the build context passed to the [Builder.builder]
1822/// callback will be that of the [Builder] itself.
1823///
1824/// For example, in the following snippet, the [ScaffoldState.showSnackBar]
1825/// method is called on the [Scaffold] widget that the build method itself
1826/// creates. If a [Builder] had not been used, and instead the `context`
1827/// argument of the build method itself had been used, no [Scaffold] would have
1828/// been found, and the [Scaffold.of] function would have returned null.
1829///
1830/// ```dart
1831///   @override
1832///   Widget build(BuildContext context) {
1833///     // here, Scaffold.of(context) returns null
1834///     return Scaffold(
1835///       appBar: AppBar(title: Text('Demo')),
1836///       body: Builder(
1837///         builder: (BuildContext context) {
1838///           return FlatButton(
1839///             child: Text('BUTTON'),
1840///             onPressed: () {
1841///               // here, Scaffold.of(context) returns the locally created Scaffold
1842///               Scaffold.of(context).showSnackBar(SnackBar(
1843///                 content: Text('Hello.')
1844///               ));
1845///             }
1846///           );
1847///         }
1848///       )
1849///     );
1850///   }
1851/// ```
1852///
1853/// The [BuildContext] for a particular widget can change location over time as
1854/// the widget is moved around the tree. Because of this, values returned from
1855/// the methods on this class should not be cached beyond the execution of a
1856/// single synchronous function.
1857///
1858/// [BuildContext] objects are actually [Element] objects. The [BuildContext]
1859/// interface is used to discourage direct manipulation of [Element] objects.
1860abstract class BuildContext {
1861  /// The current configuration of the [Element] that is this [BuildContext].
1862  Widget get widget;
1863
1864  /// The [BuildOwner] for this context. The [BuildOwner] is in charge of
1865  /// managing the rendering pipeline for this context.
1866  BuildOwner get owner;
1867
1868  /// The current [RenderObject] for the widget. If the widget is a
1869  /// [RenderObjectWidget], this is the render object that the widget created
1870  /// for itself. Otherwise, it is the render object of the first descendant
1871  /// [RenderObjectWidget].
1872  ///
1873  /// This method will only return a valid result after the build phase is
1874  /// complete. It is therefore not valid to call this from a build method.
1875  /// It should only be called from interaction event handlers (e.g.
1876  /// gesture callbacks) or layout or paint callbacks.
1877  ///
1878  /// If the render object is a [RenderBox], which is the common case, then the
1879  /// size of the render object can be obtained from the [size] getter. This is
1880  /// only valid after the layout phase, and should therefore only be examined
1881  /// from paint callbacks or interaction event handlers (e.g. gesture
1882  /// callbacks).
1883  ///
1884  /// For details on the different phases of a frame, see the discussion at
1885  /// [WidgetsBinding.drawFrame].
1886  ///
1887  /// Calling this method is theoretically relatively expensive (O(N) in the
1888  /// depth of the tree), but in practice is usually cheap because the tree
1889  /// usually has many render objects and therefore the distance to the nearest
1890  /// render object is usually short.
1891  RenderObject findRenderObject();
1892
1893  /// The size of the [RenderBox] returned by [findRenderObject].
1894  ///
1895  /// This getter will only return a valid result after the layout phase is
1896  /// complete. It is therefore not valid to call this from a build method.
1897  /// It should only be called from paint callbacks or interaction event
1898  /// handlers (e.g. gesture callbacks).
1899  ///
1900  /// For details on the different phases of a frame, see the discussion at
1901  /// [WidgetsBinding.drawFrame].
1902  ///
1903  /// This getter will only return a valid result if [findRenderObject] actually
1904  /// returns a [RenderBox]. If [findRenderObject] returns a render object that
1905  /// is not a subtype of [RenderBox] (e.g., [RenderView]), this getter will
1906  /// throw an exception in checked mode and will return null in release mode.
1907  ///
1908  /// Calling this getter is theoretically relatively expensive (O(N) in the
1909  /// depth of the tree), but in practice is usually cheap because the tree
1910  /// usually has many render objects and therefore the distance to the nearest
1911  /// render object is usually short.
1912  Size get size;
1913
1914  /// Registers this build context with [ancestor] such that when
1915  /// [ancestor]'s widget changes this build context is rebuilt.
1916  ///
1917  /// Returns `ancestor.widget`.
1918  ///
1919  /// This method is rarely called directly. Most applications should use
1920  /// [inheritFromWidgetOfExactType], which calls this method after finding
1921  /// the appropriate [InheritedElement] ancestor.
1922  ///
1923  /// All of the qualifications about when [inheritFromWidgetOfExactType] can
1924  /// be called apply to this method as well.
1925  InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect });
1926
1927  /// Obtains the nearest widget of the given type, which must be the type of a
1928  /// concrete [InheritedWidget] subclass, and registers this build context with
1929  /// that widget such that when that widget changes (or a new widget of that
1930  /// type is introduced, or the widget goes away), this build context is
1931  /// rebuilt so that it can obtain new values from that widget.
1932  ///
1933  /// This is typically called implicitly from `of()` static methods, e.g.
1934  /// [Theme.of].
1935  ///
1936  /// This method should not be called from widget constructors or from
1937  /// [State.initState] methods, because those methods would not get called
1938  /// again if the inherited value were to change. To ensure that the widget
1939  /// correctly updates itself when the inherited value changes, only call this
1940  /// (directly or indirectly) from build methods, layout and paint callbacks, or
1941  /// from [State.didChangeDependencies].
1942  ///
1943  /// This method should not be called from [State.dispose] because the element
1944  /// tree is no longer stable at that time. To refer to an ancestor from that
1945  /// method, save a reference to the ancestor in [State.didChangeDependencies].
1946  /// It is safe to use this method from [State.deactivate], which is called
1947  /// whenever the widget is removed from the tree.
1948  ///
1949  /// It is also possible to call this method from interaction event handlers
1950  /// (e.g. gesture callbacks) or timers, to obtain a value once, if that value
1951  /// is not going to be cached and reused later.
1952  ///
1953  /// Calling this method is O(1) with a small constant factor, but will lead to
1954  /// the widget being rebuilt more often.
1955  ///
1956  /// Once a widget registers a dependency on a particular type by calling this
1957  /// method, it will be rebuilt, and [State.didChangeDependencies] will be
1958  /// called, whenever changes occur relating to that widget until the next time
1959  /// the widget or one of its ancestors is moved (for example, because an
1960  /// ancestor is added or removed).
1961  ///
1962  /// The [aspect] parameter is only used when [targetType] is an
1963  /// [InheritedWidget] subclasses that supports partial updates, like
1964  /// [InheritedModel]. It specifies what "aspect" of the inherited
1965  /// widget this context depends on.
1966  InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect });
1967
1968  /// Obtains the element corresponding to the nearest widget of the given type,
1969  /// which must be the type of a concrete [InheritedWidget] subclass.
1970  ///
1971  /// Calling this method is O(1) with a small constant factor.
1972  ///
1973  /// This method does not establish a relationship with the target in the way
1974  /// that [inheritFromWidgetOfExactType] does.
1975  ///
1976  /// This method should not be called from [State.dispose] because the element
1977  /// tree is no longer stable at that time. To refer to an ancestor from that
1978  /// method, save a reference to the ancestor by calling
1979  /// [inheritFromWidgetOfExactType] in [State.didChangeDependencies]. It is
1980  /// safe to use this method from [State.deactivate], which is called whenever
1981  /// the widget is removed from the tree.
1982  InheritedElement ancestorInheritedElementForWidgetOfExactType(Type targetType);
1983
1984  /// Returns the nearest ancestor widget of the given type, which must be the
1985  /// type of a concrete [Widget] subclass.
1986  ///
1987  /// In general, [inheritFromWidgetOfExactType] is more useful, since inherited
1988  /// widgets will trigger consumers to rebuild when they change. This method is
1989  /// appropriate when used in interaction event handlers (e.g. gesture
1990  /// callbacks) or for performing one-off tasks such as asserting that you have
1991  /// or don't have a widget of a specific type as an ancestor. The return value
1992  /// of a Widget's build method should not depend on the value returned by this
1993  /// method, because the build context will not rebuild if the return value of
1994  /// this method changes. This could lead to a situation where data used in the
1995  /// build method changes, but the widget is not rebuilt.
1996  ///
1997  /// Calling this method is relatively expensive (O(N) in the depth of the
1998  /// tree). Only call this method if the distance from this widget to the
1999  /// desired ancestor is known to be small and bounded.
2000  ///
2001  /// This method should not be called from [State.deactivate] or [State.dispose]
2002  /// because the widget tree is no longer stable at that time. To refer to
2003  /// an ancestor from one of those methods, save a reference to the ancestor
2004  /// by calling [ancestorWidgetOfExactType] in [State.didChangeDependencies].
2005  Widget ancestorWidgetOfExactType(Type targetType);
2006
2007  /// Returns the [State] object of the nearest ancestor [StatefulWidget] widget
2008  /// that matches the given [TypeMatcher].
2009  ///
2010  /// This should not be used from build methods, because the build context will
2011  /// not be rebuilt if the value that would be returned by this method changes.
2012  /// In general, [inheritFromWidgetOfExactType] is more appropriate for such
2013  /// cases. This method is useful for changing the state of an ancestor widget in
2014  /// a one-off manner, for example, to cause an ancestor scrolling list to
2015  /// scroll this build context's widget into view, or to move the focus in
2016  /// response to user interaction.
2017  ///
2018  /// In general, though, consider using a callback that triggers a stateful
2019  /// change in the ancestor rather than using the imperative style implied by
2020  /// this method. This will usually lead to more maintainable and reusable code
2021  /// since it decouples widgets from each other.
2022  ///
2023  /// Calling this method is relatively expensive (O(N) in the depth of the
2024  /// tree). Only call this method if the distance from this widget to the
2025  /// desired ancestor is known to be small and bounded.
2026  ///
2027  /// This method should not be called from [State.deactivate] or [State.dispose]
2028  /// because the widget tree is no longer stable at that time. To refer to
2029  /// an ancestor from one of those methods, save a reference to the ancestor
2030  /// by calling [ancestorStateOfType] in [State.didChangeDependencies].
2031  ///
2032  /// {@tool sample}
2033  ///
2034  /// ```dart
2035  /// ScrollableState scrollable = context.ancestorStateOfType(
2036  ///   const TypeMatcher<ScrollableState>(),
2037  /// );
2038  /// ```
2039  /// {@end-tool}
2040  State ancestorStateOfType(TypeMatcher matcher);
2041
2042  /// Returns the [State] object of the furthest ancestor [StatefulWidget] widget
2043  /// that matches the given [TypeMatcher].
2044  ///
2045  /// Functions the same way as [ancestorStateOfType] but keeps visiting subsequent
2046  /// ancestors until there are none of the type matching [TypeMatcher] remaining.
2047  /// Then returns the last one found.
2048  ///
2049  /// This operation is O(N) as well though N is the entire widget tree rather than
2050  /// a subtree.
2051  State rootAncestorStateOfType(TypeMatcher matcher);
2052
2053  /// Returns the [RenderObject] object of the nearest ancestor [RenderObjectWidget] widget
2054  /// that matches the given [TypeMatcher].
2055  ///
2056  /// This should not be used from build methods, because the build context will
2057  /// not be rebuilt if the value that would be returned by this method changes.
2058  /// In general, [inheritFromWidgetOfExactType] is more appropriate for such
2059  /// cases. This method is useful only in esoteric cases where a widget needs
2060  /// to cause an ancestor to change its layout or paint behavior. For example,
2061  /// it is used by [Material] so that [InkWell] widgets can trigger the ink
2062  /// splash on the [Material]'s actual render object.
2063  ///
2064  /// Calling this method is relatively expensive (O(N) in the depth of the
2065  /// tree). Only call this method if the distance from this widget to the
2066  /// desired ancestor is known to be small and bounded.
2067  ///
2068  /// This method should not be called from [State.deactivate] or [State.dispose]
2069  /// because the widget tree is no longer stable at that time. To refer to
2070  /// an ancestor from one of those methods, save a reference to the ancestor
2071  /// by calling [ancestorRenderObjectOfType] in [State.didChangeDependencies].
2072  RenderObject ancestorRenderObjectOfType(TypeMatcher matcher);
2073
2074  /// Walks the ancestor chain, starting with the parent of this build context's
2075  /// widget, invoking the argument for each ancestor. The callback is given a
2076  /// reference to the ancestor widget's corresponding [Element] object. The
2077  /// walk stops when it reaches the root widget or when the callback returns
2078  /// false. The callback must not return null.
2079  ///
2080  /// This is useful for inspecting the widget tree.
2081  ///
2082  /// Calling this method is relatively expensive (O(N) in the depth of the tree).
2083  ///
2084  /// This method should not be called from [State.deactivate] or [State.dispose]
2085  /// because the element tree is no longer stable at that time. To refer to
2086  /// an ancestor from one of those methods, save a reference to the ancestor
2087  /// by calling [visitAncestorElements] in [State.didChangeDependencies].
2088  void visitAncestorElements(bool visitor(Element element));
2089
2090  /// Walks the children of this widget.
2091  ///
2092  /// This is useful for applying changes to children after they are built
2093  /// without waiting for the next frame, especially if the children are known,
2094  /// and especially if there is exactly one child (as is always the case for
2095  /// [StatefulWidget]s or [StatelessWidget]s).
2096  ///
2097  /// Calling this method is very cheap for build contexts that correspond to
2098  /// [StatefulWidget]s or [StatelessWidget]s (O(1), since there's only one
2099  /// child).
2100  ///
2101  /// Calling this method is potentially expensive for build contexts that
2102  /// correspond to [RenderObjectWidget]s (O(N) in the number of children).
2103  ///
2104  /// Calling this method recursively is extremely expensive (O(N) in the number
2105  /// of descendants), and should be avoided if possible. Generally it is
2106  /// significantly cheaper to use an [InheritedWidget] and have the descendants
2107  /// pull data down, than it is to use [visitChildElements] recursively to push
2108  /// data down to them.
2109  void visitChildElements(ElementVisitor visitor);
2110
2111  /// Returns a description of an [Element] from the current build context.
2112  DiagnosticsNode describeElement(String name, {DiagnosticsTreeStyle style = DiagnosticsTreeStyle.errorProperty});
2113
2114  /// Returns a description of the [Widget] associated with the current build context.
2115  DiagnosticsNode describeWidget(String name, {DiagnosticsTreeStyle style = DiagnosticsTreeStyle.errorProperty});
2116
2117  /// Adds a description of a specific type of widget missing from the current
2118  /// build context's ancestry tree.
2119  ///
2120  /// You can find an example of using this method in [debugCheckHasMaterial].
2121  List<DiagnosticsNode> describeMissingAncestor({ @required Type expectedAncestorType });
2122
2123  /// Adds a description of the ownership chain from a specific [Element]
2124  /// to the error report.
2125  ///
2126  /// The ownership chain is useful for debugging the source of an element.
2127  DiagnosticsNode describeOwnershipChain(String name);
2128}
2129
2130/// Manager class for the widgets framework.
2131///
2132/// This class tracks which widgets need rebuilding, and handles other tasks
2133/// that apply to widget trees as a whole, such as managing the inactive element
2134/// list for the tree and triggering the "reassemble" command when necessary
2135/// during hot reload when debugging.
2136///
2137/// The main build owner is typically owned by the [WidgetsBinding], and is
2138/// driven from the operating system along with the rest of the
2139/// build/layout/paint pipeline.
2140///
2141/// Additional build owners can be built to manage off-screen widget trees.
2142///
2143/// To assign a build owner to a tree, use the
2144/// [RootRenderObjectElement.assignOwner] method on the root element of the
2145/// widget tree.
2146class BuildOwner {
2147  /// Creates an object that manages widgets.
2148  BuildOwner({ this.onBuildScheduled });
2149
2150  /// Called on each build pass when the first buildable element is marked
2151  /// dirty.
2152  VoidCallback onBuildScheduled;
2153
2154  final _InactiveElements _inactiveElements = _InactiveElements();
2155
2156  final List<Element> _dirtyElements = <Element>[];
2157  bool _scheduledFlushDirtyElements = false;
2158
2159  /// Whether [_dirtyElements] need to be sorted again as a result of more
2160  /// elements becoming dirty during the build.
2161  ///
2162  /// This is necessary to preserve the sort order defined by [Element._sort].
2163  ///
2164  /// This field is set to null when [buildScope] is not actively rebuilding
2165  /// the widget tree.
2166  bool _dirtyElementsNeedsResorting;
2167
2168  /// Whether [buildScope] is actively rebuilding the widget tree.
2169  ///
2170  /// [scheduleBuildFor] should only be called when this value is true.
2171  bool get _debugIsInBuildScope => _dirtyElementsNeedsResorting != null;
2172
2173  /// The object in charge of the focus tree.
2174  ///
2175  /// Rarely used directly. Instead, consider using [FocusScope.of] to obtain
2176  /// the [FocusScopeNode] for a given [BuildContext].
2177  ///
2178  /// See [FocusManager] for more details.
2179  FocusManager get focusManager {
2180    _focusManager ??= FocusManager();
2181    return _focusManager;
2182  }
2183  FocusManager _focusManager;
2184  set focusManager(FocusManager focusManager) {
2185    _focusManager = focusManager;
2186  }
2187
2188  /// Adds an element to the dirty elements list so that it will be rebuilt
2189  /// when [WidgetsBinding.drawFrame] calls [buildScope].
2190  void scheduleBuildFor(Element element) {
2191    assert(element != null);
2192    assert(element.owner == this);
2193    assert(() {
2194      if (debugPrintScheduleBuildForStacks)
2195        debugPrintStack(label: 'scheduleBuildFor() called for $element${_dirtyElements.contains(element) ? " (ALREADY IN LIST)" : ""}');
2196      if (!element.dirty) {
2197        throw FlutterError.fromParts(<DiagnosticsNode>[
2198          ErrorSummary('scheduleBuildFor() called for a widget that is not marked as dirty.'),
2199          element.describeElement('The method was called for the following element'),
2200          ErrorDescription(
2201            'This element is not current marked as dirty. Make sure to set the dirty flag before '
2202            'calling scheduleBuildFor().'),
2203          ErrorHint(
2204            'If you did not attempt to call scheduleBuildFor() yourself, then this probably '
2205            'indicates a bug in the widgets framework. Please report it:\n'
2206            '  https://github.com/flutter/flutter/issues/new?template=BUG.md'
2207          )
2208        ]);
2209      }
2210      return true;
2211    }());
2212    if (element._inDirtyList) {
2213      assert(() {
2214        if (debugPrintScheduleBuildForStacks)
2215          debugPrintStack(label: 'BuildOwner.scheduleBuildFor() called; _dirtyElementsNeedsResorting was $_dirtyElementsNeedsResorting (now true); dirty list is: $_dirtyElements');
2216        if (!_debugIsInBuildScope) {
2217          throw FlutterError.fromParts(<DiagnosticsNode>[
2218            ErrorSummary('BuildOwner.scheduleBuildFor() called inappropriately.'),
2219            ErrorHint(
2220              'The BuildOwner.scheduleBuildFor() method should only be called while the '
2221              'buildScope() method is actively rebuilding the widget tree.'
2222            )
2223          ]);
2224        }
2225        return true;
2226      }());
2227      _dirtyElementsNeedsResorting = true;
2228      return;
2229    }
2230    if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
2231      _scheduledFlushDirtyElements = true;
2232      onBuildScheduled();
2233    }
2234    _dirtyElements.add(element);
2235    element._inDirtyList = true;
2236    assert(() {
2237      if (debugPrintScheduleBuildForStacks)
2238        debugPrint('...dirty list is now: $_dirtyElements');
2239      return true;
2240    }());
2241  }
2242
2243  int _debugStateLockLevel = 0;
2244  bool get _debugStateLocked => _debugStateLockLevel > 0;
2245
2246  /// Whether this widget tree is in the build phase.
2247  ///
2248  /// Only valid when asserts are enabled.
2249  bool get debugBuilding => _debugBuilding;
2250  bool _debugBuilding = false;
2251  Element _debugCurrentBuildTarget;
2252
2253  /// Establishes a scope in which calls to [State.setState] are forbidden, and
2254  /// calls the given `callback`.
2255  ///
2256  /// This mechanism is used to ensure that, for instance, [State.dispose] does
2257  /// not call [State.setState].
2258  void lockState(void callback()) {
2259    assert(callback != null);
2260    assert(_debugStateLockLevel >= 0);
2261    assert(() {
2262      _debugStateLockLevel += 1;
2263      return true;
2264    }());
2265    try {
2266      callback();
2267    } finally {
2268      assert(() {
2269        _debugStateLockLevel -= 1;
2270        return true;
2271      }());
2272    }
2273    assert(_debugStateLockLevel >= 0);
2274  }
2275
2276  /// Establishes a scope for updating the widget tree, and calls the given
2277  /// `callback`, if any. Then, builds all the elements that were marked as
2278  /// dirty using [scheduleBuildFor], in depth order.
2279  ///
2280  /// This mechanism prevents build methods from transitively requiring other
2281  /// build methods to run, potentially causing infinite loops.
2282  ///
2283  /// The dirty list is processed after `callback` returns, building all the
2284  /// elements that were marked as dirty using [scheduleBuildFor], in depth
2285  /// order. If elements are marked as dirty while this method is running, they
2286  /// must be deeper than the `context` node, and deeper than any
2287  /// previously-built node in this pass.
2288  ///
2289  /// To flush the current dirty list without performing any other work, this
2290  /// function can be called with no callback. This is what the framework does
2291  /// each frame, in [WidgetsBinding.drawFrame].
2292  ///
2293  /// Only one [buildScope] can be active at a time.
2294  ///
2295  /// A [buildScope] implies a [lockState] scope as well.
2296  ///
2297  /// To print a console message every time this method is called, set
2298  /// [debugPrintBuildScope] to true. This is useful when debugging problems
2299  /// involving widgets not getting marked dirty, or getting marked dirty too
2300  /// often.
2301  void buildScope(Element context, [ VoidCallback callback ]) {
2302    if (callback == null && _dirtyElements.isEmpty)
2303      return;
2304    assert(context != null);
2305    assert(_debugStateLockLevel >= 0);
2306    assert(!_debugBuilding);
2307    assert(() {
2308      if (debugPrintBuildScope)
2309        debugPrint('buildScope called with context $context; dirty list is: $_dirtyElements');
2310      _debugStateLockLevel += 1;
2311      _debugBuilding = true;
2312      return true;
2313    }());
2314    Timeline.startSync('Build', arguments: timelineWhitelistArguments);
2315    try {
2316      _scheduledFlushDirtyElements = true;
2317      if (callback != null) {
2318        assert(_debugStateLocked);
2319        Element debugPreviousBuildTarget;
2320        assert(() {
2321          context._debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
2322          debugPreviousBuildTarget = _debugCurrentBuildTarget;
2323          _debugCurrentBuildTarget = context;
2324          return true;
2325        }());
2326        _dirtyElementsNeedsResorting = false;
2327        try {
2328          callback();
2329        } finally {
2330          assert(() {
2331            context._debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
2332            assert(_debugCurrentBuildTarget == context);
2333            _debugCurrentBuildTarget = debugPreviousBuildTarget;
2334            _debugElementWasRebuilt(context);
2335            return true;
2336          }());
2337        }
2338      }
2339      _dirtyElements.sort(Element._sort);
2340      _dirtyElementsNeedsResorting = false;
2341      int dirtyCount = _dirtyElements.length;
2342      int index = 0;
2343      while (index < dirtyCount) {
2344        assert(_dirtyElements[index] != null);
2345        assert(_dirtyElements[index]._inDirtyList);
2346        assert(!_dirtyElements[index]._active || _dirtyElements[index]._debugIsInScope(context));
2347        try {
2348          _dirtyElements[index].rebuild();
2349        } catch (e, stack) {
2350          _debugReportException(
2351            ErrorDescription('while rebuilding dirty elements'),
2352            e,
2353            stack,
2354            informationCollector: () sync* {
2355              yield DiagnosticsDebugCreator(DebugCreator(_dirtyElements[index]));
2356              yield _dirtyElements[index].describeElement('The element being rebuilt at the time was index $index of $dirtyCount');
2357            },
2358          );
2359        }
2360        index += 1;
2361        if (dirtyCount < _dirtyElements.length || _dirtyElementsNeedsResorting) {
2362          _dirtyElements.sort(Element._sort);
2363          _dirtyElementsNeedsResorting = false;
2364          dirtyCount = _dirtyElements.length;
2365          while (index > 0 && _dirtyElements[index - 1].dirty) {
2366            // It is possible for previously dirty but inactive widgets to move right in the list.
2367            // We therefore have to move the index left in the list to account for this.
2368            // We don't know how many could have moved. However, we do know that the only possible
2369            // change to the list is that nodes that were previously to the left of the index have
2370            // now moved to be to the right of the right-most cleaned node, and we do know that
2371            // all the clean nodes were to the left of the index. So we move the index left
2372            // until just after the right-most clean node.
2373            index -= 1;
2374          }
2375        }
2376      }
2377      assert(() {
2378        if (_dirtyElements.any((Element element) => element._active && element.dirty)) {
2379          throw FlutterError.fromParts(<DiagnosticsNode>[
2380            ErrorSummary('buildScope missed some dirty elements.'),
2381            ErrorHint('This probably indicates that the dirty list should have been resorted but was not.'),
2382            Element.describeElements('The list of dirty elements at the end of the buildScope call was', _dirtyElements)
2383          ]);
2384        }
2385        return true;
2386      }());
2387    } finally {
2388      for (Element element in _dirtyElements) {
2389        assert(element._inDirtyList);
2390        element._inDirtyList = false;
2391      }
2392      _dirtyElements.clear();
2393      _scheduledFlushDirtyElements = false;
2394      _dirtyElementsNeedsResorting = null;
2395      Timeline.finishSync();
2396      assert(_debugBuilding);
2397      assert(() {
2398        _debugBuilding = false;
2399        _debugStateLockLevel -= 1;
2400        if (debugPrintBuildScope)
2401          debugPrint('buildScope finished');
2402        return true;
2403      }());
2404    }
2405    assert(_debugStateLockLevel >= 0);
2406  }
2407
2408  Map<Element, Set<GlobalKey>> _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans;
2409
2410  void _debugTrackElementThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans(Element node, GlobalKey key) {
2411    _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans ??= HashMap<Element, Set<GlobalKey>>();
2412    final Set<GlobalKey> keys = _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans
2413      .putIfAbsent(node, () => HashSet<GlobalKey>());
2414    keys.add(key);
2415  }
2416
2417  void _debugElementWasRebuilt(Element node) {
2418    _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans?.remove(node);
2419  }
2420
2421  /// Complete the element build pass by unmounting any elements that are no
2422  /// longer active.
2423  ///
2424  /// This is called by [WidgetsBinding.drawFrame].
2425  ///
2426  /// In debug mode, this also runs some sanity checks, for example checking for
2427  /// duplicate global keys.
2428  ///
2429  /// After the current call stack unwinds, a microtask that notifies listeners
2430  /// about changes to global keys will run.
2431  void finalizeTree() {
2432    Timeline.startSync('Finalize tree', arguments: timelineWhitelistArguments);
2433    try {
2434      lockState(() {
2435        _inactiveElements._unmountAll(); // this unregisters the GlobalKeys
2436      });
2437      assert(() {
2438        try {
2439          GlobalKey._debugVerifyIllFatedPopulation();
2440          if (_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans != null &&
2441              _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans.isNotEmpty) {
2442            final Set<GlobalKey> keys = HashSet<GlobalKey>();
2443            for (Element element in _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans.keys) {
2444              if (element._debugLifecycleState != _ElementLifecycle.defunct)
2445                keys.addAll(_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans[element]);
2446            }
2447            if (keys.isNotEmpty) {
2448              final Map<String, int> keyStringCount = HashMap<String, int>();
2449              for (String key in keys.map<String>((GlobalKey key) => key.toString())) {
2450                if (keyStringCount.containsKey(key)) {
2451                  keyStringCount[key] += 1;
2452                } else {
2453                  keyStringCount[key] = 1;
2454                }
2455              }
2456              final List<String> keyLabels = <String>[];
2457              keyStringCount.forEach((String key, int count) {
2458                if (count == 1) {
2459                  keyLabels.add(key);
2460                } else {
2461                  keyLabels.add('$key ($count different affected keys had this toString representation)');
2462                }
2463              });
2464              final Iterable<Element> elements = _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans.keys;
2465              final Map<String, int> elementStringCount = HashMap<String, int>();
2466              for (String element in elements.map<String>((Element element) => element.toString())) {
2467                if (elementStringCount.containsKey(element)) {
2468                  elementStringCount[element] += 1;
2469                } else {
2470                  elementStringCount[element] = 1;
2471                }
2472              }
2473              final List<String> elementLabels = <String>[];
2474              elementStringCount.forEach((String element, int count) {
2475                if (count == 1) {
2476                  elementLabels.add(element);
2477                } else {
2478                  elementLabels.add('$element ($count different affected elements had this toString representation)');
2479                }
2480              });
2481              assert(keyLabels.isNotEmpty);
2482              final String the = keys.length == 1 ? ' the' : '';
2483              final String s = keys.length == 1 ? '' : 's';
2484              final String were = keys.length == 1 ? 'was' : 'were';
2485              final String their = keys.length == 1 ? 'its' : 'their';
2486              final String respective = elementLabels.length == 1 ? '' : ' respective';
2487              final String those = keys.length == 1 ? 'that' : 'those';
2488              final String s2 = elementLabels.length == 1 ? '' : 's';
2489              final String those2 = elementLabels.length == 1 ? 'that' : 'those';
2490              final String they = elementLabels.length == 1 ? 'it' : 'they';
2491              final String think = elementLabels.length == 1 ? 'thinks' : 'think';
2492              final String are = elementLabels.length == 1 ? 'is' : 'are';
2493              // TODO(jacobr): make this error more structured to better expose which widgets had problems.
2494              throw FlutterError.fromParts(<DiagnosticsNode>[
2495                ErrorSummary('Duplicate GlobalKey$s detected in widget tree.'),
2496                // TODO(jacobr): refactor this code so the elements are clickable
2497                // in GUI debug tools.
2498                ErrorDescription(
2499                  'The following GlobalKey$s $were specified multiple times in the widget tree. This will lead to '
2500                  'parts of the widget tree being truncated unexpectedly, because the second time a key is seen, '
2501                  'the previous instance is moved to the new location. The key$s $were:\n'
2502                  '- ${keyLabels.join("\n  ")}\n'
2503                  'This was determined by noticing that after$the widget$s with the above global key$s $were moved '
2504                  'out of $their$respective previous parent$s2, $those2 previous parent$s2 never updated during this frame, meaning '
2505                  'that $they either did not update at all or updated before the widget$s $were moved, in either case '
2506                  'implying that $they still $think that $they should have a child with $those global key$s.\n'
2507                  'The specific parent$s2 that did not update after having one or more children forcibly removed '
2508                  'due to GlobalKey reparenting $are:\n'
2509                  '- ${elementLabels.join("\n  ")}'
2510                  '\nA GlobalKey can only be specified on one widget at a time in the widget tree.'
2511                )
2512              ]);
2513            }
2514          }
2515        } finally {
2516          _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans?.clear();
2517        }
2518        return true;
2519      }());
2520    } catch (e, stack) {
2521      _debugReportException(ErrorSummary('while finalizing the widget tree'), e, stack);
2522    } finally {
2523      Timeline.finishSync();
2524    }
2525  }
2526
2527  /// Cause the entire subtree rooted at the given [Element] to be entirely
2528  /// rebuilt. This is used by development tools when the application code has
2529  /// changed and is being hot-reloaded, to cause the widget tree to pick up any
2530  /// changed implementations.
2531  ///
2532  /// This is expensive and should not be called except during development.
2533  void reassemble(Element root) {
2534    Timeline.startSync('Dirty Element Tree');
2535    try {
2536      assert(root._parent == null);
2537      assert(root.owner == this);
2538      root.reassemble();
2539    } finally {
2540      Timeline.finishSync();
2541    }
2542  }
2543}
2544
2545/// An instantiation of a [Widget] at a particular location in the tree.
2546///
2547/// Widgets describe how to configure a subtree but the same widget can be used
2548/// to configure multiple subtrees simultaneously because widgets are immutable.
2549/// An [Element] represents the use of a widget to configure a specific location
2550/// in the tree. Over time, the widget associated with a given element can
2551/// change, for example, if the parent widget rebuilds and creates a new widget
2552/// for this location.
2553///
2554/// Elements form a tree. Most elements have a unique child, but some widgets
2555/// (e.g., subclasses of [RenderObjectElement]) can have multiple children.
2556///
2557/// Elements have the following lifecycle:
2558///
2559///  * The framework creates an element by calling [Widget.createElement] on the
2560///    widget that will be used as the element's initial configuration.
2561///  * The framework calls [mount] to add the newly created element to the tree
2562///    at a given slot in a given parent. The [mount] method is responsible for
2563///    inflating any child widgets and calling [attachRenderObject] as
2564///    necessary to attach any associated render objects to the render tree.
2565///  * At this point, the element is considered "active" and might appear on
2566///    screen.
2567///  * At some point, the parent might decide to change the widget used to
2568///    configure this element, for example because the parent rebuilt with new
2569///    state. When this happens, the framework will call [update] with the new
2570///    widget. The new widget will always have the same [runtimeType] and key as
2571///    old widget. If the parent wishes to change the [runtimeType] or key of
2572///    the widget at this location in the tree, it can do so by unmounting this
2573///    element and inflating the new widget at this location.
2574///  * At some point, an ancestor might decide to remove this element (or an
2575///    intermediate ancestor) from the tree, which the ancestor does by calling
2576///    [deactivateChild] on itself. Deactivating the intermediate ancestor will
2577///    remove that element's render object from the render tree and add this
2578///    element to the [owner]'s list of inactive elements, causing the framework
2579///    to call [deactivate] on this element.
2580///  * At this point, the element is considered "inactive" and will not appear
2581///    on screen. An element can remain in the inactive state only until
2582///    the end of the current animation frame. At the end of the animation
2583///    frame, any elements that are still inactive will be unmounted.
2584///  * If the element gets reincorporated into the tree (e.g., because it or one
2585///    of its ancestors has a global key that is reused), the framework will
2586///    remove the element from the [owner]'s list of inactive elements, call
2587///    [activate] on the element, and reattach the element's render object to
2588///    the render tree. (At this point, the element is again considered "active"
2589///    and might appear on screen.)
2590///  * If the element does not get reincorporated into the tree by the end of
2591///    the current animation frame, the framework will call [unmount] on the
2592///    element.
2593///  * At this point, the element is considered "defunct" and will not be
2594///    incorporated into the tree in the future.
2595abstract class Element extends DiagnosticableTree implements BuildContext {
2596  /// Creates an element that uses the given widget as its configuration.
2597  ///
2598  /// Typically called by an override of [Widget.createElement].
2599  Element(Widget widget)
2600    : assert(widget != null),
2601      _widget = widget;
2602
2603  Element _parent;
2604
2605  // Custom implementation of `operator ==` optimized for the ".of" pattern
2606  // used with `InheritedWidgets`.
2607  @override
2608  bool operator ==(Object other) => identical(this, other);
2609
2610  // Custom implementation of hash code optimized for the ".of" pattern used
2611  // with `InheritedWidgets`.
2612  //
2613  // `Element.inheritFromWidgetOfExactType` relies heavily on hash-based
2614  // `Set` look-ups, putting this getter on the performance critical path.
2615  //
2616  // The value is designed to fit within the SMI representation. This makes
2617  // the cached value use less memory (one field and no extra heap objects) and
2618  // cheap to compare (no indirection).
2619  //
2620  // See also:
2621  //
2622  //  * https://dart.dev/articles/dart-vm/numeric-computation, which
2623  //    explains how numbers are represented in Dart.
2624  @override
2625  int get hashCode => _cachedHash;
2626  final int _cachedHash = _nextHashCode = (_nextHashCode + 1) % 0xffffff;
2627  static int _nextHashCode = 1;
2628
2629  /// Information set by parent to define where this child fits in its parent's
2630  /// child list.
2631  ///
2632  /// Subclasses of Element that only have one child should use null for
2633  /// the slot for that child.
2634  dynamic get slot => _slot;
2635  dynamic _slot;
2636
2637  /// An integer that is guaranteed to be greater than the parent's, if any.
2638  /// The element at the root of the tree must have a depth greater than 0.
2639  int get depth => _depth;
2640  int _depth;
2641
2642  static int _sort(Element a, Element b) {
2643    if (a.depth < b.depth)
2644      return -1;
2645    if (b.depth < a.depth)
2646      return 1;
2647    if (b.dirty && !a.dirty)
2648      return -1;
2649    if (a.dirty && !b.dirty)
2650      return 1;
2651    return 0;
2652  }
2653
2654  /// The configuration for this element.
2655  @override
2656  Widget get widget => _widget;
2657  Widget _widget;
2658
2659  /// The object that manages the lifecycle of this element.
2660  @override
2661  BuildOwner get owner => _owner;
2662  BuildOwner _owner;
2663
2664  bool _active = false;
2665
2666  /// {@template flutter.widgets.reassemble}
2667  /// Called whenever the application is reassembled during debugging, for
2668  /// example during hot reload.
2669  ///
2670  /// This method should rerun any initialization logic that depends on global
2671  /// state, for example, image loading from asset bundles (since the asset
2672  /// bundle may have changed).
2673  ///
2674  /// This function will only be called during development. In release builds,
2675  /// the `ext.flutter.reassemble` hook is not available, and so this code will
2676  /// never execute.
2677  ///
2678  /// Implementers should not rely on any ordering for hot reload source update,
2679  /// reassemble, and build methods after a hot reload has been initiated. It is
2680  /// possible that a [Timer] (e.g. an [Animation]) or a debugging session
2681  /// attached to the isolate could trigger a build with reloaded code _before_
2682  /// reassemble is called. Code that expects preconditions to be set by
2683  /// reassemble after a hot reload must be resilient to being called out of
2684  /// order, e.g. by fizzling instead of throwing. That said, once reassemble is
2685  /// called, build will be called after it at least once.
2686  /// {@endtemplate}
2687  ///
2688  /// See also:
2689  ///
2690  ///  * [State.reassemble]
2691  ///  * [BindingBase.reassembleApplication]
2692  ///  * [Image], which uses this to reload images.
2693  @mustCallSuper
2694  @protected
2695  void reassemble() {
2696    markNeedsBuild();
2697    visitChildren((Element child) {
2698      child.reassemble();
2699    });
2700  }
2701
2702  bool _debugIsInScope(Element target) {
2703    Element current = this;
2704    while (current != null) {
2705      if (target == current)
2706        return true;
2707      current = current._parent;
2708    }
2709    return false;
2710  }
2711
2712  /// The render object at (or below) this location in the tree.
2713  ///
2714  /// If this object is a [RenderObjectElement], the render object is the one at
2715  /// this location in the tree. Otherwise, this getter will walk down the tree
2716  /// until it finds a [RenderObjectElement].
2717  RenderObject get renderObject {
2718    RenderObject result;
2719    void visit(Element element) {
2720      assert(result == null); // this verifies that there's only one child
2721      if (element is RenderObjectElement)
2722        result = element.renderObject;
2723      else
2724        element.visitChildren(visit);
2725    }
2726    visit(this);
2727    return result;
2728  }
2729
2730  @override
2731  List<DiagnosticsNode> describeMissingAncestor({ @required Type expectedAncestorType }) {
2732    final List<DiagnosticsNode> information = <DiagnosticsNode>[];
2733    final List<Element> ancestors = <Element>[];
2734    visitAncestorElements((Element element) {
2735      ancestors.add(element);
2736      return true;
2737    });
2738
2739    information.add(DiagnosticsProperty<Element>(
2740      'The specific widget that could not find a $expectedAncestorType ancestor was',
2741      this,
2742      style: DiagnosticsTreeStyle.errorProperty,
2743    ));
2744
2745    if (ancestors.isNotEmpty) {
2746      information.add(describeElements('The ancestors of this widget were', ancestors));
2747    } else {
2748      information.add(ErrorDescription(
2749        'This widget is the root of the tree, so it has no '
2750        'ancestors, let alone a "$expectedAncestorType" ancestor.'
2751      ));
2752    }
2753    return information;
2754  }
2755
2756  /// Returns a list of [Element]s from the current build context to the error report.
2757  static DiagnosticsNode describeElements(String name, Iterable<Element> elements) {
2758    return DiagnosticsBlock(
2759      name: name,
2760      children: elements.map<DiagnosticsNode>((Element element) => DiagnosticsProperty<Element>('', element)).toList(),
2761      allowTruncate: true,
2762    );
2763  }
2764
2765  @override
2766  DiagnosticsNode describeElement(String name, {DiagnosticsTreeStyle style = DiagnosticsTreeStyle.errorProperty}) {
2767    return DiagnosticsProperty<Element>(name, this, style: style);
2768  }
2769
2770  @override
2771  DiagnosticsNode describeWidget(String name, {DiagnosticsTreeStyle style = DiagnosticsTreeStyle.errorProperty}) {
2772    return DiagnosticsProperty<Element>(name, this, style: style);
2773  }
2774
2775  @override
2776  DiagnosticsNode describeOwnershipChain(String name) {
2777    // TODO(jacobr): make this structured so clients can support clicks on
2778    // individual entries. For example, is this an iterable with arrows as
2779    // separators?
2780    return StringProperty(name, debugGetCreatorChain(10));
2781  }
2782
2783  // This is used to verify that Element objects move through life in an
2784  // orderly fashion.
2785  _ElementLifecycle _debugLifecycleState = _ElementLifecycle.initial;
2786
2787  /// Calls the argument for each child. Must be overridden by subclasses that
2788  /// support having children.
2789  ///
2790  /// There is no guaranteed order in which the children will be visited, though
2791  /// it should be consistent over time.
2792  ///
2793  /// Calling this during build is dangerous: the child list might still be
2794  /// being updated at that point, so the children might not be constructed yet,
2795  /// or might be old children that are going to be replaced. This method should
2796  /// only be called if it is provable that the children are available.
2797  void visitChildren(ElementVisitor visitor) { }
2798
2799  /// Calls the argument for each child considered onstage.
2800  ///
2801  /// Classes like [Offstage] and [Overlay] override this method to hide their
2802  /// children.
2803  ///
2804  /// Being onstage affects the element's discoverability during testing when
2805  /// you use Flutter's [Finder] objects. For example, when you instruct the
2806  /// test framework to tap on a widget, by default the finder will look for
2807  /// onstage elements and ignore the offstage ones.
2808  ///
2809  /// The default implementation defers to [visitChildren] and therefore treats
2810  /// the element as onstage.
2811  ///
2812  /// See also:
2813  ///
2814  ///  * [Offstage] widget that hides its children.
2815  ///  * [Finder] that skips offstage widgets by default.
2816  ///  * [RenderObject.visitChildrenForSemantics], in contrast to this method,
2817  ///    designed specifically for excluding parts of the UI from the semantics
2818  ///    tree.
2819  void debugVisitOnstageChildren(ElementVisitor visitor) => visitChildren(visitor);
2820
2821  /// Wrapper around [visitChildren] for [BuildContext].
2822  @override
2823  void visitChildElements(ElementVisitor visitor) {
2824    assert(() {
2825      if (owner == null || !owner._debugStateLocked)
2826        return true;
2827      throw FlutterError.fromParts(<DiagnosticsNode>[
2828        ErrorSummary('visitChildElements() called during build.'),
2829        ErrorDescription(
2830          'The BuildContext.visitChildElements() method can\'t be called during '
2831          'build because the child list is still being updated at that point, '
2832          'so the children might not be constructed yet, or might be old children '
2833          'that are going to be replaced.'
2834        )
2835      ]);
2836    }());
2837    visitChildren(visitor);
2838  }
2839
2840  /// Update the given child with the given new configuration.
2841  ///
2842  /// This method is the core of the widgets system. It is called each time we
2843  /// are to add, update, or remove a child based on an updated configuration.
2844  ///
2845  /// If the `child` is null, and the `newWidget` is not null, then we have a new
2846  /// child for which we need to create an [Element], configured with `newWidget`.
2847  ///
2848  /// If the `newWidget` is null, and the `child` is not null, then we need to
2849  /// remove it because it no longer has a configuration.
2850  ///
2851  /// If neither are null, then we need to update the `child`'s configuration to
2852  /// be the new configuration given by `newWidget`. If `newWidget` can be given
2853  /// to the existing child (as determined by [Widget.canUpdate]), then it is so
2854  /// given. Otherwise, the old child needs to be disposed and a new child
2855  /// created for the new configuration.
2856  ///
2857  /// If both are null, then we don't have a child and won't have a child, so we
2858  /// do nothing.
2859  ///
2860  /// The [updateChild] method returns the new child, if it had to create one,
2861  /// or the child that was passed in, if it just had to update the child, or
2862  /// null, if it removed the child and did not replace it.
2863  ///
2864  /// The following table summarizes the above:
2865  ///
2866  /// |                     | **newWidget == null**  | **newWidget != null**   |
2867  /// | :-----------------: | :--------------------- | :---------------------- |
2868  /// |  **child == null**  |  Returns null.         |  Returns new [Element]. |
2869  /// |  **child != null**  |  Old child is removed, returns null. | Old child updated if possible, returns child or new [Element]. |
2870  @protected
2871  Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
2872    assert(() {
2873      if (newWidget != null && newWidget.key is GlobalKey) {
2874        final GlobalKey key = newWidget.key;
2875        key._debugReserveFor(this);
2876      }
2877      return true;
2878    }());
2879    if (newWidget == null) {
2880      if (child != null)
2881        deactivateChild(child);
2882      return null;
2883    }
2884    if (child != null) {
2885      if (child.widget == newWidget) {
2886        if (child.slot != newSlot)
2887          updateSlotForChild(child, newSlot);
2888        return child;
2889      }
2890      if (Widget.canUpdate(child.widget, newWidget)) {
2891        if (child.slot != newSlot)
2892          updateSlotForChild(child, newSlot);
2893        child.update(newWidget);
2894        assert(child.widget == newWidget);
2895        assert(() {
2896          child.owner._debugElementWasRebuilt(child);
2897          return true;
2898        }());
2899        return child;
2900      }
2901      deactivateChild(child);
2902      assert(child._parent == null);
2903    }
2904    return inflateWidget(newWidget, newSlot);
2905  }
2906
2907  /// Add this element to the tree in the given slot of the given parent.
2908  ///
2909  /// The framework calls this function when a newly created element is added to
2910  /// the tree for the first time. Use this method to initialize state that
2911  /// depends on having a parent. State that is independent of the parent can
2912  /// more easily be initialized in the constructor.
2913  ///
2914  /// This method transitions the element from the "initial" lifecycle state to
2915  /// the "active" lifecycle state.
2916  @mustCallSuper
2917  void mount(Element parent, dynamic newSlot) {
2918    assert(_debugLifecycleState == _ElementLifecycle.initial);
2919    assert(widget != null);
2920    assert(_parent == null);
2921    assert(parent == null || parent._debugLifecycleState == _ElementLifecycle.active);
2922    assert(slot == null);
2923    assert(depth == null);
2924    assert(!_active);
2925    _parent = parent;
2926    _slot = newSlot;
2927    _depth = _parent != null ? _parent.depth + 1 : 1;
2928    _active = true;
2929    if (parent != null) // Only assign ownership if the parent is non-null
2930      _owner = parent.owner;
2931    if (widget.key is GlobalKey) {
2932      final GlobalKey key = widget.key;
2933      key._register(this);
2934    }
2935    _updateInheritance();
2936    assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; }());
2937  }
2938
2939  /// Change the widget used to configure this element.
2940  ///
2941  /// The framework calls this function when the parent wishes to use a
2942  /// different widget to configure this element. The new widget is guaranteed
2943  /// to have the same [runtimeType] as the old widget.
2944  ///
2945  /// This function is called only during the "active" lifecycle state.
2946  @mustCallSuper
2947  void update(covariant Widget newWidget) {
2948    // This code is hot when hot reloading, so we try to
2949    // only call _AssertionError._evaluateAssertion once.
2950    assert(_debugLifecycleState == _ElementLifecycle.active
2951        && widget != null
2952        && newWidget != null
2953        && newWidget != widget
2954        && depth != null
2955        && _active
2956        && Widget.canUpdate(widget, newWidget));
2957    _widget = newWidget;
2958  }
2959
2960  /// Change the slot that the given child occupies in its parent.
2961  ///
2962  /// Called by [MultiChildRenderObjectElement], and other [RenderObjectElement]
2963  /// subclasses that have multiple children, when child moves from one position
2964  /// to another in this element's child list.
2965  @protected
2966  void updateSlotForChild(Element child, dynamic newSlot) {
2967    assert(_debugLifecycleState == _ElementLifecycle.active);
2968    assert(child != null);
2969    assert(child._parent == this);
2970    void visit(Element element) {
2971      element._updateSlot(newSlot);
2972      if (element is! RenderObjectElement)
2973        element.visitChildren(visit);
2974    }
2975    visit(child);
2976  }
2977
2978  void _updateSlot(dynamic newSlot) {
2979    assert(_debugLifecycleState == _ElementLifecycle.active);
2980    assert(widget != null);
2981    assert(_parent != null);
2982    assert(_parent._debugLifecycleState == _ElementLifecycle.active);
2983    assert(depth != null);
2984    _slot = newSlot;
2985  }
2986
2987  void _updateDepth(int parentDepth) {
2988    final int expectedDepth = parentDepth + 1;
2989    if (_depth < expectedDepth) {
2990      _depth = expectedDepth;
2991      visitChildren((Element child) {
2992        child._updateDepth(expectedDepth);
2993      });
2994    }
2995  }
2996
2997  /// Remove [renderObject] from the render tree.
2998  ///
2999  /// The default implementation of this function simply calls
3000  /// [detachRenderObject] recursively on its child. The
3001  /// [RenderObjectElement.detachRenderObject] override does the actual work of
3002  /// removing [renderObject] from the render tree.
3003  ///
3004  /// This is called by [deactivateChild].
3005  void detachRenderObject() {
3006    visitChildren((Element child) {
3007      child.detachRenderObject();
3008    });
3009    _slot = null;
3010  }
3011
3012  /// Add [renderObject] to the render tree at the location specified by [slot].
3013  ///
3014  /// The default implementation of this function simply calls
3015  /// [attachRenderObject] recursively on its child. The
3016  /// [RenderObjectElement.attachRenderObject] override does the actual work of
3017  /// adding [renderObject] to the render tree.
3018  void attachRenderObject(dynamic newSlot) {
3019    assert(_slot == null);
3020    visitChildren((Element child) {
3021      child.attachRenderObject(newSlot);
3022    });
3023    _slot = newSlot;
3024  }
3025
3026  Element _retakeInactiveElement(GlobalKey key, Widget newWidget) {
3027    // The "inactivity" of the element being retaken here may be forward-looking: if
3028    // we are taking an element with a GlobalKey from an element that currently has
3029    // it as a child, then we know that that element will soon no longer have that
3030    // element as a child. The only way that assumption could be false is if the
3031    // global key is being duplicated, and we'll try to track that using the
3032    // _debugTrackElementThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans call below.
3033    final Element element = key._currentElement;
3034    if (element == null)
3035      return null;
3036    if (!Widget.canUpdate(element.widget, newWidget))
3037      return null;
3038    assert(() {
3039      if (debugPrintGlobalKeyedWidgetLifecycle)
3040        debugPrint('Attempting to take $element from ${element._parent ?? "inactive elements list"} to put in $this.');
3041      return true;
3042    }());
3043    final Element parent = element._parent;
3044    if (parent != null) {
3045      assert(() {
3046        if (parent == this) {
3047          throw FlutterError.fromParts(<DiagnosticsNode>[
3048            ErrorSummary('A GlobalKey was used multiple times inside one widget\'s child list.'),
3049            DiagnosticsProperty<GlobalKey>('The offending GlobalKey was', key),
3050            parent.describeElement('The parent of the widgets with that key was'),
3051            element.describeElement('The first child to get instantiated with that key became'),
3052            DiagnosticsProperty<Widget>('The second child that was to be instantiated with that key was', widget, style: DiagnosticsTreeStyle.errorProperty),
3053            ErrorDescription('A GlobalKey can only be specified on one widget at a time in the widget tree.')
3054          ]);
3055        }
3056        parent.owner._debugTrackElementThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans(
3057          parent,
3058          key,
3059        );
3060        return true;
3061      }());
3062      parent.forgetChild(element);
3063      parent.deactivateChild(element);
3064    }
3065    assert(element._parent == null);
3066    owner._inactiveElements.remove(element);
3067    return element;
3068  }
3069
3070  /// Create an element for the given widget and add it as a child of this
3071  /// element in the given slot.
3072  ///
3073  /// This method is typically called by [updateChild] but can be called
3074  /// directly by subclasses that need finer-grained control over creating
3075  /// elements.
3076  ///
3077  /// If the given widget has a global key and an element already exists that
3078  /// has a widget with that global key, this function will reuse that element
3079  /// (potentially grafting it from another location in the tree or reactivating
3080  /// it from the list of inactive elements) rather than creating a new element.
3081  ///
3082  /// The element returned by this function will already have been mounted and
3083  /// will be in the "active" lifecycle state.
3084  @protected
3085  Element inflateWidget(Widget newWidget, dynamic newSlot) {
3086    assert(newWidget != null);
3087    final Key key = newWidget.key;
3088    if (key is GlobalKey) {
3089      final Element newChild = _retakeInactiveElement(key, newWidget);
3090      if (newChild != null) {
3091        assert(newChild._parent == null);
3092        assert(() { _debugCheckForCycles(newChild); return true; }());
3093        newChild._activateWithParent(this, newSlot);
3094        final Element updatedChild = updateChild(newChild, newWidget, newSlot);
3095        assert(newChild == updatedChild);
3096        return updatedChild;
3097      }
3098    }
3099    final Element newChild = newWidget.createElement();
3100    assert(() { _debugCheckForCycles(newChild); return true; }());
3101    newChild.mount(this, newSlot);
3102    assert(newChild._debugLifecycleState == _ElementLifecycle.active);
3103    return newChild;
3104  }
3105
3106  void _debugCheckForCycles(Element newChild) {
3107    assert(newChild._parent == null);
3108    assert(() {
3109      Element node = this;
3110      while (node._parent != null)
3111        node = node._parent;
3112      assert(node != newChild); // indicates we are about to create a cycle
3113      return true;
3114    }());
3115  }
3116
3117  /// Move the given element to the list of inactive elements and detach its
3118  /// render object from the render tree.
3119  ///
3120  /// This method stops the given element from being a child of this element by
3121  /// detaching its render object from the render tree and moving the element to
3122  /// the list of inactive elements.
3123  ///
3124  /// This method (indirectly) calls [deactivate] on the child.
3125  ///
3126  /// The caller is responsible for removing the child from its child model.
3127  /// Typically [deactivateChild] is called by the element itself while it is
3128  /// updating its child model; however, during [GlobalKey] reparenting, the new
3129  /// parent proactively calls the old parent's [deactivateChild], first using
3130  /// [forgetChild] to cause the old parent to update its child model.
3131  @protected
3132  void deactivateChild(Element child) {
3133    assert(child != null);
3134    assert(child._parent == this);
3135    child._parent = null;
3136    child.detachRenderObject();
3137    owner._inactiveElements.add(child); // this eventually calls child.deactivate()
3138    assert(() {
3139      if (debugPrintGlobalKeyedWidgetLifecycle) {
3140        if (child.widget.key is GlobalKey)
3141          debugPrint('Deactivated $child (keyed child of $this)');
3142      }
3143      return true;
3144    }());
3145  }
3146
3147  /// Remove the given child from the element's child list, in preparation for
3148  /// the child being reused elsewhere in the element tree.
3149  ///
3150  /// This updates the child model such that, e.g., [visitChildren] does not
3151  /// walk that child anymore.
3152  ///
3153  /// The element will still have a valid parent when this is called. After this
3154  /// is called, [deactivateChild] is called to sever the link to this object.
3155  @protected
3156  void forgetChild(Element child);
3157
3158  void _activateWithParent(Element parent, dynamic newSlot) {
3159    assert(_debugLifecycleState == _ElementLifecycle.inactive);
3160    _parent = parent;
3161    assert(() {
3162      if (debugPrintGlobalKeyedWidgetLifecycle)
3163        debugPrint('Reactivating $this (now child of $_parent).');
3164      return true;
3165    }());
3166    _updateDepth(_parent.depth);
3167    _activateRecursively(this);
3168    attachRenderObject(newSlot);
3169    assert(_debugLifecycleState == _ElementLifecycle.active);
3170  }
3171
3172  static void _activateRecursively(Element element) {
3173    assert(element._debugLifecycleState == _ElementLifecycle.inactive);
3174    element.activate();
3175    assert(element._debugLifecycleState == _ElementLifecycle.active);
3176    element.visitChildren(_activateRecursively);
3177  }
3178
3179  /// Transition from the "inactive" to the "active" lifecycle state.
3180  ///
3181  /// The framework calls this method when a previously deactivated element has
3182  /// been reincorporated into the tree. The framework does not call this method
3183  /// the first time an element becomes active (i.e., from the "initial"
3184  /// lifecycle state). Instead, the framework calls [mount] in that situation.
3185  ///
3186  /// See the lifecycle documentation for [Element] for additional information.
3187  @mustCallSuper
3188  void activate() {
3189    assert(_debugLifecycleState == _ElementLifecycle.inactive);
3190    assert(widget != null);
3191    assert(owner != null);
3192    assert(depth != null);
3193    assert(!_active);
3194    final bool hadDependencies = (_dependencies != null && _dependencies.isNotEmpty) || _hadUnsatisfiedDependencies;
3195    _active = true;
3196    // We unregistered our dependencies in deactivate, but never cleared the list.
3197    // Since we're going to be reused, let's clear our list now.
3198    _dependencies?.clear();
3199    _hadUnsatisfiedDependencies = false;
3200    _updateInheritance();
3201    assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; }());
3202    if (_dirty)
3203      owner.scheduleBuildFor(this);
3204    if (hadDependencies)
3205      didChangeDependencies();
3206  }
3207
3208  /// Transition from the "active" to the "inactive" lifecycle state.
3209  ///
3210  /// The framework calls this method when a previously active element is moved
3211  /// to the list of inactive elements. While in the inactive state, the element
3212  /// will not appear on screen. The element can remain in the inactive state
3213  /// only until the end of the current animation frame. At the end of the
3214  /// animation frame, if the element has not be reactivated, the framework will
3215  /// unmount the element.
3216  ///
3217  /// This is (indirectly) called by [deactivateChild].
3218  ///
3219  /// See the lifecycle documentation for [Element] for additional information.
3220  @mustCallSuper
3221  void deactivate() {
3222    assert(_debugLifecycleState == _ElementLifecycle.active);
3223    assert(widget != null);
3224    assert(depth != null);
3225    assert(_active);
3226    if (_dependencies != null && _dependencies.isNotEmpty) {
3227      for (InheritedElement dependency in _dependencies)
3228        dependency._dependents.remove(this);
3229      // For expediency, we don't actually clear the list here, even though it's
3230      // no longer representative of what we are registered with. If we never
3231      // get re-used, it doesn't matter. If we do, then we'll clear the list in
3232      // activate(). The benefit of this is that it allows Element's activate()
3233      // implementation to decide whether to rebuild based on whether we had
3234      // dependencies here.
3235    }
3236    _inheritedWidgets = null;
3237    _active = false;
3238    assert(() { _debugLifecycleState = _ElementLifecycle.inactive; return true; }());
3239  }
3240
3241  /// Called, in debug mode, after children have been deactivated (see [deactivate]).
3242  ///
3243  /// This method is not called in release builds.
3244  @mustCallSuper
3245  void debugDeactivated() {
3246    assert(_debugLifecycleState == _ElementLifecycle.inactive);
3247  }
3248
3249  /// Transition from the "inactive" to the "defunct" lifecycle state.
3250  ///
3251  /// Called when the framework determines that an inactive element will never
3252  /// be reactivated. At the end of each animation frame, the framework calls
3253  /// [unmount] on any remaining inactive elements, preventing inactive elements
3254  /// from remaining inactive for longer than a single animation frame.
3255  ///
3256  /// After this function is called, the element will not be incorporated into
3257  /// the tree again.
3258  ///
3259  /// See the lifecycle documentation for [Element] for additional information.
3260  @mustCallSuper
3261  void unmount() {
3262    assert(_debugLifecycleState == _ElementLifecycle.inactive);
3263    assert(widget != null);
3264    assert(depth != null);
3265    assert(!_active);
3266    if (widget.key is GlobalKey) {
3267      final GlobalKey key = widget.key;
3268      key._unregister(this);
3269    }
3270    assert(() { _debugLifecycleState = _ElementLifecycle.defunct; return true; }());
3271  }
3272
3273  @override
3274  RenderObject findRenderObject() => renderObject;
3275
3276  @override
3277  Size get size {
3278    assert(() {
3279      if (_debugLifecycleState != _ElementLifecycle.active) {
3280        // TODO(jacobr): is this a good separation into contract and violation?
3281        // I have added a line of white space.
3282        throw FlutterError.fromParts(<DiagnosticsNode>[
3283          ErrorSummary('Cannot get size of inactive element.'),
3284          ErrorDescription(
3285            'In order for an element to have a valid size, the element must be '
3286            'active, which means it is part of the tree.\n'
3287            'Instead, this element is in the $_debugLifecycleState state.'
3288          ),
3289          describeElement('The size getter was called for the following element')
3290        ]);
3291      }
3292      if (owner._debugBuilding) {
3293        throw FlutterError.fromParts(<DiagnosticsNode>[
3294          ErrorSummary('Cannot get size during build.'),
3295          ErrorDescription(
3296            'The size of this render object has not yet been determined because '
3297            'the framework is still in the process of building widgets, which '
3298            'means the render tree for this frame has not yet been determined. '
3299            'The size getter should only be called from paint callbacks or '
3300            'interaction event handlers (e.g. gesture callbacks).'
3301          ),
3302          ErrorSpacer(),
3303          ErrorHint(
3304            'If you need some sizing information during build to decide which '
3305            'widgets to build, consider using a LayoutBuilder widget, which can '
3306            'tell you the layout constraints at a given location in the tree. See '
3307            '<https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html> '
3308            'for more details.'
3309          ),
3310          ErrorSpacer(),
3311          describeElement('The size getter was called for the following element')
3312        ]);
3313      }
3314      return true;
3315    }());
3316    final RenderObject renderObject = findRenderObject();
3317    assert(() {
3318      if (renderObject == null) {
3319        throw FlutterError.fromParts(<DiagnosticsNode>[
3320          ErrorSummary('Cannot get size without a render object.'),
3321          ErrorHint(
3322            'In order for an element to have a valid size, the element must have '
3323            'an associated render object. This element does not have an associated '
3324            'render object, which typically means that the size getter was called '
3325            'too early in the pipeline (e.g., during the build phase) before the '
3326            'framework has created the render tree.'
3327          ),
3328          describeElement('The size getter was called for the following element')
3329        ]);
3330      }
3331      if (renderObject is RenderSliver) {
3332        throw FlutterError.fromParts(<DiagnosticsNode>[
3333          ErrorSummary('Cannot get size from a RenderSliver.'),
3334          ErrorHint(
3335            'The render object associated with this element is a '
3336            '${renderObject.runtimeType}, which is a subtype of RenderSliver. '
3337            'Slivers do not have a size per se. They have a more elaborate '
3338            'geometry description, which can be accessed by calling '
3339            'findRenderObject and then using the "geometry" getter on the '
3340            'resulting object.'
3341          ),
3342          describeElement('The size getter was called for the following element'),
3343          renderObject.describeForError('The associated render sliver was'),
3344        ]);
3345      }
3346      if (renderObject is! RenderBox) {
3347        throw FlutterError.fromParts(<DiagnosticsNode>[
3348          ErrorSummary('Cannot get size from a render object that is not a RenderBox.'),
3349          ErrorHint(
3350            'Instead of being a subtype of RenderBox, the render object associated '
3351            'with this element is a ${renderObject.runtimeType}. If this type of '
3352            'render object does have a size, consider calling findRenderObject '
3353            'and extracting its size manually.'
3354          ),
3355          describeElement('The size getter was called for the following element'),
3356          renderObject.describeForError('The associated render object was')
3357        ]);
3358      }
3359      final RenderBox box = renderObject;
3360      if (!box.hasSize) {
3361        throw FlutterError.fromParts(<DiagnosticsNode>[
3362          ErrorSummary('Cannot get size from a render object that has not been through layout.'),
3363          ErrorHint(
3364            'The size of this render object has not yet been determined because '
3365            'this render object has not yet been through layout, which typically '
3366            'means that the size getter was called too early in the pipeline '
3367            '(e.g., during the build phase) before the framework has determined '
3368           'the size and position of the render objects during layout.'
3369          ),
3370          describeElement('The size getter was called for the following element'),
3371          box.describeForError('The render object from which the size was to be obtained was')
3372        ]);
3373      }
3374      if (box.debugNeedsLayout) {
3375        throw FlutterError.fromParts(<DiagnosticsNode>[
3376          ErrorSummary('Cannot get size from a render object that has been marked dirty for layout.'),
3377          ErrorHint(
3378            'The size of this render object is ambiguous because this render object has '
3379            'been modified since it was last laid out, which typically means that the size '
3380            'getter was called too early in the pipeline (e.g., during the build phase) '
3381            'before the framework has determined the size and position of the render '
3382            'objects during layout.'
3383          ),
3384          describeElement('The size getter was called for the following element'),
3385          box.describeForError('The render object from which the size was to be obtained was'),
3386          ErrorHint(
3387            'Consider using debugPrintMarkNeedsLayoutStacks to determine why the render '
3388            'object in question is dirty, if you did not expect this.'
3389          ),
3390        ]);
3391      }
3392      return true;
3393    }());
3394    if (renderObject is RenderBox)
3395      return renderObject.size;
3396    return null;
3397  }
3398
3399  Map<Type, InheritedElement> _inheritedWidgets;
3400  Set<InheritedElement> _dependencies;
3401  bool _hadUnsatisfiedDependencies = false;
3402
3403  bool _debugCheckStateIsActiveForAncestorLookup() {
3404    assert(() {
3405      if (_debugLifecycleState != _ElementLifecycle.active) {
3406        throw FlutterError.fromParts(<DiagnosticsNode>[
3407          ErrorSummary('Looking up a deactivated widget\'s ancestor is unsafe.'),
3408          ErrorDescription(
3409            'At this point the state of the widget\'s element tree is no longer '
3410            'stable.'
3411          ),
3412          ErrorHint(
3413            'To safely refer to a widget\'s ancestor in its dispose() method, '
3414            'save a reference to the ancestor by calling inheritFromWidgetOfExactType() '
3415            'in the widget\'s didChangeDependencies() method.'
3416          )
3417        ]);
3418      }
3419      return true;
3420    }());
3421    return true;
3422  }
3423
3424  @override
3425  InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect }) {
3426    assert(ancestor != null);
3427    _dependencies ??= HashSet<InheritedElement>();
3428    _dependencies.add(ancestor);
3429    ancestor.updateDependencies(this, aspect);
3430    return ancestor.widget;
3431  }
3432
3433  @override
3434  InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect }) {
3435    assert(_debugCheckStateIsActiveForAncestorLookup());
3436    final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType];
3437    if (ancestor != null) {
3438      assert(ancestor is InheritedElement);
3439      return inheritFromElement(ancestor, aspect: aspect);
3440    }
3441    _hadUnsatisfiedDependencies = true;
3442    return null;
3443  }
3444
3445  @override
3446  InheritedElement ancestorInheritedElementForWidgetOfExactType(Type targetType) {
3447    assert(_debugCheckStateIsActiveForAncestorLookup());
3448    final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType];
3449    return ancestor;
3450  }
3451
3452  void _updateInheritance() {
3453    assert(_active);
3454    _inheritedWidgets = _parent?._inheritedWidgets;
3455  }
3456
3457  @override
3458  Widget ancestorWidgetOfExactType(Type targetType) {
3459    assert(_debugCheckStateIsActiveForAncestorLookup());
3460    Element ancestor = _parent;
3461    while (ancestor != null && ancestor.widget.runtimeType != targetType)
3462      ancestor = ancestor._parent;
3463    return ancestor?.widget;
3464  }
3465
3466  @override
3467  State ancestorStateOfType(TypeMatcher matcher) {
3468    assert(_debugCheckStateIsActiveForAncestorLookup());
3469    Element ancestor = _parent;
3470    while (ancestor != null) {
3471      if (ancestor is StatefulElement && matcher.check(ancestor.state))
3472        break;
3473      ancestor = ancestor._parent;
3474    }
3475    final StatefulElement statefulAncestor = ancestor;
3476    return statefulAncestor?.state;
3477  }
3478
3479  @override
3480  State rootAncestorStateOfType(TypeMatcher matcher) {
3481    assert(_debugCheckStateIsActiveForAncestorLookup());
3482    Element ancestor = _parent;
3483    StatefulElement statefulAncestor;
3484    while (ancestor != null) {
3485      if (ancestor is StatefulElement && matcher.check(ancestor.state))
3486        statefulAncestor = ancestor;
3487      ancestor = ancestor._parent;
3488    }
3489    return statefulAncestor?.state;
3490  }
3491
3492  @override
3493  RenderObject ancestorRenderObjectOfType(TypeMatcher matcher) {
3494    assert(_debugCheckStateIsActiveForAncestorLookup());
3495    Element ancestor = _parent;
3496    while (ancestor != null) {
3497      if (ancestor is RenderObjectElement && matcher.check(ancestor.renderObject))
3498        break;
3499      ancestor = ancestor._parent;
3500    }
3501    final RenderObjectElement renderObjectAncestor = ancestor;
3502    return renderObjectAncestor?.renderObject;
3503  }
3504
3505  @override
3506  void visitAncestorElements(bool visitor(Element element)) {
3507    assert(_debugCheckStateIsActiveForAncestorLookup());
3508    Element ancestor = _parent;
3509    while (ancestor != null && visitor(ancestor))
3510      ancestor = ancestor._parent;
3511  }
3512
3513  /// Called when a dependency of this element changes.
3514  ///
3515  /// The [inheritFromWidgetOfExactType] registers this element as depending on
3516  /// inherited information of the given type. When the information of that type
3517  /// changes at this location in the tree (e.g., because the [InheritedElement]
3518  /// updated to a new [InheritedWidget] and
3519  /// [InheritedWidget.updateShouldNotify] returned true), the framework calls
3520  /// this function to notify this element of the change.
3521  @mustCallSuper
3522  void didChangeDependencies() {
3523    assert(_active); // otherwise markNeedsBuild is a no-op
3524    assert(_debugCheckOwnerBuildTargetExists('didChangeDependencies'));
3525    markNeedsBuild();
3526  }
3527
3528  bool _debugCheckOwnerBuildTargetExists(String methodName) {
3529    assert(() {
3530      if (owner._debugCurrentBuildTarget == null) {
3531        throw FlutterError.fromParts(<DiagnosticsNode>[
3532          ErrorSummary(
3533            '$methodName for ${widget.runtimeType} was called at an '
3534            'inappropriate time.'
3535          ),
3536          ErrorDescription('It may only be called while the widgets are being built.'),
3537          ErrorHint(
3538            'A possible cause of this error is when $methodName is called during '
3539            'one of:\n'
3540            ' * network I/O event\n'
3541            ' * file I/O event\n'
3542            ' * timer\n'
3543            ' * microtask (caused by Future.then, async/await, scheduleMicrotask)'
3544          )
3545        ]);
3546      }
3547      return true;
3548    }());
3549    return true;
3550  }
3551
3552  /// Returns a description of what caused this element to be created.
3553  ///
3554  /// Useful for debugging the source of an element.
3555  String debugGetCreatorChain(int limit) {
3556    final List<String> chain = <String>[];
3557    Element node = this;
3558    while (chain.length < limit && node != null) {
3559      chain.add(node.toStringShort());
3560      node = node._parent;
3561    }
3562    if (node != null)
3563      chain.add('\u22EF');
3564    return chain.join(' \u2190 ');
3565  }
3566
3567  /// Returns the parent chain from this element back to the root of the tree.
3568  ///
3569  /// Useful for debug display of a tree of Elements with only nodes in the path
3570  /// from the root to this Element expanded.
3571  List<Element> debugGetDiagnosticChain() {
3572    final List<Element> chain = <Element>[this];
3573    Element node = _parent;
3574    while (node != null) {
3575      chain.add(node);
3576      node = node._parent;
3577    }
3578    return chain;
3579  }
3580
3581  /// A short, textual description of this element.
3582  @override
3583  String toStringShort() {
3584    return widget != null ? '${widget.toStringShort()}' : '[$runtimeType]';
3585  }
3586
3587  @override
3588  DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
3589    return _ElementDiagnosticableTreeNode(
3590      name: name,
3591      value: this,
3592      style: style,
3593    );
3594  }
3595
3596  @override
3597  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
3598    super.debugFillProperties(properties);
3599    properties.defaultDiagnosticsTreeStyle= DiagnosticsTreeStyle.dense;
3600    properties.add(ObjectFlagProperty<int>('depth', depth, ifNull: 'no depth'));
3601    properties.add(ObjectFlagProperty<Widget>('widget', widget, ifNull: 'no widget'));
3602    if (widget != null) {
3603      properties.add(DiagnosticsProperty<Key>('key', widget?.key, showName: false, defaultValue: null, level: DiagnosticLevel.hidden));
3604      widget.debugFillProperties(properties);
3605    }
3606    properties.add(FlagProperty('dirty', value: dirty, ifTrue: 'dirty'));
3607    if (_dependencies != null && _dependencies.isNotEmpty) {
3608      final List<DiagnosticsNode> diagnosticsDependencies = _dependencies
3609        .map((InheritedElement element) => element.widget.toDiagnosticsNode(style: DiagnosticsTreeStyle.sparse))
3610        .toList();
3611      properties.add(DiagnosticsProperty<List<DiagnosticsNode>>('dependencies', diagnosticsDependencies));
3612    }
3613  }
3614
3615  @override
3616  List<DiagnosticsNode> debugDescribeChildren() {
3617    final List<DiagnosticsNode> children = <DiagnosticsNode>[];
3618    visitChildren((Element child) {
3619      if (child != null) {
3620        children.add(child.toDiagnosticsNode());
3621      } else {
3622        children.add(DiagnosticsNode.message('<null child>'));
3623      }
3624    });
3625    return children;
3626  }
3627
3628  /// Returns true if the element has been marked as needing rebuilding.
3629  bool get dirty => _dirty;
3630  bool _dirty = true;
3631
3632  // Whether this is in owner._dirtyElements. This is used to know whether we
3633  // should be adding the element back into the list when it's reactivated.
3634  bool _inDirtyList = false;
3635
3636  // Whether we've already built or not. Set in [rebuild].
3637  bool _debugBuiltOnce = false;
3638
3639  // We let widget authors call setState from initState, didUpdateWidget, and
3640  // build even when state is locked because its convenient and a no-op anyway.
3641  // This flag ensures that this convenience is only allowed on the element
3642  // currently undergoing initState, didUpdateWidget, or build.
3643  bool _debugAllowIgnoredCallsToMarkNeedsBuild = false;
3644  bool _debugSetAllowIgnoredCallsToMarkNeedsBuild(bool value) {
3645    assert(_debugAllowIgnoredCallsToMarkNeedsBuild == !value);
3646    _debugAllowIgnoredCallsToMarkNeedsBuild = value;
3647    return true;
3648  }
3649
3650  /// Marks the element as dirty and adds it to the global list of widgets to
3651  /// rebuild in the next frame.
3652  ///
3653  /// Since it is inefficient to build an element twice in one frame,
3654  /// applications and widgets should be structured so as to only mark
3655  /// widgets dirty during event handlers before the frame begins, not during
3656  /// the build itself.
3657  void markNeedsBuild() {
3658    assert(_debugLifecycleState != _ElementLifecycle.defunct);
3659    if (!_active)
3660      return;
3661    assert(owner != null);
3662    assert(_debugLifecycleState == _ElementLifecycle.active);
3663    assert(() {
3664      if (owner._debugBuilding) {
3665        assert(owner._debugCurrentBuildTarget != null);
3666        assert(owner._debugStateLocked);
3667        if (_debugIsInScope(owner._debugCurrentBuildTarget))
3668          return true;
3669        if (!_debugAllowIgnoredCallsToMarkNeedsBuild) {
3670          final List<DiagnosticsNode> information = <DiagnosticsNode>[
3671            ErrorSummary('setState() or markNeedsBuild() called during build.'),
3672            ErrorDescription(
3673              'This ${widget.runtimeType} widget cannot be marked as needing to build because the framework '
3674              'is already in the process of building widgets.  A widget can be marked as '
3675              'needing to be built during the build phase only if one of its ancestors '
3676              'is currently building. This exception is allowed because the framework '
3677              'builds parent widgets before children, which means a dirty descendant '
3678              'will always be built. Otherwise, the framework might not visit this '
3679              'widget during this build phase.'
3680            ),
3681            describeElement(
3682              'The widget on which setState() or markNeedsBuild() was called was',
3683            )
3684          ];
3685          if (owner._debugCurrentBuildTarget != null)
3686            information.add(owner._debugCurrentBuildTarget.describeWidget('The widget which was currently being built when the offending call was made was'));
3687          throw FlutterError.fromParts(information);
3688        }
3689        assert(dirty); // can only get here if we're not in scope, but ignored calls are allowed, and our call would somehow be ignored (since we're already dirty)
3690      } else if (owner._debugStateLocked) {
3691        assert(!_debugAllowIgnoredCallsToMarkNeedsBuild);
3692        throw FlutterError.fromParts(<DiagnosticsNode>[
3693          ErrorSummary('setState() or markNeedsBuild() called when widget tree was locked.'),
3694          ErrorDescription(
3695            'This ${widget.runtimeType} widget cannot be marked as needing to build '
3696            'because the framework is locked.'
3697          ),
3698          describeElement('The widget on which setState() or markNeedsBuild() was called was')
3699        ]);
3700      }
3701      return true;
3702    }());
3703    if (dirty)
3704      return;
3705    _dirty = true;
3706    owner.scheduleBuildFor(this);
3707  }
3708
3709  /// Called by the [BuildOwner] when [BuildOwner.scheduleBuildFor] has been
3710  /// called to mark this element dirty, by [mount] when the element is first
3711  /// built, and by [update] when the widget has changed.
3712  void rebuild() {
3713    assert(_debugLifecycleState != _ElementLifecycle.initial);
3714    if (!_active || !_dirty)
3715      return;
3716    assert(() {
3717      if (debugOnRebuildDirtyWidget != null) {
3718        debugOnRebuildDirtyWidget(this, _debugBuiltOnce);
3719      }
3720      if (debugPrintRebuildDirtyWidgets) {
3721        if (!_debugBuiltOnce) {
3722          debugPrint('Building $this');
3723          _debugBuiltOnce = true;
3724        } else {
3725          debugPrint('Rebuilding $this');
3726        }
3727      }
3728      return true;
3729    }());
3730    assert(_debugLifecycleState == _ElementLifecycle.active);
3731    assert(owner._debugStateLocked);
3732    Element debugPreviousBuildTarget;
3733    assert(() {
3734      debugPreviousBuildTarget = owner._debugCurrentBuildTarget;
3735      owner._debugCurrentBuildTarget = this;
3736      return true;
3737    }());
3738    performRebuild();
3739    assert(() {
3740      assert(owner._debugCurrentBuildTarget == this);
3741      owner._debugCurrentBuildTarget = debugPreviousBuildTarget;
3742      return true;
3743    }());
3744    assert(!_dirty);
3745  }
3746
3747  /// Called by rebuild() after the appropriate checks have been made.
3748  @protected
3749  void performRebuild();
3750}
3751
3752class _ElementDiagnosticableTreeNode extends DiagnosticableTreeNode {
3753  _ElementDiagnosticableTreeNode({
3754    String name,
3755    @required Element value,
3756    @required DiagnosticsTreeStyle style,
3757    this.stateful = false,
3758  }) : super(
3759    name: name,
3760    value: value,
3761    style: style,
3762  );
3763
3764  final bool stateful;
3765
3766  @override
3767  Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
3768    final Map<String, Object> json = super.toJsonMap(delegate);
3769    final Element element = value;
3770    json['widgetRuntimeType'] = element.widget?.runtimeType?.toString();
3771    json['stateful'] = stateful;
3772    return json;
3773  }
3774}
3775
3776/// Signature for the constructor that is called when an error occurs while
3777/// building a widget.
3778///
3779/// The argument provides information regarding the cause of the error.
3780///
3781/// See also:
3782///
3783///  * [ErrorWidget.builder], which can be set to override the default
3784///    [ErrorWidget] builder.
3785///  * [FlutterError.reportError], which is typically called with the same
3786///    [FlutterErrorDetails] object immediately prior to [ErrorWidget.builder]
3787///    being called.
3788typedef ErrorWidgetBuilder = Widget Function(FlutterErrorDetails details);
3789
3790/// A widget that renders an exception's message.
3791///
3792/// This widget is used when a build method fails, to help with determining
3793/// where the problem lies. Exceptions are also logged to the console, which you
3794/// can read using `flutter logs`. The console will also include additional
3795/// information such as the stack trace for the exception.
3796class ErrorWidget extends LeafRenderObjectWidget {
3797  /// Creates a widget that displays the given error message.
3798  ErrorWidget(Object exception)
3799    : message = _stringify(exception),
3800      _flutterError = exception is FlutterError ? exception : null,
3801      super(key: UniqueKey());
3802
3803  /// The configurable factory for [ErrorWidget].
3804  ///
3805  /// When an error occurs while building a widget, the broken widget is
3806  /// replaced by the widget returned by this function. By default, an
3807  /// [ErrorWidget] is returned.
3808  ///
3809  /// The system is typically in an unstable state when this function is called.
3810  /// An exception has just been thrown in the middle of build (and possibly
3811  /// layout), so surrounding widgets and render objects may be in a rather
3812  /// fragile state. The framework itself (especially the [BuildOwner]) may also
3813  /// be confused, and additional exceptions are quite likely to be thrown.
3814  ///
3815  /// Because of this, it is highly recommended that the widget returned from
3816  /// this function perform the least amount of work possible. A
3817  /// [LeafRenderObjectWidget] is the best choice, especially one that
3818  /// corresponds to a [RenderBox] that can handle the most absurd of incoming
3819  /// constraints. The default constructor maps to a [RenderErrorBox].
3820  ///
3821  /// See also:
3822  ///
3823  ///  * [FlutterError.onError], which is typically called with the same
3824  ///    [FlutterErrorDetails] object immediately prior to this callback being
3825  ///    invoked, and which can also be configured to control how errors are
3826  ///    reported.
3827  static ErrorWidgetBuilder builder = (FlutterErrorDetails details) => ErrorWidget(details.exception);
3828
3829  /// The message to display.
3830  final String message;
3831  final FlutterError _flutterError;
3832
3833  static String _stringify(Object exception) {
3834    try {
3835      return exception.toString();
3836    } catch (e) {
3837      // intentionally left empty.
3838    }
3839    return 'Error';
3840  }
3841
3842  @override
3843  RenderBox createRenderObject(BuildContext context) => RenderErrorBox(message);
3844
3845  @override
3846  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
3847    super.debugFillProperties(properties);
3848    if (_flutterError == null)
3849      properties.add(StringProperty('message', message, quoted: false));
3850    else
3851      properties.add(_flutterError.toDiagnosticsNode(style: DiagnosticsTreeStyle.whitespace));
3852  }
3853}
3854
3855/// Signature for a function that creates a widget, e.g. [StatelessWidget.build]
3856/// or [State.build].
3857///
3858/// Used by [Builder.builder], [OverlayEntry.builder], etc.
3859///
3860/// See also:
3861///
3862///  * [IndexedWidgetBuilder], which is similar but also takes an index.
3863///  * [TransitionBuilder], which is similar but also takes a child.
3864///  * [ValueWidgetBuilder], which is similar but takes a value and a child.
3865typedef WidgetBuilder = Widget Function(BuildContext context);
3866
3867/// Signature for a function that creates a widget for a given index, e.g., in a
3868/// list.
3869///
3870/// Used by [ListView.builder] and other APIs that use lazily-generated widgets.
3871///
3872/// See also:
3873///
3874///  * [WidgetBuilder], which is similar but only takes a [BuildContext].
3875///  * [TransitionBuilder], which is similar but also takes a child.
3876typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
3877
3878/// A builder that builds a widget given a child.
3879///
3880/// The child should typically be part of the returned widget tree.
3881///
3882/// Used by [AnimatedBuilder.builder], as well as [WidgetsApp.builder] and
3883/// [MaterialApp.builder].
3884///
3885/// See also:
3886///
3887///  * [WidgetBuilder], which is similar but only takes a [BuildContext].
3888///  * [IndexedWidgetBuilder], which is similar but also takes an index.
3889///  * [ValueWidgetBuilder], which is similar but takes a value and a child.
3890typedef TransitionBuilder = Widget Function(BuildContext context, Widget child);
3891
3892/// A builder that creates a widget given the two callbacks `onStepContinue` and
3893/// `onStepCancel`.
3894///
3895/// Used by [Stepper.builder].
3896///
3897/// See also:
3898///
3899///  * [WidgetBuilder], which is similar but only takes a [BuildContext].
3900typedef ControlsWidgetBuilder = Widget Function(BuildContext context, { VoidCallback onStepContinue, VoidCallback onStepCancel });
3901
3902/// An [Element] that composes other [Element]s.
3903///
3904/// Rather than creating a [RenderObject] directly, a [ComponentElement] creates
3905/// [RenderObject]s indirectly by creating other [Element]s.
3906///
3907/// Contrast with [RenderObjectElement].
3908abstract class ComponentElement extends Element {
3909  /// Creates an element that uses the given widget as its configuration.
3910  ComponentElement(Widget widget) : super(widget);
3911
3912  Element _child;
3913
3914  @override
3915  void mount(Element parent, dynamic newSlot) {
3916    super.mount(parent, newSlot);
3917    assert(_child == null);
3918    assert(_active);
3919    _firstBuild();
3920    assert(_child != null);
3921  }
3922
3923  void _firstBuild() {
3924    rebuild();
3925  }
3926
3927  /// Calls the [StatelessWidget.build] method of the [StatelessWidget] object
3928  /// (for stateless widgets) or the [State.build] method of the [State] object
3929  /// (for stateful widgets) and then updates the widget tree.
3930  ///
3931  /// Called automatically during [mount] to generate the first build, and by
3932  /// [rebuild] when the element needs updating.
3933  @override
3934  void performRebuild() {
3935    if (!kReleaseMode && debugProfileBuildsEnabled)
3936      Timeline.startSync('${widget.runtimeType}',  arguments: timelineWhitelistArguments);
3937
3938    assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(true));
3939    Widget built;
3940    try {
3941      built = build();
3942      debugWidgetBuilderValue(widget, built);
3943    } catch (e, stack) {
3944      built = ErrorWidget.builder(
3945        _debugReportException(
3946          ErrorDescription('building $this'),
3947          e,
3948          stack,
3949          informationCollector: () sync* {
3950            yield DiagnosticsDebugCreator(DebugCreator(this));
3951          },
3952        )
3953      );
3954    } finally {
3955      // We delay marking the element as clean until after calling build() so
3956      // that attempts to markNeedsBuild() during build() will be ignored.
3957      _dirty = false;
3958      assert(_debugSetAllowIgnoredCallsToMarkNeedsBuild(false));
3959    }
3960    try {
3961      _child = updateChild(_child, built, slot);
3962      assert(_child != null);
3963    } catch (e, stack) {
3964      built = ErrorWidget.builder(
3965        _debugReportException(
3966          ErrorDescription('building $this'),
3967          e,
3968          stack,
3969          informationCollector: () sync* {
3970            yield DiagnosticsDebugCreator(DebugCreator(this));
3971          },
3972        )
3973      );
3974      _child = updateChild(null, built, slot);
3975    }
3976
3977    if (!kReleaseMode && debugProfileBuildsEnabled)
3978      Timeline.finishSync();
3979  }
3980
3981  /// Subclasses should override this function to actually call the appropriate
3982  /// `build` function (e.g., [StatelessWidget.build] or [State.build]) for
3983  /// their widget.
3984  @protected
3985  Widget build();
3986
3987  @override
3988  void visitChildren(ElementVisitor visitor) {
3989    if (_child != null)
3990      visitor(_child);
3991  }
3992
3993  @override
3994  void forgetChild(Element child) {
3995    assert(child == _child);
3996    _child = null;
3997  }
3998}
3999
4000/// An [Element] that uses a [StatelessWidget] as its configuration.
4001class StatelessElement extends ComponentElement {
4002  /// Creates an element that uses the given widget as its configuration.
4003  StatelessElement(StatelessWidget widget) : super(widget);
4004
4005  @override
4006  StatelessWidget get widget => super.widget;
4007
4008  @override
4009  Widget build() => widget.build(this);
4010
4011  @override
4012  void update(StatelessWidget newWidget) {
4013    super.update(newWidget);
4014    assert(widget == newWidget);
4015    _dirty = true;
4016    rebuild();
4017  }
4018}
4019
4020/// An [Element] that uses a [StatefulWidget] as its configuration.
4021class StatefulElement extends ComponentElement {
4022  /// Creates an element that uses the given widget as its configuration.
4023  StatefulElement(StatefulWidget widget)
4024      : _state = widget.createState(),
4025        super(widget) {
4026    assert(() {
4027      if (!_state._debugTypesAreRight(widget)) {
4028        throw FlutterError.fromParts(<DiagnosticsNode>[
4029          ErrorSummary('StatefulWidget.createState must return a subtype of State<${widget.runtimeType}>'),
4030          ErrorDescription(
4031            'The createState function for ${widget.runtimeType} returned a state '
4032            'of type ${_state.runtimeType}, which is not a subtype of '
4033            'State<${widget.runtimeType}>, violating the contract for createState.'
4034          )
4035        ]);
4036      }
4037      return true;
4038    }());
4039    assert(_state._element == null);
4040    _state._element = this;
4041    assert(_state._widget == null);
4042    _state._widget = widget;
4043    assert(_state._debugLifecycleState == _StateLifecycle.created);
4044  }
4045
4046  @override
4047  Widget build() => state.build(this);
4048
4049  /// The [State] instance associated with this location in the tree.
4050  ///
4051  /// There is a one-to-one relationship between [State] objects and the
4052  /// [StatefulElement] objects that hold them. The [State] objects are created
4053  /// by [StatefulElement] in [mount].
4054  State<StatefulWidget> get state => _state;
4055  State<StatefulWidget> _state;
4056
4057  @override
4058  void reassemble() {
4059    state.reassemble();
4060    super.reassemble();
4061  }
4062
4063  @override
4064  void _firstBuild() {
4065    assert(_state._debugLifecycleState == _StateLifecycle.created);
4066    try {
4067      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
4068      final dynamic debugCheckForReturnedFuture = _state.initState() as dynamic;
4069      assert(() {
4070        if (debugCheckForReturnedFuture is Future) {
4071          throw FlutterError.fromParts(<DiagnosticsNode>[
4072            ErrorSummary('${_state.runtimeType}.initState() returned a Future.'),
4073            ErrorDescription('State.initState() must be a void method without an `async` keyword.'),
4074            ErrorHint(
4075              'Rather than awaiting on asynchronous work directly inside of initState, '
4076              'call a separate method to do this work without awaiting it.'
4077            )
4078          ]);
4079        }
4080        return true;
4081      }());
4082    } finally {
4083      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
4084    }
4085    assert(() { _state._debugLifecycleState = _StateLifecycle.initialized; return true; }());
4086    _state.didChangeDependencies();
4087    assert(() { _state._debugLifecycleState = _StateLifecycle.ready; return true; }());
4088    super._firstBuild();
4089  }
4090
4091  @override
4092  void update(StatefulWidget newWidget) {
4093    super.update(newWidget);
4094    assert(widget == newWidget);
4095    final StatefulWidget oldWidget = _state._widget;
4096    // Notice that we mark ourselves as dirty before calling didUpdateWidget to
4097    // let authors call setState from within didUpdateWidget without triggering
4098    // asserts.
4099    _dirty = true;
4100    _state._widget = widget;
4101    try {
4102      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
4103      final dynamic debugCheckForReturnedFuture = _state.didUpdateWidget(oldWidget) as dynamic;
4104      assert(() {
4105        if (debugCheckForReturnedFuture is Future) {
4106          throw FlutterError.fromParts(<DiagnosticsNode>[
4107            ErrorSummary('${_state.runtimeType}.didUpdateWidget() returned a Future.'),
4108            ErrorDescription( 'State.didUpdateWidget() must be a void method without an `async` keyword.'),
4109            ErrorHint(
4110              'Rather than awaiting on asynchronous work directly inside of didUpdateWidget, '
4111              'call a separate method to do this work without awaiting it.'
4112            )
4113          ]);
4114        }
4115        return true;
4116      }());
4117    } finally {
4118      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
4119    }
4120    rebuild();
4121  }
4122
4123  @override
4124  void activate() {
4125    super.activate();
4126    // Since the State could have observed the deactivate() and thus disposed of
4127    // resources allocated in the build method, we have to rebuild the widget
4128    // so that its State can reallocate its resources.
4129    assert(_active); // otherwise markNeedsBuild is a no-op
4130    markNeedsBuild();
4131  }
4132
4133  @override
4134  void deactivate() {
4135    _state.deactivate();
4136    super.deactivate();
4137  }
4138
4139  @override
4140  void unmount() {
4141    super.unmount();
4142    _state.dispose();
4143    assert(() {
4144      if (_state._debugLifecycleState == _StateLifecycle.defunct)
4145        return true;
4146      throw FlutterError.fromParts(<DiagnosticsNode>[
4147        ErrorSummary('${_state.runtimeType}.dispose failed to call super.dispose.'),
4148        ErrorDescription(
4149          'dispose() implementations must always call their superclass dispose() method, to ensure '
4150         'that all the resources used by the widget are fully released.'
4151        )
4152      ]);
4153    }());
4154    _state._element = null;
4155    _state = null;
4156  }
4157
4158  @override
4159  InheritedWidget inheritFromElement(Element ancestor, { Object aspect }) {
4160    assert(ancestor != null);
4161    assert(() {
4162      final Type targetType = ancestor.widget.runtimeType;
4163      if (state._debugLifecycleState == _StateLifecycle.created) {
4164        throw FlutterError.fromParts(<DiagnosticsNode>[
4165          ErrorSummary('inheritFromWidgetOfExactType($targetType) or inheritFromElement() was called before ${_state.runtimeType}.initState() completed.'),
4166          ErrorDescription(
4167            'When an inherited widget changes, for example if the value of Theme.of() changes, '
4168            'its dependent widgets are rebuilt. If the dependent widget\'s reference to '
4169            'the inherited widget is in a constructor or an initState() method, '
4170            'then the rebuilt dependent widget will not reflect the changes in the '
4171            'inherited widget.',
4172          ),
4173          ErrorHint(
4174            'Typically references to inherited widgets should occur in widget build() methods. Alternatively, '
4175            'initialization based on inherited widgets can be placed in the didChangeDependencies method, which '
4176            'is called after initState and whenever the dependencies change thereafter.'
4177          )
4178        ]);
4179      }
4180      if (state._debugLifecycleState == _StateLifecycle.defunct) {
4181        throw FlutterError.fromParts(<DiagnosticsNode>[
4182          ErrorSummary('inheritFromWidgetOfExactType($targetType) or inheritFromElement() was called after dispose(): $this'),
4183          ErrorDescription(
4184            'This error happens if you call inheritFromWidgetOfExactType() on the '
4185            'BuildContext for a widget that no longer appears in the widget tree '
4186            '(e.g., whose parent widget no longer includes the widget in its '
4187            'build). This error can occur when code calls '
4188            'inheritFromWidgetOfExactType() from a timer or an animation callback.'
4189          ),
4190          ErrorHint(
4191            'The preferred solution is to cancel the timer or stop listening to the '
4192            'animation in the dispose() callback. Another solution is to check the '
4193            '"mounted" property of this object before calling '
4194            'inheritFromWidgetOfExactType() to ensure the object is still in the '
4195            'tree.'
4196          ),
4197          ErrorHint(
4198            'This error might indicate a memory leak if '
4199            'inheritFromWidgetOfExactType() is being called because another object '
4200            'is retaining a reference to this State object after it has been '
4201            'removed from the tree. To avoid memory leaks, consider breaking the '
4202            'reference to this object during dispose().'
4203          ),
4204        ]);
4205      }
4206      return true;
4207    }());
4208    return super.inheritFromElement(ancestor, aspect: aspect);
4209  }
4210
4211  @override
4212  void didChangeDependencies() {
4213    super.didChangeDependencies();
4214    _state.didChangeDependencies();
4215  }
4216
4217  @override
4218  DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
4219    return _ElementDiagnosticableTreeNode(
4220      name: name,
4221      value: this,
4222      style: style,
4223      stateful: true,
4224    );
4225  }
4226
4227  @override
4228  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
4229    super.debugFillProperties(properties);
4230    properties.add(DiagnosticsProperty<State<StatefulWidget>>('state', state, defaultValue: null));
4231  }
4232}
4233
4234/// An [Element] that uses a [ProxyWidget] as its configuration.
4235abstract class ProxyElement extends ComponentElement {
4236  /// Initializes fields for subclasses.
4237  ProxyElement(ProxyWidget widget) : super(widget);
4238
4239  @override
4240  ProxyWidget get widget => super.widget;
4241
4242  @override
4243  Widget build() => widget.child;
4244
4245  @override
4246  void update(ProxyWidget newWidget) {
4247    final ProxyWidget oldWidget = widget;
4248    assert(widget != null);
4249    assert(widget != newWidget);
4250    super.update(newWidget);
4251    assert(widget == newWidget);
4252    updated(oldWidget);
4253    _dirty = true;
4254    rebuild();
4255  }
4256
4257  /// Called during build when the [widget] has changed.
4258  ///
4259  /// By default, calls [notifyClients]. Subclasses may override this method to
4260  /// avoid calling [notifyClients] unnecessarily (e.g. if the old and new
4261  /// widgets are equivalent).
4262  @protected
4263  void updated(covariant ProxyWidget oldWidget) {
4264    notifyClients(oldWidget);
4265  }
4266
4267  /// Notify other objects that the widget associated with this element has
4268  /// changed.
4269  ///
4270  /// Called during [update] (via [updated]) after changing the widget
4271  /// associated with this element but before rebuilding this element.
4272  @protected
4273  void notifyClients(covariant ProxyWidget oldWidget);
4274}
4275
4276/// An [Element] that uses a [ParentDataWidget] as its configuration.
4277class ParentDataElement<T extends RenderObjectWidget> extends ProxyElement {
4278  /// Creates an element that uses the given widget as its configuration.
4279  ParentDataElement(ParentDataWidget<T> widget) : super(widget);
4280
4281  @override
4282  ParentDataWidget<T> get widget => super.widget;
4283
4284  @override
4285  void mount(Element parent, dynamic newSlot) {
4286    assert(() {
4287      final List<Widget> badAncestors = <Widget>[];
4288      Element ancestor = parent;
4289      while (ancestor != null) {
4290        if (ancestor is ParentDataElement<RenderObjectWidget>) {
4291          badAncestors.add(ancestor.widget);
4292        } else if (ancestor is RenderObjectElement) {
4293          if (widget.debugIsValidAncestor(ancestor.widget))
4294            break;
4295          badAncestors.add(ancestor.widget);
4296        }
4297        ancestor = ancestor._parent;
4298      }
4299      if (ancestor != null && badAncestors.isEmpty)
4300        return true;
4301      // TODO(jacobr): switch to describing the invalid parent chain in terms
4302      // of DiagnosticsNode objects when possible.
4303      throw FlutterError.fromParts(<DiagnosticsNode>[
4304        ErrorSummary('Incorrect use of ParentDataWidget.'),
4305        // TODO(jacobr): fix this constructor call to use FlutterErrorBuilder.
4306        ...widget.debugDescribeInvalidAncestorChain(
4307          description: '$this',
4308          ownershipChain: ErrorDescription(parent.debugGetCreatorChain(10)),
4309          foundValidAncestor: ancestor != null,
4310          badAncestors: badAncestors,
4311        ),
4312      ]);
4313    }());
4314    super.mount(parent, newSlot);
4315  }
4316
4317  void _applyParentData(ParentDataWidget<T> widget) {
4318    void applyParentDataToChild(Element child) {
4319      if (child is RenderObjectElement) {
4320        child._updateParentData(widget);
4321      } else {
4322        assert(child is! ParentDataElement<RenderObjectWidget>);
4323        child.visitChildren(applyParentDataToChild);
4324      }
4325    }
4326    visitChildren(applyParentDataToChild);
4327  }
4328
4329  /// Calls [ParentDataWidget.applyParentData] on the given widget, passing it
4330  /// the [RenderObject] whose parent data this element is ultimately
4331  /// responsible for.
4332  ///
4333  /// This allows a render object's [RenderObject.parentData] to be modified
4334  /// without triggering a build. This is generally ill-advised, but makes sense
4335  /// in situations such as the following:
4336  ///
4337  ///  * Build and layout are currently under way, but the [ParentData] in question
4338  ///    does not affect layout, and the value to be applied could not be
4339  ///    determined before build and layout (e.g. it depends on the layout of a
4340  ///    descendant).
4341  ///
4342  ///  * Paint is currently under way, but the [ParentData] in question does not
4343  ///    affect layout or paint, and the value to be applied could not be
4344  ///    determined before paint (e.g. it depends on the compositing phase).
4345  ///
4346  /// In either case, the next build is expected to cause this element to be
4347  /// configured with the given new widget (or a widget with equivalent data).
4348  ///
4349  /// Only [ParentDataWidget]s that return true for
4350  /// [ParentDataWidget.debugCanApplyOutOfTurn] can be applied this way.
4351  ///
4352  /// The new widget must have the same child as the current widget.
4353  ///
4354  /// An example of when this is used is the [AutomaticKeepAlive] widget. If it
4355  /// receives a notification during the build of one of its descendants saying
4356  /// that its child must be kept alive, it will apply a [KeepAlive] widget out
4357  /// of turn. This is safe, because by definition the child is already alive,
4358  /// and therefore this will not change the behavior of the parent this frame.
4359  /// It is more efficient than requesting an additional frame just for the
4360  /// purpose of updating the [KeepAlive] widget.
4361  void applyWidgetOutOfTurn(ParentDataWidget<T> newWidget) {
4362    assert(newWidget != null);
4363    assert(newWidget.debugCanApplyOutOfTurn());
4364    assert(newWidget.child == widget.child);
4365    _applyParentData(newWidget);
4366  }
4367
4368  @override
4369  void notifyClients(ParentDataWidget<T> oldWidget) {
4370    _applyParentData(widget);
4371  }
4372}
4373
4374/// An [Element] that uses an [InheritedWidget] as its configuration.
4375class InheritedElement extends ProxyElement {
4376  /// Creates an element that uses the given widget as its configuration.
4377  InheritedElement(InheritedWidget widget) : super(widget);
4378
4379  @override
4380  InheritedWidget get widget => super.widget;
4381
4382  final Map<Element, Object> _dependents = HashMap<Element, Object>();
4383
4384  @override
4385  void _updateInheritance() {
4386    assert(_active);
4387    final Map<Type, InheritedElement> incomingWidgets = _parent?._inheritedWidgets;
4388    if (incomingWidgets != null)
4389      _inheritedWidgets = HashMap<Type, InheritedElement>.from(incomingWidgets);
4390    else
4391      _inheritedWidgets = HashMap<Type, InheritedElement>();
4392    _inheritedWidgets[widget.runtimeType] = this;
4393  }
4394
4395  @override
4396  void debugDeactivated() {
4397    assert(() {
4398      assert(_dependents.isEmpty);
4399      return true;
4400    }());
4401    super.debugDeactivated();
4402  }
4403
4404  /// Returns the dependencies value recorded for [dependent]
4405  /// with [setDependencies].
4406  ///
4407  /// Each dependent element is mapped to a single object value
4408  /// which represents how the element depends on this
4409  /// [InheritedElement]. This value is null by default and by default
4410  /// dependent elements are rebuilt unconditionally.
4411  ///
4412  /// Subclasses can manage these values with [updateDependencies]
4413  /// so that they can selectively rebuild dependents in
4414  /// [notifyDependent].
4415  ///
4416  /// This method is typically only called in overrides of [updateDependencies].
4417  ///
4418  /// See also:
4419  ///
4420  ///  * [updateDependencies], which is called each time a dependency is
4421  ///    created with [inheritFromWidgetOfExactType].
4422  ///  * [setDependencies], which sets dependencies value for a dependent
4423  ///    element.
4424  ///  * [notifyDependent], which can be overridden to use a dependent's
4425  ///    dependencies value to decide if the dependent needs to be rebuilt.
4426  ///  * [InheritedModel], which is an example of a class that uses this method
4427  ///    to manage dependency values.
4428  @protected
4429  Object getDependencies(Element dependent) {
4430    return _dependents[dependent];
4431  }
4432
4433  /// Sets the value returned by [getDependencies] value for [dependent].
4434  ///
4435  /// Each dependent element is mapped to a single object value
4436  /// which represents how the element depends on this
4437  /// [InheritedElement]. The [updateDependencies] method sets this value to
4438  /// null by default so that dependent elements are rebuilt unconditionally.
4439  ///
4440  /// Subclasses can manage these values with [updateDependencies]
4441  /// so that they can selectively rebuild dependents in [notifyDependent].
4442  ///
4443  /// This method is typically only called in overrides of [updateDependencies].
4444  ///
4445  /// See also:
4446  ///
4447  ///  * [updateDependencies], which is called each time a dependency is
4448  ///    created with [inheritFromWidgetOfExactType].
4449  ///  * [getDependencies], which returns the current value for a dependent
4450  ///    element.
4451  ///  * [notifyDependent], which can be overridden to use a dependent's
4452  ///    [getDependencies] value to decide if the dependent needs to be rebuilt.
4453  ///  * [InheritedModel], which is an example of a class that uses this method
4454  ///    to manage dependency values.
4455  @protected
4456  void setDependencies(Element dependent, Object value) {
4457    _dependents[dependent] = value;
4458  }
4459
4460  /// Called by [inheritFromWidgetOfExactType] when a new [dependent] is added.
4461  ///
4462  /// Each dependent element can be mapped to a single object value with
4463  /// [setDependencies]. This method can lookup the existing dependencies with
4464  /// [getDependencies].
4465  ///
4466  /// By default this method sets the inherited dependencies for [dependent]
4467  /// to null. This only serves to record an unconditional dependency on
4468  /// [dependent].
4469  ///
4470  /// Subclasses can manage their own dependencies values so that they
4471  /// can selectively rebuild dependents in [notifyDependent].
4472  ///
4473  /// See also:
4474  ///
4475  ///  * [getDependencies], which returns the current value for a dependent
4476  ///    element.
4477  ///  * [setDependencies], which sets the value for a dependent element.
4478  ///  * [notifyDependent], which can be overridden to use a dependent's
4479  ///    dependencies value to decide if the dependent needs to be rebuilt.
4480  ///  * [InheritedModel], which is an example of a class that uses this method
4481  ///    to manage dependency values.
4482  @protected
4483  void updateDependencies(Element dependent, Object aspect) {
4484    setDependencies(dependent, null);
4485  }
4486
4487  /// Called by [notifyClients] for each dependent.
4488  ///
4489  /// Calls `dependent.didChangeDependencies()` by default.
4490  ///
4491  /// Subclasses can override this method to selectively call
4492  /// [didChangeDependencies] based on the value of [getDependencies].
4493  ///
4494  /// See also:
4495  ///
4496  ///  * [updateDependencies], which is called each time a dependency is
4497  ///    created with [inheritFromWidgetOfExactType].
4498  ///  * [getDependencies], which returns the current value for a dependent
4499  ///    element.
4500  ///  * [setDependencies], which sets the value for a dependent element.
4501  ///  * [InheritedModel], which is an example of a class that uses this method
4502  ///    to manage dependency values.
4503  @protected
4504  void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {
4505    dependent.didChangeDependencies();
4506  }
4507
4508  /// Calls [Element.didChangeDependencies] of all dependent elements, if
4509  /// [InheritedWidget.updateShouldNotify] returns true.
4510  ///
4511  /// Called by [update], immediately prior to [build].
4512  ///
4513  /// Calls [notifyClients] to actually trigger the notifications.
4514  @override
4515  void updated(InheritedWidget oldWidget) {
4516    if (widget.updateShouldNotify(oldWidget))
4517      super.updated(oldWidget);
4518  }
4519
4520  /// Notifies all dependent elements that this inherited widget has changed, by
4521  /// calling [Element.didChangeDependencies].
4522  ///
4523  /// This method must only be called during the build phase. Usually this
4524  /// method is called automatically when an inherited widget is rebuilt, e.g.
4525  /// as a result of calling [State.setState] above the inherited widget.
4526  ///
4527  /// See also:
4528  ///
4529  ///  * [InheritedNotifier], a subclass of [InheritedWidget] that also calls
4530  ///    this method when its [Listenable] sends a notification.
4531  @override
4532  void notifyClients(InheritedWidget oldWidget) {
4533    assert(_debugCheckOwnerBuildTargetExists('notifyClients'));
4534    for (Element dependent in _dependents.keys) {
4535      assert(() {
4536        // check that it really is our descendant
4537        Element ancestor = dependent._parent;
4538        while (ancestor != this && ancestor != null)
4539          ancestor = ancestor._parent;
4540        return ancestor == this;
4541      }());
4542      // check that it really depends on us
4543      assert(dependent._dependencies.contains(this));
4544      notifyDependent(oldWidget, dependent);
4545    }
4546  }
4547}
4548
4549/// An [Element] that uses a [RenderObjectWidget] as its configuration.
4550///
4551/// [RenderObjectElement] objects have an associated [RenderObject] widget in
4552/// the render tree, which handles concrete operations like laying out,
4553/// painting, and hit testing.
4554///
4555/// Contrast with [ComponentElement].
4556///
4557/// For details on the lifecycle of an element, see the discussion at [Element].
4558///
4559/// ## Writing a RenderObjectElement subclass
4560///
4561/// There are three common child models used by most [RenderObject]s:
4562///
4563/// * Leaf render objects, with no children: The [LeafRenderObjectElement] class
4564///   handles this case.
4565///
4566/// * A single child: The [SingleChildRenderObjectElement] class handles this
4567///   case.
4568///
4569/// * A linked list of children: The [MultiChildRenderObjectElement] class
4570///   handles this case.
4571///
4572/// Sometimes, however, a render object's child model is more complicated. Maybe
4573/// it has a two-dimensional array of children. Maybe it constructs children on
4574/// demand. Maybe it features multiple lists. In such situations, the
4575/// corresponding [Element] for the [Widget] that configures that [RenderObject]
4576/// will be a new subclass of [RenderObjectElement].
4577///
4578/// Such a subclass is responsible for managing children, specifically the
4579/// [Element] children of this object, and the [RenderObject] children of its
4580/// corresponding [RenderObject].
4581///
4582/// ### Specializing the getters
4583///
4584/// [RenderObjectElement] objects spend much of their time acting as
4585/// intermediaries between their [widget] and their [renderObject]. To make this
4586/// more tractable, most [RenderObjectElement] subclasses override these getters
4587/// so that they return the specific type that the element expects, e.g.:
4588///
4589/// ```dart
4590/// class FooElement extends RenderObjectElement {
4591///
4592///   @override
4593///   Foo get widget => super.widget;
4594///
4595///   @override
4596///   RenderFoo get renderObject => super.renderObject;
4597///
4598///   // ...
4599/// }
4600/// ```
4601///
4602/// ### Slots
4603///
4604/// Each child [Element] corresponds to a [RenderObject] which should be
4605/// attached to this element's render object as a child.
4606///
4607/// However, the immediate children of the element may not be the ones that
4608/// eventually produce the actual [RenderObject] that they correspond to. For
4609/// example a [StatelessElement] (the element of a [StatelessWidget]) simply
4610/// corresponds to whatever [RenderObject] its child (the element returned by
4611/// its [StatelessWidget.build] method) corresponds to.
4612///
4613/// Each child is therefore assigned a _slot_ token. This is an identifier whose
4614/// meaning is private to this [RenderObjectElement] node. When the descendant
4615/// that finally produces the [RenderObject] is ready to attach it to this
4616/// node's render object, it passes that slot token back to this node, and that
4617/// allows this node to cheaply identify where to put the child render object
4618/// relative to the others in the parent render object.
4619///
4620/// ### Updating children
4621///
4622/// Early in the lifecycle of an element, the framework calls the [mount]
4623/// method. This method should call [updateChild] for each child, passing in
4624/// the widget for that child, and the slot for that child, thus obtaining a
4625/// list of child [Element]s.
4626///
4627/// Subsequently, the framework will call the [update] method. In this method,
4628/// the [RenderObjectElement] should call [updateChild] for each child, passing
4629/// in the [Element] that was obtained during [mount] or the last time [update]
4630/// was run (whichever happened most recently), the new [Widget], and the slot.
4631/// This provides the object with a new list of [Element] objects.
4632///
4633/// Where possible, the [update] method should attempt to map the elements from
4634/// the last pass to the widgets in the new pass. For example, if one of the
4635/// elements from the last pass was configured with a particular [Key], and one
4636/// of the widgets in this new pass has that same key, they should be paired up,
4637/// and the old element should be updated with the widget (and the slot
4638/// corresponding to the new widget's new position, also). The [updateChildren]
4639/// method may be useful in this regard.
4640///
4641/// [updateChild] should be called for children in their logical order. The
4642/// order can matter; for example, if two of the children use [PageStorage]'s
4643/// `writeState` feature in their build method (and neither has a [Widget.key]),
4644/// then the state written by the first will be overwritten by the second.
4645///
4646/// #### Dynamically determining the children during the build phase
4647///
4648/// The child widgets need not necessarily come from this element's widget
4649/// verbatim. They could be generated dynamically from a callback, or generated
4650/// in other more creative ways.
4651///
4652/// #### Dynamically determining the children during layout
4653///
4654/// If the widgets are to be generated at layout time, then generating them when
4655/// the [update] method won't work: layout of this element's render object
4656/// hasn't started yet at that point. Instead, the [update] method can mark the
4657/// render object as needing layout (see [RenderObject.markNeedsLayout]), and
4658/// then the render object's [RenderObject.performLayout] method can call back
4659/// to the element to have it generate the widgets and call [updateChild]
4660/// accordingly.
4661///
4662/// For a render object to call an element during layout, it must use
4663/// [RenderObject.invokeLayoutCallback]. For an element to call [updateChild]
4664/// outside of its [update] method, it must use [BuildOwner.buildScope].
4665///
4666/// The framework provides many more checks in normal operation than it does
4667/// when doing a build during layout. For this reason, creating widgets with
4668/// layout-time build semantics should be done with great care.
4669///
4670/// #### Handling errors when building
4671///
4672/// If an element calls a builder function to obtain widgets for its children,
4673/// it may find that the build throws an exception. Such exceptions should be
4674/// caught and reported using [FlutterError.reportError]. If a child is needed
4675/// but a builder has failed in this way, an instance of [ErrorWidget] can be
4676/// used instead.
4677///
4678/// ### Detaching children
4679///
4680/// It is possible, when using [GlobalKey]s, for a child to be proactively
4681/// removed by another element before this element has been updated.
4682/// (Specifically, this happens when the subtree rooted at a widget with a
4683/// particular [GlobalKey] is being moved from this element to an element
4684/// processed earlier in the build phase.) When this happens, this element's
4685/// [forgetChild] method will be called with a reference to the affected child
4686/// element.
4687///
4688/// The [forgetChild] method of a [RenderObjectElement] subclass must remove the
4689/// child element from its child list, so that when it next [update]s its
4690/// children, the removed child is not considered.
4691///
4692/// For performance reasons, if there are many elements, it may be quicker to
4693/// track which elements were forgotten by storing them in a [Set], rather than
4694/// proactively mutating the local record of the child list and the identities
4695/// of all the slots. For example, see the implementation of
4696/// [MultiChildRenderObjectElement].
4697///
4698/// ### Maintaining the render object tree
4699///
4700/// Once a descendant produces a render object, it will call
4701/// [insertChildRenderObject]. If the descendant's slot changes identity, it
4702/// will call [moveChildRenderObject]. If a descendant goes away, it will call
4703/// [removeChildRenderObject].
4704///
4705/// These three methods should update the render tree accordingly, attaching,
4706/// moving, and detaching the given child render object from this element's own
4707/// render object respectively.
4708///
4709/// ### Walking the children
4710///
4711/// If a [RenderObjectElement] object has any children [Element]s, it must
4712/// expose them in its implementation of the [visitChildren] method. This method
4713/// is used by many of the framework's internal mechanisms, and so should be
4714/// fast. It is also used by the test framework and [debugDumpApp].
4715abstract class RenderObjectElement extends Element {
4716  /// Creates an element that uses the given widget as its configuration.
4717  RenderObjectElement(RenderObjectWidget widget) : super(widget);
4718
4719  @override
4720  RenderObjectWidget get widget => super.widget;
4721
4722  /// The underlying [RenderObject] for this element.
4723  @override
4724  RenderObject get renderObject => _renderObject;
4725  RenderObject _renderObject;
4726
4727  RenderObjectElement _ancestorRenderObjectElement;
4728
4729  RenderObjectElement _findAncestorRenderObjectElement() {
4730    Element ancestor = _parent;
4731    while (ancestor != null && ancestor is! RenderObjectElement)
4732      ancestor = ancestor._parent;
4733    return ancestor;
4734  }
4735
4736  ParentDataElement<RenderObjectWidget> _findAncestorParentDataElement() {
4737    Element ancestor = _parent;
4738    while (ancestor != null && ancestor is! RenderObjectElement) {
4739      if (ancestor is ParentDataElement<RenderObjectWidget>)
4740        return ancestor;
4741      ancestor = ancestor._parent;
4742    }
4743    return null;
4744  }
4745
4746  @override
4747  void mount(Element parent, dynamic newSlot) {
4748    super.mount(parent, newSlot);
4749    _renderObject = widget.createRenderObject(this);
4750    assert(() { _debugUpdateRenderObjectOwner(); return true; }());
4751    assert(_slot == newSlot);
4752    attachRenderObject(newSlot);
4753    _dirty = false;
4754  }
4755
4756  @override
4757  void update(covariant RenderObjectWidget newWidget) {
4758    super.update(newWidget);
4759    assert(widget == newWidget);
4760    assert(() { _debugUpdateRenderObjectOwner(); return true; }());
4761    widget.updateRenderObject(this, renderObject);
4762    _dirty = false;
4763  }
4764
4765  void _debugUpdateRenderObjectOwner() {
4766    assert(() {
4767      _renderObject.debugCreator = DebugCreator(this);
4768      return true;
4769    }());
4770  }
4771
4772  @override
4773  void performRebuild() {
4774    widget.updateRenderObject(this, renderObject);
4775    _dirty = false;
4776  }
4777
4778  /// Updates the children of this element to use new widgets.
4779  ///
4780  /// Attempts to update the given old children list using the given new
4781  /// widgets, removing obsolete elements and introducing new ones as necessary,
4782  /// and then returns the new child list.
4783  ///
4784  /// During this function the `oldChildren` list must not be modified. If the
4785  /// caller wishes to remove elements from `oldChildren` re-entrantly while
4786  /// this function is on the stack, the caller can supply a `forgottenChildren`
4787  /// argument, which can be modified while this function is on the stack.
4788  /// Whenever this function reads from `oldChildren`, this function first
4789  /// checks whether the child is in `forgottenChildren`. If it is, the function
4790  /// acts as if the child was not in `oldChildren`.
4791  ///
4792  /// This function is a convenience wrapper around [updateChild], which updates
4793  /// each individual child. When calling [updateChild], this function uses the
4794  /// previous element as the `newSlot` argument.
4795  @protected
4796  List<Element> updateChildren(List<Element> oldChildren, List<Widget> newWidgets, { Set<Element> forgottenChildren }) {
4797    assert(oldChildren != null);
4798    assert(newWidgets != null);
4799
4800    Element replaceWithNullIfForgotten(Element child) {
4801      return forgottenChildren != null && forgottenChildren.contains(child) ? null : child;
4802    }
4803
4804    // This attempts to diff the new child list (newWidgets) with
4805    // the old child list (oldChildren), and produce a new list of elements to
4806    // be the new list of child elements of this element. The called of this
4807    // method is expected to update this render object accordingly.
4808
4809    // The cases it tries to optimize for are:
4810    //  - the old list is empty
4811    //  - the lists are identical
4812    //  - there is an insertion or removal of one or more widgets in
4813    //    only one place in the list
4814    // If a widget with a key is in both lists, it will be synced.
4815    // Widgets without keys might be synced but there is no guarantee.
4816
4817    // The general approach is to sync the entire new list backwards, as follows:
4818    // 1. Walk the lists from the top, syncing nodes, until you no longer have
4819    //    matching nodes.
4820    // 2. Walk the lists from the bottom, without syncing nodes, until you no
4821    //    longer have matching nodes. We'll sync these nodes at the end. We
4822    //    don't sync them now because we want to sync all the nodes in order
4823    //    from beginning to end.
4824    // At this point we narrowed the old and new lists to the point
4825    // where the nodes no longer match.
4826    // 3. Walk the narrowed part of the old list to get the list of
4827    //    keys and sync null with non-keyed items.
4828    // 4. Walk the narrowed part of the new list forwards:
4829    //     * Sync non-keyed items with null
4830    //     * Sync keyed items with the source if it exists, else with null.
4831    // 5. Walk the bottom of the list again, syncing the nodes.
4832    // 6. Sync null with any items in the list of keys that are still
4833    //    mounted.
4834
4835    int newChildrenTop = 0;
4836    int oldChildrenTop = 0;
4837    int newChildrenBottom = newWidgets.length - 1;
4838    int oldChildrenBottom = oldChildren.length - 1;
4839
4840    final List<Element> newChildren = oldChildren.length == newWidgets.length ?
4841        oldChildren : List<Element>(newWidgets.length);
4842
4843    Element previousChild;
4844
4845    // Update the top of the list.
4846    while ((oldChildrenTop <= oldChildrenBottom) && (newChildrenTop <= newChildrenBottom)) {
4847      final Element oldChild = replaceWithNullIfForgotten(oldChildren[oldChildrenTop]);
4848      final Widget newWidget = newWidgets[newChildrenTop];
4849      assert(oldChild == null || oldChild._debugLifecycleState == _ElementLifecycle.active);
4850      if (oldChild == null || !Widget.canUpdate(oldChild.widget, newWidget))
4851        break;
4852      final Element newChild = updateChild(oldChild, newWidget, previousChild);
4853      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
4854      newChildren[newChildrenTop] = newChild;
4855      previousChild = newChild;
4856      newChildrenTop += 1;
4857      oldChildrenTop += 1;
4858    }
4859
4860    // Scan the bottom of the list.
4861    while ((oldChildrenTop <= oldChildrenBottom) && (newChildrenTop <= newChildrenBottom)) {
4862      final Element oldChild = replaceWithNullIfForgotten(oldChildren[oldChildrenBottom]);
4863      final Widget newWidget = newWidgets[newChildrenBottom];
4864      assert(oldChild == null || oldChild._debugLifecycleState == _ElementLifecycle.active);
4865      if (oldChild == null || !Widget.canUpdate(oldChild.widget, newWidget))
4866        break;
4867      oldChildrenBottom -= 1;
4868      newChildrenBottom -= 1;
4869    }
4870
4871    // Scan the old children in the middle of the list.
4872    final bool haveOldChildren = oldChildrenTop <= oldChildrenBottom;
4873    Map<Key, Element> oldKeyedChildren;
4874    if (haveOldChildren) {
4875      oldKeyedChildren = <Key, Element>{};
4876      while (oldChildrenTop <= oldChildrenBottom) {
4877        final Element oldChild = replaceWithNullIfForgotten(oldChildren[oldChildrenTop]);
4878        assert(oldChild == null || oldChild._debugLifecycleState == _ElementLifecycle.active);
4879        if (oldChild != null) {
4880          if (oldChild.widget.key != null)
4881            oldKeyedChildren[oldChild.widget.key] = oldChild;
4882          else
4883            deactivateChild(oldChild);
4884        }
4885        oldChildrenTop += 1;
4886      }
4887    }
4888
4889    // Update the middle of the list.
4890    while (newChildrenTop <= newChildrenBottom) {
4891      Element oldChild;
4892      final Widget newWidget = newWidgets[newChildrenTop];
4893      if (haveOldChildren) {
4894        final Key key = newWidget.key;
4895        if (key != null) {
4896          oldChild = oldKeyedChildren[key];
4897          if (oldChild != null) {
4898            if (Widget.canUpdate(oldChild.widget, newWidget)) {
4899              // we found a match!
4900              // remove it from oldKeyedChildren so we don't unsync it later
4901              oldKeyedChildren.remove(key);
4902            } else {
4903              // Not a match, let's pretend we didn't see it for now.
4904              oldChild = null;
4905            }
4906          }
4907        }
4908      }
4909      assert(oldChild == null || Widget.canUpdate(oldChild.widget, newWidget));
4910      final Element newChild = updateChild(oldChild, newWidget, previousChild);
4911      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
4912      assert(oldChild == newChild || oldChild == null || oldChild._debugLifecycleState != _ElementLifecycle.active);
4913      newChildren[newChildrenTop] = newChild;
4914      previousChild = newChild;
4915      newChildrenTop += 1;
4916    }
4917
4918    // We've scanned the whole list.
4919    assert(oldChildrenTop == oldChildrenBottom + 1);
4920    assert(newChildrenTop == newChildrenBottom + 1);
4921    assert(newWidgets.length - newChildrenTop == oldChildren.length - oldChildrenTop);
4922    newChildrenBottom = newWidgets.length - 1;
4923    oldChildrenBottom = oldChildren.length - 1;
4924
4925    // Update the bottom of the list.
4926    while ((oldChildrenTop <= oldChildrenBottom) && (newChildrenTop <= newChildrenBottom)) {
4927      final Element oldChild = oldChildren[oldChildrenTop];
4928      assert(replaceWithNullIfForgotten(oldChild) != null);
4929      assert(oldChild._debugLifecycleState == _ElementLifecycle.active);
4930      final Widget newWidget = newWidgets[newChildrenTop];
4931      assert(Widget.canUpdate(oldChild.widget, newWidget));
4932      final Element newChild = updateChild(oldChild, newWidget, previousChild);
4933      assert(newChild._debugLifecycleState == _ElementLifecycle.active);
4934      assert(oldChild == newChild || oldChild == null || oldChild._debugLifecycleState != _ElementLifecycle.active);
4935      newChildren[newChildrenTop] = newChild;
4936      previousChild = newChild;
4937      newChildrenTop += 1;
4938      oldChildrenTop += 1;
4939    }
4940
4941    // Clean up any of the remaining middle nodes from the old list.
4942    if (haveOldChildren && oldKeyedChildren.isNotEmpty) {
4943      for (Element oldChild in oldKeyedChildren.values) {
4944        if (forgottenChildren == null || !forgottenChildren.contains(oldChild))
4945          deactivateChild(oldChild);
4946      }
4947    }
4948
4949    return newChildren;
4950  }
4951
4952  @override
4953  void deactivate() {
4954    super.deactivate();
4955    assert(!renderObject.attached,
4956      'A RenderObject was still attached when attempting to deactivate its '
4957      'RenderObjectElement: $renderObject');
4958  }
4959
4960  @override
4961  void unmount() {
4962    super.unmount();
4963    assert(!renderObject.attached,
4964      'A RenderObject was still attached when attempting to unmount its '
4965      'RenderObjectElement: $renderObject');
4966    widget.didUnmountRenderObject(renderObject);
4967  }
4968
4969  void _updateParentData(ParentDataWidget<RenderObjectWidget> parentData) {
4970    parentData.applyParentData(renderObject);
4971  }
4972
4973  @override
4974  void _updateSlot(dynamic newSlot) {
4975    assert(slot != newSlot);
4976    super._updateSlot(newSlot);
4977    assert(slot == newSlot);
4978    _ancestorRenderObjectElement.moveChildRenderObject(renderObject, slot);
4979  }
4980
4981  @override
4982  void attachRenderObject(dynamic newSlot) {
4983    assert(_ancestorRenderObjectElement == null);
4984    _slot = newSlot;
4985    _ancestorRenderObjectElement = _findAncestorRenderObjectElement();
4986    _ancestorRenderObjectElement?.insertChildRenderObject(renderObject, newSlot);
4987    final ParentDataElement<RenderObjectWidget> parentDataElement = _findAncestorParentDataElement();
4988    if (parentDataElement != null)
4989      _updateParentData(parentDataElement.widget);
4990  }
4991
4992  @override
4993  void detachRenderObject() {
4994    if (_ancestorRenderObjectElement != null) {
4995      _ancestorRenderObjectElement.removeChildRenderObject(renderObject);
4996      _ancestorRenderObjectElement = null;
4997    }
4998    _slot = null;
4999  }
5000
5001  /// Insert the given child into [renderObject] at the given slot.
5002  ///
5003  /// The semantics of `slot` are determined by this element. For example, if
5004  /// this element has a single child, the slot should always be null. If this
5005  /// element has a list of children, the previous sibling is a convenient value
5006  /// for the slot.
5007  @protected
5008  void insertChildRenderObject(covariant RenderObject child, covariant dynamic slot);
5009
5010  /// Move the given child to the given slot.
5011  ///
5012  /// The given child is guaranteed to have [renderObject] as its parent.
5013  ///
5014  /// The semantics of `slot` are determined by this element. For example, if
5015  /// this element has a single child, the slot should always be null. If this
5016  /// element has a list of children, the previous sibling is a convenient value
5017  /// for the slot.
5018  @protected
5019  void moveChildRenderObject(covariant RenderObject child, covariant dynamic slot);
5020
5021  /// Remove the given child from [renderObject].
5022  ///
5023  /// The given child is guaranteed to have [renderObject] as its parent.
5024  @protected
5025  void removeChildRenderObject(covariant RenderObject child);
5026
5027  @override
5028  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5029    super.debugFillProperties(properties);
5030    properties.add(DiagnosticsProperty<RenderObject>('renderObject', renderObject, defaultValue: null));
5031  }
5032}
5033
5034/// The element at the root of the tree.
5035///
5036/// Only root elements may have their owner set explicitly. All other
5037/// elements inherit their owner from their parent.
5038abstract class RootRenderObjectElement extends RenderObjectElement {
5039  /// Initializes fields for subclasses.
5040  RootRenderObjectElement(RenderObjectWidget widget) : super(widget);
5041
5042  /// Set the owner of the element. The owner will be propagated to all the
5043  /// descendants of this element.
5044  ///
5045  /// The owner manages the dirty elements list.
5046  ///
5047  /// The [WidgetsBinding] introduces the primary owner,
5048  /// [WidgetsBinding.buildOwner], and assigns it to the widget tree in the call
5049  /// to [runApp]. The binding is responsible for driving the build pipeline by
5050  /// calling the build owner's [BuildOwner.buildScope] method. See
5051  /// [WidgetsBinding.drawFrame].
5052  void assignOwner(BuildOwner owner) {
5053    _owner = owner;
5054  }
5055
5056  @override
5057  void mount(Element parent, dynamic newSlot) {
5058    // Root elements should never have parents.
5059    assert(parent == null);
5060    assert(newSlot == null);
5061    super.mount(parent, newSlot);
5062  }
5063}
5064
5065/// An [Element] that uses a [LeafRenderObjectWidget] as its configuration.
5066class LeafRenderObjectElement extends RenderObjectElement {
5067  /// Creates an element that uses the given widget as its configuration.
5068  LeafRenderObjectElement(LeafRenderObjectWidget widget) : super(widget);
5069
5070  @override
5071  void forgetChild(Element child) {
5072    assert(false);
5073  }
5074
5075  @override
5076  void insertChildRenderObject(RenderObject child, dynamic slot) {
5077    assert(false);
5078  }
5079
5080  @override
5081  void moveChildRenderObject(RenderObject child, dynamic slot) {
5082    assert(false);
5083  }
5084
5085  @override
5086  void removeChildRenderObject(RenderObject child) {
5087    assert(false);
5088  }
5089
5090  @override
5091  List<DiagnosticsNode> debugDescribeChildren() {
5092    return widget.debugDescribeChildren();
5093  }
5094}
5095
5096/// An [Element] that uses a [SingleChildRenderObjectWidget] as its configuration.
5097///
5098/// The child is optional.
5099///
5100/// This element subclass can be used for RenderObjectWidgets whose
5101/// RenderObjects use the [RenderObjectWithChildMixin] mixin. Such widgets are
5102/// expected to inherit from [SingleChildRenderObjectWidget].
5103class SingleChildRenderObjectElement extends RenderObjectElement {
5104  /// Creates an element that uses the given widget as its configuration.
5105  SingleChildRenderObjectElement(SingleChildRenderObjectWidget widget) : super(widget);
5106
5107  @override
5108  SingleChildRenderObjectWidget get widget => super.widget;
5109
5110  Element _child;
5111
5112  @override
5113  void visitChildren(ElementVisitor visitor) {
5114    if (_child != null)
5115      visitor(_child);
5116  }
5117
5118  @override
5119  void forgetChild(Element child) {
5120    assert(child == _child);
5121    _child = null;
5122  }
5123
5124  @override
5125  void mount(Element parent, dynamic newSlot) {
5126    super.mount(parent, newSlot);
5127    _child = updateChild(_child, widget.child, null);
5128  }
5129
5130  @override
5131  void update(SingleChildRenderObjectWidget newWidget) {
5132    super.update(newWidget);
5133    assert(widget == newWidget);
5134    _child = updateChild(_child, widget.child, null);
5135  }
5136
5137  @override
5138  void insertChildRenderObject(RenderObject child, dynamic slot) {
5139    final RenderObjectWithChildMixin<RenderObject> renderObject = this.renderObject;
5140    assert(slot == null);
5141    assert(renderObject.debugValidateChild(child));
5142    renderObject.child = child;
5143    assert(renderObject == this.renderObject);
5144  }
5145
5146  @override
5147  void moveChildRenderObject(RenderObject child, dynamic slot) {
5148    assert(false);
5149  }
5150
5151  @override
5152  void removeChildRenderObject(RenderObject child) {
5153    final RenderObjectWithChildMixin<RenderObject> renderObject = this.renderObject;
5154    assert(renderObject.child == child);
5155    renderObject.child = null;
5156    assert(renderObject == this.renderObject);
5157  }
5158}
5159
5160/// An [Element] that uses a [MultiChildRenderObjectWidget] as its configuration.
5161///
5162/// This element subclass can be used for RenderObjectWidgets whose
5163/// RenderObjects use the [ContainerRenderObjectMixin] mixin with a parent data
5164/// type that implements [ContainerParentDataMixin<RenderObject>]. Such widgets
5165/// are expected to inherit from [MultiChildRenderObjectWidget].
5166class MultiChildRenderObjectElement extends RenderObjectElement {
5167  /// Creates an element that uses the given widget as its configuration.
5168  MultiChildRenderObjectElement(MultiChildRenderObjectWidget widget)
5169    : assert(!debugChildrenHaveDuplicateKeys(widget, widget.children)),
5170      super(widget);
5171
5172  @override
5173  MultiChildRenderObjectWidget get widget => super.widget;
5174
5175  /// The current list of children of this element.
5176  ///
5177  /// This list is filtered to hide elements that have been forgotten (using
5178  /// [forgetChild]).
5179  @protected
5180  @visibleForTesting
5181  Iterable<Element> get children => _children.where((Element child) => !_forgottenChildren.contains(child));
5182
5183  List<Element> _children;
5184  // We keep a set of forgotten children to avoid O(n^2) work walking _children
5185  // repeatedly to remove children.
5186  final Set<Element> _forgottenChildren = HashSet<Element>();
5187
5188  @override
5189  void insertChildRenderObject(RenderObject child, Element slot) {
5190    final ContainerRenderObjectMixin<RenderObject, ContainerParentDataMixin<RenderObject>> renderObject = this.renderObject;
5191    assert(renderObject.debugValidateChild(child));
5192    renderObject.insert(child, after: slot?.renderObject);
5193    assert(renderObject == this.renderObject);
5194  }
5195
5196  @override
5197  void moveChildRenderObject(RenderObject child, dynamic slot) {
5198    final ContainerRenderObjectMixin<RenderObject, ContainerParentDataMixin<RenderObject>> renderObject = this.renderObject;
5199    assert(child.parent == renderObject);
5200    renderObject.move(child, after: slot?.renderObject);
5201    assert(renderObject == this.renderObject);
5202  }
5203
5204  @override
5205  void removeChildRenderObject(RenderObject child) {
5206    final ContainerRenderObjectMixin<RenderObject, ContainerParentDataMixin<RenderObject>> renderObject = this.renderObject;
5207    assert(child.parent == renderObject);
5208    renderObject.remove(child);
5209    assert(renderObject == this.renderObject);
5210  }
5211
5212  @override
5213  void visitChildren(ElementVisitor visitor) {
5214    for (Element child in _children) {
5215      if (!_forgottenChildren.contains(child))
5216        visitor(child);
5217    }
5218  }
5219
5220  @override
5221  void forgetChild(Element child) {
5222    assert(_children.contains(child));
5223    assert(!_forgottenChildren.contains(child));
5224    _forgottenChildren.add(child);
5225  }
5226
5227  @override
5228  void mount(Element parent, dynamic newSlot) {
5229    super.mount(parent, newSlot);
5230    _children = List<Element>(widget.children.length);
5231    Element previousChild;
5232    for (int i = 0; i < _children.length; i += 1) {
5233      final Element newChild = inflateWidget(widget.children[i], previousChild);
5234      _children[i] = newChild;
5235      previousChild = newChild;
5236    }
5237  }
5238
5239  @override
5240  void update(MultiChildRenderObjectWidget newWidget) {
5241    super.update(newWidget);
5242    assert(widget == newWidget);
5243    _children = updateChildren(_children, widget.children, forgottenChildren: _forgottenChildren);
5244    _forgottenChildren.clear();
5245  }
5246}
5247
5248/// A wrapper class for the [Element] that is the creator of a [RenderObject].
5249///
5250/// Attaching a [DebugCreator] attach the [RenderObject] will lead to better error
5251/// message.
5252class DebugCreator {
5253  /// Create a [DebugCreator] instance with input [Element].
5254  DebugCreator(this.element);
5255
5256  /// The creator of the [RenderObject].
5257  final Element element;
5258
5259  @override
5260  String toString() => element.debugGetCreatorChain(12);
5261}
5262
5263FlutterErrorDetails _debugReportException(
5264  DiagnosticsNode context,
5265  dynamic exception,
5266  StackTrace stack, {
5267  InformationCollector informationCollector,
5268}) {
5269  final FlutterErrorDetails details = FlutterErrorDetails(
5270    exception: exception,
5271    stack: stack,
5272    library: 'widgets library',
5273    context: context,
5274    informationCollector: informationCollector,
5275  );
5276  FlutterError.reportError(details);
5277  return details;
5278}
5279