prefer-asserts-in-initializer-lists

Same as prefer_asserts_in_initializer_lists in Dart lints

Group
Style
Path
lint/style/prefer-asserts-in-initializer-lists
Default
Off, opt in
Origin
Dart lints
Rule
314 of 512

Flags leading constructor-body asserts that could live in the initializer list.

An assert at the start of a generative constructor body that does not need the instance (no this, no instance member of the class or its superclasses and mixins) can move into the initializer list, where it runs before the object is used and works for const constructors too. Fields initialized by this.x formals count as available, since the formal holds the same value, as do fields a super.x formal passes to a superclass constructor's this.x parameter. The analyzer retains the last class's superclass/mixin chain for subsequent extension type constructors.

class A {
  A(int a) { assert(a != 0); } // flagged
  A(int a) : assert(a != 0);   // ok
}

Invalid

example.dartdart
int limit = 10;

class Range {
  final int start;
  final int end;
  Range(this.start, this.end) {
    assert(start <= end);
    assert(end < limit);
    print(start);
  }
  Range.of(int a, int b) : start = a, end = b {
    assert(a <= b, 'ordered');
  }
  Range.single(int v) : start = v, end = v {
    assert(isValid(v));
  }
  Range.list(List<int> items) : start = items.first, end = items.last {
    assert(items.every((e) => e >= 0));
  }
  static bool isValid(int v) => v >= 0;
}

class Sub extends Range {
  Sub(int a) : super(a, a) {
    assert(a > 0);
  }
}

class Parent {
  final int value;
  Parent(this.value);
}

class SuperFormal extends Parent {
  SuperFormal(super.value) {
    assert(value > 0);
  }
}

extension type CheckedValue(int? value) {
  CheckedValue.checked(this.value) {
    assert(value != null);
  }
}

class ParameterMessage {
  ParameterMessage(int value) {
    assert(value > 0, value);
  }
}

class NestedAssertions {
  NestedAssertions(int value) {
    assert(() {
      assert(value > 0);
      return true;
    }());
    assert(value < 10);
    print(value);
    assert(value != 5);
  }
}
Assert should be in the initializer list.
6 Range(this.start, this.end) {
7 assert(start <= end);
Assert should be in the initializer list.
7 assert(start <= end);
8 assert(end < limit);
Assert should be in the initializer list.
11 Range.of(int a, int b) : start = a, end = b {
12 assert(a <= b, 'ordered');
Assert should be in the initializer list.
14 Range.single(int v) : start = v, end = v {
15 assert(isValid(v));
Assert should be in the initializer list.
17 Range.list(List<int> items) : start = items.first, end = items.last {
18 assert(items.every((e) => e >= 0));
Assert should be in the initializer list.
24 Sub(int a) : super(a, a) {
25 assert(a > 0);
Assert should be in the initializer list.
35 SuperFormal(super.value) {
36 assert(value > 0);
Assert should be in the initializer list.
41 CheckedValue.checked(this.value) {
42 assert(value != null);
Assert should be in the initializer list.
47 ParameterMessage(int value) {
48 assert(value > 0, value);
Assert should be in the initializer list.
53 NestedAssertions(int value) {
54 assert(() {
Assert should be in the initializer list.
57 }());
58 assert(value < 10);

Valid

example.dartdart
class Range {
  final int start;
  final int end;
  int get length => end - start;
  Range(this.start, this.end) : assert(start <= end);
  Range.checked(this.start, this.end) {
    assert(length >= 0);
  }
  Range.self(this.start, this.end) {
    assert(this.start <= this.end);
  }
  Range.method(this.start, this.end) {
    assert(validate());
  }
  Range.late(int a, int b) : start = a, end = b {
    print(a);
    assert(a <= b);
  }
  factory Range.make(int a) {
    assert(a > 0);
    return Range(a, a);
  }
  Range.other(Range other) : start = other.start, end = other.end {
    assert(other.length >= 0);
  }
  bool validate() => start <= end;
}

class External extends Object with Mixed {
  final int x;
  External(this.x) {
    assert(mixed > 0);
  }
}

mixin Mixed {
  int get mixed => 1;
}

class Parent {
  final int value;
  Parent(this.value);
}

class SuperFormal extends Parent {
  SuperFormal(super.value) : assert(value > 0);
}

extension type CheckedValue(int? value) {
  CheckedValue.checked(this.value) : assert(value != null);
}

class InstanceMessage {
  InstanceMessage(int value) {
    assert(value > 0, this);
  }
  InstanceMessage.property(int value) {
    assert(value > 0, this.toString());
  }
}

class InitializerClosure {
  final bool value;
  InitializerClosure(int input)
      : value = (() {
          assert(input > 0);
          return true;
        })() {
    assert(input > 0, this);
  }
}

class SuperClosureParent {
  SuperClosureParent(bool value);
}

class SuperArgumentClosure extends SuperClosureParent {
  SuperArgumentClosure(int input)
      : super((() {
          assert(input > 0);
          return true;
        })()) {
    assert(input > 0, this);
  }
}

Configure prefer-asserts-in-initializer-lists

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "prefer-asserts-in-initializer-lists": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/style/prefer-asserts-in-initializer-lists: <reason>