[M] Change in dart/sdk[main]: [analyzer] introduce `UNNECESSARY_SET_LITERAL`

0 views
Skip to first unread message

Ahmed Ashour (Gerrit)

unread,
Jan 26, 2023, 10:38:19 AM1/26/23
to rev...@dartlang.org

Ahmed Ashour has uploaded this change for review.

View Change

[analyzer] introduce `UNNECESSARY_SET_LITERAL`

Fixes #50900

Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
---
M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
M pkg/analyzer/lib/src/error/best_practices_verifier.dart
M pkg/analyzer/lib/src/error/error_code_values.g.dart
M pkg/analyzer/messages.yaml
M pkg/analyzer/test/src/diagnostics/test_all.dart
A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
7 files changed, 125 insertions(+), 7 deletions(-)

diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index e8e1748..3d22663 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -1629,6 +1629,10 @@
status: hasFix
HintCode.UNNECESSARY_QUESTION_MARK:
status: hasFix
+HintCode.UNNECESSARY_SET_LITERAL:
+ status: needsFix
+ notes: |-
+ Remove the set literal.
HintCode.UNNECESSARY_TYPE_CHECK_FALSE:
status: hasFix
HintCode.UNNECESSARY_TYPE_CHECK_TRUE:
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index cc68cbd..eb02b3f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -1135,6 +1135,14 @@
);

/// No parameters.
+ static const HintCode UNNECESSARY_SET_LITERAL = HintCode(
+ 'UNNECESSARY_SET_LITERAL',
+ "Unneeded set literal for a single expression in a function expression "
+ "with a 'void' return type.",
+ correctionMessage: "Try removing the set literal around th expression.",
+ );
+
+ /// No parameters.
static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCode(
'UNNECESSARY_TYPE_CHECK',
"Unnecessary type check; the result is always 'false'.",
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 7e468b3..28ee153 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -585,8 +585,10 @@

@override
void visitFunctionExpression(FunctionExpression node) {
+ var body = node.body;
if (node.parent is! FunctionDeclaration) {
- _checkForMissingReturn(node.body, node);
+ _checkForMissingReturn(body, node);
+ _checkForUnnecessarySetLiteral(body, node);
}
if (!(node as FunctionExpressionImpl).wasFunctionTypeSupplied) {
_checkStrictInferenceInParameters(node.parameters, body: node.body);
@@ -1553,6 +1555,22 @@
return false;
}

+ void _checkForUnnecessarySetLiteral(
+ FunctionBody body, FunctionExpression node) {
+ if (body is ExpressionFunctionBodyImpl) {
+ var parameterType = node.staticParameterElement?.type;
+ if (parameterType is FunctionType && parameterType.returnType.isVoid) {
+ var expression = body.expression;
+ if (expression is SetOrMapLiteralImpl &&
+ expression.isSet &&
+ expression.elements.length == 1) {
+ _errorReporter.reportErrorForNode(
+ HintCode.UNNECESSARY_SET_LITERAL, expression);
+ }
+ }
+ }
+ }
+
void _checkRequiredParameter(FormalParameterList node) {
final requiredParameters =
node.parameters.where((p) => p.declaredElement?.hasRequired == true);
diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart
index 2a67b49..ad8b7da 100644
--- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
+++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
@@ -669,6 +669,7 @@
HintCode.UNNECESSARY_NULL_COMPARISON_FALSE,
HintCode.UNNECESSARY_NULL_COMPARISON_TRUE,
HintCode.UNNECESSARY_QUESTION_MARK,
+ HintCode.UNNECESSARY_SET_LITERAL,
HintCode.UNNECESSARY_TYPE_CHECK_FALSE,
HintCode.UNNECESSARY_TYPE_CHECK_TRUE,
HintCode.UNREACHABLE_SWITCH_CASE,
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 56df52a..6cdd659 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -1021,7 +1021,7 @@
```
ASYNC_FOR_IN_WRONG_CONTEXT:
problemMessage: The async for-in loop can only be used in an async function.
- correctionMessage: "Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for-in loop."
+ correctionMessage: Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for-in loop.
hasPublishedDocs: true
comment: No parameters.
documentation: |-
@@ -1122,13 +1122,13 @@
```
AWAIT_IN_WRONG_CONTEXT:
problemMessage: The await expression can only be used in an async function.
- correctionMessage: "Try marking the function body with either 'async' or 'async*'."
+ correctionMessage: Try marking the function body with either 'async' or 'async*'.
comment: |-
16.30 Await Expressions: It is a compile-time error if the function
immediately enclosing _a_ is not declared asynchronous. (Where _a_ is the
await expression.)
BODY_MIGHT_COMPLETE_NORMALLY:
- problemMessage: "The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type."
+ problemMessage: The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type.
correctionMessage: Try adding either a return or a throw statement at the end.
hasPublishedDocs: true
comment: |-
@@ -1207,7 +1207,7 @@
}
```
BREAK_LABEL_ON_SWITCH_MEMBER:
- problemMessage: "A break label resolves to the 'case' or 'default' statement."
+ problemMessage: A break label resolves to the 'case' or 'default' statement.
hasPublishedDocs: true
comment: No parameters.
documentation: |-
@@ -1264,7 +1264,7 @@
}
```
BUILT_IN_IDENTIFIER_AS_TYPE:
- problemMessage: "The built-in identifier '{0}' can't be used as a type."
+ problemMessage: The built-in identifier '{0}' can't be used as a type.
correctionMessage: Try correcting the name to match an existing type.
hasPublishedDocs: true
comment: |-
@@ -6927,7 +6927,7 @@

This error is only reported in libraries which are not null safe.
INVALID_CAST_FUNCTION_EXPR:
- problemMessage: "The function expression type '{0}' isn't of type '{1}'. This means its parameter or return type doesn't match what is expected. Consider changing parameter type(s) or the returned type(s)."
+ problemMessage: The function expression type '{0}' isn't of type '{1}'. This means its parameter or return type doesn't match what is expected. Consider changing parameter type(s) or the returned type(s).
comment: |-
Parameters:
0: the type of the torn-off function expression
@@ -20614,6 +20614,11 @@
```dart
dynamic x;
```
+ UNNECESSARY_SET_LITERAL:
+ problemMessage: Unneeded set literal for a single expression in a function expression with a 'void' return type.
+ correctionMessage: Try removing the set literal around th expression.
+ hasPublishedDocs: false
+ comment: No parameters.
UNNECESSARY_TYPE_CHECK_FALSE:
sharedName: UNNECESSARY_TYPE_CHECK
problemMessage: "Unnecessary type check; the result is always 'false'."
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 0263ccc..9de9d6a 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -810,6 +810,7 @@
as unnecessary_null_check_pattern;
import 'unnecessary_null_comparison_test.dart' as unnecessary_null_comparison;
import 'unnecessary_question_mark_test.dart' as unnecessary_question_mark;
+import 'unnecessary_set_literal_test.dart' as unnecessary_set_literal;
import 'unnecessary_type_check_test.dart' as unnecessary_type_check;
import 'unqualified_reference_to_non_local_static_member_test.dart'
as unqualified_reference_to_non_local_static_member;
@@ -1384,6 +1385,7 @@
unnecessary_null_check_pattern.main();
unnecessary_null_comparison.main();
unnecessary_question_mark.main();
+ unnecessary_set_literal.main();
unnecessary_type_check.main();
unqualified_reference_to_non_local_static_member.main();
unqualified_reference_to_static_member_of_extended_type.main();
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
new file mode 100644
index 0000000..b908d55
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UnnecessarySetLiteralTest);
+ });
+}
+
+@reflectiveTest
+class UnnecessarySetLiteralTest extends PubPackageResolutionTest {
+ test_blockFunctionBody() async {
+ await assertNoErrorsInCode(r'''
+void g(void Function(int) fun) {}
+
+void f() {
+ g((value) {1;});
+}
+''');
+ }
+
+ test_closure_map() async {
+ await assertNoErrorsInCode(r'''
+void g(void Function(int) fun) {}
+
+void f() {
+ g((value) => {1: 2});
+}
+''');
+ }
+
+ test_closure_multipleElements() async {
+ await assertNoErrorsInCode(r'''
+void g(void Function(int) fun) {}
+
+void f() {
+ g((value) => {1, 2});
+}
+''');
+ }
+
+ test_closure_object() async {
+ await assertNoErrorsInCode(r'''
+void g(Object Function(int) fun) {}
+
+void f() {
+ g((value) => {1});
+}
+''');
+ }
+
+ test_closure_void() async {
+ await assertErrorsInCode(r'''
+void g(void Function(int) fun) {}
+
+void f() {
+ g((value) => {1});
+}
+''', [
+ error(HintCode.UNNECESSARY_SET_LITERAL, 61, 3),
+ ]);
+ }
+}

