Version 2.12.0-117.0.dev

Merge commit '6a097edc48d9ec20da9d6e6b586b37b63eb05812' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart
new file mode 100644
index 0000000..f74d1ec
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, 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.
+
+Null nullExpr = null;
+
+void var_identical_null(int? x) {
+  if (identical(x, null)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
+void var_notIdentical_null(int? x) {
+  if (!identical(x, null)) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+void null_identical_var(int? x) {
+  if (identical(null, x)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
+void null_notIdentical_var(int? x) {
+  if (!identical(null, x)) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+void var_identical_nullExpr(int? x) {
+  if (identical(x, nullExpr)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void var_notIdentical_nullExpr(int? x) {
+  if (!identical(x, nullExpr)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void nullExpr_identical_var(int? x) {
+  if (identical(nullExpr, x)) {
+    x;
+  } else {
+    x;
+  }
+}
+
+void nullExpr_notIdentical_var(int? x) {
+  if (!identical(nullExpr, x)) {
+    x;
+  } else {
+    x;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart
new file mode 100644
index 0000000..febe994
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_prefixed.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, 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 'dart:core';
+import 'dart:core' as core;
+
+void test(int? x) {
+  if (core.identical(x, null)) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart
new file mode 100644
index 0000000..1fdc9fe
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/identical_spoof.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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.
+
+bool identical(Object? x, Object? y) => false;
+
+void test(int? x) {
+  if (identical(x, null)) {
+    x;
+  } else {
+    x;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 1b4b7a0..a07074f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -312,8 +312,19 @@
     return typeArgs;
   }
 
+  bool _isCallToIdentical(AstNode invocation) {
+    if (invocation is MethodInvocation) {
+      var invokedMethod = invocation.methodName.staticElement;
+      return invokedMethod != null &&
+          invokedMethod.name == 'identical' &&
+          invokedMethod.library.isDartCore;
+    }
+    return false;
+  }
+
   void _resolveArguments(ArgumentList argumentList) {
-    argumentList.accept(_resolver);
+    _resolver.visitArgumentList(argumentList,
+        isIdentical: _isCallToIdentical(argumentList.parent));
   }
 
   void _resolveInvocation({
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 56ed8d4..b3a30c8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -788,8 +788,9 @@
   }
 
   @override
-  void visitArgumentList(ArgumentList node) {
+  void visitArgumentList(ArgumentList node, {bool isIdentical = false}) {
     DartType callerType = InferenceContext.getContext(node);
+    NodeList<Expression> arguments = node.arguments;
     if (callerType is FunctionType) {
       Map<String, DartType> namedParameterTypes =
           callerType.namedParameterTypes;
@@ -798,7 +799,6 @@
       int normalCount = normalParameterTypes.length;
       int optionalCount = optionalParameterTypes.length;
 
-      NodeList<Expression> arguments = node.arguments;
       Iterable<Expression> positional =
           arguments.takeWhile((l) => l is! NamedExpression);
       Iterable<Expression> required = positional.take(normalCount);
@@ -840,7 +840,23 @@
         }
       }
     }
-    super.visitArgumentList(node);
+    checkUnreachableNode(node);
+    int length = arguments.length;
+    for (var i = 0; i < length; i++) {
+      if (isIdentical && length > 1 && i == 1) {
+        var firstArg = arguments[0];
+        _flowAnalysis?.flow
+            ?.equalityOp_rightBegin(firstArg, firstArg.staticType);
+      }
+      arguments[i].accept(this);
+    }
+    if (isIdentical && length > 1) {
+      var secondArg = arguments[1];
+      _flowAnalysis?.flow
+          ?.equalityOp_end(node.parent, secondArg, secondArg.staticType);
+    }
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
   }
 
   @override
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 287c5dd..5e8f2a9 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -32,129 +32,34 @@
 /// analytics logic, it has been moved here.
 Future<void> runDartdev(List<String> args, SendPort port) async {
   VmInteropHandler.initialize(port);
-
-  int result;
-
-  // The exit code for the dartdev process; null indicates that it has not been
-  // set yet. The value is set in the catch and finally blocks below.
-  int exitCode;
-
-  // Any caught non-UsageExceptions when running the sub command.
-  Object exception;
-  StackTrace stackTrace;
-
-  // The Analytics instance used to report information back to Google Analytics;
-  // see lib/src/analytics.dart.
-  final analytics = createAnalyticsInstance(
-    args.contains('--disable-dartdev-analytics'),
-  );
-
-  // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
-  // the user is on a terminal, and the machine is not a bot, then print the
-  // disclosure and set analytics.disclosureShownOnTerminal to true.
-  if (analytics is DartdevAnalytics &&
-      !analytics.disclosureShownOnTerminal &&
-      io.stdout.hasTerminal &&
-      !isBot()) {
-    print(analyticsNoticeOnFirstRunMessage);
-    analytics.disclosureShownOnTerminal = true;
+  if (args.contains('run')) {
+    // These flags have a format that can't be handled by package:args, so while
+    // they are valid flags we'll assume the VM has verified them by this point.
+    args = args
+        .where(
+          (element) => !(element.contains('--observe') ||
+              element.contains('--enable-vm-service')),
+        )
+        .toList();
   }
 
-  // When `--disable-analytics` or `--enable-analytics` are called we perform
-  // the respective intention and print any notices to standard out and exit.
-  if (args.contains('--disable-analytics')) {
-    // This block also potentially catches the case of (disableAnalytics &&
-    // enableAnalytics), in which we favor the disabling of analytics.
-    analytics.enabled = false;
+  // Finally, call the runner to execute the command; see DartdevRunner.
 
-    // Alert the user that analytics has been disabled.
-    print(analyticsDisabledNoticeMessage);
-    VmInteropHandler.exit(0);
-    return;
-  } else if (args.contains('--enable-analytics')) {
-    analytics.enabled = true;
-
-    // Alert the user again that anonymous data will be collected.
-    print(analyticsNoticeOnFirstRunMessage);
-    VmInteropHandler.exit(0);
-    return;
-  }
-
+  final runner = DartdevRunner(args);
+  var exitCode = 1;
   try {
-    final runner = DartdevRunner(args, analytics);
-
-    // Run can't be called with the '--disable-dartdev-analytics' flag; remove
-    // it if it is contained in args.
-    if (args.contains('--disable-dartdev-analytics')) {
-      args = List.from(args)..remove('--disable-dartdev-analytics');
-    }
-
-    if (args.contains('run')) {
-      // These flags have a format that can't be handled by package:args, so while
-      // they are valid flags we'll assume the VM has verified them by this point.
-      args = args
-          .where(
-            (element) => !(element.contains('--observe') ||
-                element.contains('--enable-vm-service')),
-          )
-          .toList();
-    }
-
-    // If ... help pub ... is in the args list, remove 'help', and add '--help'
-    // to the end of the list. This will make it possible to use the help
-    // command to access subcommands of pub such as `dart help pub publish`; see
-    // https://github.com/dart-lang/sdk/issues/42965.
-    if (PubUtils.shouldModifyArgs(args, runner.commands.keys.toList())) {
-      args = PubUtils.modifyArgs(args);
-    }
-
-    // Finally, call the runner to execute the command; see DartdevRunner.
-    result = await runner.run(args);
-  } catch (e, st) {
-    if (e is UsageException) {
-      io.stderr.writeln('$e');
-      exitCode = 64;
-    } else {
-      // Set the exception and stack trace only for non-UsageException cases:
-      exception = e;
-      stackTrace = st;
-      io.stderr.writeln('$e');
-      io.stderr.writeln('$st');
-      exitCode = 1;
-    }
+    exitCode = await runner.run(args);
+  } on UsageException catch (e) {
+    // TODO(sigurdm): It is unclear when a UsageException gets to here, and
+    // when it is in DartdevRunner.runCommand.
+    io.stderr.writeln('$e');
+    exitCode = 64;
   } finally {
-    // Set the exitCode, if it wasn't set in the catch block above.
-    exitCode ??= result ?? 0;
-
-    // Send analytics before exiting
-    if (analytics.enabled) {
-      // And now send the exceptions and events to Google Analytics:
-      if (exception != null) {
-        unawaited(
-          analytics.sendException(
-              '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
-              fatal: true),
-        );
-      }
-
-      await analytics.waitForLastPing(
-          timeout: const Duration(milliseconds: 200));
-    }
-
-    // Set the enabled flag in the analytics object to true. Note: this will not
-    // enable the analytics unless the disclosure was shown (terminal detected),
-    // and the machine is not detected to be a bot.
-    if (analytics.firstRun) {
-      analytics.enabled = true;
-    }
-    analytics.close();
     VmInteropHandler.exit(exitCode);
   }
 }
 
 class DartdevRunner extends CommandRunner<int> {
-  final Analytics analytics;
-
   @override
   final ArgParser argParser = ArgParser(
     usageLineLength: dartdevUsageLineLength,
@@ -164,8 +69,7 @@
   static const String dartdevDescription =
       'A command-line utility for Dart development';
 
-  DartdevRunner(List<String> args, this.analytics)
-      : super('dart', '$dartdevDescription.') {
+  DartdevRunner(List<String> args) : super('dart', '$dartdevDescription.') {
     final bool verbose = args.contains('-v') || args.contains('--verbose');
 
     argParser.addFlag('verbose',
@@ -180,12 +84,9 @@
     argParser.addFlag('diagnostics',
         negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);
 
-    // A hidden flag to disable analytics on this run, this constructor can be
-    // called with this flag, but should be removed before run() is called as
-    // the flag has not been added to all sub-commands.
     argParser.addFlag(
-      'disable-dartdev-analytics',
-      negatable: false,
+      'analytics',
+      negatable: true,
       help: 'Disable anonymous analytics for this `dart *` run',
       hide: true,
     );
@@ -212,7 +113,38 @@
   @override
   Future<int> runCommand(ArgResults topLevelResults) async {
     final stopwatch = Stopwatch()..start();
-    assert(!topLevelResults.arguments.contains('--disable-dartdev-analytics'));
+    // The Analytics instance used to report information back to Google Analytics;
+    // see lib/src/analytics.dart.
+    final analytics = createAnalyticsInstance(!topLevelResults['analytics']);
+
+    // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
+    // the user is on a terminal, and the machine is not a bot, then print the
+    // disclosure and set analytics.disclosureShownOnTerminal to true.
+    if (analytics is DartdevAnalytics &&
+        !analytics.disclosureShownOnTerminal &&
+        io.stdout.hasTerminal &&
+        !isBot()) {
+      print(analyticsNoticeOnFirstRunMessage);
+      analytics.disclosureShownOnTerminal = true;
+    }
+
+    // When `--disable-analytics` or `--enable-analytics` are called we perform
+    // the respective intention and print any notices to standard out and exit.
+    if (topLevelResults['disable-analytics']) {
+      // This block also potentially catches the case of (disableAnalytics &&
+      // enableAnalytics), in which we favor the disabling of analytics.
+      analytics.enabled = false;
+
+      // Alert the user that analytics has been disabled.
+      print(analyticsDisabledNoticeMessage);
+      return 0;
+    } else if (topLevelResults['enable-analytics']) {
+      analytics.enabled = true;
+
+      // Alert the user again that anonymous data will be collected.
+      print(analyticsNoticeOnFirstRunMessage);
+      return 0;
+    }
 
     if (topLevelResults.command == null &&
         topLevelResults.arguments.isNotEmpty) {
@@ -222,14 +154,12 @@
         io.stderr.writeln(
             "Error when reading '$firstArg': No such file or directory.");
         // This is the exit code used by the frontend.
-        VmInteropHandler.exit(254);
+        return 254;
       }
     }
 
-    isDiagnostics = topLevelResults['diagnostics'];
-
     final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
-    log = isDiagnostics
+    log = topLevelResults['diagnostics']
         ? Logger.verbose(ansi: ansi)
         : Logger.standard(ansi: ansi);
 
@@ -247,8 +177,15 @@
       analytics.sendScreenView(path),
     );
 
+    // The exit code for the dartdev process; null indicates that it has not been
+    // set yet. The value is set in the catch and finally blocks below.
+    int exitCode;
+
+    // Any caught non-UsageExceptions when running the sub command.
+    Object exception;
+    StackTrace stackTrace;
     try {
-      final exitCode = await super.runCommand(topLevelResults);
+      exitCode = await super.runCommand(topLevelResults);
 
       if (path != null && analytics.enabled) {
         // Send the event to analytics
@@ -268,8 +205,16 @@
           ),
         );
       }
-
-      return exitCode;
+    } on UsageException catch (e) {
+      io.stderr.writeln('$e');
+      exitCode = 64;
+    } catch (e, st) {
+      // Set the exception and stack trace only for non-UsageException cases:
+      exception = e;
+      stackTrace = st;
+      io.stderr.writeln('$e');
+      io.stderr.writeln('$st');
+      exitCode = 1;
     } finally {
       stopwatch.stop();
       if (analytics.enabled) {
@@ -281,6 +226,32 @@
           ),
         );
       }
+      // Set the exitCode, if it wasn't set in the catch block above.
+      exitCode ??= 0;
+
+      // Send analytics before exiting
+      if (analytics.enabled) {
+        // And now send the exceptions and events to Google Analytics:
+        if (exception != null) {
+          unawaited(
+            analytics.sendException(
+                '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
+                fatal: true),
+          );
+        }
+
+        await analytics.waitForLastPing(
+            timeout: const Duration(milliseconds: 200));
+      }
+
+      // Set the enabled flag in the analytics object to true. Note: this will not
+      // enable the analytics unless the disclosure was shown (terminal detected),
+      // and the machine is not detected to be a bot.
+      if (analytics.firstRun) {
+        analytics.enabled = true;
+      }
+      analytics.close();
+      return exitCode;
     }
   }
 }
diff --git a/pkg/dartdev/lib/src/analytics.dart b/pkg/dartdev/lib/src/analytics.dart
index 14b9fb2..c9b1edf 100644
--- a/pkg/dartdev/lib/src/analytics.dart
+++ b/pkg/dartdev/lib/src/analytics.dart
@@ -57,7 +57,7 @@
   }
 
   if (disableAnalytics) {
-    // Dartdev tests pass a hidden 'disable-dartdev-analytics' flag which is
+    // Dartdev tests pass a hidden 'no-analytics' flag which is
     // handled here.
     //
     // Also, stdout.hasTerminal is checked; if there is no terminal we infer
diff --git a/pkg/dartdev/lib/src/utils.dart b/pkg/dartdev/lib/src/utils.dart
index 43249c3..c168bf4 100644
--- a/pkg/dartdev/lib/src/utils.dart
+++ b/pkg/dartdev/lib/src/utils.dart
@@ -38,31 +38,6 @@
   return s;
 }
 
-/// Static util methods used in dartdev to potentially modify the order of the
-/// arguments passed into dartdev.
-class PubUtils {
-  /// If [doModifyArgs] returns true, then this method returns a modified copy
-  /// of the argument list, 'help' is removed from the interior of the list, and
-  /// '--help' is added to the end of the list of arguments. This method returns
-  /// a modified copy of the list, the list itself is not modified.
-  static List<String> modifyArgs(List<String> args) => List.from(args)
-    ..remove('help')
-    ..add('--help');
-
-  /// If ... help pub ..., and no other verb (such as 'analyze') appears before
-  /// the ... help pub ... in the argument list, then return true.
-  static bool shouldModifyArgs(List<String> args, List<String> allCmds) =>
-      args != null &&
-      allCmds != null &&
-      args.isNotEmpty &&
-      allCmds.isNotEmpty &&
-      args.firstWhere((arg) => allCmds.contains(arg), orElse: () => '') ==
-          'help' &&
-      args.contains('help') &&
-      args.contains('pub') &&
-      args.indexOf('help') + 1 == args.indexOf('pub');
-}
-
 extension FileSystemEntityExtension on FileSystemEntity {
   String get name => p.basename(path);
 
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
index 26d9822..8c74972 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -23,7 +23,7 @@
   group('Sending analytics', () {
     test('help', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('help', []);
+      final result = p.runSync(['help']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -51,7 +51,7 @@
     });
     test('create', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('create', ['-tpackage-simple', 'name']);
+      final result = p.runSync(['create', '-tpackage-simple', 'name']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -82,7 +82,7 @@
 
     test('pub get', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('pub', ['get', '--dry-run']);
+      final result = p.runSync(['pub', 'get', '--dry-run']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -113,7 +113,7 @@
 
     test('format', () {
       final p = project(logAnalytics: true);
-      final result = p.runSync('format', ['-l80']);
+      final result = p.runSync(['format', '-l80']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
@@ -146,7 +146,8 @@
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args)',
           logAnalytics: true);
-      final result = p.runSync('run', [
+      final result = p.runSync([
+        'run',
         '--no-pause-isolates-on-exit',
         '--enable-asserts',
         'lib/main.dart',
@@ -184,7 +185,8 @@
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
-      final result = p.runSync('run', [
+      final result = p.runSync([
+        'run',
         '--enable-experiment=non-nullable',
         'lib/main.dart',
       ]);
@@ -221,7 +223,7 @@
           mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
       final result = p
-          .runSync('compile', ['kernel', 'lib/main.dart', '-o', 'main.kernel']);
+          .runSync(['compile', 'kernel', 'lib/main.dart', '-o', 'main.kernel']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index 12e1776..f2d9895 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -64,7 +64,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('analyze', ['--help']);
+    var result = p.runSync(['analyze', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -74,7 +74,7 @@
 
   test('multiple directories', () {
     p = project();
-    var result = p.runSync('analyze', ['/no/such/dir1/', '/no/such/dir2/']);
+    var result = p.runSync(['analyze', '/no/such/dir1/', '/no/such/dir2/']);
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
@@ -84,7 +84,7 @@
 
   test('no such directory', () {
     p = project();
-    var result = p.runSync('analyze', ['/no/such/dir1/']);
+    var result = p.runSync(['analyze', '/no/such/dir1/']);
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
@@ -95,7 +95,7 @@
   test('current working directory', () {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = p.runSync('analyze', [], workingDir: p.dirPath);
+    var result = p.runSync(['analyze'], workingDir: p.dirPath);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -104,7 +104,7 @@
 
   test('no errors', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -113,7 +113,7 @@
 
   test('one error', () {
     p = project(mainSrc: "int get foo => 'str';\n");
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -125,7 +125,7 @@
 
   test('two errors', () {
     p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -136,7 +136,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', ['--fatal-warnings', p.dirPath]);
+    var result = p.runSync(['analyze', '--fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
@@ -147,7 +147,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
@@ -158,7 +158,7 @@
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync('analyze', ['--no-fatal-warnings', p.dirPath]);
+    var result = p.runSync(['analyze', '--no-fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -167,7 +167,7 @@
 
   test('info implicit no --fatal-infos', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync('analyze', [p.dirPath]);
+    var result = p.runSync(['analyze', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -176,7 +176,7 @@
 
   test('info --fatal-infos', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync('analyze', ['--fatal-infos', p.dirPath]);
+    var result = p.runSync(['analyze', '--fatal-infos', p.dirPath]);
 
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
@@ -190,7 +190,7 @@
   var one = 1;
   return result;
 }''');
-    var result = p.runSync('analyze', ['--verbose', p.dirPath]);
+    var result = p.runSync(['analyze', '--verbose', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 57e669a..f2f5f31 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -27,8 +27,9 @@
   test('Implicit --help', () {
     final p = project();
     var result = p.runSync(
-      'compile',
-      [],
+      [
+        'compile',
+      ],
     );
     expect(result.stderr, contains('Compile Dart'));
     expect(result.exitCode, compileErrorExitCode);
@@ -37,8 +38,7 @@
   test('--help', () {
     final p = project();
     final result = p.runSync(
-      'compile',
-      ['--help'],
+      ['compile', '--help'],
     );
     expect(result.stdout, contains('Compile Dart'));
     expect(result.exitCode, 0);
@@ -48,8 +48,8 @@
     final p = project(mainSrc: 'void main() { print("I love jit"); }');
     final outFile = path.join(p.dirPath, 'main.jit');
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'jit-snapshot',
         '-o',
         outFile,
@@ -61,7 +61,7 @@
     expect(File(outFile).existsSync(), true,
         reason: 'File not found: $outFile');
 
-    result = p.runSync('run', ['main.jit']);
+    result = p.runSync(['run', 'main.jit']);
     expect(result.stdout, contains('I love jit'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
@@ -73,8 +73,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'lib', 'main.exe'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'exe',
         inFile,
       ],
@@ -102,8 +102,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'exe',
         '--define',
         'life=42',
@@ -134,8 +134,8 @@
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.aot'));
 
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'aot-snapshot',
         '-o',
         'main.aot',
@@ -163,8 +163,8 @@
     final p = project(mainSrc: 'void main() { print("I love kernel"); }');
     final outFile = path.join(p.dirPath, 'main.dill');
     var result = p.runSync(
-      'compile',
       [
+        'compile',
         'kernel',
         '-o',
         outFile,
@@ -176,7 +176,7 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
 
-    result = p.runSync('run', ['main.dill']);
+    result = p.runSync(['run', 'main.dill']);
     expect(result.stdout, contains('I love kernel'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
@@ -187,7 +187,8 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.js'));
 
-    final result = p.runSync('compile', [
+    final result = p.runSync([
+      'compile',
       'js',
       '-m',
       '-o',
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 38a8ebd..7f5c846 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -36,7 +36,7 @@
   test('list templates', () {
     p = project();
 
-    ProcessResult result = p.runSync('create', ['--list-templates']);
+    ProcessResult result = p.runSync(['create', '--list-templates']);
     expect(result.exitCode, 0);
 
     String output = result.stdout.toString();
@@ -50,7 +50,9 @@
   test('no directory given', () {
     p = project();
 
-    ProcessResult result = p.runSync('create', []);
+    ProcessResult result = p.runSync([
+      'create',
+    ]);
     expect(result.exitCode, 1);
   });
 
@@ -58,7 +60,7 @@
     p = project();
 
     ProcessResult result = p.runSync(
-        'create', ['--template', CreateCommand.defaultTemplateId, p.dir.path]);
+        ['create', '--template', CreateCommand.defaultTemplateId, p.dir.path]);
     expect(result.exitCode, 73);
   });
 
@@ -66,7 +68,7 @@
     p = project();
 
     ProcessResult result =
-        p.runSync('create', ['--no-pub', '--template', 'foo-bar', p.dir.path]);
+        p.runSync(['create', '--no-pub', '--template', 'foo-bar', p.dir.path]);
     expect(result.exitCode, isNot(0));
   });
 
@@ -76,7 +78,7 @@
       p = project();
 
       ProcessResult result = p
-          .runSync('create', ['--force', '--template', templateId, p.dir.path]);
+          .runSync(['create', '--force', '--template', templateId, p.dir.path]);
       expect(result.exitCode, 0);
 
       String projectName = path.basename(p.dir.path);
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 40c7860..8a92d7b 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -29,9 +29,9 @@
   ProcessResult runFix(List<String> args, {String workingDir}) {
     if (runFromSource) {
       var binary = path.join(Directory.current.path, 'bin', 'dartdev.dart');
-      return p.runSync(binary, ['fix', ...?args], workingDir: workingDir);
+      return p.runSync([binary, 'fix', ...?args], workingDir: workingDir);
     }
-    return p.runSync('fix', args, workingDir: workingDir);
+    return p.runSync(['fix', ...args], workingDir: workingDir);
   }
 
   test('none', () {
@@ -65,6 +65,7 @@
     - prefer_single_quotes
 ''',
     );
+
     var result = runFix(['--apply'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 6416ffc..0475ee3 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
-import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -20,7 +19,7 @@
   // For each command description, assert that the values are not empty, don't
   // have trailing white space and end with a period.
   test('description formatting', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       expect(commandKey, isNotEmpty);
@@ -32,7 +31,7 @@
 
   // Assert that all found usageLineLengths are the same and null
   test('argParser usageLineLength', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       if (command.argParser != null) {
@@ -62,7 +61,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('--help', []);
+    var result = p.runSync(['--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -80,7 +79,7 @@
 
   test('--help --verbose', () {
     p = project();
-    var result = p.runSync('--help', ['--verbose']);
+    var result = p.runSync(['--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, isEmpty);
@@ -90,7 +89,7 @@
 
   test('--help -v', () {
     p = project();
-    var result = p.runSync('--help', ['-v']);
+    var result = p.runSync(['--help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, isEmpty);
@@ -100,7 +99,7 @@
 
   test('help', () {
     p = project();
-    var result = p.runSync('help', []);
+    var result = p.runSync(['help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -118,7 +117,7 @@
 
   test('help --verbose', () {
     p = project();
-    var result = p.runSync('help', ['--verbose']);
+    var result = p.runSync(['help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains('migrate '));
@@ -126,7 +125,7 @@
 
   test('help -v', () {
     p = project();
-    var result = p.runSync('help', ['-v']);
+    var result = p.runSync(['help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains('migrate '));
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index cded95b..6f36795 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -19,7 +19,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('format', ['--help']);
+    var result = p.runSync(['format', '--help']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -32,7 +32,7 @@
 
   test('--help --verbose', () {
     p = project();
-    var result = p.runSync('format', ['--help', '--verbose']);
+    var result = p.runSync(['format', '--help', '--verbose']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -45,7 +45,7 @@
 
   test('unchanged', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    ProcessResult result = p.runSync('format', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, startsWith('Formatted 1 file (0 changed) in '));
@@ -53,7 +53,7 @@
 
   test('formatted', () {
     p = project(mainSrc: 'int get foo =>       1;\n');
-    ProcessResult result = p.runSync('format', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -65,7 +65,7 @@
   test('unknown file', () {
     p = project(mainSrc: 'int get foo => 1;\n');
     var unknownFilePath = '${p.relativeFilePath}-unknown-file.dart';
-    ProcessResult result = p.runSync('format', [unknownFilePath]);
+    ProcessResult result = p.runSync(['format', unknownFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr,
         startsWith('No file or directory found at "$unknownFilePath".'));
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index c272e43..afbaf09 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
-import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -22,14 +21,14 @@
   List<String> _commandsNotTested = <String>[
     'help', // `dart help help` is redundant
   ];
-  DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+  DartdevRunner(['--no-analytics'])
       .commands
       .forEach((String commandKey, Command command) {
     if (!_commandsNotTested.contains(commandKey)) {
       test('(help $commandKey == $commandKey --help)', () {
         p = project();
-        var result = p.runSync('help', [commandKey]);
-        var verbHelpResult = p.runSync(commandKey, ['--help']);
+        var result = p.runSync(['help', commandKey]);
+        var verbHelpResult = p.runSync([commandKey, '--help']);
 
         expect(result.stdout, contains(verbHelpResult.stdout));
         expect(result.stderr, contains(verbHelpResult.stderr));
@@ -39,15 +38,15 @@
 
   test('(help pub == pub --help)', () {
     p = project();
-    var result = p.runSync('help', ['pub']);
-    var pubHelpResult = p.runSync('pub', ['--help']);
+    var result = p.runSync(['help', 'pub']);
+    var pubHelpResult = p.runSync(['pub', '--help']);
 
     expect(result.stdout, contains(pubHelpResult.stdout));
     expect(result.stderr, contains(pubHelpResult.stderr));
   });
 
   test('(--help flags also have -h abbr)', () {
-    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
+    DartdevRunner(['--no-analytics'])
         .commands
         .forEach((String commandKey, Command command) {
       var helpOption = command.argParser.options['help'];
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 8101640..681d550 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -21,7 +21,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('migrate', ['--help']);
+    var result = p.runSync(['migrate', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -34,7 +34,7 @@
   test('directory implicit', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
     var result =
-        p.runSync('migrate', ['--no-web-preview'], workingDir: p.dirPath);
+        p.runSync(['migrate', '--no-web-preview'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
@@ -42,7 +42,7 @@
 
   test('directory explicit', () {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
-    var result = p.runSync('migrate', ['--no-web-preview', p.dirPath]);
+    var result = p.runSync(['migrate', '--no-web-preview', p.dirPath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
@@ -50,7 +50,7 @@
 
   test('bad directory', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('migrate', ['foo_bar_dir']);
+    var result = p.runSync(['migrate', 'foo_bar_dir']);
     expect(result.exitCode, 1);
     expect(result.stderr, contains('foo_bar_dir does not exist'));
     expect(result.stdout, isEmpty);
@@ -58,7 +58,7 @@
 
   test('pub get needs running', () {
     p = project(mainSrc: 'import "package:foo/foo.dart";\n');
-    var result = p.runSync('migrate', [p.dirPath]);
+    var result = p.runSync(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
@@ -67,7 +67,7 @@
 
   test('non-pub-related error', () {
     p = project(mainSrc: 'var missing = "semicolon"\n');
-    var result = p.runSync('migrate', [p.dirPath]);
+    var result = p.runSync(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index 82f00d0..e164858 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -26,7 +26,7 @@
   }
 
   test('implicit --help', () {
-    final result = project().runSync('pub', []);
+    final result = project().runSync(['pub']);
     expect(result, isNotNull);
     expect(result.exitCode, 64);
     expect(result.stderr, contains('Missing subcommand for "dart pub".'));
@@ -35,17 +35,17 @@
   });
 
   test('--help', () {
-    _assertPubHelpInvoked(project().runSync('pub', ['--help']));
+    _assertPubHelpInvoked(project().runSync(['pub', '--help']));
   });
 
   test('-h', () {
-    _assertPubHelpInvoked(project().runSync('pub', ['-h']));
+    _assertPubHelpInvoked(project().runSync(['pub', '-h']));
   });
 
   test('help cache', () {
     p = project();
-    var result = p.runSync('help', ['pub', 'cache']);
-    var result2 = p.runSync('pub', ['cache', '--help']);
+    var result = p.runSync(['help', 'pub', 'cache']);
+    var result2 = p.runSync(['pub', 'cache', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -58,8 +58,8 @@
 
   test('help publish', () {
     p = project();
-    var result = p.runSync('help', ['pub', 'publish']);
-    var result2 = p.runSync('pub', ['publish', '--help']);
+    var result = p.runSync(['help', 'pub', 'publish']);
+    var result2 = p.runSync(['pub', 'publish', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -77,10 +77,10 @@
         "void main() { int? a; a = null; print('a is \$a.'); }");
 
     // run 'pub get'
-    p.runSync('pub', ['get']);
+    p.runSync(['pub', 'get']);
 
     var result = p.runSync(
-        'pub', ['run', '--enable-experiment=no-non-nullable', 'main.dart']);
+        ['pub', 'run', '--enable-experiment=no-non-nullable', 'main.dart']);
 
     expect(result.exitCode, 254);
     expect(result.stdout, isEmpty);
@@ -93,7 +93,7 @@
 
   test('failure', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('pub', ['deps']);
+    var result = p.runSync(['pub', 'deps']);
     expect(result.exitCode, 65);
     expect(result.stdout, isEmpty);
     expect(result.stderr, contains('No pubspec.lock file found'));
@@ -101,7 +101,7 @@
 
   test('failure unknown option', () {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync('pub', ['deps', '--foo']);
+    var result = p.runSync(['pub', 'deps', '--foo']);
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
     expect(result.stderr, startsWith('Could not find an option named "foo".'));
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 9d2125c..59bffba 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -20,7 +20,7 @@
 
   test('--help', () {
     p = project();
-    var result = p.runSync('run', ['--help']);
+    var result = p.runSync(['run', '--help']);
 
     expect(result.stdout, contains('Run a Dart program.'));
     expect(result.stdout, contains('Debugging options:'));
@@ -30,7 +30,7 @@
 
   test("'Hello World'", () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
-    ProcessResult result = p.runSync('run', [p.relativeFilePath]);
+    ProcessResult result = p.runSync(['run', p.relativeFilePath]);
 
     expect(result.stdout, contains('Hello World'));
     expect(result.stderr, isEmpty);
@@ -40,7 +40,7 @@
   test('no such file', () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     ProcessResult result =
-        p.runSync('run', ['no/such/file/${p.relativeFilePath}']);
+        p.runSync(['run', 'no/such/file/${p.relativeFilePath}']);
 
     expect(result.stderr, isNotEmpty);
     expect(result.exitCode, isNot(0));
@@ -51,7 +51,7 @@
     // name (package name) will be the name of the temporary directory on disk
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/main.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync('run', []);
+    ProcessResult result = p.runSync(['run']);
 
     expect(result.stdout, contains('Hello main.dart'));
     expect(result.stderr, isEmpty);
@@ -62,7 +62,7 @@
   test('missing implicit packageName.dart', () {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/foo.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync('run', []);
+    ProcessResult result = p.runSync(['run']);
 
     expect(result.stdout, isEmpty);
     expect(
@@ -75,7 +75,8 @@
   test('arguments are properly passed', () {
     p = project();
     p.file('main.dart', 'void main(args) { print(args); }');
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--enable-experiment=triple-shift',
       'main.dart',
       'argument1',
@@ -111,7 +112,7 @@
 void main(List<String> args) => print("$b $args");
 ''');
 
-      ProcessResult result = p.runSync('run', ['bar:main', '--arg1', 'arg2']);
+      ProcessResult result = p.runSync(['run', 'bar:main', '--arg1', 'arg2']);
 
       expect(result.stderr, isEmpty);
       expect(result.stdout, contains('FOO BAR [--arg1, arg2]'));
@@ -126,7 +127,8 @@
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with absolute path
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync('run', [
+    final result = p.runSync([
+      'run',
       '--enable-experiment=triple-shift',
       name,
       '--argument1',
@@ -144,7 +146,8 @@
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with File uri
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync('run', [
+    final result = p.runSync([
+      'run',
       Uri.file(name).toString(),
       '--argument1',
       'argument2',
@@ -167,7 +170,8 @@
     //
     // This test ensures that allowed arguments for dart run which are valid VM
     // arguments are properly handled by the VM.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--observe',
       '--pause-isolates-on-start',
       // This should negate the above flag.
@@ -186,7 +190,8 @@
     expect(result.exitCode, 0);
 
     // Again, with --disable-service-auth-codes.
-    result = p.runSync('run', [
+    result = p.runSync([
+      'run',
       '--observe',
       '--pause-isolates-on-start',
       // This should negate the above flag.
@@ -211,7 +216,8 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--vm-name=foo',
       p.relativeFilePath,
     ]);
@@ -229,7 +235,8 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--verbose_gc',
       p.relativeFilePath,
     ]);
@@ -247,7 +254,8 @@
 
     // Ensure --enable-asserts doesn't cause the dartdev isolate to fail to
     // load. Regression test for: https://github.com/dart-lang/sdk/issues/42831
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       '--enable-asserts',
       p.relativeFilePath,
     ]);
@@ -261,7 +269,8 @@
     p = project(mainSrc: 'void main() { assert(false); }');
 
     // Any VM flags passed after the script shouldn't be interpreted by the VM.
-    ProcessResult result = p.runSync('run', [
+    ProcessResult result = p.runSync([
+      'run',
       p.relativeFilePath,
       '--enable-asserts',
     ]);
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index ff85982..00be2bc 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -21,7 +21,7 @@
   test('--help', () {
     p = project();
 
-    final result = p.runSync('test', ['--help']);
+    final result = p.runSync(['test', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains(' tests in this package'));
@@ -31,7 +31,7 @@
   test('dart help test', () {
     p = project();
 
-    final result = p.runSync('help', ['test']);
+    final result = p.runSync(['help', 'test']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains(' tests in this package'));
@@ -43,7 +43,7 @@
     var pubspec = File(path.join(p.dirPath, 'pubspec.yaml'));
     pubspec.deleteSync();
 
-    var result = p.runSync('test', []);
+    var result = p.runSync(['test']);
 
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('No pubspec.yaml file found'));
@@ -63,7 +63,7 @@
 ''');
 
     // An implicit `pub get` will happen.
-    final result = p.runSync('test', ['--no-color', '--reporter', 'expanded']);
+    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('All tests passed!'));
     expect(result.exitCode, 0);
@@ -86,7 +86,8 @@
 }
 ''');
 
-    final result = p.runSync('test', []);
+    final result = p.runSync(['test']);
+    expect(result.exitCode, 65);
     expect(
       result.stdout,
       contains('You need to add a dependency on package:test'),
@@ -94,10 +95,10 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 65);
 
-    final resultPubAdd = p.runSync('pub', ['add', 'test']);
+    final resultPubAdd = p.runSync(['pub', 'add', 'test']);
 
     expect(resultPubAdd.exitCode, 0);
-    final result2 = p.runSync('test', ['--no-color', '--reporter', 'expanded']);
+    final result2 = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
     expect(result2.stderr, isEmpty);
     expect(result2.stdout, contains('All tests passed!'));
     expect(result2.exitCode, 0);
@@ -117,7 +118,7 @@
 }
 ''');
 
-    final result = p.runSync('test', ['--no-color', '--reporter', 'expanded']);
+    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.exitCode, 0);
     expect(result.stdout, contains('All tests passed!'));
     expect(result.stderr, isEmpty);
@@ -138,8 +139,13 @@
 ''');
 
     final result = p.runSync(
-      '--enable-experiment=non-nullable',
-      ['test', '--no-color', '--reporter', 'expanded'],
+      [
+        '--enable-experiment=non-nullable',
+        'test',
+        '--no-color',
+        '--reporter',
+        'expanded',
+      ],
     );
     expect(result.exitCode, 1);
   });
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
index 1d197d7..b5a3452 100644
--- a/pkg/dartdev/test/no_such_file_test.dart
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -14,12 +14,12 @@
   test('Ensure parsing fails after encountering invalid file', () {
     // Regression test for https://github.com/dart-lang/sdk/issues/43991
     p = project();
-    final noArgsResult = p.runSync('foo.dart', []);
+    final noArgsResult = p.runSync(['foo.dart']);
     expect(noArgsResult.stderr, isNotEmpty);
     expect(noArgsResult.stdout, isEmpty);
     expect(noArgsResult.exitCode, 64);
 
-    final argsResult = p.runSync('foo.dart', ['--bar']);
+    final argsResult = p.runSync(['foo.dart', '--bar']);
     expect(argsResult.stderr, noArgsResult.stderr);
     expect(argsResult.stdout, isEmpty);
     expect(argsResult.exitCode, 64);
@@ -29,7 +29,7 @@
       () {
     // Regression test for https://github.com/dart-lang/sdk/issues/43785
     p = project();
-    final result = p.runSync('--snapshot=abc', ['foo.dart']);
+    final result = p.runSync(['--snapshot=abc', 'foo.dart']);
     expect(result.stderr, isNotEmpty);
     expect(result.stderr, contains("Error when reading 'foo.dart':"));
     expect(result.stdout, isEmpty);
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index a8de016..48dcfd7 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -75,17 +75,15 @@
   }
 
   ProcessResult runSync(
-    String command,
-    List<String> args, {
+    List<String> arguments, {
     String workingDir,
   }) {
-    var arguments = [
-      command,
-      ...?args,
-    ];
-
-    arguments.add('--disable-dartdev-analytics');
-    return Process.runSync(Platform.resolvedExecutable, arguments,
+    return Process.runSync(
+        Platform.resolvedExecutable,
+        [
+          '--no-analytics',
+          ...arguments,
+        ],
         workingDirectory: workingDir ?? dir.path,
         environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
   }
diff --git a/pkg/dartdev/test/utils_test.dart b/pkg/dartdev/test/utils_test.dart
index 51f6d5f..111326b 100644
--- a/pkg/dartdev/test/utils_test.dart
+++ b/pkg/dartdev/test/utils_test.dart
@@ -101,39 +101,6 @@
     });
   });
 
-  group('PubUtils', () {
-    test('doModifyArgs', () {
-      const allCmds = ['analyze', 'help', 'pub', 'migrate'];
-      expect(PubUtils.shouldModifyArgs(null, null), isFalse);
-      expect(PubUtils.shouldModifyArgs([], null), isFalse);
-      expect(PubUtils.shouldModifyArgs(null, []), isFalse);
-      expect(PubUtils.shouldModifyArgs([], []), isFalse);
-      expect(PubUtils.shouldModifyArgs(['-h'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['--help'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['help'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['pub'], allCmds), isFalse);
-      expect(PubUtils.shouldModifyArgs(['analyze', 'help', 'pub'], allCmds),
-          isFalse);
-
-      expect(PubUtils.shouldModifyArgs(['--some-flag', 'help', 'pub'], allCmds),
-          isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub'], allCmds), isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub', 'publish'], allCmds),
-          isTrue);
-      expect(PubUtils.shouldModifyArgs(['help', 'pub', 'analyze'], allCmds),
-          isTrue);
-    });
-
-    test('modifyArgs', () {
-      expect(PubUtils.modifyArgs(['--some-flag', 'help', 'pub']),
-          orderedEquals(['--some-flag', 'pub', '--help']));
-      expect(PubUtils.modifyArgs(['help', 'pub']),
-          orderedEquals(['pub', '--help']));
-      expect(PubUtils.modifyArgs(['help', 'pub', 'publish']),
-          orderedEquals(['pub', 'publish', '--help']));
-    });
-  });
-
   group('wrapText', () {
     test('oneLine_wordLongerThanLine', () {
       expect(wrapText('http://long-url', width: 10), equals('http://long-url'));
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 43f7c3d..2b1cf58 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2004,6 +2004,11 @@
           new List<DartType>.filled(
               calleeTypeParameters.length, const DynamicType()));
     }
+    TreeNode parent = arguments.parent;
+    bool isIdentical = arguments.positional.length == 2 &&
+        parent is StaticInvocation &&
+        parent.target.name.name == 'identical' &&
+        parent.target.parent == typeSchemaEnvironment.coreTypes.coreLibrary;
     // TODO(paulberry): if we are doing top level inference and type arguments
     // were omitted, report an error.
     for (int position = 0; position < arguments.positional.length; position++) {
@@ -2044,6 +2049,14 @@
             : legacyErasure(result.inferredType);
         Expression expression =
             _hoist(result.expression, inferredType, hoistedExpressions);
+        if (isIdentical && arguments.positional.length == 2) {
+          if (position == 0) {
+            flowAnalysis?.equalityOp_rightBegin(expression, inferredType);
+          } else {
+            flowAnalysis?.equalityOp_end(
+                arguments.parent, expression, inferredType);
+          }
+        }
         arguments.positional[position] = expression..parent = arguments;
       }
       if (inferenceNeeded || typeChecksNeeded) {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 72e10c8..cb53b76 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -209,15 +209,11 @@
                           char** argv,
                           CommandLineOptions* vm_options,
                           CommandLineOptions* inputs) {
-  const char* kPrefix = "-";
-  const intptr_t kPrefixLen = strlen(kPrefix);
-
   // Skip the binary name.
   int i = 1;
 
   // Parse out the vm options.
-  while ((i < argc) &&
-         OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
+  while ((i < argc) && OptionProcessor::IsValidShortFlag(argv[i])) {
     if (OptionProcessor::TryProcess(argv[i], vm_options)) {
       i += 1;
       continue;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 76d3b51..7299ade 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1140,10 +1140,10 @@
 
   // Parse command line arguments.
   if (app_snapshot == nullptr) {
-    int result = Options::ParseArguments(
+    bool success = Options::ParseArguments(
         argc, argv, vm_run_app_snapshot, &vm_options, &script_name,
         &dart_options, &print_flags_seen, &verbose_debug_seen);
-    if (result < 0) {
+    if (!success) {
       if (Options::help_option()) {
         Options::PrintUsage();
         Platform::Exit(0);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 2e962c1..d019ce4 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -282,6 +282,26 @@
   return true;
 }
 
+// Returns true if arg starts with the characters "--" followed by option, but
+// all '_' in the option name are treated as '-'.
+static bool IsOption(const char* arg, const char* option) {
+  if (arg[0] != '-' || arg[1] != '-') {
+    // Special case first two characters to avoid recognizing __flag.
+    return false;
+  }
+  for (int i = 0; option[i] != '\0'; i++) {
+    auto c = arg[i + 2];
+    if (c == '\0') {
+      // Not long enough.
+      return false;
+    }
+    if ((c == '_' ? '-' : c) != option[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
 const char* Options::vm_service_server_ip_ = DEFAULT_VM_SERVICE_SERVER_IP;
 int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
 bool Options::ProcessEnableVmServiceOption(const char* arg,
@@ -366,17 +386,14 @@
   return false;
 }
 
-int Options::ParseArguments(int argc,
-                            char** argv,
-                            bool vm_run_app_snapshot,
-                            CommandLineOptions* vm_options,
-                            char** script_name,
-                            CommandLineOptions* dart_options,
-                            bool* print_flags_seen,
-                            bool* verbose_debug_seen) {
-  const char* kPrefix = "--";
-  const intptr_t kPrefixLen = strlen(kPrefix);
-
+bool Options::ParseArguments(int argc,
+                             char** argv,
+                             bool vm_run_app_snapshot,
+                             CommandLineOptions* vm_options,
+                             char** script_name,
+                             CommandLineOptions* dart_options,
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen) {
   // Store the executable name.
   Platform::SetExecutableName(argv[0]);
 
@@ -395,43 +412,26 @@
       i++;
     } else {
       // Check if this flag is a potentially valid VM flag.
-      if (!OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
+      if (!OptionProcessor::IsValidFlag(argv[i])) {
         break;
       }
-      // The following two flags are processed by both the embedder and
-      // the VM.
-      const char* kPrintFlags1 = "--print-flags";
-      const char* kPrintFlags2 = "--print_flags";
-      const char* kVerboseDebug1 = "--verbose_debug";
-      const char* kVerboseDebug2 = "--verbose-debug";
-
-      // The following two flags are processed as DartDev flags and are not to
+      // The following flags are processed as DartDev flags and are not to
       // be treated as if they are VM flags.
-      const char* kEnableDartDevAnalytics1 = "--enable-analytics";
-      const char* kEnableDartDevAnalytics2 = "--enable_analytics";
-      const char* kDisableDartDevAnalytics1 = "--disable-analytics";
-      const char* kDisableDartDevAnalytics2 = "--disable_analytics";
-
-      if ((strncmp(argv[i], kPrintFlags1, strlen(kPrintFlags1)) == 0) ||
-          (strncmp(argv[i], kPrintFlags2, strlen(kPrintFlags2)) == 0)) {
+      if (IsOption(argv[i], "print-flags")) {
         *print_flags_seen = true;
-      } else if ((strncmp(argv[i], kVerboseDebug1, strlen(kVerboseDebug1)) ==
-                  0) ||
-                 (strncmp(argv[i], kVerboseDebug2, strlen(kVerboseDebug2)) ==
-                  0)) {
+      } else if (IsOption(argv[i], "verbose-debug")) {
         *verbose_debug_seen = true;
-      } else if ((strncmp(argv[i], kEnableDartDevAnalytics1,
-                          strlen(kEnableDartDevAnalytics1)) == 0) ||
-                 (strncmp(argv[i], kEnableDartDevAnalytics2,
-                          strlen(kEnableDartDevAnalytics2)) == 0)) {
+      } else if (IsOption(argv[i], "enable-analytics")) {
         enable_dartdev_analytics = true;
         skipVmOption = true;
-      } else if ((strncmp(argv[i], kDisableDartDevAnalytics1,
-                          strlen(kDisableDartDevAnalytics1)) == 0) ||
-                 (strncmp(argv[i], kDisableDartDevAnalytics2,
-                          strlen(kDisableDartDevAnalytics2)) == 0)) {
+      } else if (IsOption(argv[i], "disable-analytics")) {
         disable_dartdev_analytics = true;
         skipVmOption = true;
+      } else if (IsOption(argv[i], "no-analytics")) {
+        // Just add this option even if we don't go to dartdev.
+        // It is irelevant for the vm.
+        dart_options->AddArgument("--no-analytics");
+        skipVmOption = true;
       }
       if (!skipVmOption) {
         temp_vm_options.AddArgument(argv[i]);
@@ -465,7 +465,6 @@
 
   bool implicitly_use_dart_dev = false;
   bool run_script = false;
-
   // Get the script name.
   if (i < argc) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -506,25 +505,19 @@
     DartDevIsolate::set_should_run_dart_dev(true);
     // Let DartDev handle the default help message.
     dart_options->AddArgument("help");
-    return 0;
+    return true;
   } else if (!Options::disable_dart_dev() &&
              (enable_dartdev_analytics || disable_dartdev_analytics)) {
     // The analytics flags are a special case as we don't have a target script
     // or DartDev command but we still want to launch DartDev.
     DartDevIsolate::set_should_run_dart_dev(true);
 
-    if (enable_dartdev_analytics) {
-      dart_options->AddArgument("--enable-analytics");
-    }
-    if (disable_dartdev_analytics) {
-      dart_options->AddArgument("--disable-analytics");
-    }
-    return 0;
+    return true;
   }
 
 #endif    // !defined(DART_PRECOMPILED_RUNTIME)
   else {  // NOLINT
-    return -1;
+    return false;
   }
   USE(enable_dartdev_analytics);
   USE(disable_dartdev_analytics);
@@ -547,7 +540,7 @@
     while (tmp_i < argc) {
       // Check if this flag is a potentially valid VM flag. If not, we've likely
       // hit a script name and are done parsing VM flags.
-      if (!OptionProcessor::IsValidFlag(argv[tmp_i], kPrefix, kPrefixLen)) {
+      if (!OptionProcessor::IsValidFlag(argv[tmp_i])) {
         break;
       }
       OptionProcessor::TryProcess(argv[tmp_i], vm_options);
@@ -596,14 +589,12 @@
       first_option = false;
     }
   }
-
-
   // Verify consistency of arguments.
 
   // snapshot_depfile is an alias for depfile. Passing them both is an error.
   if ((snapshot_deps_filename_ != NULL) && (depfile_ != NULL)) {
     Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
-    return -1;
+    return false;
   }
   if (snapshot_deps_filename_ != NULL) {
     depfile_ = snapshot_deps_filename_;
@@ -612,25 +603,25 @@
 
   if ((packages_file_ != NULL) && (strlen(packages_file_) == 0)) {
     Syslog::PrintErr("Empty package file name specified.\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == NULL)) {
     Syslog::PrintErr(
         "Generating a snapshot requires a filename (--snapshot).\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ == kNone) && (depfile_ != NULL) &&
       (snapshot_filename_ == NULL) && (depfile_output_filename_ == NULL)) {
     Syslog::PrintErr(
         "Generating a depfile requires an output filename"
         " (--depfile-output-filename or --snapshot).\n");
-    return -1;
+    return false;
   }
   if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
     Syslog::PrintErr(
         "Specifying an option to generate a snapshot and"
         " run using a snapshot is invalid.\n");
-    return -1;
+    return false;
   }
 
   // If --snapshot is given without --snapshot-kind, default to script snapshot.
@@ -638,7 +629,7 @@
     gen_snapshot_kind_ = kKernel;
   }
 
-  return 0;
+  return true;
 }
 
 }  // namespace bin
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index f900a3c..2ab8598 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -85,14 +85,15 @@
 
 class Options {
  public:
-  static int ParseArguments(int argc,
-                            char** argv,
-                            bool vm_run_app_shapshot,
-                            CommandLineOptions* vm_options,
-                            char** script_name,
-                            CommandLineOptions* dart_options,
-                            bool* print_flags_seen,
-                            bool* verbose_debug_seen);
+  // Returns true if argument parsing succeeded. False otherwise.
+  static bool ParseArguments(int argc,
+                             char** argv,
+                             bool vm_run_app_shapshot,
+                             CommandLineOptions* vm_options,
+                             char** script_name,
+                             CommandLineOptions* dart_options,
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen);
 
 #define STRING_OPTION_GETTER(flag, variable)                                   \
   static const char* variable() { return variable##_; }
diff --git a/runtime/bin/options.cc b/runtime/bin/options.cc
index 1eed113..7ad5d20 100644
--- a/runtime/bin/options.cc
+++ b/runtime/bin/options.cc
@@ -9,12 +9,12 @@
 
 OptionProcessor* OptionProcessor::first_ = NULL;
 
-bool OptionProcessor::IsValidFlag(const char* name,
-                                  const char* prefix,
-                                  intptr_t prefix_length) {
-  const intptr_t name_length = strlen(name);
-  return ((name_length > prefix_length) &&
-          (strncmp(name, prefix, prefix_length) == 0));
+bool OptionProcessor::IsValidFlag(const char* name) {
+  return name[0] == '-' && name[1] == '-' && name[2] != '\0';
+}
+
+bool OptionProcessor::IsValidShortFlag(const char* name) {
+  return name[0] == '-' && name[1] != '\0';
 }
 
 const char* OptionProcessor::ProcessOption(const char* option,
diff --git a/runtime/bin/options.h b/runtime/bin/options.h
index 4bcd7de..bb5f5ee 100644
--- a/runtime/bin/options.h
+++ b/runtime/bin/options.h
@@ -22,9 +22,11 @@
 
   virtual ~OptionProcessor() {}
 
-  static bool IsValidFlag(const char* name,
-                          const char* prefix,
-                          intptr_t prefix_length);
+  // Returns true if name starts with "--".
+  static bool IsValidFlag(const char* name);
+
+  // Returns true if name starts with "-".
+  static bool IsValidShortFlag(const char* name);
 
   virtual bool Process(const char* option, CommandLineOptions* options) = 0;
 
diff --git a/tools/VERSION b/tools/VERSION
index ed6a03a..c7c1689 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 116
+PRERELEASE 117
 PRERELEASE_PATCH 0
\ No newline at end of file