prefer-const-border-radius

Same as prefer-const-border-radius in Dart Code Metrics

Path
lint/performance/prefer-const-border-radius
Default
On (recommended)
Origin
Dart Code Metrics
Domain
flutter
Rule
326 of 512
recommendedflutter

Flags BorderRadius.only(...) whose four corner radii are all equal.

When every corner uses the same Radius.circular(n), BorderRadius.circular(n) is shorter and const-constructible, so Flutter can canonicalize and reuse the value instead of rebuilding it. The rule fires only when all four corners (topLeft, topRight, bottomLeft, bottomRight) are present and their Radius.circular(...) values are textually equal.

Invalid

example.dartdart
// Test cases for prefer-const-border-radius rule
// Flags BorderRadius.only(...) where all radii are equal

void testAllRadiiEqual() {
  final border1 = BorderRadius.only(
    topLeft: Radius.circular(8),
    topRight: Radius.circular(8),
    bottomLeft: Radius.circular(8),
    bottomRight: Radius.circular(8),
  );

  final border2 = BorderRadius.only(
    topLeft: Radius.circular(16),
    topRight: Radius.circular(16),
    bottomLeft: Radius.circular(16),
    bottomRight: Radius.circular(16),
  );
}

void testInlineAllRadiiEqual() {
  final border = BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
}

class MyWidget {
  final border = BorderRadius.only(
    topLeft: Radius.circular(12),
    topRight: Radius.circular(12),
    bottomLeft: Radius.circular(12),
    bottomRight: Radius.circular(12),
  );
}

void testSmallRadius() {
  final border = BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4), bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4));
}

// Regression: the violation must still be found inside Dart 3 containers
// (pattern declaration, labeled statement, switch expression and subject,
// collection if/spread, record field).
void containersRegression(int rcount) {
  final (ra, _) = (BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), 0);
  lbl: {
    final rb = BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
    print(rb);
  }
  final rc = switch (rcount) {
    0 => BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)),
    _ => null,
  };
  final rd = switch (BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))) {
    _ => 0,
  };
  final re = [if (rcount > 0) BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))];
  final rf = [...[BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))]];
  final rg = (p: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), q: 0);
  print([ra, rc, rd, re, rf, rg]);
}
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
9 bottomRight: Radius.circular(8),
10 );
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
16 bottomRight: Radius.circular(16),
17 );
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
20void testInlineAllRadiiEqual() {
21 final border = BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
24class MyWidget {
25 final border = BorderRadius.only(
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
33void testSmallRadius() {
34 final border = BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4), bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4));
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
40void containersRegression(int rcount) {
41 final (ra, _) = (BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), 0);
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
42 lbl: {
43 final rb = BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
46 final rc = switch (rcount) {
47 0 => BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)),
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
49 };
50 final rd = switch (BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))) {
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
52 };
53 final re = [if (rcount > 0) BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))];
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
53 final re = [if (rcount > 0) BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))];
54 final rf = [...[BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))]];
`BorderRadius.only()` with all equal radii should use `BorderRadius.circular()`.
54 final rf = [...[BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))]];
55 final rg = (p: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), q: 0);

Valid

example.dartdart
// Good examples for prefer-const-border-radius rule
// Using BorderRadius.circular() when appropriate

void testBorderRadiusCircular() {
  final border1 = BorderRadius.circular(8);
  final border2 = BorderRadius.circular(16);
  final border3 = BorderRadius.circular(12);
}

void testBorderRadiusOnlyWithDifferentRadii() {
  final border = BorderRadius.only(
    topLeft: Radius.circular(8),
    topRight: Radius.circular(16),
    bottomLeft: Radius.circular(8),
    bottomRight: Radius.circular(4),
  );
}

void testBorderRadiusByAll() {
  final border = BorderRadius.all(Radius.circular(8));
}

class MyWidget {
  final border1 = BorderRadius.circular(10);
  final border2 = BorderRadius.only(
    topLeft: Radius.circular(8),
    topRight: Radius.circular(12),
  );
  final border3 = BorderRadius.all(Radius.circular(16));
}

Configure prefer-const-border-radius

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "performance": {
        "prefer-const-border-radius": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/performance/prefer-const-border-radius: <reason>
  • prefer-containsprefer_containsrecommended

    Prefers contains to comparing the result of indexOf with a constant.

  • prefer-correct-edge-insets-constructorprefer-correct-edge-insets-constructorrecommendedflutter

    Flags an EdgeInsets.only(...) that a more specific constructor expresses better.

  • prefer-declaring-const-constructorprefer_declaring_const_constructorflutter

    Flags a generative constructor that is legally eligible to be const.

  • prefer-foreachprefer_foreach

    Prefers forEach to a for-in loop that only passes each element to a function.

  • prefer-return-await

    Await returned SDK Futures inside a try body protected by a catch clause.

  • prefer-single-setstateflutter

    Merge consecutive Flutter State.setState statements in the same block.

  • prefer-use-callbackflutter_hooks

    Prefer useCallback for synchronous memoized function literals.

  • prefer-use-memoflutter_hooks

    Prefer memoizing freshly allocated collection values used as hook keys.