diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart index 04b130cb7d..279ddcbae6 100644 --- a/packages/flutter/lib/src/rendering/layer.dart +++ b/packages/flutter/lib/src/rendering/layer.dart @@ -52,6 +52,13 @@ abstract class Layer { newLayer._previousSibling = _previousSibling; if (_previousSibling != null) newLayer._previousSibling._nextSibling = newLayer; + assert(() { + Layer node = this; + while (node.parent != null) + node = node.parent; + assert(node != newLayer); // indicates we are about to create a cycle + return true; + }); newLayer._parent = _parent; if (_parent._firstChild == this) _parent._firstChild = newLayer; @@ -182,6 +189,13 @@ class ContainerLayer extends Layer { assert(child._parent == null); assert(child._nextSibling == null); assert(child._previousSibling == null); + assert(() { + Layer node = this; + while (node.parent != null) + node = node.parent; + assert(node != child); // indicates we are about to create a cycle + return true; + }); child._parent = this; child._previousSibling = _lastChild; if (_lastChild != null) diff --git a/packages/flutter/lib/src/rendering/node.dart b/packages/flutter/lib/src/rendering/node.dart index fb989de505..552fba1e58 100644 --- a/packages/flutter/lib/src/rendering/node.dart +++ b/packages/flutter/lib/src/rendering/node.dart @@ -90,6 +90,13 @@ class AbstractNode { void adoptChild(AbstractNode child) { assert(child != null); assert(child._parent == null); + assert(() { + AbstractNode node = this; + while (node.parent != null) + node = node.parent; + assert(node != child); // indicates we are about to create a cycle + return true; + }); child._parent = this; if (attached) child.attach(); diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 62496dfb9b..df4628c40a 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -773,6 +773,7 @@ abstract class Element implements BuildContext { Element newChild = _findAndActivateElement(key, newWidget); if (newChild != null) { assert(newChild._parent == null); + assert(() { _debugCheckForCycles(newChild); return true; }); newChild._parent = this; newChild._updateDepth(); newChild.attachRenderObject(newSlot); @@ -782,11 +783,23 @@ abstract class Element implements BuildContext { } } Element newChild = newWidget.createElement(); + assert(() { _debugCheckForCycles(newChild); return true; }); newChild.mount(this, newSlot); assert(newChild._debugLifecycleState == _ElementLifecycle.active); return newChild; } + void _debugCheckForCycles(Element newChild) { + assert(newChild._parent == null); + assert(() { + Element node = this; + while (node._parent != null) + node = node._parent; + assert(node != newChild); // indicates we are about to create a cycle + return true; + }); + } + void _deactivateChild(Element child) { assert(child != null); assert(child._parent == this); diff --git a/packages/flutter_sprites/lib/src/node.dart b/packages/flutter_sprites/lib/src/node.dart index 54dae3d672..38052e1ff0 100644 --- a/packages/flutter_sprites/lib/src/node.dart +++ b/packages/flutter_sprites/lib/src/node.dart @@ -403,6 +403,14 @@ class Node { assert(child._parent == null); assert(!(child is PhysicsGroup) || this is PhysicsGroup || this is PhysicsWorld); + assert(() { + Node node = this; + while (node.parent != null) + node = node.parent; + assert(node != child); // indicates we are about to create a cycle + return true; + }); + _childrenNeedSorting = true; _children.add(child); child._parent = this;