Adjust `hasObviousType` to include negated numeric literals

Bug: https://github.com/dart-lang/sdk/issues/60243
Change-Id: I51509ef84d4b65f68b2ae84cce8ba12894666292
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413500
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
diff --git a/pkg/linter/lib/src/util/obvious_types.dart b/pkg/linter/lib/src/util/obvious_types.dart
index 590209f..eda5cbd 100644
--- a/pkg/linter/lib/src/util/obvious_types.dart
+++ b/pkg/linter/lib/src/util/obvious_types.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/dart/element/type.dart';
 // ignore: implementation_imports
@@ -180,6 +181,11 @@
           // A non-generic class or extension type.
           return true;
         }
+      case PrefixExpression()
+          when (self.operand is IntegerLiteral ||
+                  self.operand is DoubleLiteral) &&
+              self.operator.type == TokenType.MINUS:
+        return self.operand.hasObviousType;
       case CascadeExpression():
         return self.target.hasObviousType;
       case AsExpression():
diff --git a/pkg/linter/test/rules/omit_obvious_local_variable_types_test.dart b/pkg/linter/test/rules/omit_obvious_local_variable_types_test.dart
index c3651d4..6b80a66 100644
--- a/pkg/linter/test/rules/omit_obvious_local_variable_types_test.dart
+++ b/pkg/linter/test/rules/omit_obvious_local_variable_types_test.dart
@@ -81,7 +81,7 @@
   test_forEach_noDeclaredType() async {
     await assertNoDiagnostics(r'''
 f() {
-  for (var i in [1, 2, 3]) { }
+  for (var i in [1, -2, 3]) { }
 }
 ''');
   }
@@ -91,7 +91,7 @@
 f() {
   for (int i in list) { }
 }
-var list = [1, 2, 3];
+var list = [1, -2, 3];
 ''');
   }
 
@@ -99,7 +99,7 @@
     await assertDiagnostics(
       r'''
 f() {
-  for (int i in <int>[1, 2, 3]) { }
+  for (int i in <int>[1, -2, 3]) { }
 }
 ''',
       [lint(13, 3)],
diff --git a/pkg/linter/test/rules/specify_nonobvious_local_variable_types_test.dart b/pkg/linter/test/rules/specify_nonobvious_local_variable_types_test.dart
index 185e979..d5b5c19 100644
--- a/pkg/linter/test/rules/specify_nonobvious_local_variable_types_test.dart
+++ b/pkg/linter/test/rules/specify_nonobvious_local_variable_types_test.dart
@@ -231,6 +231,14 @@
 ''');
   }
 
+  test_literal_double_negated() async {
+    await assertNoDiagnostics(r'''
+f() {
+  var d = -1.5;
+}
+''');
+  }
+
   // The type is not obvious.
   test_literal_doubleTypedInt() async {
     await assertNoDiagnostics(r'''
@@ -248,6 +256,14 @@
 ''');
   }
 
+  test_literal_int_negated() async {
+    await assertNoDiagnostics(r'''
+f() {
+  var i = -1;
+}
+''');
+  }
+
   // `Null` is not obvious, the inferred type is `dynamic`.
   test_literal_null() async {
     await assertNoDiagnostics(r'''