use-setters-to-change-properties

Same as use_setters_to_change_properties in Dart lints

Group
Style
Path
lint/style/use-setters-to-change-properties
Default
Off, opt in
Origin
Dart lints
Rule
503 of 512

Flags one-parameter void methods that only assign that parameter to a field.

A method whose whole body is field = value conceptually changes a property; a setter states that directly and lets callers use assignment syntax.

class Rectangle {
  num width = 0;
  void setWidth(num width) {   // flagged
    this.width = width;
  }
  set height(num value) => _height = value;  // preferred
}

The assignment target must resolve to a field or setter, including a property on another typed receiver. Overriding methods are exempt; extension methods never override, even with @override. Extension receivers use their declared type-parameter bounds; null assertions and null-aware assignments look up properties on the non-null receiver. Unavailable external inheritance metadata conservatively exempts public methods; private names cannot override across libraries.

Invalid

example.dartdart
class Rectangle {
  num width = 0;
  num _height = 0;

  void setWidth(num width) {
    this.width = width;
  }

  void changeHeight(num value) => _height = value;

  void updateWidth(num value) {
    width = value;
  }

  num get height => _height;
}

class Base {
  int count = 0;
}

// Inherited field assigned through `this`.
class Derived extends Base {
  void setCount(int value) => this.count = value;
}

mixin Named {
  String name = '';

  void rename(String newName) => name = newName;
}

// Assigning through an explicit setter.
class Box {
  int _size = 0;
  set size(int value) => _size = value;
  int get size => _size;

  void resize(int value) {
    size = value;
  }
}

class Remote extends SomeUnknownBase {
  int port = 0;
  void setPort(int value) => port = value;
}

class PropertyBase {
  int port = 0;
}
class InheritedProperty extends PropertyBase {
  void setPort(int value) => port = value;
}

class Payload {
  int value = 0;
}
class WritesOther {
  final Payload payload = Payload();
  void update(int value) => payload.value = value;
  void updateArgument(Payload other) => other.value = other.value;
}

// Resolve the implicit property target through a locally declared extension.
class ExtensionTarget {
  int value = 0;
}

extension ChangeValue on ExtensionTarget {
  void changeValue(int newValue) {
    value = newValue;
  }

  void changeExplicitly(int newValue) => this.value = newValue;
}
The method is used to change a property.
4
5 void setWidth(num width) {
The method is used to change a property.
8
9 void changeHeight(num value) => _height = value;
The method is used to change a property.
10
11 void updateWidth(num value) {
The method is used to change a property.
23class Derived extends Base {
24 void setCount(int value) => this.count = value;
The method is used to change a property.
29
30 void rename(String newName) => name = newName;
The method is used to change a property.
38
39 void resize(int value) {
The method is used to change a property.
45 int port = 0;
46 void setPort(int value) => port = value;
The method is used to change a property.
52class InheritedProperty extends PropertyBase {
53 void setPort(int value) => port = value;
The method is used to change a property.
60 final Payload payload = Payload();
61 void update(int value) => payload.value = value;
The method is used to change a property.
70extension ChangeValue on ExtensionTarget {
71 void changeValue(int newValue) {
The method is used to change a property.
74
75 void changeExplicitly(int newValue) => this.value = newValue;

Valid

example.dartdart
class Rectangle {
  num _width = 0;
  num _height = 0;

  set width(num value) => _width = value;
  num get width => _width;

  // Not a plain assignment of the parameter.
  void doubleHeight(num value) => _height = value * 2;

  // More than one statement.
  void setBoth(num value) {
    _width = value;
    _height = value;
  }

  // Compound assignment.
  void grow(num value) => _height += value;

  // Non-void return type.
  num setHeight(num value) => _height = value;

  // Two parameters.
  void resize(num w, num h) => _width = w;

  num get height => _height;
}

// Overriding an inherited method.
abstract class Settable {
  void setValue(int value);
}

class Impl implements Settable {
  int value = 0;

  @override
  void setValue(int value) => this.value = value;
}

// Assigning a top-level variable is not a property change.
int globalCount = 0;

class Counter {
  void setGlobal(int value) => globalCount = value;
}


// Implementing an SDK interface member.
class Recorder implements Sink<int> {
  int last = 0;
  void add(int data) {
    last = data;
  }

  void close() {}
}

class ExtensionTarget {
  int value = 0;
}

extension ChangeValue on ExtensionTarget {
  void updateLocal(int newValue) {
    var value = 0;
    value = newValue;
  }

  void updateGlobal(int newValue) => globalCount = newValue;
}

Configure use-setters-to-change-properties

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "use-setters-to-change-properties": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/style/use-setters-to-change-properties: <reason>