To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
Gerrit-Change-Number: 279962
Gerrit-PatchSet: 1
Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
Gerrit-MessageType: newchange

Ahmed Ashour (Gerrit)

unread,
Jan 26, 2023, 10:43:13 AM1/26/23
to rev...@dartlang.org

Ahmed Ashour uploaded patch set #2 to this change.

View Change

[analyzer] introduce `UNNECESSARY_SET_LITERAL`

Fixes #50900

Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
---
M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
M pkg/analyzer/lib/src/error/best_practices_verifier.dart
M pkg/analyzer/lib/src/error/error_code_values.g.dart
M pkg/analyzer/messages.yaml
M pkg/analyzer/test/src/diagnostics/test_all.dart
A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
7 files changed, 125 insertions(+), 7 deletions(-)

To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
Gerrit-Change-Number: 279962
Gerrit-PatchSet: 2
Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
Gerrit-MessageType: newpatchset

Brian Wilkerson (Gerrit)

unread,
Jan 26, 2023, 10:54:45 AM1/26/23
to Ahmed Ashour, rev...@dartlang.org, Brian Wilkerson

Attention is currently required from: Ahmed Ashour.

View Change

1 comment:

  • Patchset:

    • Patch Set #2:

      I would prefer to resolve the question of the breadth of the warning before we try to implement it.

      Discussion in the issue.

To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
Gerrit-Change-Number: 279962
Gerrit-PatchSet: 2
Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
Gerrit-Comment-Date: Thu, 26 Jan 2023 15:54:40 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

CBuild (Gerrit)

unread,
Jan 26, 2023, 12:03:39 PM1/26/23
to Ahmed Ashour, rev...@dartlang.org, Commit Queue, Samuel Rawlins, Brian Wilkerson

Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

go/dart-cbuild result: FAILURE (REGRESSIONS DETECTED)

Details: https://goto.google.com/dart-cbuild/find/79f690bf00b102ec3e79a278db0829e83f2a5c43
Bugs: go/dart-cbuild-bug/79f690bf00b102ec3e79a278db0829e83f2a5c43

