avoid-returning-this
Same as avoid_returning_this in Dart lints
- Group
- Style
- Path
lint/style/avoid-returning-this- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 132 of 512
Flags methods that return this only to enable a fluent interface.
Dart's cascade operator (..) chains calls on the same receiver without any
cooperation from the API, so a method returning its own receiver adds
nothing but a misleading return type. Return void and let callers cascade.
class Builder {
Builder add(int x) { // flagged at `return this`
_items.add(x);
return this;
}
Builder clear() => this; // flagged at `clear`
}
Only methods whose declared return type is the enclosing class, enum, or
mixin and whose every return yields an unparenthesized this are reported.
Methods that override an inherited member are exempt.
Invalid
class Builder {
final List<int> _items = [];
Builder add(int x) {
_items.add(x);
return this;
}
Builder clear() => this;
Builder addAll(List<int> xs) {
if (xs.isEmpty) {
return this;
}
_items.addAll(xs);
return this;
}
Builder get self => this;
}
class Generic<T> {
Generic<T> touch() => this;
}
mixin Fluent {
Fluent reset() {
return this;
}
}
enum Level {
low;
Level same() => this;
}
// An unresolved superclass does not establish an override.
class Remote extends SomeUnknownBase {
Remote ping() => this;
}
class NestedReturns {
NestedReturns run() {
NestedReturns local() {
return NestedReturns();
}
final callback = () {
return NestedReturns();
};
return this;
}
}
class ControlReturns {
ControlReturns guarded(bool fail) {
try {
if (fail) throw StateError('failed');
return this;
} catch (_) {
return this;
} finally {
return this;
}
}
ControlReturns branches(int value) {
switch (value) {
case 0:
return this;
default:
outer:
for (var i = 0; i < value; i++) {
if (i == 1) return this;
break outer;
}
}
while (value-- > 0) {
return this;
}
do {
return this;
} while (false);
}
ControlReturns callbacks() {
final callback = () {
return this;
};
ControlReturns local() {
return this;
}
return this;
}
} _items.add(x); return this; Builder clear() => this; if (xs.isEmpty) { return this; Builder get self => this;class Generic<T> { Generic<T> touch() => this; Fluent reset() { return this; Level same() => this;class Remote extends SomeUnknownBase { Remote ping() => this; }; return this; if (fail) throw StateError('failed'); return this; case 0: return this; } return this;Valid
class Builder {
final List<int> _items = [];
// Use cascades instead of returning `this`.
void add(int x) => _items.add(x);
// Returns a new instance, not `this`.
Builder copy() => Builder().._items.addAll(_items);
// Some paths return something else.
Builder pick(Builder other, bool first) {
if (first) return this;
return other;
}
// Return type is not the enclosing type.
Object identity() => this;
// Operators are not methods.
Builder operator +(int x) => this;
}
// Overriding an inherited member is required by the interface.
abstract class Chain {
Chain next();
}
class Link implements Chain {
@override
Chain next() => this;
}
class Node extends Link {
@override
Link next() => this;
}
// Extensions are not checked.
extension on String {
String same() => this;
}
// Static methods cannot return `this`; nested closures do not count.
class Holder {
Holder run() {
final f = () => this;
return Holder();
}
}
class GroupedReceiver {
GroupedReceiver arrow() => (this);
GroupedReceiver block() {
return (/* grouping is significant to this lint */ this);
}
GroupedReceiver mixed(bool flag) {
if (flag) return this;
return ((this));
}
}
class NestedOnly {
NestedOnly run() {
NestedOnly local() {
return this;
}
final callback = () {
return this;
};
}
}
class ReturnedClosure {
ReturnedClosure run() {
return (() {
return this;
})();
}
}Configure avoid-returning-this
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"avoid-returning-this": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/avoid-returning-this: <reason>More style rules
- avoid-setters-without-getters
avoid_setters_without_gettersFlags a setter that has no corresponding getter.
- avoid-single-cascade-in-expression-statements
avoid_single_cascade_in_expression_statementsrecommendedFlags an expression statement that is a cascade with a single section.
- avoid-single-child-column-or-row
avoid_single_child_column_or_rowflutterFlags a
Column,Row, orFlexwidget built with a single child. - avoid-top-level-member-access
Flags mutable global state: non-
const, non-finaltop-level variables and static fields, plus every read of mutable top-level variables. - avoid-types-on-closure-parameters
avoid_types_on_closure_parametersFlags type annotations on closure parameters whose types come from context.
- avoid-unnecessary-block
Flags standalone nested blocks that introduce no lexical declarations.
- avoid-unnecessary-call
Prefer direct invocation of functions and resolved callable instances.
- avoid-unnecessary-continue
Flags an unlabeled continue at the end of a loop body or its final branch.