debugAssertIsValid method Null safety

  1. @override
bool debugAssertIsValid(
  1. {bool isAppliedConstraint = false,
  2. InformationCollector? informationCollector}
)
override

Asserts that the constraints are valid.

This might involve checks more detailed than isNormalized.

For example, the BoxConstraints subclass verifies that the constraints are not double.nan.

If the isAppliedConstraint argument is true, then even stricter rules are enforced. This argument is set to true when checking constraints that are about to be applied to a RenderObject during layout, as opposed to constraints that may be further affected by other constraints. For example, the asserts for verifying the validity of RenderConstrainedBox.additionalConstraints do not set this argument, but the asserts for verifying the argument passed to the RenderObject.layout method do.

The informationCollector argument takes an optional callback which is called when an exception is to be thrown. The collected information is then included in the message after the error line.

Returns the same as isNormalized if asserts are disabled.

Implementation

@override
bool debugAssertIsValid({
  bool isAppliedConstraint = false,
  InformationCollector? informationCollector,
}) {
  assert(() {
    bool hasErrors = false;
    final StringBuffer errorMessage = StringBuffer('\n');
    void verify(bool check, String message) {
      if (check) {
        return;
      }
      hasErrors = true;
      errorMessage.writeln('  $message');
    }
    void verifyDouble(double property, String name, {bool mustBePositive = false, bool mustBeNegative = false}) {
      verify(property != null, 'The "$name" is null.');
      if (property.isNaN) {
        String additional = '.';
        if (mustBePositive) {
          additional = ', expected greater than or equal to zero.';
        } else if (mustBeNegative) {
          additional = ', expected less than or equal to zero.';
        }
        verify(false, 'The "$name" is NaN$additional');
      } else if (mustBePositive) {
        verify(property >= 0.0, 'The "$name" is negative.');
      } else if (mustBeNegative) {
        verify(property <= 0.0, 'The "$name" is positive.');
      }
    }
    verify(axis != null, 'The "axis" is null.');
    verify(growthDirection != null, 'The "growthDirection" is null.');
    verifyDouble(scrollOffset, 'scrollOffset');
    verifyDouble(overlap, 'overlap');
    verifyDouble(crossAxisExtent, 'crossAxisExtent');
    verifyDouble(scrollOffset, 'scrollOffset', mustBePositive: true);
    verify(crossAxisDirection != null, 'The "crossAxisDirection" is null.');
    verify(axisDirectionToAxis(axisDirection) != axisDirectionToAxis(crossAxisDirection), 'The "axisDirection" and the "crossAxisDirection" are along the same axis.');
    verifyDouble(viewportMainAxisExtent, 'viewportMainAxisExtent', mustBePositive: true);
    verifyDouble(remainingPaintExtent, 'remainingPaintExtent', mustBePositive: true);
    verifyDouble(remainingCacheExtent, 'remainingCacheExtent', mustBePositive: true);
    verifyDouble(cacheOrigin, 'cacheOrigin', mustBeNegative: true);
    verifyDouble(precedingScrollExtent, 'precedingScrollExtent', mustBePositive: true);
    verify(isNormalized, 'The constraints are not normalized.'); // should be redundant with earlier checks
    if (hasErrors) {
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('$runtimeType is not valid: $errorMessage'),
        if (informationCollector != null)
          ...informationCollector(),
        DiagnosticsProperty<SliverConstraints>('The offending constraints were', this, style: DiagnosticsTreeStyle.errorProperty),
      ]);
    }
    return true;
  }());
  return true;
}