mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Merge pull request #1637 from Hixie/asserts
Improve exceptions and asserts for rendering lib.
This commit is contained in:
commit
cb9152ca79
@ -79,16 +79,16 @@ abstract class RenderSector extends RenderObject {
|
||||
}
|
||||
|
||||
SectorConstraints get constraints => super.constraints;
|
||||
bool debugDoesMeetConstraints() {
|
||||
void debugAssertDoesMeetConstraints() {
|
||||
assert(constraints != null);
|
||||
assert(deltaRadius != null);
|
||||
assert(deltaRadius < double.INFINITY);
|
||||
assert(deltaTheta != null);
|
||||
assert(deltaTheta < double.INFINITY);
|
||||
return constraints.minDeltaRadius <= deltaRadius &&
|
||||
deltaRadius <= math.max(constraints.minDeltaRadius, constraints.maxDeltaRadius) &&
|
||||
constraints.minDeltaTheta <= deltaTheta &&
|
||||
deltaTheta <= math.max(constraints.minDeltaTheta, constraints.maxDeltaTheta);
|
||||
assert(constraints.minDeltaRadius <= deltaRadius);
|
||||
assert(deltaRadius <= math.max(constraints.minDeltaRadius, constraints.maxDeltaRadius));
|
||||
assert(constraints.minDeltaTheta <= deltaTheta);
|
||||
assert(deltaTheta <= math.max(constraints.minDeltaTheta, constraints.maxDeltaTheta));
|
||||
}
|
||||
void performResize() {
|
||||
// default behaviour for subclasses that have sizedByParent = true
|
||||
|
||||
@ -350,8 +350,9 @@ class RenderBlockViewport extends RenderBlockBase {
|
||||
double result;
|
||||
if (intrinsicCallback == null) {
|
||||
assert(() {
|
||||
'RenderBlockViewport does not support returning intrinsic dimensions if the relevant callbacks have not been specified.';
|
||||
return RenderObject.debugInDebugDoesMeetConstraints;
|
||||
if (!RenderObject.debugCheckingIntrinsics)
|
||||
throw new UnsupportedError('$runtimeType does not support returning intrinsic dimensions if the relevant callbacks have not been specified.');
|
||||
return true;
|
||||
});
|
||||
return constrainer(0.0);
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ class BoxConstraints extends Constraints {
|
||||
/// Returns new box constraints that are smaller by the given edge dimensions.
|
||||
BoxConstraints deflate(EdgeDims edges) {
|
||||
assert(edges != null);
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
double horizontal = edges.left + edges.right;
|
||||
double vertical = edges.top + edges.bottom;
|
||||
double deflatedMinWidth = math.max(0.0, minWidth - horizontal);
|
||||
@ -113,7 +113,7 @@ class BoxConstraints extends Constraints {
|
||||
|
||||
/// Returns new box constraints that remove the minimum width and height requirements.
|
||||
BoxConstraints loosen() {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
return new BoxConstraints(
|
||||
minWidth: 0.0,
|
||||
maxWidth: maxWidth,
|
||||
@ -154,14 +154,14 @@ class BoxConstraints extends Constraints {
|
||||
/// Returns the width that both satisfies the constraints and is as close as
|
||||
/// possible to the given width.
|
||||
double constrainWidth([double width = double.INFINITY]) {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
return width.clamp(minWidth, maxWidth);
|
||||
}
|
||||
|
||||
/// Returns the height that both satisfies the constraints and is as close as
|
||||
/// possible to the given height.
|
||||
double constrainHeight([double height = double.INFINITY]) {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
return height.clamp(minHeight, maxHeight);
|
||||
}
|
||||
|
||||
@ -192,9 +192,15 @@ class BoxConstraints extends Constraints {
|
||||
/// Whether there is exactly one size that satifies the constraints.
|
||||
bool get isTight => hasTightWidth && hasTightHeight;
|
||||
|
||||
/// Whether there is an upper bound on the maximum width.
|
||||
bool get hasBoundedWidth => maxWidth < double.INFINITY;
|
||||
|
||||
/// Whether there is an upper bound on the maximum height.
|
||||
bool get hasBoundedHeight => maxHeight < double.INFINITY;
|
||||
|
||||
/// Whether the given size satisfies the constraints.
|
||||
bool isSatisfiedBy(Size size) {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
return (minWidth <= size.width) && (size.width <= maxWidth) &&
|
||||
(minHeight <= size.height) && (size.height <= maxHeight);
|
||||
}
|
||||
@ -245,8 +251,8 @@ class BoxConstraints extends Constraints {
|
||||
return b * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
assert(a.isNormalized);
|
||||
assert(b.isNormalized);
|
||||
assert(a.debugAssertIsNormalized);
|
||||
assert(b.debugAssertIsNormalized);
|
||||
return new BoxConstraints(
|
||||
minWidth: ui.lerpDouble(a.minWidth, b.minWidth, t),
|
||||
maxWidth: ui.lerpDouble(a.maxWidth, b.maxWidth, t),
|
||||
@ -255,8 +261,34 @@ class BoxConstraints extends Constraints {
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns whether the object's constraints are normalized.
|
||||
/// Constraints are normalised if the minimums are less than or
|
||||
/// equal to the corresponding maximums.
|
||||
///
|
||||
/// For example, a BoxConstraints object with a minWidth of 100.0
|
||||
/// and a maxWidth of 90.0 is not normalized.
|
||||
///
|
||||
/// Most of the APIs on BoxConstraints expect the constraints to be
|
||||
/// normalized and have undefined behavior when they are not. In
|
||||
/// checked mode, many of these APIs will assert if the constraints
|
||||
/// are not normalized.
|
||||
bool get isNormalized => minWidth <= maxWidth && minHeight <= maxHeight;
|
||||
|
||||
/// Same as [isNormalized] but, in checked mode, throws an exception
|
||||
/// if isNormalized is false.
|
||||
bool get debugAssertIsNormalized {
|
||||
assert(() {
|
||||
if (maxWidth < minWidth && maxHeight < minHeight)
|
||||
throw new RenderingError('BoxConstraints has both width and height constraints non-normalized.\n$this');
|
||||
if (maxWidth < minWidth)
|
||||
throw new RenderingError('BoxConstraints has non-normalized width constraints.\n$this');
|
||||
if (maxHeight < minHeight)
|
||||
throw new RenderingError('BoxConstraints has non-normalized height constraints.\n$this');
|
||||
return isNormalized;
|
||||
});
|
||||
return isNormalized;
|
||||
}
|
||||
|
||||
BoxConstraints normalize() {
|
||||
return new BoxConstraints(
|
||||
minWidth: minWidth,
|
||||
@ -267,13 +299,13 @@ class BoxConstraints extends Constraints {
|
||||
}
|
||||
|
||||
bool operator ==(dynamic other) {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
if (other is! BoxConstraints)
|
||||
return false;
|
||||
final BoxConstraints typedOther = other;
|
||||
assert(typedOther.isNormalized);
|
||||
assert(typedOther.debugAssertIsNormalized);
|
||||
return minWidth == typedOther.minWidth &&
|
||||
maxWidth == typedOther.maxWidth &&
|
||||
minHeight == typedOther.minHeight &&
|
||||
@ -281,7 +313,7 @@ class BoxConstraints extends Constraints {
|
||||
}
|
||||
|
||||
int get hashCode {
|
||||
assert(isNormalized);
|
||||
assert(debugAssertIsNormalized);
|
||||
return hashValues(minWidth, maxWidth, minHeight, maxHeight);
|
||||
}
|
||||
|
||||
@ -362,7 +394,7 @@ abstract class RenderBox extends RenderObject {
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.isNormalized);
|
||||
assert(constraints.debugAssertIsNormalized);
|
||||
return constraints.constrainWidth(0.0);
|
||||
}
|
||||
|
||||
@ -371,7 +403,7 @@ abstract class RenderBox extends RenderObject {
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||
assert(constraints.isNormalized);
|
||||
assert(constraints.debugAssertIsNormalized);
|
||||
return constraints.constrainWidth(0.0);
|
||||
}
|
||||
|
||||
@ -380,7 +412,7 @@ abstract class RenderBox extends RenderObject {
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.isNormalized);
|
||||
assert(constraints.debugAssertIsNormalized);
|
||||
return constraints.constrainHeight(0.0);
|
||||
}
|
||||
|
||||
@ -393,7 +425,7 @@ abstract class RenderBox extends RenderObject {
|
||||
///
|
||||
/// Override in subclasses that implement [performLayout].
|
||||
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||
assert(constraints.isNormalized);
|
||||
assert(constraints.debugAssertIsNormalized);
|
||||
return constraints.constrainHeight(0.0);
|
||||
}
|
||||
|
||||
@ -447,7 +479,7 @@ abstract class RenderBox extends RenderObject {
|
||||
_size = new _DebugSize(_size, this, debugCanParentUseSize);
|
||||
return true;
|
||||
});
|
||||
assert(debugDoesMeetConstraints());
|
||||
assert(() { debugAssertDoesMeetConstraints(); return true; });
|
||||
}
|
||||
|
||||
Rect get semanticBounds => Point.origin & size;
|
||||
@ -532,32 +564,91 @@ abstract class RenderBox extends RenderObject {
|
||||
|
||||
/// The box constraints most recently received from the parent.
|
||||
BoxConstraints get constraints => super.constraints;
|
||||
bool debugDoesMeetConstraints() {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
RenderObject.debugInDebugDoesMeetConstraints = true;
|
||||
void debugAssertDoesMeetConstraints() {
|
||||
assert(constraints != null);
|
||||
// verify that the size is not infinite
|
||||
assert(_size != null);
|
||||
assert(() {
|
||||
'See https://flutter.io/layout/#unbounded-constraints';
|
||||
return !_size.isInfinite;
|
||||
});
|
||||
// verify that the size is not infinite
|
||||
if (_size.isInfinite) {
|
||||
StringBuffer information = new StringBuffer();
|
||||
if (!constraints.hasBoundedWidth) {
|
||||
RenderBox node = this;
|
||||
while (!node.constraints.hasBoundedWidth && node.parent is RenderBox)
|
||||
node = node.parent;
|
||||
information.writeln('The nearest ancestor providing an unbounded width constraint is:');
|
||||
information.writeln(' $node');
|
||||
List<String> settings = <String>[];
|
||||
node.debugDescribeSettings(settings);
|
||||
for (String line in settings)
|
||||
information.writeln(' $line');
|
||||
}
|
||||
if (!constraints.hasBoundedHeight) {
|
||||
RenderBox node = this;
|
||||
while (!node.constraints.hasBoundedHeight && node.parent is RenderBox)
|
||||
node = node.parent;
|
||||
information.writeln('The nearest ancestor providing an unbounded height constraint is:');
|
||||
information.writeln(' $node');
|
||||
List<String> settings = <String>[];
|
||||
node.debugDescribeSettings(settings);
|
||||
for (String line in settings)
|
||||
information.writeln(' $line');
|
||||
}
|
||||
throw new RenderingError(
|
||||
'$runtimeType object was given an infinite size during layout.\n'
|
||||
'This probably means that it is a render object that tries to be\n'
|
||||
'as big as possible, but it was put inside another render object\n'
|
||||
'that allows its children to pick their own size.\n'
|
||||
'$information'
|
||||
'See https://flutter.io/layout/ for more information.'
|
||||
);
|
||||
}
|
||||
// verify that the size is within the constraints
|
||||
bool result = constraints.isSatisfiedBy(_size);
|
||||
if (!result)
|
||||
debugPrint("${this.runtimeType} does not meet its constraints. Constraints: $constraints, size: $_size");
|
||||
if (!constraints.isSatisfiedBy(_size)) {
|
||||
throw new RenderingError(
|
||||
'$runtimeType does not meet its constraints.\n'
|
||||
'Constraints: $constraints\n'
|
||||
'Size: $_size\n'
|
||||
'If you are not writing your own RenderBox subclass, then this is not\n'
|
||||
'your fault. Contact support: https://github.com/flutter/flutter/issues/new'
|
||||
);
|
||||
}
|
||||
// verify that the intrinsics are also within the constraints
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
RenderObject.debugCheckingIntrinsics = true;
|
||||
double intrinsic;
|
||||
StringBuffer failures = new StringBuffer();
|
||||
int failureCount = 0;
|
||||
intrinsic = getMinIntrinsicWidth(constraints);
|
||||
assert(intrinsic == constraints.constrainWidth(intrinsic));
|
||||
if (intrinsic != constraints.constrainWidth(intrinsic)) {
|
||||
failures.writeln(' * getMinIntrinsicWidth() -- returned: w=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMaxIntrinsicWidth(constraints);
|
||||
assert(intrinsic == constraints.constrainWidth(intrinsic));
|
||||
if (intrinsic != constraints.constrainWidth(intrinsic)) {
|
||||
failures.writeln(' * getMaxIntrinsicWidth() -- returned: w=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMinIntrinsicHeight(constraints);
|
||||
assert(intrinsic == constraints.constrainHeight(intrinsic));
|
||||
if (intrinsic != constraints.constrainHeight(intrinsic)) {
|
||||
failures.writeln(' * getMinIntrinsicHeight() -- returned: h=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
intrinsic = getMaxIntrinsicHeight(constraints);
|
||||
assert(intrinsic == constraints.constrainHeight(intrinsic));
|
||||
RenderObject.debugInDebugDoesMeetConstraints = false;
|
||||
return result;
|
||||
if (intrinsic != constraints.constrainHeight(intrinsic)) {
|
||||
failures.writeln(' * getMaxIntrinsicHeight() -- returned: h=$intrinsic');
|
||||
failureCount += 1;
|
||||
}
|
||||
RenderObject.debugCheckingIntrinsics = false;
|
||||
if (failures.isNotEmpty) {
|
||||
assert(failureCount > 0);
|
||||
throw new RenderingError(
|
||||
'The intrinsic dimension methods of the $runtimeType class returned values that violate the given constraints.\n'
|
||||
'The constraints were: $constraints\n'
|
||||
'The following method${failureCount > 1 ? "s" : ""} returned values outside of those constraints:\n'
|
||||
'$failures'
|
||||
'If you are not writing your own RenderBox subclass, then this is not\n'
|
||||
'your fault. Contact support: https://github.com/flutter/flutter/issues/new'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void markNeedsLayout() {
|
||||
|
||||
@ -724,52 +724,45 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
|
||||
void visitChildren(RenderObjectVisitor visitor) { }
|
||||
|
||||
dynamic debugOwner;
|
||||
static int _debugPrintedExceptionCount = 0;
|
||||
void _debugReportException(String method, dynamic exception, StackTrace stack) {
|
||||
try {
|
||||
if (debugRenderingExceptionHandler != null) {
|
||||
debugRenderingExceptionHandler(this, method, exception, stack);
|
||||
} else {
|
||||
debugPrint('-- EXCEPTION CAUGHT BY RENDERING LIBRARY -------------------------------');
|
||||
debugPrint('The following exception was raised during $method():');
|
||||
debugPrint('$exception');
|
||||
debugPrint('The following RenderObject was being processed when the exception was fired:\n${this}');
|
||||
if (debugOwner != null)
|
||||
debugPrint('This RenderObject had the following owner:\n$debugOwner');
|
||||
int depth = 0;
|
||||
List<String> descendants = <String>[];
|
||||
const int maxDepth = 5;
|
||||
void visitor(RenderObject child) {
|
||||
descendants.add('${" " * depth}$child');
|
||||
depth += 1;
|
||||
if (depth < maxDepth)
|
||||
child.visitChildren(visitor);
|
||||
depth -= 1;
|
||||
}
|
||||
visitChildren(visitor);
|
||||
if (descendants.length > 1) {
|
||||
debugPrint('This RenderObject had the following descendants (showing up to depth $maxDepth):');
|
||||
} else if (descendants.length == 1) {
|
||||
debugPrint('This RenderObject had the following child:');
|
||||
} else {
|
||||
debugPrint('This RenderObject has no descendants.');
|
||||
}
|
||||
descendants.forEach(debugPrint);
|
||||
assert(() {
|
||||
if (debugInDebugDoesMeetConstraints) {
|
||||
debugPrint('This exception was thrown while debugDoesMeetConstraints() was running.');
|
||||
debugPrint('debugDoesMeetConstraints() verifies that some invariants are not being');
|
||||
debugPrint('violated. For example, it verifies that RenderBox objects are sized in');
|
||||
debugPrint('a manner consistent with the constraints provided, and, in addition, that');
|
||||
debugPrint('the getMinIntrinsicWidth(), getMaxIntrinsicWidth(), etc, functions all');
|
||||
debugPrint('return consistent values within the same constraints.');
|
||||
debugPrint('If you are not writing your own RenderObject subclass, then this is not');
|
||||
debugPrint('your fault. Contact support: https://github.com/flutter/flutter/issues/new');
|
||||
_debugPrintedExceptionCount += 1;
|
||||
if (_debugPrintedExceptionCount == 1) {
|
||||
debugPrint('-- EXCEPTION CAUGHT BY RENDERING LIBRARY -------------------------------');
|
||||
debugPrint('The following exception was raised during $method():');
|
||||
debugPrint('$exception');
|
||||
debugPrint('The following RenderObject was being processed when the exception was fired:\n${this}');
|
||||
if (debugOwner != null)
|
||||
debugPrint('This RenderObject had the following owner:\n$debugOwner');
|
||||
int depth = 0;
|
||||
List<String> descendants = <String>[];
|
||||
const int maxDepth = 5;
|
||||
void visitor(RenderObject child) {
|
||||
descendants.add('${" " * depth}$child');
|
||||
depth += 1;
|
||||
if (depth < maxDepth)
|
||||
child.visitChildren(visitor);
|
||||
depth -= 1;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
debugPrint('Stack trace:');
|
||||
debugPrint('$stack');
|
||||
debugPrint('------------------------------------------------------------------------');
|
||||
visitChildren(visitor);
|
||||
if (descendants.length > 1) {
|
||||
debugPrint('This RenderObject had the following descendants (showing up to depth $maxDepth):');
|
||||
} else if (descendants.length == 1) {
|
||||
debugPrint('This RenderObject had the following child:');
|
||||
} else {
|
||||
debugPrint('This RenderObject has no descendants.');
|
||||
}
|
||||
descendants.forEach(debugPrint);
|
||||
debugPrint('Stack trace:');
|
||||
debugPrint('$stack');
|
||||
debugPrint('------------------------------------------------------------------------');
|
||||
} else {
|
||||
debugPrint('Another exception was raised: ${exception.toString().split("\n")[0]}');
|
||||
}
|
||||
}
|
||||
} catch (exception) {
|
||||
debugPrint('(exception during exception handler: $exception)');
|
||||
@ -809,15 +802,23 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
|
||||
Constraints _constraints;
|
||||
/// The layout constraints most recently supplied by the parent.
|
||||
Constraints get constraints => _constraints;
|
||||
/// Override this function in a subclass to verify that your state matches the constraints object.
|
||||
bool debugDoesMeetConstraints();
|
||||
/// When true, debugDoesMeetConstraints() is currently executing.
|
||||
/// Verify that the object's constraints are being met. Override
|
||||
/// this function in a subclass to verify that your state matches
|
||||
/// the constraints object. This function is only called in checked
|
||||
/// mode. If the constraints are not met, it should assert or throw
|
||||
/// an exception.
|
||||
void debugAssertDoesMeetConstraints();
|
||||
|
||||
/// When true, debugAssertDoesMeetConstraints() is currently
|
||||
/// executing asserts for verifying the consistent behaviour of
|
||||
/// intrinsic dimensions methods.
|
||||
///
|
||||
/// This should be set by implementations of debugDoesMeetConstraints() so that
|
||||
/// tests can selectively ignore custom layout callbacks. It should not be set
|
||||
/// outside of debugDoesMeetConstraints() implementations and should not be used
|
||||
/// for purposes other than tests.
|
||||
static bool debugInDebugDoesMeetConstraints = false;
|
||||
/// This should only be set by debugAssertDoesMeetConstraints()
|
||||
/// implementations. It is used by tests to selectively ignore
|
||||
/// custom layout callbacks. It should not be set outside of
|
||||
/// debugAssertDoesMeetConstraints(), and should not be checked in
|
||||
/// release mode (where it will always be false).
|
||||
static bool debugCheckingIntrinsics = false;
|
||||
bool debugAncestorsAlreadyMarkedNeedsLayout() {
|
||||
if (_relayoutSubtreeRoot == null)
|
||||
return true; // we haven't yet done layout even once, so there's nothing for us to do
|
||||
@ -1022,7 +1023,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
|
||||
assert(() { _debugDoingThisResize = true; return true; });
|
||||
try {
|
||||
performResize();
|
||||
assert(debugDoesMeetConstraints());
|
||||
assert(() { debugAssertDoesMeetConstraints(); return true; });
|
||||
} catch (e, stack) {
|
||||
_debugReportException('performResize', e, stack);
|
||||
}
|
||||
@ -1038,7 +1039,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
|
||||
try {
|
||||
performLayout();
|
||||
markNeedsSemanticsUpdate();
|
||||
assert(debugDoesMeetConstraints());
|
||||
assert(() { debugAssertDoesMeetConstraints(); return true; });
|
||||
} catch (e, stack) {
|
||||
_debugReportException('performLayout', e, stack);
|
||||
}
|
||||
@ -2023,3 +2024,10 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// Error thrown when the rendering library encounters a contract violation.
|
||||
class RenderingError extends AssertionError {
|
||||
RenderingError(this.message);
|
||||
final String message;
|
||||
String toString() => message;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
|
||||
|
||||
// We never call layout() on this class, so this should never get
|
||||
// checked. (This class is laid out using scheduleInitialLayout().)
|
||||
bool debugDoesMeetConstraints() { assert(false); return false; }
|
||||
void debugAssertDoesMeetConstraints() { assert(false); }
|
||||
|
||||
void performResize() {
|
||||
assert(false);
|
||||
|
||||
@ -155,10 +155,14 @@ class _MixedViewportElement extends RenderObjectElement<MixedViewport> {
|
||||
|
||||
double _noIntrinsicExtent(BoxConstraints constraints) {
|
||||
assert(() {
|
||||
'MixedViewport does not support returning intrinsic dimensions. ' +
|
||||
'Calculating the intrinsic dimensions would require walking the entire child list, ' +
|
||||
'which defeats the entire point of having a lazily-built list of children.';
|
||||
return RenderObject.debugInDebugDoesMeetConstraints;
|
||||
if (!RenderObject.debugCheckingIntrinsics) {
|
||||
throw new UnsupportedError(
|
||||
'MixedViewport does not support returning intrinsic dimensions.\n'
|
||||
'Calculating the intrinsic dimensions would require walking the entire child list,\n'
|
||||
'which defeats the entire point of having a lazily-built list of children.'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -442,13 +442,14 @@ class ScrollableViewportState extends ScrollableState<ScrollableViewport> {
|
||||
class Block extends StatelessComponent {
|
||||
Block({
|
||||
Key key,
|
||||
this.children,
|
||||
this.children: const <Widget>[],
|
||||
this.padding,
|
||||
this.initialScrollOffset,
|
||||
this.scrollDirection: Axis.vertical,
|
||||
this.onScroll,
|
||||
this.scrollableKey
|
||||
}) : super(key: key) {
|
||||
assert(children != null);
|
||||
assert(!children.any((Widget child) => child == null));
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
|
||||
BoxConstraints getSizeConstraints;
|
||||
|
||||
Size getSize(BoxConstraints constraints) {
|
||||
if (!RenderObject.debugInDebugDoesMeetConstraints)
|
||||
if (!RenderObject.debugCheckingIntrinsics)
|
||||
getSizeConstraints = constraints;
|
||||
return new Size(200.0, 300.0);
|
||||
}
|
||||
@ -23,7 +23,7 @@ class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
|
||||
bool performLayoutIsChild;
|
||||
|
||||
void performLayout(Size size, BoxConstraints constraints) {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
expect(() {
|
||||
performLayoutSize = size;
|
||||
performLayoutConstraints = constraints;
|
||||
@ -36,7 +36,7 @@ class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
|
||||
bool shouldRelayoutCalled = false;
|
||||
bool shouldRelayoutValue = false;
|
||||
bool shouldRelayout(_) {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
shouldRelayoutCalled = true;
|
||||
return shouldRelayoutValue;
|
||||
}
|
||||
|
||||
@ -14,13 +14,13 @@ class TestOneChildLayoutDelegate extends OneChildLayoutDelegate {
|
||||
Size childSizeFromGetPositionForChild;
|
||||
|
||||
Size getSize(BoxConstraints constraints) {
|
||||
if (!RenderObject.debugInDebugDoesMeetConstraints)
|
||||
if (!RenderObject.debugCheckingIntrinsics)
|
||||
constraintsFromGetSize = constraints;
|
||||
return new Size(200.0, 300.0);
|
||||
}
|
||||
|
||||
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
constraintsFromGetConstraintsForChild = constraints;
|
||||
return new BoxConstraints(
|
||||
minWidth: 100.0,
|
||||
@ -31,7 +31,7 @@ class TestOneChildLayoutDelegate extends OneChildLayoutDelegate {
|
||||
}
|
||||
|
||||
Offset getPositionForChild(Size size, Size childSize) {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
sizeFromGetPositionForChild = size;
|
||||
childSizeFromGetPositionForChild = childSize;
|
||||
return Offset.zero;
|
||||
@ -40,7 +40,7 @@ class TestOneChildLayoutDelegate extends OneChildLayoutDelegate {
|
||||
bool shouldRelayoutCalled = false;
|
||||
bool shouldRelayoutValue = false;
|
||||
bool shouldRelayout(_) {
|
||||
assert(!RenderObject.debugInDebugDoesMeetConstraints);
|
||||
assert(!RenderObject.debugCheckingIntrinsics);
|
||||
shouldRelayoutCalled = true;
|
||||
return shouldRelayoutValue;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user