avoid-duplicate-factories

Path
lint/correctness/avoid-duplicate-factories
Default
Off, opt in
Origin
Falcon
Rule
49 of 512

Flags factories in one type with the same implementation, ignoring factory names and alpha-renaming parameters by position. Local bindings and closures are skipped rather than confusing shadowed names with constructor parameters.

Invalid

example.dartdart
class A {
  A(int value);
  factory A.first(int data) => A(data);
  factory A.second(int renamed) => A(renamed);
}
class B {
  B();
  factory B.empty() => B();
  factory B.withData(String unused) => B();
}
class C {
  C(int value);
  factory C.first(int x) { return C(x + 1); }
  factory C.second(int y) => C(y + 1);
}
class D {
  D(int left, int right);
  factory D.first(int x, int y) => D(x, y);
  factory D.second(int a, int b) => D(a, b);
}
class E {
  E(String value);
  factory E.first() => E('constant');
  factory E.second() => E( 'constant' );
}
class F {
  factory F.first() = G;
  factory F.second() = G;
}
class G implements F { G(); }
class ConditionalBinding {
  final int result;
  ConditionalBinding._(this.result);
  factory ConditionalBinding.a(bool flag, int value) =>
      ConditionalBinding._(flag ? value : 0);
  factory ConditionalBinding.b(bool flag, int other) => ConditionalBinding._(flag ? other : 0);
}
class MapKeys {
  MapKeys._(Map<int, int> values);
  factory MapKeys.a(int value) => MapKeys._({value: 0});
  factory MapKeys.b(int other) => MapKeys._({other: 0});
}
class RecordValues {
  RecordValues._(Object value);
  factory RecordValues.a(int value) => RecordValues._((result: value));
  factory RecordValues.b(int other) => RecordValues._((result: other));
}
class RecordTypes {
  RecordTypes._(Object value);
  factory RecordTypes.a(Object value) => RecordTypes._(value as ({int value}));
  factory RecordTypes.b(Object other) => RecordTypes._(other as ({int value}));
}
This factory has the same implementation as `A.first` — remove it or add unique functionality.
3 factory A.first(int data) => A(data);
4 factory A.second(int renamed) => A(renamed);
This factory has the same implementation as `B.empty` — remove it or add unique functionality.
8 factory B.empty() => B();
9 factory B.withData(String unused) => B();
This factory has the same implementation as `C.first` — remove it or add unique functionality.
13 factory C.first(int x) { return C(x + 1); }
14 factory C.second(int y) => C(y + 1);
This factory has the same implementation as `D.first` — remove it or add unique functionality.
18 factory D.first(int x, int y) => D(x, y);
19 factory D.second(int a, int b) => D(a, b);
This factory has the same implementation as `E.first` — remove it or add unique functionality.
23 factory E.first() => E('constant');
24 factory E.second() => E( 'constant' );
This factory has the same implementation as `F.first` — remove it or add unique functionality.
27 factory F.first() = G;
28 factory F.second() = G;
This factory has the same implementation as `ConditionalBinding.a` — remove it or add unique functionality.
35 ConditionalBinding._(flag ? value : 0);
36 factory ConditionalBinding.b(bool flag, int other) => ConditionalBinding._(flag ? other : 0);
This factory has the same implementation as `MapKeys.a` — remove it or add unique functionality.
40 factory MapKeys.a(int value) => MapKeys._({value: 0});
41 factory MapKeys.b(int other) => MapKeys._({other: 0});
This factory has the same implementation as `RecordValues.a` — remove it or add unique functionality.
45 factory RecordValues.a(int value) => RecordValues._((result: value));
46 factory RecordValues.b(int other) => RecordValues._((result: other));
This factory has the same implementation as `RecordTypes.a` — remove it or add unique functionality.
50 factory RecordTypes.a(Object value) => RecordTypes._(value as ({int value}));
51 factory RecordTypes.b(Object other) => RecordTypes._(other as ({int value}));

Valid

example.dartdart
class A {
  A(int value);
  factory A.first(int data) => A(data);
  factory A.second(int data) => A(data + 1);
}
class B {
  B(String value);
  factory B.first() => B('a b');
  factory B.second() => B('ab');
}
class C {
  C(int left, int right);
  factory C.first(int x, int y) => C(x, y);
  factory C.second(int a, int b) => C(b, a);
}
class D {
  D(int value);
  factory D.first(int x) => D(x);
}
class E {
  E(int value);
  factory E.first(int x) => E(x);
}
class F {
  F(int value);
  factory F.first(dynamic value) => F(value.first);
  factory F.second(dynamic other) => F(other.second);
}
class H {
  H(int value);
  factory H.first(int data) { final x = data + 1; return H(x); }
  factory H.second(int data) { final x = data + 2; return H(x); }
}
class Foo {
  Foo._();
  int value = 0;
  int count = 0;
  factory Foo.a(int value) => Foo._()..value = value;
  factory Foo.b(int count) => Foo._()..count = count;
}
class V {
  V._(Object value);
  factory V.fromInt(int v) => V._(v);
  factory V.fromString(String v) => V._(v);
}
class P {
  P(double value);
  factory P.small({double v = 4}) => P(v);
  factory P.large({double v = 16}) => P(v);
}
abstract class Q {
  const factory Q.a() = R;
  factory Q.b() = R;
}
class R implements Q { const R(); }
class ConditionalBinding {
  static int value = 7;
  final int result;
  ConditionalBinding._(this.result);
  factory ConditionalBinding.a(bool flag, int value) =>
      ConditionalBinding._(flag ? value : 0);
  factory ConditionalBinding.b(bool flag, int other) =>
      ConditionalBinding._(flag ? value : 0);
}
class NamedLabels {
  NamedLabels._({int value = 0, int other = 0});
  factory NamedLabels.a(int value) => NamedLabels._(value: value);
  factory NamedLabels.b(int other) => NamedLabels._(other: other);
}
class RecordLabels {
  RecordLabels._(Object value);
  factory RecordLabels.a(int value) => RecordLabels._((value: value));
  factory RecordLabels.b(int other) => RecordLabels._((other: other));
}
class RecordTypes {
  RecordTypes._(Object value);
  factory RecordTypes.a(Object value) => RecordTypes._(value as ({int value}));
  factory RecordTypes.b(Object other) => RecordTypes._(other as ({int other}));
}

Configure avoid-duplicate-factories

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-duplicate-factories": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/correctness/avoid-duplicate-factories: <reason>