avoid-unused-parameters

Same as avoid-unused-parameters in Dart Code Metrics

Path
lint/correctness/avoid-unused-parameters
Default
On (recommended)
Origin
Dart Code Metrics
Rule
184 of 512
recommended

Disallow declared parameters that are never used, excluding primary constructors.

Invalid

example.dartdart
// Test cases for avoid-unused-parameters rule
// Flags function/method parameters that are declared but never referenced

void logMessage(String message, String unused) {
  print(message);
}

void processData(int value, String ignore, bool flag) {
  print(value);
  if (flag) {
    print("flagged");
  }
}

void simpleUnused(String name, String unused) {
  return;
}

class MyClass {
  void method(int id, String unused) {
    print(id);
  }

  void anotherMethod(int a, int b, int c) {
    print(a);
  }

  static void staticMethod(String key, String ignored) {
    print(key);
  }
}

typedef Callback = void Function(String result, String unused);

void functionWithCallback(Callback cb, String unused) {
  cb("result");
}

Future<void> asyncFunction(int timeout, String unused) {
  return Future.delayed(Duration(milliseconds: timeout));
}

extension StringExt on String {
  void customMethod(String value, String unused) {
    print(value);
  }
}

// A name appearing inside an interpolation only as a member (`${obj.param}`) is
// not a read of the parameter. Scanning the raw text collected it and silently
// suppressed this report; the parsed interpolations do not.
class InterpolationPrecision {
  String memberNotParameter(Object obj, int param) {
    return "value ${obj.param}";
  }
}

void shadowedByCallback(int value) {
  [1].map((value) => value + 1).toList();
}

class ConstructorParameters {
  ConstructorParameters(int unused) {
    print('constructed');
  }
}