View Change

    To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
    Gerrit-Change-Number: 279962
    Gerrit-PatchSet: 2
    Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
    Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
    Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
    Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
    Gerrit-Comment-Date: Thu, 26 Jan 2023 17:03:34 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Ahmed Ashour (Gerrit)

    unread,
    Jan 26, 2023, 1:23:51 PM1/26/23
    to rev...@dartlang.org

    Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

    Ahmed Ashour uploaded patch set #3 to this change.

    View Change

    [analyzer] introduce `UNNECESSARY_SET_LITERAL`

    Fixes #50900

    Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
    ---
    M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
    M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
    M pkg/analyzer/lib/src/error/best_practices_verifier.dart
    M pkg/analyzer/lib/src/error/error_code_values.g.dart
    M pkg/analyzer/messages.yaml
    M pkg/analyzer/test/src/diagnostics/test_all.dart
    A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
    7 files changed, 136 insertions(+), 7 deletions(-)

    To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
    Gerrit-Change-Number: 279962
    Gerrit-PatchSet: 3
    Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
    Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
    Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
    Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
    Gerrit-MessageType: newpatchset

    Ahmed Ashour (Gerrit)

    unread,
    Jan 26, 2023, 1:24:20 PM1/26/23
    to rev...@dartlang.org, CBuild, Commit Queue, Samuel Rawlins, Brian Wilkerson

    Attention is currently required from: Samuel Rawlins.

    View Change

    1 comment:

    To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
    Gerrit-Change-Number: 279962
    Gerrit-PatchSet: 3
    Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
    Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
    Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
    Gerrit-Comment-Date: Thu, 26 Jan 2023 18:24:14 +0000

    CBuild (Gerrit)

    unread,
    Jan 26, 2023, 2:57:47 PM1/26/23
    to Ahmed Ashour, rev...@dartlang.org, Samuel Rawlins, Commit Queue, Brian Wilkerson

    Attention is currently required from: Samuel Rawlins.

    go/dart-cbuild result: FAILURE (REGRESSIONS DETECTED)

    Details: https://goto.google.com/dart-cbuild/find/764bbe4273acadf94a4c0612c8d0bf1793b8d451
    Bugs: go/dart-cbuild-bug/764bbe4273acadf94a4c0612c8d0bf1793b8d451

    View Change

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 3
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
      Gerrit-Comment-Date: Thu, 26 Jan 2023 19:57:41 +0000

      Samuel Rawlins (Gerrit)

      unread,
      Jan 27, 2023, 9:44:42 PM1/27/23
      to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

      Attention is currently required from: Ahmed Ashour.

      View Change

      4 comments:

      • File pkg/analyzer/lib/src/dart/error/hint_codes.g.dart:

      • File pkg/analyzer/lib/src/error/best_practices_verifier.dart:

        • Patch Set #3, Line 1558: void _checkForUnnecessarySetLiteral(

          Would you mind adding a comment above this explaining what we're checking? Especially because the name doesn't convey that this is specifically checking for `=> { ... }`

      • File pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart:

        • Patch Set #3, Line 10: main() {

          I think we also need to test async functions with `Future<void>`, maybe `FutureOr<void>`. This is legal:

          ```
          Future<void> f() async => { print(1) };
          ```

          Generators, (sync*, async*) however cannot use `=>` so don't need to cover those.

        • Patch Set #3, Line 29: await assertNoErrorsInCode(r'''

          Curious, why don't these tests just use one function?

          ```
          void f() => {1: 2};
          ```

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 3
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Comment-Date: Sat, 28 Jan 2023 02:44:37 +0000

      Ahmed Ashour (Gerrit)

      unread,
      Jan 29, 2023, 1:55:55 PM1/29/23
      to rev...@dartlang.org

      Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

      Ahmed Ashour uploaded patch set #4 to this change.

      View Change

      [analyzer] introduce `UNNECESSARY_SET_LITERAL`

      Fixes #50900

      Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      ---
      M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
      M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
      M pkg/analyzer/lib/src/error/best_practices_verifier.dart
      M pkg/analyzer/lib/src/error/error_code_values.g.dart
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/src/diagnostics/test_all.dart
      A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
      7 files changed, 207 insertions(+), 7 deletions(-)

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 4
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>

      Ahmed Ashour (Gerrit)

      unread,
      Jan 29, 2023, 1:57:35 PM1/29/23
      to rev...@dartlang.org, Samuel Rawlins, CBuild, Commit Queue, Brian Wilkerson

      Attention is currently required from: Samuel Rawlins.

      View Change

      4 comments:

      • File pkg/analyzer/lib/src/dart/error/hint_codes.g.dart:

        • Done

      • File pkg/analyzer/lib/src/error/best_practices_verifier.dart:

        • Would you mind adding a comment above this explaining what we're checking? Especially because the na […]

          Done

      • File pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart:

        • I think we also need to test async functions with `Future<void>`, maybe `FutureOr<void>`. […]

          Thanks, that was missing. Done.

        • Curious, why don't these tests just use one function? […]

          If I correctly understand, having only `void f() => {1: 2};` has a parent of `FunctionDeclaration`, and this doesn't call `_checkForUnnecessarySetLiteral`, which is the implementation in question, i.e.:

          ```dart
          if (node.parent is! FunctionDeclaration) {
          _checkForMissingReturn(body, node);
          _checkForUnnecessarySetLiteral(body, node);
          }
          ```

          In other words, this test case is exactly as the one which triggers the hint, but returns a map instead of the set.

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 4
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
      Gerrit-Comment-Date: Sun, 29 Jan 2023 18:57:29 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Samuel Rawlins <sraw...@google.com>
      Gerrit-MessageType: comment

      Ahmed Ashour (Gerrit)

      unread,
      Jan 29, 2023, 2:45:31 PM1/29/23
      to rev...@dartlang.org

      Attention is currently required from: Samuel Rawlins.

      Ahmed Ashour uploaded patch set #5 to this change.

      View Change

      [analyzer] introduce `UNNECESSARY_SET_LITERAL`

      Fixes #50900

      Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      ---
      M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
      M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
      M pkg/analyzer/lib/src/error/best_practices_verifier.dart
      M pkg/analyzer/lib/src/error/error_code_values.g.dart
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/src/diagnostics/test_all.dart
      A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
      7 files changed, 201 insertions(+), 7 deletions(-)

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 5
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
      Gerrit-MessageType: newpatchset

      Ahmed Ashour (Gerrit)

      unread,
      Jan 29, 2023, 9:11:45 PM1/29/23
      to rev...@dartlang.org

      Attention is currently required from: Samuel Rawlins.

      Ahmed Ashour uploaded patch set #6 to this change.

      View Change

      [analyzer] introduce `UNNECESSARY_SET_LITERAL`

      Fixes #50900

      Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      ---
      M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
      M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
      M pkg/analyzer/lib/src/error/best_practices_verifier.dart
      M pkg/analyzer/lib/src/error/error_code_values.g.dart
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/src/diagnostics/test_all.dart
      A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
      7 files changed, 233 insertions(+), 7 deletions(-)

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 6

      Samuel Rawlins (Gerrit)

      unread,
      Jan 31, 2023, 12:30:46 PM1/31/23
      to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

      Attention is currently required from: Ahmed Ashour.

      View Change

      2 comments:

      • File pkg/analyzer/messages.yaml:

        • Patch Set #6, Line 20637: problemMessage: Unneeded set literal for a single expression in a function expression with a 'void' return type.

          I think we can improve the message here. I think this message now has a focus on correctness but it doesn't really help someone who doesn't understand what they've written with `=> { ... }`. This one is really hard to write concisely...

          Maybe something like, "Braces unnecessarily wrap this expression in a set literal." I think we don't need to go into the specifics of void-returning. I think you quickly get into the weeds ("Well usually the type system protects you from using these set literal braces, but in the case of void, we're pretty loosey goosey, so that setters (which must return void) are still allowed to use arrow functions ...").

      • File pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart:

        • Patch Set #3, Line 29: await assertNoErrorsInCode(r'''

          If I correctly understand, having only `void f() => {1: 2};` has a parent of `FunctionDeclaration`, […]

          Oh, in that case I think there is a bug in the implementation. For example, the new Hint should be reported for:

          ```
          void f() => {1};
          ```

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 6
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Comment-Date: Tue, 31 Jan 2023 17:30:41 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Samuel Rawlins <sraw...@google.com>
      Comment-In-Reply-To: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-MessageType: comment

      Ahmed Ashour (Gerrit)

      unread,
      Feb 1, 2023, 7:47:28 AM2/1/23
      to rev...@dartlang.org

      Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

      Ahmed Ashour uploaded patch set #7 to this change.

      View Change

      [analyzer] introduce `UNNECESSARY_SET_LITERAL`

      Fixes #50900

      Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      ---
      M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
      M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
      M pkg/analyzer/lib/src/error/best_practices_verifier.dart
      M pkg/analyzer/lib/src/error/error_code_values.g.dart
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/src/diagnostics/test_all.dart
      A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
      7 files changed, 323 insertions(+), 7 deletions(-)

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 7
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>

      Ahmed Ashour (Gerrit)

      unread,
      Feb 1, 2023, 7:48:33 AM2/1/23
      to rev...@dartlang.org, Samuel Rawlins, CBuild, Commit Queue, Brian Wilkerson

      Attention is currently required from: Samuel Rawlins.

      View Change

      2 comments:

      • File pkg/analyzer/messages.yaml:

        • Patch Set #6, Line 20637: problemMessage: Unneeded set literal for a single expression in a function expression with a 'void' return type.

        • I think we can improve the message here. […]

          Yes, that would be much better.

      • File pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart:

        • Oh, in that case I think there is a bug in the implementation. […]

          I see, initially it was for only closures. PTAL.

      To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
      Gerrit-Change-Number: 279962
      Gerrit-PatchSet: 7
      Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
      Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
      Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
      Gerrit-Comment-Date: Wed, 01 Feb 2023 12:48:27 +0000

      CBuild (Gerrit)

      unread,
      Feb 1, 2023, 1:23:55 PM2/1/23
      to Ahmed Ashour, rev...@dartlang.org, Samuel Rawlins, Commit Queue, Brian Wilkerson

      Attention is currently required from: Samuel Rawlins.

      go/dart-cbuild result: FAILURE (REGRESSIONS DETECTED)

      Details: https://goto.google.com/dart-cbuild/find/e31b3a27769a4cbfb183ce992043ba5cfbc169b3
      Bugs: go/dart-cbuild-bug/e31b3a27769a4cbfb183ce992043ba5cfbc169b3

      View Change

        To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: sdk
        Gerrit-Branch: main
        Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
        Gerrit-Change-Number: 279962
        Gerrit-PatchSet: 7
        Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
        Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
        Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
        Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
        Gerrit-Comment-Date: Wed, 01 Feb 2023 18:23:49 +0000

        Samuel Rawlins (Gerrit)

        unread,
        Feb 1, 2023, 1:33:18 PM2/1/23
        to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

        Attention is currently required from: Ahmed Ashour.

        View Change

        2 comments:

        • Patchset:

          • Patch Set #7:

            Note, this will take a bit to land, as I have to prepare internal code. Also need to check flutter, etc.

        • File pkg/analyzer/lib/src/error/best_practices_verifier.dart:

          • Patch Set #7, Line 1564: FunctionBody body, FunctionExpression node) {

            This function is implemented so carefully, I love it. Thanks!

        To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: sdk
        Gerrit-Branch: main
        Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
        Gerrit-Change-Number: 279962
        Gerrit-PatchSet: 7
        Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
        Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
        Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
        Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
        Gerrit-Comment-Date: Wed, 01 Feb 2023 18:33:13 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Gerrit-MessageType: comment

        Samuel Rawlins (Gerrit)

        unread,
        Feb 7, 2023, 11:51:50 AM2/7/23
        to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

        Attention is currently required from: Ahmed Ashour.

        Patch set 7:Code-Review +1

        View Change

          To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: sdk
          Gerrit-Branch: main
          Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
          Gerrit-Change-Number: 279962
          Gerrit-PatchSet: 7
          Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
          Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
          Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
          Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
          Gerrit-Comment-Date: Tue, 07 Feb 2023 16:51:45 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes
          Gerrit-MessageType: comment

          Samuel Rawlins (Gerrit)

          unread,
          Feb 7, 2023, 11:51:55 AM2/7/23
          to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

          Attention is currently required from: Ahmed Ashour.

          Patch set 7:Commit-Queue +2

          View Change

            To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: sdk
            Gerrit-Branch: main
            Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
            Gerrit-Change-Number: 279962
            Gerrit-PatchSet: 7
            Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
            Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
            Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Comment-Date: Tue, 07 Feb 2023 16:51:50 +0000

            Samuel Rawlins (Gerrit)

            unread,
            Feb 7, 2023, 1:33:36 PM2/7/23
            to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

            Attention is currently required from: Ahmed Ashour.

            View Change

            1 comment:

            To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: sdk
            Gerrit-Branch: main
            Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
            Gerrit-Change-Number: 279962
            Gerrit-PatchSet: 7
            Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
            Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
            Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Comment-Date: Tue, 07 Feb 2023 18:33:28 +0000

            Ahmed Ashour (Gerrit)

            unread,
            Feb 7, 2023, 2:27:35 PM2/7/23
            to rev...@dartlang.org

            Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

            Ahmed Ashour uploaded patch set #8 to this change.

            View Change

            [analyzer] introduce `UNNECESSARY_SET_LITERAL`

            Fixes #50900

            Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
            ---
            M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
            M pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart

            M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
            M pkg/analyzer/lib/src/error/best_practices_verifier.dart
            M pkg/analyzer/lib/src/error/error_code_values.g.dart
            M pkg/analyzer/messages.yaml
            M pkg/analyzer/test/src/diagnostics/test_all.dart
            A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
            8 files changed, 327 insertions(+), 9 deletions(-)

            To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: sdk
            Gerrit-Branch: main
            Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
            Gerrit-Change-Number: 279962
            Gerrit-PatchSet: 8
            Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
            Gerrit-CC: Brian Wilkerson <brianwi...@google.com>

            Ahmed Ashour (Gerrit)

            unread,
            Feb 7, 2023, 2:29:31 PM2/7/23
            to rev...@dartlang.org, Samuel Rawlins, CBuild, Commit Queue, Brian Wilkerson

            Attention is currently required from: Samuel Rawlins.

            View Change

            1 comment:

            • Patchset:

              • Done, PTAL.

            To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: sdk
            Gerrit-Branch: main
            Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
            Gerrit-Change-Number: 279962
            Gerrit-PatchSet: 8
            Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
            Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
            Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
            Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
            Gerrit-Comment-Date: Tue, 07 Feb 2023 19:29:24 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No

            CBuild (Gerrit)

            unread,
            Feb 7, 2023, 3:09:32 PM2/7/23
            to Ahmed Ashour, rev...@dartlang.org, Samuel Rawlins, Commit Queue, Brian Wilkerson

            Attention is currently required from: Samuel Rawlins.

            go/dart-cbuild result: FAILURE (NO REGRESSIONS DETECTED)

            Details: https://goto.google.com/dart-cbuild/find/6b2b6df0ff641163ac7406444838017b61fdead4

            View Change

              To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: sdk
              Gerrit-Branch: main
              Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
              Gerrit-Change-Number: 279962
              Gerrit-PatchSet: 8
              Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
              Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
              Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
              Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
              Gerrit-Comment-Date: Tue, 07 Feb 2023 20:09:28 +0000

              Samuel Rawlins (Gerrit)

              unread,
              Feb 7, 2023, 4:05:07 PM2/7/23
              to Ahmed Ashour, rev...@dartlang.org, CBuild, Commit Queue, Brian Wilkerson

              Attention is currently required from: Ahmed Ashour, Samuel Rawlins.

              Patch set 8:Commit-Queue +2

              View Change

                To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: sdk
                Gerrit-Branch: main
                Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
                Gerrit-Change-Number: 279962
                Gerrit-PatchSet: 8
                Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
                Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
                Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
                Gerrit-Attention: Samuel Rawlins <sraw...@google.com>
                Gerrit-Attention: Ahmed Ashour <asas...@yahoo.com>
                Gerrit-Comment-Date: Tue, 07 Feb 2023 21:05:02 +0000

                Commit Queue (Gerrit)

                unread,
                Feb 7, 2023, 4:05:15 PM2/7/23
                to Ahmed Ashour, rev...@dartlang.org, Samuel Rawlins, CBuild, Brian Wilkerson

                Commit Queue submitted this change.

                View Change



                7 is the latest approved patch-set.
                The change was submitted with unreviewed changes in the following files:

                ```
                The name of the file: pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
                Insertions: 44, Deletions: 0.

                The diff is too large to show. Please review the diff.
                ```

                Approvals: Samuel Rawlins: Looks good to me, approved; Commit
                [analyzer] introduce `UNNECESSARY_SET_LITERAL`

                Fixes #50900

                Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
                Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279962
                Commit-Queue: Samuel Rawlins <sraw...@google.com>
                Reviewed-by: Samuel Rawlins <sraw...@google.com>

                ---
                M pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
                M pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
                M pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
                M pkg/analyzer/lib/src/error/best_practices_verifier.dart
                M pkg/analyzer/lib/src/error/error_code_values.g.dart
                M pkg/analyzer/messages.yaml
                M pkg/analyzer/test/src/diagnostics/test_all.dart
                A pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
                8 files changed, 330 insertions(+), 9 deletions(-)

                diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
                index 51f682f..f7449f6 100644
                --- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
                +++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
                @@ -1547,6 +1547,10 @@

                status: hasFix
                HintCode.UNNECESSARY_QUESTION_MARK:
                status: hasFix
                +HintCode.UNNECESSARY_SET_LITERAL:
                + status: needsFix
                + notes: |-
                + Remove the set literal.
                HintCode.UNNECESSARY_TYPE_CHECK_FALSE:
                status: hasFix
                HintCode.UNNECESSARY_TYPE_CHECK_TRUE:
                diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
                index d6bf55a..6fd48ec 100644
                --- a/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
                +++ b/pkg/analysis_server/test/src/services/correction/fix/convert_for_each_to_for_loop_test.dart
                @@ -4,6 +4,7 @@

                import 'package:analysis_server/src/services/correction/fix.dart';
                import 'package:analysis_server/src/services/linter/lint_names.dart';
                +import 'package:analyzer/error/error.dart';
                import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
                import 'package:test_reflective_loader/test_reflective_loader.dart';

                @@ -284,7 +285,8 @@
                list.forEach((x) => {print('')});
                }
                ''');
                - await assertNoFix();
                + await assertNoFix(
                + errorFilter: (error) => error.errorCode.type == ErrorType.LINT);
                }

                Future<void> test_setLiteral_multiple() async {
                @@ -317,6 +319,6 @@
                <int>{x};
                }
                }
                -''');
                +''', errorFilter: (error) => error.errorCode.type == ErrorType.LINT);
                }
                }
                diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
                index ee1cb96..ac2e89f 100644
                --- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
                +++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
                @@ -807,6 +807,13 @@

                );

                /// No parameters.
                + static const HintCode UNNECESSARY_SET_LITERAL = HintCode(
                + 'UNNECESSARY_SET_LITERAL',
                +    "Braces unnecessarily wrap this expression in a set literal.",
                + correctionMessage: "Try removing the set literal around the expression.",

                + );
                +
                + /// No parameters.
                static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCode(
                'UNNECESSARY_TYPE_CHECK',
                "Unnecessary type check; the result is always 'false'.",
                diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
                index 627e45f..2a43cd5 100644
                --- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
                +++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
                @@ -585,12 +585,14 @@


                @override
                void visitFunctionExpression(FunctionExpression node) {
                + var body = node.body;
                if (node.parent is! FunctionDeclaration) {
                - _checkForMissingReturn(node.body, node);
                + _checkForMissingReturn(body, node);
                }
                     if (!(node as FunctionExpressionImpl).wasFunctionTypeSupplied) {
                _checkStrictInferenceInParameters(node.parameters, body: node.body);
                }
                +    _checkForUnnecessarySetLiteral(body, node);
                super.visitFunctionExpression(node);
                }

                @@ -1555,6 +1557,47 @@
                return false;
                }

                + /// Generate hints related to returning a set literal in an
                + /// [ExpressionFunctionBody], having a single expression,
                + /// for a function of `void` return type.

                + void _checkForUnnecessarySetLiteral(
                + FunctionBody body, FunctionExpression node) {
                + if (body is ExpressionFunctionBodyImpl) {
                + var parameterType = node.staticParameterElement?.type;
                +
                +      DartType? returnType;
                + if (parameterType is FunctionType) {
                + returnType = parameterType.returnType;
                + } else {
                + var parent = node.parent;
                + if (parent is! FunctionDeclaration) return;
                + returnType = parent.returnType?.type;
                + }
                + if (returnType == null) return;
                +
                + bool isReturnVoid;
                + if (returnType.isVoid) {
                + isReturnVoid = true;
                + } else if (returnType is ParameterizedType &&
                + (returnType.isDartAsyncFuture || returnType.isDartAsyncFutureOr)) {
                + var typeArguments = returnType.typeArguments;
                + isReturnVoid = typeArguments.length == 1 && typeArguments.first.isVoid;
                + } else {
                + isReturnVoid = false;
                + }
                + if (isReturnVoid) {

                + var expression = body.expression;
                +        if (expression is SetOrMapLiteralImpl && expression.isSet) {
                + var elements = expression.elements;
                + if (elements.length == 1 && elements.first is Expression) {

                + _errorReporter.reportErrorForNode(
                + HintCode.UNNECESSARY_SET_LITERAL, expression);
                + }
                + }
                + }
                + }
                + }
                +
                void _checkRequiredParameter(FormalParameterList node) {
                final requiredParameters =
                node.parameters.where((p) => p.declaredElement?.hasRequired == true);
                diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart
                index 36a172b..e60dde1 100644
                --- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
                +++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
                @@ -648,6 +648,7 @@

                HintCode.UNNECESSARY_NULL_COMPARISON_FALSE,
                HintCode.UNNECESSARY_NULL_COMPARISON_TRUE,
                HintCode.UNNECESSARY_QUESTION_MARK,
                + HintCode.UNNECESSARY_SET_LITERAL,
                HintCode.UNNECESSARY_TYPE_CHECK_FALSE,
                HintCode.UNNECESSARY_TYPE_CHECK_TRUE,
                HintCode.UNREACHABLE_SWITCH_CASE,
                diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
                index ee556a3..5092ee1 100644

                --- a/pkg/analyzer/messages.yaml
                +++ b/pkg/analyzer/messages.yaml
                @@ -1021,7 +1021,7 @@
                ```
                ASYNC_FOR_IN_WRONG_CONTEXT:
                problemMessage: The async for-in loop can only be used in an async function.
                - correctionMessage: "Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for-in loop."
                + correctionMessage: Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for-in loop.
                hasPublishedDocs: true
                comment: No parameters.
                documentation: |-
                @@ -1122,7 +1122,7 @@

                ```
                AWAIT_IN_WRONG_CONTEXT:
                problemMessage: The await expression can only be used in an async function.
                - correctionMessage: "Try marking the function body with either 'async' or 'async*'."
                + correctionMessage: Try marking the function body with either 'async' or 'async*'.
                comment: |-
                16.30 Await Expressions: It is a compile-time error if the function
                immediately enclosing _a_ is not declared asynchronous. (Where _a_ is the
                @@ -1140,7 +1140,7 @@
                Parameters:
                0: the name of the base mixin being implemented

                BODY_MIGHT_COMPLETE_NORMALLY:
                - problemMessage: "The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type."
                + problemMessage: The body might complete normally, causing 'null' to be returned, but the return type, '{0}', is a potentially non-nullable type.
                correctionMessage: Try adding either a return or a throw statement at the end.
                hasPublishedDocs: true
                comment: |-
                @@ -1219,7 +1219,7 @@

                }
                ```
                BREAK_LABEL_ON_SWITCH_MEMBER:
                - problemMessage: "A break label resolves to the 'case' or 'default' statement."
                + problemMessage: A break label resolves to the 'case' or 'default' statement.
                hasPublishedDocs: true
                comment: No parameters.
                documentation: |-
                @@ -1276,7 +1276,7 @@

                }
                ```
                BUILT_IN_IDENTIFIER_AS_TYPE:
                - problemMessage: "The built-in identifier '{0}' can't be used as a type."
                + problemMessage: The built-in identifier '{0}' can't be used as a type.
                correctionMessage: Try correcting the name to match an existing type.
                hasPublishedDocs: true
                comment: |-
                @@ -6975,7 +6975,7 @@


                This error is only reported in libraries which are not null safe.
                INVALID_CAST_FUNCTION_EXPR:
                - problemMessage: "The function expression type '{0}' isn't of type '{1}'. This means its parameter or return type doesn't match what is expected. Consider changing parameter type(s) or the returned type(s)."
                + problemMessage: The function expression type '{0}' isn't of type '{1}'. This means its parameter or return type doesn't match what is expected. Consider changing parameter type(s) or the returned type(s).
                comment: |-
                Parameters:
                0: the type of the torn-off function expression
                @@ -20058,6 +20058,11 @@

                ```dart
                dynamic x;
                ```
                + UNNECESSARY_SET_LITERAL:
                +    problemMessage: Braces unnecessarily wrap this expression in a set literal.
                + correctionMessage: Try removing the set literal around the expression.

                + hasPublishedDocs: false
                + comment: No parameters.
                UNNECESSARY_TYPE_CHECK_FALSE:
                sharedName: UNNECESSARY_TYPE_CHECK
                problemMessage: "Unnecessary type check; the result is always 'false'."
                diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
                index 460123b..907bab5 100644
                --- a/pkg/analyzer/test/src/diagnostics/test_all.dart
                +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
                @@ -827,6 +827,7 @@

                as unnecessary_null_check_pattern;
                import 'unnecessary_null_comparison_test.dart' as unnecessary_null_comparison;
                import 'unnecessary_question_mark_test.dart' as unnecessary_question_mark;
                +import 'unnecessary_set_literal_test.dart' as unnecessary_set_literal;
                import 'unnecessary_type_check_test.dart' as unnecessary_type_check;
                import 'unqualified_reference_to_non_local_static_member_test.dart'
                as unqualified_reference_to_non_local_static_member;
                @@ -1410,6 +1411,7 @@

                unnecessary_null_check_pattern.main();
                unnecessary_null_comparison.main();
                unnecessary_question_mark.main();
                + unnecessary_set_literal.main();
                unnecessary_type_check.main();
                unqualified_reference_to_non_local_static_member.main();
                unqualified_reference_to_static_member_of_extended_type.main();
                diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
                new file mode 100644
                index 0000000..6bc86a9
                --- /dev/null
                +++ b/pkg/analyzer/test/src/diagnostics/unnecessary_set_literal_test.dart
                @@ -0,0 +1,243 @@

                +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
                +// for details. All rights reserved. Use of this source code is governed by a
                +// BSD-style license that can be found in the LICENSE file.
                +
                +import 'package:analyzer/src/dart/error/hint_codes.dart';
                +import 'package:test_reflective_loader/test_reflective_loader.dart';
                +
                +import '../dart/resolution/context_collection_resolution.dart';
                +
                +main() {
                + defineReflectiveSuite(() {
                + defineReflectiveTests(UnnecessarySetLiteralTest);
                + });
                +}
                +
                +@reflectiveTest
                +class UnnecessarySetLiteralTest extends PubPackageResolutionTest {
                + test_blockFunctionBody() async {
                + await assertNoErrorsInCode(r'''
                +void g(void Function() fun) {}
                +
                +void f() {
                + g(() {1;});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_dynamic() async {
                + await assertNoErrorsInCode(r'''
                +void g(Function() fun) {}
                +
                +void f() {
                + g(() => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_future() async {
                + await assertNoErrorsInCode(r'''
                +void g(Future Function() fun) {}
                +
                +void f() {
                + g(() async => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_future_object() async {
                + await assertNoErrorsInCode(r'''
                +void g(Future<Object> Function() fun) {}
                +
                +void f() {
                + g(() async => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_future_void() async {
                + await assertErrorsInCode(r'''
                +void g(Future<void> Function() fun) {}
                +
                +void f() {
                + g(() async => {1});
                +}
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 67, 3),
                + ]);
                + }
                +
                + test_expressionFunctionBody_futureOr() async {
                + await assertNoErrorsInCode(r'''
                +import 'dart:async';
                +
                +void g(FutureOr Function() fun) {}
                +
                +void f() {
                + g(() async => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_futureOr_object() async {
                + await assertNoErrorsInCode(r'''
                +import 'dart:async';
                +
                +void g(FutureOr<Object> Function() fun) {}
                +
                +void f() {
                + g(() async => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_futureOr_void() async {
                + await assertErrorsInCode(r'''
                +import 'dart:async';
                +
                +void g(FutureOr<void> Function() fun) {}
                +
                +void f() {
                + g(() async => {1});
                +}
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 91, 3),
                + ]);
                + }
                +
                + test_expressionFunctionBody_map() async {
                + await assertNoErrorsInCode(r'''
                +void g(void Function() fun) {}
                +
                +void f() {
                + g(() => {1: 2});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_multipleElements() async {
                + await assertNoErrorsInCode(r'''
                +void g(void Function() fun) {}
                +
                +void f() {
                + g(() => {1, 2});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_object() async {
                + await assertNoErrorsInCode(r'''
                +void g(Object Function() fun) {}
                +
                +void f() {
                + g(() => {1});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_statement() async {
                + await assertNoErrorsInCode(r'''
                +void g(void Function(bool) fun) {}
                +
                +void f() {
                + g((value) => {if (value) print('')});

                +}
                +''');
                + }
                +
                +  test_expressionFunctionBody_void() async {
                + await assertErrorsInCode(r'''
                +void g(void Function() fun) {}
                +
                +void f() {
                + g(() => {1});
                +}
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 53, 3),
                + ]);
                + }
                +
                + test_functionDeclaration_dynamic() async {
                + await assertNoErrorsInCode(r'''
                +f() => {1};
                +''');
                + }
                +
                + test_functionDeclaration_future() async {
                + await assertNoErrorsInCode(r'''
                +Future f() async => {1};
                +''');
                + }
                +
                + test_functionDeclaration_future_object() async {
                + await assertNoErrorsInCode(r'''
                +Future<Object> f() async => {1};
                +''');
                + }
                +
                + test_functionDeclaration_future_void() async {
                + await assertErrorsInCode(r'''
                +Future<void> f() async => {1};
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 26, 3),
                + ]);
                + }
                +
                + test_functionDeclaration_futureOr() async {
                + await assertNoErrorsInCode(r'''
                +import 'dart:async';
                +
                +FutureOr f() async => {1};
                +''');
                + }
                +
                + test_functionDeclaration_futureOr_object() async {
                + await assertNoErrorsInCode(r'''
                +import 'dart:async';
                +
                +FutureOr<Object> f() async => {1};
                +''');
                + }
                +
                + test_functionDeclaration_futureOr_void() async {
                + await assertErrorsInCode(r'''
                +import 'dart:async';
                +
                +FutureOr<void> f() async => {1};
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 50, 3),
                + ]);
                + }
                +
                + test_functionDeclaration_map() async {
                + await assertNoErrorsInCode(r'''
                +void f() => {1: 2};
                +''');
                + }
                +
                + test_functionDeclaration_multipleElements() async {
                + await assertNoErrorsInCode(r'''
                +void f() => {1, 2};
                +''');
                + }
                +
                + test_functionDeclaration_object() async {
                + await assertNoErrorsInCode(r'''
                +Object f() => {1};
                +''');
                + }
                +
                + test_functionDeclaration_statement() async {
                + await assertNoErrorsInCode(r'''
                +void f(bool value) => {if (value) print('')};
                +''');
                + }
                +
                + test_functionDeclaration_void() async {
                + await assertErrorsInCode(r'''
                +void f() => {1};
                +''', [
                + error(HintCode.UNNECESSARY_SET_LITERAL, 12, 3),
                + ]);
                + }
                +}

                To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: sdk
                Gerrit-Branch: main
                Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
                Gerrit-Change-Number: 279962
                Gerrit-PatchSet: 9
                Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
                Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
                Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
                Gerrit-MessageType: merged

                CBuild (Gerrit)

                unread,
                Feb 7, 2023, 4:44:01 PM2/7/23
                to Commit Queue, Ahmed Ashour, rev...@dartlang.org, Samuel Rawlins, Brian Wilkerson

                go/dart-cbuild result: SUCCESS

                Details: https://goto.google.com/dart-cbuild/find/b5a8206c8b03f1b9cbc0372ea703bdd11df3ca42

                View Change

                  To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: sdk
                  Gerrit-Branch: main
                  Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
                  Gerrit-Change-Number: 279962
                  Gerrit-PatchSet: 9
                  Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
                  Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
                  Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
                  Gerrit-Comment-Date: Tue, 07 Feb 2023 21:43:57 +0000

                  Oleh Prypin (Gerrit)

                  unread,
                  Feb 15, 2023, 6:24:34 AM2/15/23
                  to Commit Queue, Ahmed Ashour, rev...@dartlang.org, Oleh Prypin, Samuel Rawlins, CBuild, Brian Wilkerson

                  View Change

                  1 comment:

                  To view, visit change 279962. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: sdk
                  Gerrit-Branch: main
                  Gerrit-Change-Id: I7c7535e3fa7dcd25bf11034790a14b1bdfc50a77
                  Gerrit-Change-Number: 279962
                  Gerrit-PatchSet: 9
                  Gerrit-Owner: Ahmed Ashour <asas...@yahoo.com>
                  Gerrit-Reviewer: Samuel Rawlins <sraw...@google.com>
                  Gerrit-CC: Brian Wilkerson <brianwi...@google.com>
                  Gerrit-CC: Oleh Prypin <opr...@google.com>
                  Gerrit-Comment-Date: Wed, 15 Feb 2023 11:24:30 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: No
                  Gerrit-MessageType: comment
                  Reply all
                  Reply to author
                  Forward
                  0 new messages