|
|
|
|
|
|
error = new UIWidgetsError(new List<DiagnosticsNode>{ |
|
|
|
new ErrorSummary("Multiple widgets used the same GlobalKey."), |
|
|
|
new ErrorDescription( |
|
|
|
"The key $key was used by multiple widgets. The parents of those widgets were " + |
|
|
|
$"The key {key} was used by multiple widgets. The parents of those widgets were " + |
|
|
|
" ${parent.toString()}\n" + |
|
|
|
$" {parent.toString()}\n" + |
|
|
|
"A GlobalKey can only be specified on one widget at a time in the widget tree." |
|
|
|
) |
|
|
|
}); |
|
|
|
|
|
|
D.assert(element.widget.key != null); |
|
|
|
GlobalKey key = (GlobalKey) element.widget.key; |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, key); |
|
|
|
|
|
|
|
|
|
|
|
duplicates = duplicates ?? new Dictionary<GlobalKey, HashSet<Element>>(); |
|
|
|
var elements = duplicates.putIfAbsent(key, () => new HashSet<Element>()); |
|
|
|
elements.Add(element); |
|
|
|
|
|
|
public abstract Element createElement(); |
|
|
|
|
|
|
|
public override string toStringShort() { |
|
|
|
return key == null ? GetType().ToString() : GetType() + "-" + key; |
|
|
|
return key == null ? GetType().ToString() : $"{GetType()}-{key}"; |
|
|
|
} |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
|
|
|
public virtual void didUpdateWidget(StatefulWidget oldWidget) { |
|
|
|
} |
|
|
|
|
|
|
|
public virtual void reassemble() { |
|
|
|
} |
|
|
|
|
|
|
|
public void setState(VoidCallback fn = null) { |
|
|
|
D.assert(() => { |
|
|
|
if (_debugLifecycleState == _StateLifecycle.defunct) { |
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (fn != null) { |
|
|
|
fn(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
D.assert(!children.Any(child => child == null)); |
|
|
|
this.children = children; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
public delegate bool ElementVisitorBool(Element element); |
|
|
|
|
|
|
|
public interface BuildContext { |
|
|
|
bool debugDoingBuild { get; } |
|
|
|
|
|
|
|
|
|
|
|
bool debugDoingBuild { get; } |
|
|
|
|
|
|
|
RenderObject findRenderObject(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
State rootAncestorStateOfType(TypeMatcher matcher); |
|
|
|
|
|
|
|
T findRootAncestorStateOfType<T>() where T: State ;//: State<StatefulWidget>;
|
|
|
|
T findRootAncestorStateOfType<T>() where T: State; |
|
|
|
|
|
|
|
RenderObject ancestorRenderObjectOfType(TypeMatcher matcher); |
|
|
|
|
|
|
|
|
|
|
D.assert(element.owner == this); |
|
|
|
D.assert(() => { |
|
|
|
if (WidgetsD.debugPrintScheduleBuildForStacks) { |
|
|
|
Debug.Log("scheduleBuildFor() called for " + element + |
|
|
|
Debug.LogFormat("scheduleBuildFor() called for {0} {1}", element, |
|
|
|
(_dirtyElements.Contains(element) ? " (ALREADY IN LIST)" : "")); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
"calling scheduleBuildFor()."), |
|
|
|
new ErrorHint( |
|
|
|
"If you did not attempt to call scheduleBuildFor() yourself, then this probably " + |
|
|
|
"indicates a bug in the widgets framework. Please report it:\n" + |
|
|
|
" https://github.com/flutter/flutter/issues/new?template=BUG.md" |
|
|
|
"indicates a bug in the widgets framework." |
|
|
|
), |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int _debugStateLockLevel = 0; |
|
|
|
|
|
|
|
internal bool _debugStateLocked { |
|
|
|
get { return _debugStateLockLevel > 0; } |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
bool _debugBuilding = false; |
|
|
|
|
|
|
|
internal Element _debugCurrentBuildTarget; |
|
|
|
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
IEnumerable<DiagnosticsNode> infoCollector() { |
|
|
|
//yield return new DiagnosticsDebugCreator(new DebugCreator(_dirtyElements[index]));
|
|
|
|
yield return new DiagnosticsDebugCreator(new DebugCreator(_dirtyElements[index])); |
|
|
|
"while rebuilding dirty elements", ex, |
|
|
|
new ErrorDescription("while rebuilding dirty elements"), |
|
|
|
ex, |
|
|
|
informationCollector: infoCollector |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal void _debugElementWasRebuilt(Element node) { |
|
|
|
if (_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans != null) { |
|
|
|
_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans.Remove(node); |
|
|
|
} |
|
|
|
_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans?.Remove(node); |
|
|
|
} |
|
|
|
|
|
|
|
public void finalizeTree() { |
|
|
|
|
|
|
|
|
|
|
D.assert(keyLabels.isNotEmpty()); |
|
|
|
|
|
|
|
string the = keys.Count == 1 ? " the" : ""; |
|
|
|
string s = keys.Count == 1 ? "" : "s"; |
|
|
|
string were = keys.Count == 1 ? "was" : "were"; |
|
|
|
string their = keys.Count == 1 ? "its" : "their"; |
|
|
|
string respective = elementLabels.Count == 1 ? "" : " respective"; |
|
|
|
string those = keys.Count == 1 ? "that" : "those"; |
|
|
|
string s2 = elementLabels.Count == 1 ? "" : "s"; |
|
|
|
string those2 = elementLabels.Count == 1 ? "that" : "those"; |
|
|
|
string they = elementLabels.Count == 1 ? "it" : "they"; |
|
|
|
string think = elementLabels.Count == 1 ? "thinks" : "think"; |
|
|
|
string are = elementLabels.Count == 1 ? "is" : "are"; |
|
|
|
|
|
|
|
"The following GlobalKeys were specified multiple times in the widget tree. This will lead to " + |
|
|
|
$"The following GlobalKey{s} {were} specified multiple times in the widget tree. This will lead to " + |
|
|
|
"the previous instance is moved to the new location. The keys were:\n" + "- " + |
|
|
|
$"the previous instance is moved to the new location. The key{s} {were}:\n" + "- " + |
|
|
|
"This was determined by noticing that after$the widgets with the above global keys were moved " + |
|
|
|
"out of their respective previous parent, those previous parents never updated during this frame, meaning " + |
|
|
|
"that they either did not update at all or updated before the widgets were moved, in either case " + |
|
|
|
"implying that they still think that they should have a child with those global keys.\n" + |
|
|
|
"The specific parent that did not update after having one or more children forcibly removed " + |
|
|
|
"due to GlobalKey reparenting are:\n" + |
|
|
|
$"This was determined by noticing that after {the} widget{s} with the above global key{s} {were} moved " + |
|
|
|
$"out of {their} {respective} previous parent{s2}, {those2} previous parent{s2} never updated during this frame, meaning " + |
|
|
|
$"that {they} either did not update at all or updated before the widget{s} {were} moved, in either case " + |
|
|
|
$"implying that {they} still {think} that {they} should have a child with {those} global key{s}.\n" + |
|
|
|
$"The specific parent{s2} that did not update after having one or more children forcibly removed " + |
|
|
|
$"due to GlobalKey reparenting {are}:\n" + |
|
|
|
), |
|
|
|
) |
|
|
|
if (_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans != null) { |
|
|
|
_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans.Clear(); |
|
|
|
} |
|
|
|
_debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans?.Clear(); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
WidgetsD._debugReportException("while finalizing the widget tree", ex); |
|
|
|
WidgetsD._debugReportException(new ErrorSummary("while finalizing the widget tree"), ex); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void reassemble(Element root) { |
|
|
|
try { |
|
|
|
D.assert(root._parent == null); |
|
|
|
D.assert(root.owner == this); |
|
|
|
root.reassemble(); |
|
|
|
} |
|
|
|
finally { |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal Widget _widget; |
|
|
|
|
|
|
|
public virtual bool debugDoingBuild { get; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal BuildOwner _owner; |
|
|
|
|
|
|
|
public BuildOwner owner { |
|
|
|
|
|
|
public bool _active = false; |
|
|
|
|
|
|
|
public virtual void reassemble() { |
|
|
|
markNeedsBuild(); |
|
|
|
visitChildren((Element child) => { |
|
|
|
child.reassemble(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
public virtual bool debugDoingBuild { get; } |
|
|
|
|
|
|
|
internal bool _debugIsInScope(Element target) { |
|
|
|
Element current = this; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
protected virtual Element updateChild(Element child, Widget newWidget, object newSlot) { |
|
|
|
/*D.assert(() => { |
|
|
|
if (newWidget != null && newWidget.key is GlobalKey) { |
|
|
|
GlobalKey key = (GlobalKey) newWidget.key; |
|
|
|
key._debugReserveFor(this); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
});*/ |
|
|
|
|
|
|
|
if (child != null) |
|
|
|
if (child != null) { |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
if (hasSameSuperclass && child.widget == newWidget) { |
|
|
|
if (child.slot != newSlot) |
|
|
|
if (child.slot != newSlot) { |
|
|
|
} |
|
|
|
|
|
|
|
if (child.slot != newSlot) |
|
|
|
if (child.slot != newSlot) { |
|
|
|
} |
|
|
|
|
|
|
|
child.update(newWidget); |
|
|
|
D.assert(child.widget == newWidget); |
|
|
|
D.assert(() => { |
|
|
|
|
|
|
bool hadDependencies = (_dependencies != null && _dependencies.isNotEmpty()) || |
|
|
|
_hadUnsatisfiedDependencies; |
|
|
|
_active = true; |
|
|
|
if (_dependencies != null) { |
|
|
|
_dependencies.Clear(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_dependencies?.Clear(); |
|
|
|
_hadUnsatisfiedDependencies = false; |
|
|
|
_updateInheritance(); |
|
|
|
D.assert(() => { |
|
|
|
|
|
|
new ErrorHint( |
|
|
|
"If you need some sizing information during build to decide which " + |
|
|
|
"widgets to build, consider using a LayoutBuilder widget, which can " + |
|
|
|
"tell you the layout constraints at a given location in the tree. See " + |
|
|
|
"<https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html> " + |
|
|
|
"for more details." |
|
|
|
"tell you the layout constraints at a given location in the tree." |
|
|
|
), |
|
|
|
new ErrorSpacer(), |
|
|
|
describeElement("The size getter was called for the following element"), |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public virtual InheritedWidget inheritFromElement(InheritedElement ancestor, object aspect = null) { |
|
|
|
D.assert(ancestor != null); |
|
|
|
_dependencies = _dependencies ?? new HashSet<InheritedElement>(); |
|
|
|
_dependencies.Add(ancestor); |
|
|
|
ancestor.updateDependencies(this, aspect); |
|
|
|
return ancestor.widget; |
|
|
|
return dependOnInheritedElement(ancestor, aspect: aspect); |
|
|
|
} |
|
|
|
|
|
|
|
public virtual InheritedWidget dependOnInheritedElement(InheritedElement ancestor, object aspect = null) { |
|
|
|
|
|
|
|
|
|
|
internal virtual void _updateInheritance() { |
|
|
|
D.assert(_active); |
|
|
|
_inheritedWidgets = _parent == null ? null : _parent._inheritedWidgets; |
|
|
|
_inheritedWidgets = _parent?._inheritedWidgets; |
|
|
|
} |
|
|
|
|
|
|
|
public virtual Widget ancestorWidgetOfExactType(Type targetType) { |
|
|
|
|
|
|
ancestor = ancestor._parent; |
|
|
|
} |
|
|
|
|
|
|
|
return ancestor == null ? null : ancestor.widget; |
|
|
|
return ancestor?.widget; |
|
|
|
while (ancestor != null && ancestor.widget.GetType() != typeof(T)) |
|
|
|
while (ancestor != null && ancestor.widget.GetType() != typeof(T)) { |
|
|
|
} |
|
|
|
|
|
|
|
return ancestor?.widget as T; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var statefulAncestor = ancestor as StatefulElement; |
|
|
|
return statefulAncestor == null ? null : statefulAncestor.state; |
|
|
|
return statefulAncestor?.state; |
|
|
|
} |
|
|
|
|
|
|
|
public T findAncestorStateOfType<T>() where T : State{ |
|
|
|
|
|
|
if (ancestor is StatefulElement stateAncestor && stateAncestor.state is T) |
|
|
|
if (ancestor is StatefulElement stateAncestor && stateAncestor.state is T) { |
|
|
|
} |
|
|
|
|
|
|
|
ancestor = ancestor._parent; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
ancestor = ancestor._parent; |
|
|
|
} |
|
|
|
|
|
|
|
return statefulAncestor == null ? null : statefulAncestor.state; |
|
|
|
return statefulAncestor?.state; |
|
|
|
public T findRootAncestorStateOfType<T>() where T : State{//<StatefulWidget> {
|
|
|
|
public T findRootAncestorStateOfType<T>() where T : State { |
|
|
|
if (ancestor is StatefulElement stateAncestor && stateAncestor.state is T) |
|
|
|
if (ancestor is StatefulElement stateAncestor && stateAncestor.state is T) { |
|
|
|
} |
|
|
|
|
|
|
|
ancestor = ancestor._parent; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
D.assert(_debugCheckStateIsActiveForAncestorLookup()); |
|
|
|
Element ancestor = _parent; |
|
|
|
while (ancestor != null) { |
|
|
|
if (ancestor is RenderObjectElement && ancestor.renderObject is T) |
|
|
|
if (ancestor is RenderObjectElement && ancestor.renderObject is T) { |
|
|
|
} |
|
|
|
|
|
|
|
ancestor = ancestor._parent; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public List<Element> debugGetDiagnosticChain() { |
|
|
|
var chain = new List<Element>(); |
|
|
|
var chain = new List<Element>() {this}; |
|
|
|
Element node = _parent; |
|
|
|
while (node != null) { |
|
|
|
chain.Add(node); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!_debugAllowIgnoredCallsToMarkNeedsBuild) { |
|
|
|
throw new UIWidgetsError( |
|
|
|
new List<DiagnosticsNode>(){ |
|
|
|
List<DiagnosticsNode> information = new List<DiagnosticsNode>() { |
|
|
|
new ErrorSummary("setState() or markNeedsBuild() called during build.\n"), |
|
|
|
new ErrorDescription("This " + widget.GetType() + |
|
|
|
" widget cannot be marked as needing to build because the framework " + |
|
|
|
|
|
|
"builds parent widgets before children, which means a dirty descendant " + |
|
|
|
"will always be built. Otherwise, the framework might not visit this " + |
|
|
|
"widget during this build phase.\n" + |
|
|
|
"The widget on which setState() or markNeedsBuild() was called was:\n" + |
|
|
|
" " + this + "\n" + |
|
|
|
(owner._debugCurrentBuildTarget == null |
|
|
|
? "" |
|
|
|
: "The widget which was currently being built when the offending call was made was:\n " + |
|
|
|
owner._debugCurrentBuildTarget)) |
|
|
|
|
|
|
|
} |
|
|
|
"widget during this build phase.\n"), |
|
|
|
describeElement("The widget on which setState() or markNeedsBuild() was called was") |
|
|
|
}; |
|
|
|
if (owner._debugCurrentBuildTarget != null) { |
|
|
|
information.Add(owner._debugCurrentBuildTarget.describeWidget("The widget which was currently being built when the offending call was made was")); |
|
|
|
} |
|
|
|
throw new UIWidgetsError( |
|
|
|
information |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
D.assert(() => { |
|
|
|
|
|
|
|
if (WidgetsD.debugPrintRebuildDirtyWidgets) { |
|
|
|
if (!_debugBuiltOnce) { |
|
|
|
Debug.Log("Building " + this); |
|
|
|
|
|
|
protected abstract void performRebuild(); |
|
|
|
} |
|
|
|
|
|
|
|
public delegate Widget ErrorWidgetBuilder(UIWidgetsErrorDetails details); |
|
|
|
|
|
|
|
internal class _ElementDiagnosticableTreeNode : DiagnosticableTreeNode { |
|
|
|
internal _ElementDiagnosticableTreeNode( |
|
|
|
Element value, |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
readonly bool stateful; |
|
|
|
|
|
|
|
/*public override Dictionary<string, object> toJsonMap() { |
|
|
|
Dictionary<string, object> json = base.toJsonMap(); |
|
|
|
Element element = value as Element; |
|
|
|
json["widgetRuntimeType"] = element.widget?.GetType()?.ToString(); |
|
|
|
json["stateful"] = stateful; |
|
|
|
return json; |
|
|
|
}*/ |
|
|
|
|
|
|
|
public override Dictionary<string, object> toJsonMap(DiagnosticsSerializationDelegate Delegate) { |
|
|
|
Dictionary<string, object> json = base.toJsonMap(Delegate); |
|
|
|
Element element = value as Element; |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public delegate Widget ErrorWidgetBuilder(UIWidgetsErrorDetails details); |
|
|
|
|
|
|
|
public class ErrorWidget : LeafRenderObjectWidget { |
|
|
|
public ErrorWidget(Exception exception, string message = null) : base(key: new UniqueKey()) { |
|
|
|
|
|
|
return new ErrorWidget(error, message); |
|
|
|
} |
|
|
|
|
|
|
|
public static ErrorWidgetBuilder builder = (details) => new ErrorWidget(details.exception); |
|
|
|
public static ErrorWidgetBuilder builder = _defaultErrorWidgetBuilder; |
|
|
|
|
|
|
|
static Widget _defaultErrorWidgetBuilder(UIWidgetsErrorDetails details) { |
|
|
|
string message = ""; |
|
|
|
|
|
|
} |
|
|
|
catch (Exception e) { |
|
|
|
_debugDoingBuild = false; |
|
|
|
built = ErrorWidget.builder(WidgetsD._debugReportException("building " + this, e)); |
|
|
|
|
|
|
|
IEnumerable<DiagnosticsNode> informationCollector() { |
|
|
|
yield return new DiagnosticsDebugCreator(new DebugCreator(this)); |
|
|
|
} |
|
|
|
built = ErrorWidget.builder(WidgetsD._debugReportException("building " + this, e, informationCollector)); |
|
|
|
} |
|
|
|
finally { |
|
|
|
_dirty = false; |
|
|
|
|
|
|
D.assert(_child != null); |
|
|
|
} |
|
|
|
catch (Exception e) { |
|
|
|
built = ErrorWidget.builder(WidgetsD._debugReportException("building " + this, e)); |
|
|
|
IEnumerable<DiagnosticsNode> informationCollector() { |
|
|
|
yield return new DiagnosticsDebugCreator(new DebugCreator(this)); |
|
|
|
} |
|
|
|
built = ErrorWidget.builder(WidgetsD._debugReportException("building " + this, e, informationCollector)); |
|
|
|
_child = updateChild(null, built, slot); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
}); |
|
|
|
D.assert(_state._element == null); |
|
|
|
_state._element = this; |
|
|
|
D.assert(_state._widget == null); |
|
|
|
D.assert(_state._widget == null, () => $"The createState function for {widget} returned an old or invalid state " + |
|
|
|
$"instance: {_state._widget}, which is not null, violating the contract " + |
|
|
|
"for createState."); |
|
|
|
protected override Widget build() { |
|
|
|
return _state.build(this); |
|
|
|
} |
|
|
|
|
|
|
|
protected override Widget build() { |
|
|
|
return _state.build(this); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void reassemble() { |
|
|
|
state.reassemble(); |
|
|
|
base.reassemble(); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void _firstBuild() { |
|
|
|
D.assert(_state._debugLifecycleState == _StateLifecycle.created); |
|
|
|
|
|
|
internal readonly Dictionary<Element, object> _dependents = new Dictionary<Element, object>(); |
|
|
|
|
|
|
|
internal override void _updateInheritance() { |
|
|
|
Dictionary<Type, InheritedElement> incomingWidgets = |
|
|
|
_parent == null ? null : _parent._inheritedWidgets; |
|
|
|
D.assert(_active); |
|
|
|
Dictionary<Type, InheritedElement> incomingWidgets = _parent?._inheritedWidgets; |
|
|
|
|
|
|
|
if (incomingWidgets != null) { |
|
|
|
_inheritedWidgets = new Dictionary<Type, InheritedElement>(incomingWidgets); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
RenderObject _renderObject; |
|
|
|
|
|
|
|
public override RenderObject renderObject { |
|
|
|
get { return _renderObject; } |
|
|
|
} |
|
|
|
|
|
|
|
bool _debugDoingBuild = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override RenderObject renderObject { |
|
|
|
get { return _renderObject; } |
|
|
|
} |
|
|
|
|
|
|
|
RenderObjectElement _ancestorRenderObjectElement; |
|
|
|
|
|
|
|
RenderObjectElement _findAncestorRenderObjectElement() { |
|
|
|
|
|
|
ParentDataElement _findAncestorParentDataElement() { |
|
|
|
Element ancestor = _parent; |
|
|
|
ParentDataElement result = null; |
|
|
|
//ParentData>
|
|
|
|
while (ancestor != null && !(ancestor is RenderObjectElement)) { |
|
|
|
if (ancestor is ParentDataElement parentDataElement) { |
|
|
|
result = parentDataElement; |
|
|
|
|
|
|
if (result == null || ancestor == null) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
// Check that no other ParentDataWidgets want to provide parent data.
|
|
|
|
|
|
|
|
List<ParentDataElement> badAncestors = new List<ParentDataElement>(); |
|
|
|
ancestor = ancestor._parent; |
|
|
|
while (ancestor != null && !(ancestor is RenderObjectElement)) { |
|
|
|
|
|
|
badAncestors.Insert(0, result); |
|
|
|
try { |
|
|
|
List<ErrorDescription> errors = new List<ErrorDescription>(); |
|
|
|
foreach (ParentDataElement<ParentData> parentDataElement in badAncestors) |
|
|
|
foreach (ParentDataElement<ParentData> parentDataElement in badAncestors) { |
|
|
|
} |
|
|
|
|
|
|
|
List<DiagnosticsNode> results = new List<DiagnosticsNode>(); |
|
|
|
results.Add( new ErrorSummary("Incorrect use of ParentDataWidget.")); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Update the middle of the list.
|
|
|
|
while (newChildrenTop <= newChildrenBottom) { |
|
|
|
Element oldChild = null; |
|
|
|
Widget newWidget = newWidgets[newChildrenTop]; |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
catch (UIWidgetsError e) { |
|
|
|
UIWidgetsError.reportError(new UIWidgetsErrorDetails( |
|
|
|
context: new ErrorDescription("while apply parent data"), |
|
|
|
exception: e |
|
|
|
)); |
|
|
|
WidgetsD._debugReportException(new ErrorSummary("while apply parent data"), e); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
D.assert(_ancestorRenderObjectElement == null); |
|
|
|
_slot = newSlot; |
|
|
|
_ancestorRenderObjectElement = _findAncestorRenderObjectElement(); |
|
|
|
if (_ancestorRenderObjectElement != null) { |
|
|
|
_ancestorRenderObjectElement.insertChildRenderObject(renderObject, newSlot); |
|
|
|
} |
|
|
|
_ancestorRenderObjectElement?.insertChildRenderObject(renderObject, newSlot); |
|
|
|
|
|
|
|
ParentDataElement parentDataElement = _findAncestorParentDataElement(); |
|
|
|
if (parentDataElement != null) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public class DebugCreator { |
|
|
|
public DebugCreator(RenderObjectElement element) { |
|
|
|
public DebugCreator(Element element) { |
|
|
|
public readonly RenderObjectElement element; |
|
|
|
public readonly Element element; |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
return element.debugGetCreatorChain(12); |
|
|
|