void localFunctionParameters() {
  void local(int used, int unused) {
    print(used);
  }
  local(1, 2);
}
Parameter `unused` is declared but not used.
3
4void logMessage(String message, String unused) {
Parameter `ignore` is declared but not used.
7
8void processData(int value, String ignore, bool flag) {
Parameter `name` is declared but not used.
14
15void simpleUnused(String name, String unused) {
Parameter `unused` is declared but not used.
14
15void simpleUnused(String name, String unused) {
Parameter `unused` is declared but not used.
19class MyClass {
20 void method(int id, String unused) {
Parameter `b` is declared but not used.
23
24 void anotherMethod(int a, int b, int c) {
Parameter `c` is declared but not used.
23
24 void anotherMethod(int a, int b, int c) {
Parameter `ignored` is declared but not used.
27
28 static void staticMethod(String key, String ignored) {
Parameter `unused` is declared but not used.
34
35void functionWithCallback(Callback cb, String unused) {
Parameter `unused` is declared but not used.
38
39Future<void> asyncFunction(int timeout, String unused) {
Parameter `unused` is declared but not used.
43extension StringExt on String {
44 void customMethod(String value, String unused) {
Parameter `param` is declared but not used.
52class InterpolationPrecision {
53 String memberNotParameter(Object obj, int param) {
Parameter `value` is declared but not used.
57
58void shadowedByCallback(int value) {
Parameter `unused` is declared but not used.
62class ConstructorParameters {
63 ConstructorParameters(int unused) {
Parameter `unused` is declared but not used.
68void localFunctionParameters() {
69 void local(int used, int unused) {

Valid

example.dartdart
// Good examples for avoid-unused-parameters rule
// Using all declared parameters

void logMessage(String message) {
  print(message);
}

void processData(int value, String name, bool flag) {
  print(value);
  print(name);
  if (flag) {
    print("flagged");
  }
}

void usingAllParameters(String a, String b, String c) {
  print(a);
  print(b);
  print(c);
}

class MyClass {
  void method(int id, String name) {
    print(id);
    print(name);
  }

  void anotherMethod(int a, int b, int c) {
    print(a + b + c);
  }

  static void staticMethod(String key, String value) {
    print("$key: $value");
  }
}

typedef Callback = void Function(String result);

void functionWithCallback(Callback cb) {
  cb("result");
}

Future<void> asyncFunction(int timeout) {
  return Future.delayed(Duration(milliseconds: timeout));
}

extension StringExt on String {
  void customMethod(String value) {
    print(value);
  }

  int compareWith(String other) {
    return length.compareTo(other.length);
  }
}

void functionUsingInNestedScope(String param) {
  void inner() {
    print(param);
  }
  inner();
}

// Parameter used only inside a closure with a BLOCK body (regression: the
// reference collector must descend into block-bodied closures).
List<int> mapInClosure(int factor) {
  return [1, 2, 3].map((x) {
    return x * factor;
  }).toList();
}

// Parameter used only inside a switch-case body.
String describe(int code) {
  switch (code) {
    case 200:
      return 'ok';
    default:
      return 'code $code';
  }
}

// Parameter used only inside a cascade section.
void configure(Object target, String label) {
  target
    ..toString()
    ..hashCode.toString()
    ..runtimeType.toString();
  print(label);
}

class Overrides {
  // @override methods keep the supertype's parameter list; an unused param here
  // is not the author's to remove, so it is exempt.
  @override
  void didUpdateWidget(Object oldWidget) {
    print('updated');
  }
}

// All-underscore parameter names are conventional "unused" markers.
void ignoresArgs(int __, String ___) {
  print('ignored');
}

// Parameter used only inside a map-comprehension iterable
// (`{ for (..) k: v }` lives in `Map.elements`, not `Map.entries`).
Map<String, int> buildLookup(List<String> keys) {
  return {for (final k in keys) k: k.length};
}

// Dart 3 destructuring: the parameter is read only in the initializer of a
// pattern declaration / pattern assignment / pattern for-in, or inside a
// labeled statement.
String recordPatternDecl(Object shape) {
  final (label, sides) = switch (shape) {
    int() => ('int', 0),
    _ => ('other', 4),
  };

  return '$label$sides';
}

String recordPatternAssign(Object shape) {
  String label;
  int sides;
  (label, sides) = switch (shape) {
    int() => ('int', 0),
    _ => ('other', 4),
  };

  return '$label$sides';
}

int patternForIn(List<(int, int)> pairs) {
  var total = 0;
  for (final (a, b) in pairs) {
    total += a + b;
  }

  return total;
}

int labeledLoop(int value) {
  outer:
  for (var i = 0; i < 3; i++) {
    if (value > 1) break outer;
  }

  return 0;
}

// Parameter used only as a bare generic tear-off (`fn<int>`, no call).
void useTearOff(T Function<T>(T) fn) {
  final g = fn<int>;
  print(g);
}

// A genuine interpolated read still counts as a use, in both `$id` and
// `${expr}` form.
class InterpolationReads {
  String simple(int count) => "n=$count";

  String complex(int count) => "n=${count + 1}";
}

// A Dart 3 pattern assignment writes to its targets, which counts as a use
// just as a plain `x = …` assignment does.
class PatternAssignTarget {
  void reassign(int a, int b) {
    (a, b) = (1, 2);
  }
}

void sourceOrderAndNestedScopes(int value) {
  print(value);
  {
    final value = 1;
    print(value);
  }
}

void capturedOutsideShadow(int value) {
  final callback = () => value;
  for (final value in [1]) {
    print(value);
  }
  print(callback());
}

class FieldFormal {
  final int value;

  FieldFormal(this.value) {
    print('constructed');
  }
}

class InitializerUse {
  final int value;

  InitializerUse(int input) : value = input;
}

class Base {
  Base({int? key});
}

class SuperFormal extends Base {
  SuperFormal({super.key}) {
    print('constructed');
  }
}

void usedLocalFunctionParameter() {
  void local(int value) {
    print(value);
  }
  local(1);
}

void unbracedIfScope(int value, bool condition) {
  if (condition) int value = 1;
  print(value);
}

void unbracedElseScope(int value, bool condition) {
  if (condition) print('then'); else int value = 1;
  print(value);
}

void unbracedWhileScope(int value, bool condition) {
  while (condition) int value = 1;
  print(value);
}

void unbracedDoScope(int value, bool condition) {
  do int value = 1; while (condition);
  print(value);
}

void unbracedForScope(int value, bool condition) {
  for (; condition;) int value = 1;
  print(value);
}

Configure avoid-unused-parameters

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-unused-parameters": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/correctness/avoid-unused-parameters: <reason>
  • avoid-watch-outside-buildrecommendedprovider

    Flags listening Provider accesses proven to run outside Flutter builds.

  • avoid-web-libraries-in-flutteravoid_web_libraries_in_flutterrecommendedflutter

    Disallow importing web-only dart: libraries from Flutter code.

  • await-only-futuresawait_only_futuresrecommended

    Await only values assignable to futures; FutureOr, dynamic, bottom types and extension types are accepted like the analyzer.

  • banned-importscross-file

    Report imports forbidden by package-relative architectural boundaries.

  • cancel-subscriptionscancel_subscriptionsrecommended

    Cancel instances of dart:async StreamSubscription.

  • check-is-not-closed-after-async-gaprecommendedbloc

    Flags Bloc add and emit calls after an await without a fresh isClosed check.

  • close-sinksclose_sinksrecommended

    Close instances of dart:core Sink.

  • collection-methods-unrelated-typecollection_methods_unrelated_typerecommended

    Reports collection lookups whose argument type is unrelated to the collection's type argument.