avoid-unmodified-loop-condition
- Group
- Correctness
- Path
lint/correctness/avoid-unmodified-loop-condition- Default
- On (recommended)
- Origin
- Falcon
- Rule
- 154 of 512
Flags loop conditions whose local scalar inputs are never modified by the loop.
A forgotten update can make a while, do or condition-bearing for loop
repeat forever. Conditions must consist of resolved local scalar bindings,
literals, operators, and immutable String length/emptiness properties. Any
write to a referenced declaration in the body, condition or for-update avoids
a report; initialization and writes after the loop do not count. Shadowed
names are distinct bindings. Literal-only conditions belong to other rules.
Unknown types, mutable-object properties, calls in conditions, captured writes, and loops containing a possible break, labeled continue, return, throw, yield, await, or resolved Never-returning call are deliberately ignored. Exit checks include nested constructs; this is not an infinite-loop proof.
Invalid
void unchangedBool(bool running) {
while (running) {
print(running);
}
}
void unchangedComparison(int count, int limit) {
while (count < limit) {
print(count);
}
count++;
}
void unchangedString(String text) {
while (text.isNotEmpty) {
print(text);
}
}
void unchangedDo(bool running) {
do {
print(running);
} while (running);
}
void unrelatedUpdate(int count) {
for (var index = 0; count > 0; index++) {
print(index);
}
}
void shadowedWrite(int count) {
while (count > 0) {
var count = 1;
count--;
print(count);
}
}
void initializationIsNotUpdate() {
for (var index = 0; index < 10;) {
print(index);
}
}
void multipleInputs(int left, int right, bool active) {
while (active && left != right) {
print(left);
}
}
void inferredLiteral() {
var running = true;
while (!(!running)) {
print(running);
}
}void unchangedBool(bool running) { while (running) {void unchangedComparison(int count, int limit) { while (count < limit) {void unchangedString(String text) { while (text.isNotEmpty) { print(running); } while (running);void unrelatedUpdate(int count) { for (var index = 0; count > 0; index++) {void shadowedWrite(int count) { while (count > 0) {void initializationIsNotUpdate() { for (var index = 0; index < 10;) {void multipleInputs(int left, int right, bool active) { while (active && left != right) { var running = true; while (!(!running)) {Valid
void updatedWhile(int count) {
while (count > 0) {
count--;
}
}
void updatedDo(int count) {
do {
count -= 1;
} while (count > 0);
}
void updatedFor() {
for (var index = 0; index < 10; index++) {
print(index);
}
}
void oneInputChanges(int left, int right) {
while (left < right) {
right--;
}
}
void explicitExit(bool running, bool stop) {
while (running) {
if (stop) break;
}
}
void returns(bool running) {
while (running) {
return;
}
}
void throws(bool running) {
while (running) {
throw StateError('stopped');
}
}
void mutatingCondition(int count) {
while (count-- > 0) {
print(count);
}
}
void unknownCondition(bool Function() next) {
while (next()) {
print('next');
}
}
void mutableProperty(List<int> items) {
while (items.isNotEmpty) {
items.removeLast();
}
}
void dynamicCondition(dynamic running) {
while (running) {
print(running);
}
}
bool globalRunning = true;
void globalCondition() {
while (globalRunning) {
print(globalRunning);
}
}
void intentionalInfinite() {
while (true) {}
for (;;) {}
}
void closureWrite() {
var running = true;
final stop = () { running = false; };
while (running) {
stop();
}
}
void localFunctionWrite() {
var running = true;
void stop() { running = false; }
while (running) {
stop();
}
}
Future<void> asynchronousExit(bool running, Future<void> Function() wait) async {
while (running) {
await wait();
}
}
void patternUpdate(int left, int right) {
while (left < right) {
(left, right) = (right, left);
}
}
void nestedWrite(int count, List<int> items) {
while (count > 0) {
for (count in items) {
print(count);
}
}
}
void labeledContinue(bool ready) {
outer: for (var index = 0; index < 10; index++) {
while (ready) {
continue outer;
}
}
}
Never stop() => throw StateError('stopped');
void neverReturningCall(bool ready) {
while (ready) {
stop();
}
}
class Terminator {
Never terminate() => throw StateError('stopped');
}
void neverReturningMethod(bool ready, Terminator terminator) {
while (ready) {
terminator.terminate();
}
}Configure avoid-unmodified-loop-condition
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"avoid-unmodified-loop-condition": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/avoid-unmodified-loop-condition: <reason>More correctness rules
- avoid-unnecessary-setstaterecommendedflutter
Avoid setState during build, initState, or didUpdateWidget.
- avoid-unnecessary-stateful-widgetsrecommendedflutter
Warns when a
StatefulWidget's local State contains only a pure build method. - avoid-unreachable-for-loop
Reports iteration of a collection in a branch that requires it to be empty.
- avoid-unrelated-type-castsrecommended
Flags casts between types proven unrelated by canonical type resolution.
- avoid-unsafe-collection-methods
Flags potentially throwing element access on SDK collections.
- avoid-unsafe-reduce
Warn when SDK Iterable.reduce can receive an empty collection.
- avoid-unused-after-null-check
Reports a null-checked local ignored by a branch that passes another local of the same resolved type to a call.
- avoid-unused-parameters
avoid-unused-parametersrecommendedDisallow declared parameters that are never used, excluding primary constructors.