Extract NullableObjectExtension.

Change-Id: I2fe2704d875082d20e1586f924aeebd6653703ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250262
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index a9d3bc5..322ebfa 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -23,6 +23,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
+import 'package:analyzer/src/utilities/extensions/object.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
@@ -1645,11 +1646,3 @@
     required this.summary,
   });
 }
-
-extension on Object? {
-  /// If the target is [T], return it, otherwise `null`.
-  T? ifTypeOrNull<T>() {
-    final self = this;
-    return self is T ? self : null;
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index dce0c9a..01f79da 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -46,6 +46,7 @@
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/this_access_tracker.dart';
 import 'package:analyzer/src/summary2/macro_application_error.dart';
+import 'package:analyzer/src/utilities/extensions/object.dart';
 import 'package:analyzer/src/utilities/extensions/string.dart';
 import 'package:collection/collection.dart';
 
@@ -5339,11 +5340,3 @@
     }
   }
 }
-
-extension on Object? {
-  /// If the target is [T], return it, otherwise `null`.
-  T? ifTypeOrNull<T>() {
-    final self = this;
-    return self is T ? self : null;
-  }
-}
diff --git a/pkg/analyzer/lib/src/utilities/extensions/object.dart b/pkg/analyzer/lib/src/utilities/extensions/object.dart
new file mode 100644
index 0000000..82b5d38
--- /dev/null
+++ b/pkg/analyzer/lib/src/utilities/extensions/object.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, 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.
+
+extension NullableObjectExtension on Object? {
+  /// If the target is [T], return it, otherwise `null`.
+  T? ifTypeOrNull<T>() {
+    final self = this;
+    return self is T ? self : null;
+  }
+}
diff --git a/pkg/analyzer/test/src/utilities/extensions/object_test.dart b/pkg/analyzer/test/src/utilities/extensions/object_test.dart
new file mode 100644
index 0000000..72074e4
--- /dev/null
+++ b/pkg/analyzer/test/src/utilities/extensions/object_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, 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/utilities/extensions/object.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NullableObjectExtensionTest);
+  });
+}
+
+@reflectiveTest
+class NullableObjectExtensionTest {
+  test_ifTypeOrNull_int() {
+    expect(0.ifTypeOrNull<int>(), 0);
+    expect(0.ifTypeOrNull<num>(), 0);
+    expect(0.ifTypeOrNull<Object>(), 0);
+    expect(0.ifTypeOrNull<String>(), isNull);
+  }
+
+  test_ifTypeOrNull_null() {
+    expect(null.ifTypeOrNull<Object>(), isNull);
+    expect(null.ifTypeOrNull<int>(), isNull);
+  }
+}
diff --git a/pkg/analyzer/test/src/utilities/extensions/test_all.dart b/pkg/analyzer/test/src/utilities/extensions/test_all.dart
index 8beb97b..5d7a7a5 100644
--- a/pkg/analyzer/test/src/utilities/extensions/test_all.dart
+++ b/pkg/analyzer/test/src/utilities/extensions/test_all.dart
@@ -5,12 +5,14 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'collection_test.dart' as collection;
+import 'object_test.dart' as object;
 import 'stream_test.dart' as stream;
 import 'string_test.dart' as string;
 
 main() {
   defineReflectiveSuite(() {
     collection.main();
+    object.main();
     stream.main();
     string.main();
   }, name: 'extensions');
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 0ce5403..a884ea3 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/utilities/extensions/object.dart';
 
 /// A CompletionTarget represents an edge in the parse tree which connects an
 /// AST node (the [containingNode] of the completion) to one of its children
@@ -697,11 +698,3 @@
     }
   }
 }
-
-extension on Object? {
-  /// If the target is [T], return it, otherwise `null`.
-  T? ifTypeOrNull<T>() {
-    final self = this;
-    return self is T ? self : null;
-  }
-}