Rules / Complexity / prefer-moving-to-variable

prefer-moving-to-variable

lint/complexity/prefer-moving-to-variable
recommended
Same as prefer-moving-to-variable · Dart Code Metrics

Flags a non-trivial expression duplicated across local variable initializers in the same block.

Repeating the same complex expression risks the copies drifting apart and recomputes the work; binding it to one variable names the value and evaluates it once. Within a block, the rule compares local-variable initializer source text (trivial literals and bare identifiers are ignored) and flags a repeat once its occurrence count reaches the threshold.

Options

allowed_duplicated_chains (integer, default: 2) — the occurrence index at which a repeat is flagged; 2 flags the 2nd and later occurrences, 3 the 3rd and later. Values below 2 are clamped to 2.

Invalid

example.dartdart
// Test cases for prefer-moving-to-variable rule
// violations: same non-trivial expression used to initialize two different variables

void duplicateComputation() {
  final a = calculateExpensive(10);
  final b = calculateExpensive(10);
}

void duplicateFieldAccess() {
  final x = obj.property.value;
  final y = obj.property.value;
}

class Processor {
  void process() {
    final first = getResult(data);
    final second = getResult(data);
    combine(first, second);
  }
}

void duplicateBinaryExpression() {
  final x = a + b;
  final y = a + b;
}

void duplicateMethodCall() {
  final v1 = list.where((e) => e > 5).toList();
  final v2 = list.where((e) => e > 5).toList();
}
Duplicate expression — extract to a shared variable
5 final a = calculateExpensive(10);
6 final b = calculateExpensive(10);
Duplicate expression — extract to a shared variable
10 final x = obj.property.value;
11 final y = obj.property.value;
Duplicate expression — extract to a shared variable
16 final first = getResult(data);
17 final second = getResult(data);
Duplicate expression — extract to a shared variable
23 final x = a + b;
24 final y = a + b;
Duplicate expression — extract to a shared variable
28 final v1 = list.where((e) => e > 5).toList();
29 final v2 = list.where((e) => e > 5).toList();

Valid

example.dartdart
// Test cases for prefer-moving-to-variable rule
// No violations: each variable has a distinct initializer or trivial literal

void distinctComputations() {
  final a = calculateExpensive(10);
  final b = calculateExpensive(20);
}

void singleUse() {
  final result = getResult(data);
  print(result);
}

// Trivial literals are not flagged
void trivialLiterals() {
  final x = 42;
  final y = 42;
  final s1 = "hello";
  final s2 = "hello";
}

class Processor {
  void process() {
    final first = getResult(dataA);
    final second = getResult(dataB);
    combine(first, second);
  }
}

// Only one assignment of complex expression
void singleComplexAssignment() {
  final x = obj.method().chain().result;
  print(x);
}

// Identifiers (trivial) don't trigger violation
void identifierDuplicates() {
  final a = variable1;
  final b = variable1;
}

// Different chained calls
void differentChains() {
  final c1 = obj.method1().result;
  final c2 = obj.method2().result;
}

How to configure

Set the severity of prefer-moving-to-variable in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "prefer-moving-to-variable": "error"
      }
    }
  }
}