unnecessary-parenthesis
Same as unnecessary_parenthesis in Dart lints
- Group
- Style
- Path
lint/style/unnecessary-parenthesis- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 470 of 512
Flags parentheses that can be removed without changing the meaning or hurting readability.
Parentheses are always reported when they sit directly inside other
parentheses, a string interpolation, the only argument of an argument list,
or the condition of an if, while, do, or switch. Elsewhere they are
reported around a single token (identifier, literal) or a null-aware chain
unless they are needed: before .hashCode/.runtimeType/.toString()/
.noSuchMethod(), before !, before a member of a nullable-type extension,
or around a null-aware index in a conditional then branch or map key.
Parentheses are kept around conditional expressions, type literals,
cascades and anything inside a cascade, function expressions in a constructor
field initializer, ==/!= comparisons that are assigned, returned, or
yielded, a switch expression starting a statement, and expressions with
internal whitespace (binary, as, is, await, assignments, ...) unless
the parentheses are the whole right-hand side, return value, argument, or
record field. Inside another expression they are kept when the parent is a
binary, conditional, as, is, or function invocation, before a member
access on a prefix/postfix expression, and where removing them would turn a
set or map literal into a statement block.
Generic constructor tear-offs need parentheses when type arguments are
followed by invocation arguments ((C.named)<T>()), but not when the
instantiated tear-off is used as a value ((C.named)<T>). When constructor
signatures are unavailable, a type-qualified target is kept unless it is
known to be a nonconstructor member.
Explicit expression grouping is retained by the parser, including parentheses separated from their expression by comments. Pattern grouping is not an expression and is not reported. The official exemption for a parenthesized non-record argument to a record-typed parameter (a missing trailing comma) only applies to code that does not compile and is not modeled here.
a = (b); // flagged
print((x)); // flagged
a = (b == c); // ok
(b ? c : d).foo(); // ok
Invalid
class Point {
final int x;
final int y;
Point(this.x, int y) : y = (y);
}
int value() => 1;
void f(int a, int b, bool c, String s, List<int> list, int? n) {
a = (b);
print((a));
print((a + b));
if ((c)) {}
while ((c)) {}
print('${(a)}');
var x = (1);
var y = ('text');
var z = (a).isEven;
var w = (s).length;
var v = a + ((b));
var u = (value());
var t = (list[0]);
switch ((a)) {
default:
}
var r = (n?.isEven) ?? false;
print([x, y, z, w, v, u, t, r]);
}
int g(int a) {
return (a);
}
int h(int a) => (a);
void literalTarget() {
(1.5).floor();
print(!(!true));
}
void cascadeClosure(List<int> list) {
list
..forEach((e) {
var even = (e.isEven);
print(even);
});
}
// Only the expression parentheses are reported, not wildcard-pattern grouping.
int groupedSwitch(Object value) => switch ((value)) {
(_) => (1),
};
// A declaration pattern's grouping is not the initializer's expression grouping.
void patternDeclaration() {
var (_) = ('a');
} final int y; Point(this.x, int y) : y = (y);void f(int a, int b, bool c, String s, List<int> list, int? n) { a = (b); a = (b); print((a)); print((a)); print((a + b)); print((a + b)); if ((c)) {} if ((c)) {} while ((c)) {} while ((c)) {} print('${(a)}'); print('${(a)}'); var x = (1); var x = (1); var y = ('text'); var y = ('text'); var z = (a).isEven; var z = (a).isEven; var w = (s).length; var w = (s).length; var v = a + ((b)); var v = a + ((b)); var u = (value()); var u = (value()); var t = (list[0]); var t = (list[0]); switch ((a)) { } var r = (n?.isEven) ?? false;int g(int a) { return (a); int h(int a) => (a);void literalTarget() { (1.5).floor(); (1.5).floor(); print(!(!true)); ..forEach((e) { var even = (e.isEven);// Only the expression parentheses are reported, not wildcard-pattern grouping.int groupedSwitch(Object value) => switch ((value)) {int groupedSwitch(Object value) => switch ((value)) { (_) => (1),void patternDeclaration() { var (_) = ('a');Valid
class Holder {
bool Function() e;
Holder(bool Function()? e) : e = e ?? (() => true);
}
extension NullableString on String? {
bool get isBlank => this == null || this!.isEmpty;
}
int value() => 1;
void f(int a, int b, bool c, String? s, List<int> list, int? n, Object o, List<int>? maybeList) {
var x = a + b;
print(x);
var y = (a + b) * 2;
var z = (c ? a : b).isEven;
var w = (a == b);
c = (a != b);
var v = (o as int).isEven;
var u = !(o is int);
var t = (List<int>).hashCode;
var r = (n)!;
var q = (-a).abs();
var p = (a++).isEven;
var m = (s?.length).hashCode;
var k = (s?.length).toString();
var j = (s?.trim()).isBlank;
var i = (list..clear()).length;
({1, 2, 3}).forEach(print);
(switch (a) { _ => 1 });
print([y, z, w, v, u, t, r, q, p, m, k, j, i]);
print(c ? (maybeList?[0]) : null);
print({(maybeList?[0]): 1});
final items = [...(o as List<int>)];
print(items);
list..add(1)..[0] = (a + b);
}
bool g(int a, int b) {
return (a == b);
}
Iterable<bool> gen(int a, int b) sync* {
yield (a == b);
}
int h(int a, int b) => a * (b + 1);
void cases(Object o) {
switch (o) {
case const (1 + 2):
break;
}
}
class Callback {
bool Function() e;
Callback() : e = (() => true);
}
// Pattern grouping is distinct from parenthesized expressions.
int wildcardPattern(Object? value) => switch (value) {
(_) => 1,
};
int nestedWildcardPattern(Object? value) => switch (value) {
((/* grouping */ _)) => 1,
};
int recordPattern((int?, int?) value) => switch (value) {
(null, final int right) => right,
(final int left, null) => left,
(_) => 0,
};
void statementPattern(Object? value) {
if (value case (_)) {}
switch (value) {
case (_):
break;
}
}
// A pattern initializer has a non-expression declaration parent, unlike an
// ordinary variable initializer.
Future<void> patternInitializers(
int a,
int b,
Object value,
Future<(int, int)> Function() fetch,
) async {
var (sum) = (a + b);
var (cast) = (value as int);
var (check) = (value is int);
final (left, right) = (await fetch());
print([sum, cast, check, left, right]);
}Configure unnecessary-parenthesis
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"unnecessary-parenthesis": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/unnecessary-parenthesis: <reason>More style rules
- unnecessary-raw-strings
unnecessary_raw_stringsrecommendedFlags raw string literals that contain no backslash or
$. - unnecessary-string-escapes
unnecessary_string_escapesrecommendedFlags backslashes that do not affect a string's value.
- unnecessary-string-interpolations
unnecessary_string_interpolationsrecommendedFlags a string literal whose entire content is a single interpolation of a provably non-nullable
String. - unnecessary-this
unnecessary_thisrecommendedFlags a redundant
this.qualifier on member access. - unreachable-from-main
unreachable_from_mainReport public declarations that no entry point of an executable library reaches.
- use-colored-box
use_colored_boxrecommendedflutterPrefers
ColoredBoxover aContainerthat only paints a color behind its child. - use-decorated-box
use_decorated_boxrecommendedflutterPrefers
DecoratedBoxover aContainerthat only decorates its child. - use-design-system-item
use-design-system-itemflutterFlags construction of a widget or type that should be replaced by its design-system equivalent.