Silence a bunch of annoying bogus dartanalyzer warnings.

- several places where we use a getter knowing that it will return a
   subclass of its declared type, even asserting that it does, but
   where the analyzer is worried that the getter might start returning
   a new value unexpectedly, solved by having a temporary local
   variable shadow the getter and asserting that it doesn't change
   value
 - many many places where we do this with parentData specifically,
   solved by type-erasing parentData.
 - a place where a mixin wants to be subclassing another class, and
   uses its methods, solved by saying that the mixin is abstract but
   implements the superclass

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/1160923008
This commit is contained in:
Hixie 2015-06-05 09:44:09 -07:00
parent 9ea7ac504c
commit 3cf7368d97
2 changed files with 21 additions and 3 deletions

View File

@ -336,13 +336,19 @@ abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
}
void insert(RenderObjectWrapper child, dynamic slot) {
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
assert(slot == null);
assert(root is RenderObjectWithChildMixin);
root.child = child.root;
assert(root == this.root); // TODO(ianh): Remove this once the analyzer is cleverer
}
void removeChild(UINode node) {
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
assert(root is RenderObjectWithChildMixin);
root.child = null;
super.removeChild(node);
assert(root == this.root); // TODO(ianh): Remove this once the analyzer is cleverer
}
void remove() {
@ -482,15 +488,19 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
}
void insert(RenderObjectWrapper child, dynamic slot) {
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
assert(slot == null || slot is RenderObject);
assert(root is ContainerRenderObjectMixin);
root.add(child.root, before: slot);
assert(root == this.root); // TODO(ianh): Remove this once the analyzer is cleverer
}
void removeChild(UINode node) {
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
assert(root is ContainerRenderObjectMixin);
root.remove(node.root);
super.removeChild(node);
assert(root == this.root); // TODO(ianh): Remove this once the analyzer is cleverer
}
void remove() {
@ -521,6 +531,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
void syncRenderObject(MultiChildRenderObjectWrapper old) {
super.syncRenderObject(old);
final root = this.root; // TODO(ianh): Remove this once the analyzer is cleverer
if (root is! ContainerRenderObjectMixin)
return;
@ -597,7 +608,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
assert(old.root is ContainerRenderObjectMixin);
assert(oldNode.root != null);
old.root.remove(oldNode.root);
(old.root as ContainerRenderObjectMixin).remove(oldNode.root); // TODO(ianh): Remove cast once the analyzer is cleverer
root.add(oldNode.root, before: nextSibling);
return true;
@ -639,6 +650,8 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
removeChild(oldNode);
advanceOldStartIndex();
}
assert(root == this.root); // TODO(ianh): Remove this once the analyzer is cleverer
}
}

View File

@ -44,7 +44,7 @@ abstract class RenderObject extends AbstractNode {
// parentData is only for use by the RenderObject that actually lays this
// node out, and any other nodes who happen to know exactly what
// kind of node that is.
ParentData parentData;
dynamic parentData; // TODO(ianh): change the type of this back to ParentData once the analyzer is cleverer
void setParentData(RenderObject child) {
// override this to setup .parentData correctly for your class
assert(!_debugDoingLayout);
@ -107,8 +107,10 @@ abstract class RenderObject extends AbstractNode {
_needsLayout = true;
assert(_relayoutSubtreeRoot != null);
if (_relayoutSubtreeRoot != this) {
final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer
assert(parent is RenderObject);
parent.markNeedsLayout();
assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer
} else {
_nodesNeedingLayout.add(this);
scheduler.ensureVisualUpdate();
@ -136,11 +138,13 @@ abstract class RenderObject extends AbstractNode {
_needsLayout = false;
}
void layout(dynamic constraints, { bool parentUsesSize: false }) {
final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer
RenderObject relayoutSubtreeRoot;
if (!parentUsesSize || sizedByParent || parent is! RenderObject)
relayoutSubtreeRoot = this;
else
relayoutSubtreeRoot = parent._relayoutSubtreeRoot;
assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer
if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _relayoutSubtreeRoot)
return;
_constraints = constraints;
@ -150,6 +154,7 @@ abstract class RenderObject extends AbstractNode {
performLayout();
_needsLayout = false;
markNeedsPaint();
assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer
}
bool get sizedByParent => false; // return true if the constraints are the only input to the sizing algorithm (in particular, child nodes have no impact)
void performResize(); // set the local dimensions, using only the constraints (only called if sizedByParent is true)
@ -257,7 +262,7 @@ class HitTestResult {
// GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD
abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> {
abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> implements RenderObject {
ChildType _child;
ChildType get child => _child;
void set child (ChildType value) {