avoid-shadowed-extension-methods

Path
lint/suspicious/avoid-shadowed-extension-methods
Default
Off, opt in
Origin
Falcon
Rule
136 of 512

Flags extension instance methods and accessors hidden by their target's members.

Instance members take precedence over implicit extension invocation, so a colliding extension member needs an explicit extension override to be called. Rename it instead. The target is resolved by declaration identity, including aliases and inherited members; getters, fields and setters can also hide a method. Static extension declarations and other extensions do not compete. Unresolved, dynamic and nullable targets are skipped; type parameters are checked only when their resolved non-nullable bound proves the collision. This checks extension declarations, not local variables inside extensions. SDK members absent from the precise instance-signature inventory are skipped.

Invalid

example.dartdart
class Base {
  void inherited() {}
}

class Target extends Base {
  void run() {}
  int get size => 0;
  int field = 0;
  set setting(int value) {}
}

typedef Alias = Target;

extension Hidden on Target {
  void run() {}
  void inherited() {}
  void size() {}
  void field() {}
  int get setting => 1;
}

extension Aliased on Alias {
  void run() {}
}

extension Bounded<T extends Target> on T {
  void inherited() {}
}

extension on Target {
  set size(int value) {}
}
The extension target already has this member. Rename the extension member.
14extension Hidden on Target {
15 void run() {}
The extension target already has this member. Rename the extension member.
15 void run() {}
16 void inherited() {}
The extension target already has this member. Rename the extension member.
16 void inherited() {}
17 void size() {}
The extension target already has this member. Rename the extension member.
17 void size() {}
18 void field() {}
The extension target already has this member. Rename the extension member.
18 void field() {}
19 int get setting => 1;
The extension target already has this member. Rename the extension member.
22extension Aliased on Alias {
23 void run() {}
The extension target already has this member. Rename the extension member.
26extension Bounded<T extends Target> on T {
27 void inherited() {}
The extension target already has this member. Rename the extension member.
30extension on Target {
31 set size(int value) {}

Valid

example.dartdart
class Target {
  void run() {}
  static void staticOnly() {}
}

class Unrelated {
  void differentOwner() {}
}

extension Renamed on Target {
  void customRun() {}
  void differentOwner() {}
  void staticOnly() {}
  static void run() {}
}

extension NullableTarget on Target? {
  void run() {}
}

extension DynamicTarget on dynamic {
  void run() {}
}

extension First on Target {
  void extensionOnly() {}
}

extension Second on Target {
  void extensionOnly() {}
}

extension Unbounded<T> on T {
  void run() {}
}

class OrdinarySubclass extends Target {
  void run() {}
}

extension StaticIntMember on int {
  void parse() {}
}

extension StaticBigIntMember on BigInt {
  void two() {}
}

extension StaticDurationMember on Duration {
  void zero() {}
}

Configure avoid-shadowed-extension-methods

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "suspicious": {
        "avoid-shadowed-extension-methods": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/suspicious/avoid-shadowed-extension-methods: <reason>