cascade-after-null-coalescing
- Group
- Suspicious
- Path
lint/suspicious/cascade-after-null-coalescing- Default
- Off, opt in
- Origin
- Falcon
- Rule
- 198 of 512
Flags a cascade after an unparenthesized null-coalescing expression.
In a ?? b..method(), the cascade applies to the result of a ?? b, not
just b. Parenthesize the receiver as (a ?? b)..method() or the fallback
as a ?? (b..method()) to make that choice explicit. The receiver may also
be a ternary whose trailing else expression ends in ??. Explicit receiver
parentheses and parentheses around the fallback are respected, and ??
nested in other receiver subexpressions is not flagged.
Both ordinary and null-aware cascades are checked without type inference.
Invalid
class Box {
int value = 0;
void reset() { value = 0; }
}
Box choose(Box? first, Box second) => first ?? second..reset();
void cascades(Box? first, Box? middle, Box second) {
final assigned = first ?? second..value = 1;
first ?? second..reset()..value = 2;
final nested = first ?? middle ?? second..reset();
final list = [first ?? second..reset()];
final wrapped = (first ?? second..reset());
final nullable = first ?? middle?..reset();
final operandOnly = first ?? (second)..reset();
final ternary = first == null ? second : middle ?? second..reset();
final deepTernary = first == null ? second : middle == null ? second : first ?? second..reset();
} Box choose(Box? first, Box second) => first ?? second..reset();void cascades(Box? first, Box? middle, Box second) { final assigned = first ?? second..value = 1; final assigned = first ?? second..value = 1; first ?? second..reset()..value = 2; first ?? second..reset()..value = 2; final nested = first ?? middle ?? second..reset(); final nested = first ?? middle ?? second..reset(); final list = [first ?? second..reset()]; final list = [first ?? second..reset()]; final wrapped = (first ?? second..reset()); final wrapped = (first ?? second..reset()); final nullable = first ?? middle?..reset(); final nullable = first ?? middle?..reset(); final operandOnly = first ?? (second)..reset(); final operandOnly = first ?? (second)..reset(); final ternary = first == null ? second : middle ?? second..reset(); final ternary = first == null ? second : middle ?? second..reset(); final deepTernary = first == null ? second : middle == null ? second : first ?? second..reset();Valid
class Box {
int value = 0;
void reset() { value = 0; }
}
Box choose(Box? first, Box second) => (first ?? second)..reset();
void cascades(Box? first, Box? middle, Box second, bool condition) {
final explicitReceiver = (first ?? second)..value = 1;
final explicitFallback = first ?? (second..reset());
final multiple = (first ?? second)..reset()..value = 2;
final nestedReceiver = ((first ?? middle) ?? second)..reset();
final nestedFallback = first ?? (middle ?? (second..reset()));
final ordinary = second..reset();
final nullAware = (first ?? middle)?..reset();
final conditional = (condition ? first : second)?..reset();
final methodCall = (first ?? second).reset();
final ternaryReceiver = (condition ? first : middle ?? second)..reset();
final ternaryFallback = condition ? second : (middle ?? (second..reset()));
final parenthesizedElse = condition ? second : (first ?? second)..reset();
final coalescingThen = condition ? first ?? second : second..reset();
}Configure cascade-after-null-coalescing
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"suspicious": {
"cascade-after-null-coalescing": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/suspicious/cascade-after-null-coalescing: <reason>More suspicious rules
- control-flow-in-finally
control_flow_in_finallyrecommendedFlags
return,break, orcontinuethat escapes afinallyblock. - empty-catches
empty_catchesrecommendedFlags empty
catchblocks. - empty-statements
empty_statementsrecommendedFlags stray empty statements (a lone
;). - no-duplicate-case-values
no_duplicate_case_valuesrecommendedFlags semantically equal constant values within one switch.
- no-empty-block
no-empty-blockFlags empty blocks (
{}). - no-equal-arguments
no-equal-argumentsFlags an argument passed more than once in the same invocation.
- no-equal-then-else
no-equal-then-elserecommendedFlags an
if/elseor ternary whose two branches are identical. - no-magic-string
Extract inline string literals into named variables or constants.