Rules / Style / prefer-final-fields
prefer-final-fields
Flags a private field that is initialized but never reassigned, so it could
be final.
Marking such fields final documents that they never change after
construction and lets the compiler enforce it, preventing accidental
mutation. The analysis is deliberately conservative to avoid false positives:
a whole-file scan first records every name that is ever assigned, compound
assigned, or incremented, and any such write disqualifies that name (matched
by identifier, so a like-named field in another class also protects it). A
candidate is reported only when it is provably initialized through exactly one
safe channel — a declaration initializer with no constructor ever touching it,
or no initializer but every non-redirecting generative constructor setting it
via : _x = ... or a this._x formal. Only private (underscore-prefixed)
fields are considered, and those already final, const, late, external,
or abstract are skipped.
Invalid
example.dartdart
// Private fields only ever initialized, never reassigned.
class A {
int _a = 1;
int get a => _a;
}
class B {
static int _shared = 0;
static int read() => _shared;
}
class C {
int _c;
C(this._c);
}
class D {
int _d;
D(int v) : _d = v;
}
class E {
String _e = 'x';
String describe() => _e;
}
class F {
final List<int> items = [];
int _f;
F(this._f);
}
The private field '_a' could be 'final'.
2class A {
3 int _a = 1;
∙
The private field '_shared' could be 'final'.
7class B {
8 static int _shared = 0;
∙
The private field '_c' could be 'final'.
The private field '_d' could be 'final'.
The private field '_e' could be 'final'.
22class E {
23 String _e = 'x';
∙
The private field '_f' could be 'final'.
28 final List<int> items = [];
29 int _f;
∙
Valid
example.dartdart
// Fields that are reassigned, already final, public, or late.
class A {
int _a = 0;
void inc() {
_a += 1;
}
}
class B {
int _b = 0;
void assign(int v) {
_b = v;
}
}
class C {
final int _c;
C(this._c);
}
class D {
int value = 0;
void bump() {
value++;
}
}
class E {
late int _e;
void init() {
_e = 5;
}
}
class F {
int _f = 0;
void tick() {
_f++;
}
}
How to configure
Set the severity of prefer-final-fields in your falcon.json:
falcon.jsonjson
{
"linter": {
"rules": {
"style": {
"prefer-final-fields": "error"
}
}
}
}