prefer-const-constructors
Same as prefer_const_constructors in Dart lints
- Group
- Style
- Path
lint/style/prefer-const-constructors- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 327 of 512
Prefers const when invoking a const constructor with constant arguments.
When a constructor is declared const and the invocation would be a valid
constant expression (constant arguments the constructor accepts, set
elements and map keys with primitive equality, no type parameters in type
arguments), invoking it with const produces a canonicalized instance
instead of allocating a new one. The rule flags such invocations outside a
constant context (where const is already implied). It stays silent when
the constructor cannot be resolved to a declaration known to be const,
when an argument cannot be proven constant, for Object() (often used to create
unique identity tokens), for constructors of deferred-imported classes, and
for a generic class invoked without type arguments whose approximate context
contains type parameters. As in the analyzer, assignments use their result
type rather than their target type.
class A {
const A();
}
final a = A(); // BAD
final b = const A(); // GOOD
Invalid
class Point {
const Point(this.x, this.y);
const Point.origin()
: x = 0,
y = 0;
final int x;
final int y;
}
class Label {
const Label(this.text, {this.point = const Point.origin()});
final String text;
final Point point;
}
class Box<T> {
const Box(this.value);
final T value;
}
const int limit = 10;
void use(Object value) {}
void constructors() {
final a = Point(1, 2);
final b = Point.origin();
final c = new Point(3, 4);
final d = new Point.origin();
final e = Box<int>(limit);
final f = Label('title', point: const Point(0, 1));
use(Point(limit, -1));
final List<Point> points = [Point(5, 6)];
final Point g = .origin();
print([a, b, c, d, e, f, points, g]);
}
enum Shade { dark, light }
class Swatch {
const Swatch(this.value, {this.shade});
const Swatch.named(this.value) : shade = null;
const factory Swatch.redirect(Object? value) = Swatch;
static const int base = 1;
final Object? value;
final Shade? shade;
}
class Generic<T> {
const Generic(this.value);
const Generic.named(this.value);
final T value;
}
int top() => 0;
void evaluatedArguments() {
const local = 2;
print(Swatch(Shade.dark));
print(Swatch(Swatch.base));
print(Swatch(local));
print(Generic<int>.named(1));
print(Swatch.redirect(1));
print(Swatch('a' 'b'));
print(Swatch(#symbol));
print(Swatch(int));
print(Swatch(top));
print(Swatch(Swatch.named));
print(Swatch(Shade.values));
print(Swatch(identical(1, 2)));
print(Swatch([if (true) 1]));
print(Swatch({Swatch(1): 1}));
final generic = Generic(1);
print(generic);
}
// The context type `Box<List<T>>` has no type parameter as a type argument
// of `Box` itself, so making it `const` changes nothing.
Box<List<T>> emptyBox<T>() => Box([]);void constructors() { final a = Point(1, 2); final a = Point(1, 2); final b = Point.origin(); final b = Point.origin(); final c = new Point(3, 4); final c = new Point(3, 4); final d = new Point.origin(); final d = new Point.origin(); final e = Box<int>(limit); final e = Box<int>(limit); final f = Label('title', point: const Point(0, 1)); final f = Label('title', point: const Point(0, 1)); use(Point(limit, -1)); use(Point(limit, -1)); final List<Point> points = [Point(5, 6)]; final List<Point> points = [Point(5, 6)]; final Point g = .origin(); const local = 2; print(Swatch(Shade.dark)); print(Swatch(Shade.dark)); print(Swatch(Swatch.base)); print(Swatch(Swatch.base)); print(Swatch(local)); print(Swatch(local)); print(Generic<int>.named(1)); print(Generic<int>.named(1)); print(Swatch.redirect(1)); print(Swatch.redirect(1)); print(Swatch('a' 'b')); print(Swatch('a' 'b')); print(Swatch(#symbol)); print(Swatch(#symbol)); print(Swatch(int)); print(Swatch(int)); print(Swatch(top)); print(Swatch(top)); print(Swatch(Swatch.named)); print(Swatch(Swatch.named)); print(Swatch(Shade.values)); print(Swatch(Shade.values)); print(Swatch(identical(1, 2))); print(Swatch(identical(1, 2))); print(Swatch([if (true) 1])); print(Swatch([if (true) 1])); print(Swatch({Swatch(1): 1})); print(Swatch([if (true) 1])); print(Swatch({Swatch(1): 1})); print(Swatch({Swatch(1): 1})); final generic = Generic(1);// of `Box` itself, so making it `const` changes nothing.Box<List<T>> emptyBox<T>() => Box([]);Valid
class Point {
const Point(this.x, this.y);
const Point.origin()
: x = 0,
y = 0;
final int x;
final int y;
}
class Mutable {
Mutable(this.value);
int value;
}
class Box<T> {
const Box(this.value);
final T value;
}
void use(Object value) {}
Box<T> wrap<T>(T value) => Box<T>(value);
void constructors(int x) {
const a = Point(1, 2);
final b = const Point.origin();
final c = Point(x, 2);
final d = Mutable(1);
final e = Object();
final f = const [Point(1, 2), Point.origin()];
final g = Unknown(1);
use(Point(x, x));
final Point h = const .origin();
print([a, b, c, d, e, f, g, h]);
}
class Holder {
const Holder([this.point = const Point(0, 0)]);
final Point point;
}
@Deprecated('use Point.origin')
const origin = Point(0, 0);
class Keyed {
const Keyed();
@override
bool operator ==(Object other) => other is Keyed;
@override
int get hashCode => 0;
}
class Wrapper {
const Wrapper(this.value, {required this.flag}) : assert(value != null);
final Object? value;
final bool flag;
}
class Pair<T> {
const Pair(this.first);
final T first;
}
class Notify<T> {
const Notify();
void call(Pair<T> pair) {}
}
void notConstant(Notify<int> notify, Object? unknown) {
print(Wrapper({1.5: 1}, flag: true));
// Only the key itself can be const: `Keyed` overrides `==`.
print(Wrapper({const Keyed(): 1}, flag: true));
print(Wrapper(null, flag: true));
}
class Typed<T> {
Pair<T> make() => Pair(1 as T);
void send(void Function(Pair<T>) sink) => sink(Pair(null as T));
}
void constantPatterns(Object v) {
switch (v) {
case const (Point(1, 2)):
break;
default:
break;
}
if (v case const (Point.origin())) {
print(v);
}
}Configure prefer-const-constructors
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"prefer-const-constructors": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-const-constructors: <reason>More style rules
- prefer-const-constructors-in-immutables
prefer_const_constructors_in_immutablesflutterPrefers
constconstructors in immutable classes and extension types. - prefer-const-declarations
prefer_const_declarationsrecommendedFlags
finaldeclarations whose initializers are all constant expressions. - prefer-const-literals-to-create-immutables
prefer_const_literals_to_create_immutablesPrefers
constlist, set, and map literals as arguments to constructors of@immutableclasses. - prefer-constrained-box-over-containerflutter
Prefers
ConstrainedBoxover aContainerused only forconstraints. - prefer-constructors-over-static-methods
prefer_constructors_over_static_methodsFlags static methods that create and return an instance of their own class.
- prefer-containerflutter
Suggests collapsing compatible nested layout widgets into one
Container. - prefer-correct-callback-field-name
Match callback field names to a configured regular expression.
- prefer-correct-error-name
Require configured error parameter names in catches and SDK error callbacks.