Version 2.18.0-179.0.dev

Merge commit '57b192f3a63ac109cd7550071c52cec69e637aeb' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
index 889c88c..b2b8745 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
@@ -4,15 +4,31 @@
 
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:collection/collection.dart';
 
 class AddAwait extends CorrectionProducer {
-  @override
-  bool get canBeAppliedInBulk => true;
+  /// The kind of correction to be made.
+  final _CorrectionKind _correctionKind;
 
   @override
-  bool get canBeAppliedToFile => true;
+  bool canBeAppliedInBulk;
+
+  @override
+  bool canBeAppliedToFile;
+
+  AddAwait.nonBool()
+      : _correctionKind = _CorrectionKind.nonBool,
+        canBeAppliedInBulk = false,
+        canBeAppliedToFile = false;
+
+  AddAwait.unawaited()
+      : _correctionKind = _CorrectionKind.unawaited,
+        canBeAppliedInBulk = true,
+        canBeAppliedToFile = true;
 
   @override
   FixKind get fixKind => DartFixKind.ADD_AWAIT;
@@ -22,8 +38,34 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
+    if (_correctionKind == _CorrectionKind.unawaited) {
+      await _addAwait(builder);
+    } else if (_correctionKind == _CorrectionKind.nonBool) {
+      await _computeNonBool(builder);
+    }
+  }
+
+  Future<void> _addAwait(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(node.offset, 'await ');
     });
   }
+
+  Future<void> _computeNonBool(ChangeBuilder builder) async {
+    var expr = node;
+    if (expr is! Expression) return;
+    var staticType = expr.staticType;
+    if (staticType is! ParameterizedType) return;
+
+    if (staticType.isDartAsyncFuture &&
+        staticType.typeArguments.firstOrNull?.isDartCoreBool == true) {
+      await _addAwait(builder);
+    }
+  }
+}
+
+/// The kinds of corrections supported by [AddAwait].
+enum _CorrectionKind {
+  unawaited,
+  nonBool,
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index 0b1f3c6..853558be 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -49,8 +49,8 @@
   Future<void> _removeFromDeclarationList(
       ChangeBuilder builder, VariableDeclarationList declarationList) async {
     // we need a type
-    var typeNode = declarationList.type;
-    if (typeNode == null) {
+    var type = declarationList.type;
+    if (type == null) {
       return;
     }
     // ignore if an incomplete variable declaration
@@ -63,19 +63,60 @@
     if (selectionOffset > firstVariable.name.end) {
       return;
     }
+
+    var initializer = firstVariable.initializer;
     // The variable must have an initializer, otherwise there is no other
     // source for its type.
-    if (firstVariable.initializer == null) {
+    if (initializer == null) {
+      return;
+    }
+
+    String? typeArgumentsText;
+    int? typeArgumentsOffset;
+    if (type is NamedType) {
+      var typeArguments = type.typeArguments;
+      if (typeArguments != null) {
+        if (initializer is CascadeExpression) {
+          initializer = initializer.target;
+        }
+        if (initializer is TypedLiteral) {
+          if (initializer.typeArguments == null) {
+            typeArgumentsText = utils.getNodeText(typeArguments);
+            if (initializer is ListLiteral) {
+              typeArgumentsOffset = initializer.leftBracket.offset;
+            } else if (initializer is SetOrMapLiteral) {
+              typeArgumentsOffset = initializer.leftBracket.offset;
+            } else {
+              throw StateError('Unhandled subclass of TypedLiteral');
+            }
+          }
+        } else if (initializer is InstanceCreationExpression) {
+          if (initializer.constructorName.type.typeArguments == null) {
+            typeArgumentsText = utils.getNodeText(typeArguments);
+            typeArgumentsOffset = initializer.constructorName.type.end;
+          }
+        }
+      }
+    }
+    if (initializer is SetOrMapLiteral &&
+        initializer.typeArguments == null &&
+        typeArgumentsText == null) {
+      // This is to prevent the fix from converting a valid map or set literal
+      // into an ambiguous literal. We could apply this in more places
+      // by examining the elements of the collection.
       return;
     }
     var keyword = declarationList.keyword;
     await builder.addDartFileEdit(file, (builder) {
-      var typeRange = range.startStart(typeNode, firstVariable);
+      var typeRange = range.startStart(type, firstVariable);
       if (keyword != null && keyword.lexeme != 'var') {
         builder.addSimpleReplacement(typeRange, '');
       } else {
         builder.addSimpleReplacement(typeRange, 'var ');
       }
+      if (typeArgumentsText != null && typeArgumentsOffset != null) {
+        builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
+      }
     });
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
index 49ddf35..3c5a55b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -64,6 +64,8 @@
                 typeArgumentsOffset = initializer.leftBracket.offset;
               } else if (initializer is SetOrMapLiteral) {
                 typeArgumentsOffset = initializer.leftBracket.offset;
+              } else {
+                throw StateError('Unhandled subclass of TypedLiteral');
               }
             }
           } else if (initializer is InstanceCreationExpression) {
@@ -77,9 +79,9 @@
       if (initializer is SetOrMapLiteral &&
           initializer.typeArguments == null &&
           typeArgumentsText == null) {
-        // TODO(brianwilkerson) This is to prevent the fix from converting a
-        //  valid map or set literal into an ambiguous literal. We could apply
-        //  this in more places by examining the elements of the collection.
+        // This is to prevent the fix from converting a valid map or set literal
+        // into an ambiguous literal. We could apply this in more places
+        // by examining the elements of the collection.
         return;
       }
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index dfcb63a..02cf698 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -621,7 +621,7 @@
       RemoveTypeAnnotation.new,
     ],
     LintNames.unawaited_futures: [
-      AddAwait.new,
+      AddAwait.unawaited,
     ],
     LintNames.unnecessary_brace_in_string_interps: [
       RemoveInterpolationBraces.new,
@@ -1010,6 +1010,7 @@
     ],
     CompileTimeErrorCode.NON_BOOL_CONDITION: [
       AddNeNull.new,
+      AddAwait.nonBool,
     ],
     CompileTimeErrorCode.NON_CONST_GENERATIVE_ENUM_CONSTRUCTOR: [
       AddConst.new,
diff --git a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
index 99f4ab7..d5fdf25 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
@@ -54,6 +54,45 @@
     await assertNoAssistAt('v');
   }
 
+  Future<void> test_generic_instanceCreation_withoutArguments() async {
+    await resolveTestCode('''
+C<int> c = C();
+class C<T> {}
+''');
+    await assertHasAssistAt('c = ', '''
+var c = C<int>();
+class C<T> {}
+''');
+  }
+
+  Future<void> test_generic_listLiteral() async {
+    await resolveTestCode('''
+List<int> l = [];
+''');
+    await assertHasAssistAt('l = ', '''
+var l = <int>[];
+''');
+  }
+
+  Future<void> test_generic_setLiteral_ambiguous() async {
+    await resolveTestCode('''
+Set f() {
+  /*caret*/Set s = {};
+  return s;
+}
+''');
+    await assertNoAssist();
+  }
+
+  Future<void> test_generic_setLiteral_cascade() async {
+    await resolveTestCode('''
+Set<String> s = {}..addAll([]);
+''');
+    await assertHasAssistAt('s = ', '''
+var s = <String>{}..addAll([]);
+''');
+  }
+
   Future<void> test_instanceCreation_freeStanding() async {
     await resolveTestCode('''
 class A {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
index d6c2893..cd15fc2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
@@ -67,4 +67,35 @@
 }
 ''');
   }
+
+  Future<void> test_nonBoolCondition_futureBool() async {
+    await resolveTestCode('''
+Future<bool> doSomething() async => true;
+
+Future<void> f() async {
+  if (doSomething()) {
+  }
+}
+''');
+    await assertHasFix('''
+Future<bool> doSomething() async => true;
+
+Future<void> f() async {
+  if (await doSomething()) {
+  }
+}
+''');
+  }
+
+  Future<void> test_nonBoolCondition_futureInt() async {
+    await resolveTestCode('''
+Future<int> doSomething() async => 0;
+
+Future<void> f() async {
+  if (doSomething()) {
+  }
+}
+''');
+    await assertNoFix();
+  }
 }
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 11e023e..6d5ea0d 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/dart/element/scope.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart' as file_system;
@@ -636,25 +637,31 @@
 
   void reportLint(AstNode? node,
       {List<Object> arguments = const [],
+      List<DiagnosticMessage>? contextMessages,
       ErrorCode? errorCode,
       bool ignoreSyntheticNodes = true}) {
     if (node != null && (!node.isSynthetic || !ignoreSyntheticNodes)) {
-      reporter.reportErrorForNode(errorCode ?? lintCode, node, arguments);
+      reporter.reportErrorForNode(
+          errorCode ?? lintCode, node, arguments, contextMessages);
     }
   }
 
   void reportLintForOffset(int offset, int length,
-      {List<Object> arguments = const [], ErrorCode? errorCode}) {
+      {List<Object> arguments = const [],
+      List<DiagnosticMessage>? contextMessages,
+      ErrorCode? errorCode}) {
     reporter.reportErrorForOffset(
-        errorCode ?? lintCode, offset, length, arguments);
+        errorCode ?? lintCode, offset, length, arguments, contextMessages);
   }
 
   void reportLintForToken(Token? token,
       {List<Object> arguments = const [],
+      List<DiagnosticMessage>? contextMessages,
       ErrorCode? errorCode,
       bool ignoreSyntheticTokens = true}) {
     if (token != null && (!token.isSynthetic || !ignoreSyntheticTokens)) {
-      reporter.reportErrorForToken(errorCode ?? lintCode, token, arguments);
+      reporter.reportErrorForToken(
+          errorCode ?? lintCode, token, arguments, contextMessages);
     }
   }
 
diff --git a/tools/VERSION b/tools/VERSION
index abce37d..1ac7c56 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 178
+PRERELEASE 179
 PRERELEASE_PATCH 0
\ No newline at end of file