Remove unused parts of migration tooling
Change-Id: Ib18224f42880c47be63e6f6814db99ac05eced48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278373
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
deleted file mode 100644
index edec874..0000000
--- a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2019, 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.
-
-// TODO(jcollins-g): Merge this with similar utilities in dartdoc
-// and extract into a separate package, generate testing and mirrors, and
-// reimport that into the SDK, before cut and paste gets out of hand.
-
-/// This is a modified version of dartdoc's
-/// SubprocessLauncher from test/src/utils.dart, for use with the
-/// nnbd_migration script.
-library;
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'multi_future_tracker.dart';
-
-/// Maximum number of parallel subprocesses. Use this to to avoid overloading
-/// your CPU.
-final MultiFutureTracker maxParallel =
- MultiFutureTracker(Platform.numberOfProcessors);
-
-/// Route all executions of pub through this [MultiFutureTracker] to avoid
-/// parallel executions of the pub command.
-final MultiFutureTracker pubTracker = MultiFutureTracker(1);
-
-final RegExp quotables = RegExp(r'[ "\r\n\$]');
-
-/// SubprocessLauncher manages one or more launched, non-interactive
-/// subprocesses. It handles I/O streams, parses JSON output if
-/// available, and logs debugging information so the user can see exactly
-/// what was run.
-class SubprocessLauncher {
- final String context;
- final Map<String, String> environmentDefaults;
-
- SubprocessLauncher(this.context, [Map<String, String>? environment])
- : environmentDefaults = environment ?? <String, String>{};
-
- /// Wraps [runStreamedImmediate] as a closure around
- /// [maxParallel.addFutureFromClosure].
- ///
- /// This essentially implements a 'make -j N' limit for all subcommands.
- Future<Iterable<Map>?> runStreamed(String executable, List<String> arguments,
- // TODO(jcollins-g): Fix primitive obsession: consolidate parameters into
- // another object.
- {String? workingDirectory,
- Map<String, String>? environment,
- bool includeParentEnvironment = true,
- void Function(String)? perLine,
- int retries = 0,
- String? instance,
- bool allowNonzeroExit = false}) async {
- // TODO(jcollins-g): The closure wrapping we've done has made it impossible
- // to catch exceptions when calling runStreamed. Fix this.
- return maxParallel.runFutureFromClosure(() async {
- return retryClosure(
- () async => await runStreamedImmediate(executable, arguments,
- workingDirectory: workingDirectory,
- environment: environment,
- includeParentEnvironment: includeParentEnvironment,
- perLine: perLine,
- instance: instance,
- allowNonzeroExit: allowNonzeroExit),
- retries: retries);
- });
- }
-
- /// A wrapper around start/await process.exitCode that will display the
- /// output of the executable continuously and fail on non-zero exit codes.
- /// It will also parse any valid JSON objects (one per line) it encounters
- /// on stdout/stderr, and return them. Returns null if no JSON objects
- /// were encountered, or if DRY_RUN is set to 1 in the execution environment.
- ///
- /// Makes running programs in grinder similar to set -ex for bash, even on
- /// Windows (though some of the bashisms will no longer make sense).
- /// TODO(jcollins-g): refactor to return a stream of stderr/stdout lines
- /// and their associated JSON objects.
- Future<Iterable<Map>?> runStreamedImmediate(
- String executable, List<String> arguments,
- {String? workingDirectory,
- Map<String, String>? environment,
- bool includeParentEnvironment = true,
- void Function(String)? perLine,
- // A tag added to [context] to construct the line prefix.
- // Use this to indicate the process or processes with the tag
- // share something in common, like a hostname, a package, or a
- // multi-step procedure.
- String? instance,
- bool allowNonzeroExit = false}) async {
- String prefix = context.isNotEmpty
- ? '$context${instance != null ? "-$instance" : ""}: '
- : '';
-
- environment ??= {};
- environment.addAll(environmentDefaults);
- List<Map>? jsonObjects;
-
- /// Parses json objects generated by the subprocess. If a json object
- /// contains the key 'message' or the keys 'data' and 'text', return that
- /// value as a collection of lines suitable for printing.
- Iterable<String> jsonCallback(String line) {
- if (perLine != null) perLine(line);
- Map? result;
- try {
- result = json.decoder.convert(line) as Map?;
- } on FormatException {
- // ignore
- }
- if (result != null) {
- jsonObjects ??= [];
- jsonObjects!.add(result);
- if (result.containsKey('message')) {
- line = result['message'] as String;
- } else if (result.containsKey('data') &&
- result['data'] is Map &&
- (result['data'] as Map).containsKey('key')) {
- line = result['data']['text'] as String;
- }
- }
- return line.split('\n');
- }
-
- stderr.write('$prefix+ ');
- if (workingDirectory != null) stderr.write('(cd "$workingDirectory" && ');
- stderr.write(environment.keys.map((String key) {
- if (environment![key]!.contains(quotables)) {
- return "$key='${environment[key]}'";
- } else {
- return '$key=${environment[key]}';
- }
- }).join(' '));
- stderr.write(' ');
- stderr.write(executable);
- if (arguments.isNotEmpty) {
- for (String arg in arguments) {
- if (arg.contains(quotables)) {
- stderr.write(" '$arg'");
- } else {
- stderr.write(' $arg');
- }
- }
- }
- if (workingDirectory != null) stderr.write(')');
- stderr.write('\n');
-
- if (Platform.environment.containsKey('DRY_RUN')) return null;
-
- String realExecutable = executable;
- final List<String> realArguments = [];
- if (Platform.isLinux) {
- // Use GNU coreutils to force line buffering. This makes sure that
- // subprocesses that die due to fatal signals do not chop off the
- // last few lines of their output.
- //
- // Dart does not actually do this (seems to flush manually) unless
- // the VM crashes.
- realExecutable = 'stdbuf';
- realArguments.addAll(['-o', 'L', '-e', 'L']);
- realArguments.add(executable);
- }
- realArguments.addAll(arguments);
-
- Process process = await Process.start(realExecutable, realArguments,
- workingDirectory: workingDirectory,
- environment: environment,
- includeParentEnvironment: includeParentEnvironment);
- Future<void> stdoutFuture = _printStream(process.stdout, stdout,
- prefix: prefix, filter: jsonCallback);
- Future<void> stderrFuture = _printStream(process.stderr, stderr,
- prefix: prefix, filter: jsonCallback);
- await Future.wait([stderrFuture, stdoutFuture, process.exitCode]);
-
- int exitCode = await process.exitCode;
- if (exitCode != 0 && !allowNonzeroExit) {
- throw ProcessException(executable, arguments,
- 'SubprocessLauncher got non-zero exitCode: $exitCode', exitCode);
- }
- return jsonObjects;
- }
-
- /// From flutter:dev/tools/dartdoc.dart, modified.
- static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
- {String prefix = '', Iterable<String> Function(String line)? filter}) {
- filter ??= (line) => [line];
- return stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .expand(filter)
- .listen((String line) {
- output.write('$prefix$line'.trim());
- output.write('\n');
- }).asFuture();
- }
-}
diff --git a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
deleted file mode 100644
index 5c6babb..0000000
--- a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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:io';
-
-import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(SubprocessLauncherTest);
- });
-}
-
-@reflectiveTest
-class SubprocessLauncherTest {
- Function(String)? outputCallback;
- List<String>? output;
- late Directory tempDir;
-
- void setUp() async {
- output = [];
- outputCallback = output!.add;
- tempDir = await Directory.systemTemp.createTemp();
- }
-
- void tearDown() async {
- await tempDir.delete(recursive: true);
- }
-
- Future<void> test_subprocessPassesArgs() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessPassesArgs');
- File testScript =
- File(path.join(tempDir.path, 'subprocess_test_script.dart'));
- await testScript.writeAsString(r'''
- import 'dart:io';
-
- main(List<String> args) {
- print('args: $args');
- }''');
-
- await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, [testScript.path, 'testArgument'],
- perLine: outputCallback);
- expect(output, anyElement(contains('args: [testArgument]')));
- }
-
- Future<void> test_subprocessPassesEnvironment() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessPassesEnvironment');
- File testScript =
- File(path.join(tempDir.path, 'subprocess_test_script.dart'));
- await testScript.writeAsString(r'''
- import 'dart:io';
-
- main(List<String> args) {
- print('environment: ${Platform.environment}');
- }''');
-
- await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, [testScript.path],
- environment: {'__SUBPROCESS_PASSES_ENVIRONMENT_TEST': 'yes'},
- perLine: outputCallback);
- expect(
- output,
- anyElement(contains(RegExp(
- '^environment: .*__SUBPROCESS_PASSES_ENVIRONMENT_TEST: yes'))));
- }
-
- Future<void> test_subprocessRunsValidExecutable() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessRunsValidExecutable');
-
- await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, ['--version'],
- perLine: outputCallback);
- expect(output, anyElement(contains('Dart')));
- }
-
- Future<void> test_subprocessSetsWorkingDirectory() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessSetsWorkingDirectory');
- File testScript =
- File(path.join(tempDir.path, 'subprocess_test_script.dart'));
- await testScript.writeAsString(r'''
- import 'dart:io';
-
- main() {
- print('working directory: ${Directory.current.path}');
- }''');
-
- await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, [testScript.path],
- workingDirectory: tempDir.path, perLine: outputCallback);
- expect(
- output,
- anyElement(contains(
- 'working directory: ${tempDir.resolveSymbolicLinksSync()}')));
- }
-
- Future<void> test_subprocessThrowsOnNonzeroExitCode() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessThrowsOnNonzeroExitCode');
- File testScript =
- File(path.join(tempDir.path, 'subprocess_test_script.dart'));
- await testScript.writeAsString(r'''
- import 'dart:io';
-
- main() {
- exit(1);
- }''');
- await expectLater(
- () async => await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, [testScript.path],
- perLine: outputCallback),
- throwsA(TypeMatcher<ProcessException>()));
- }
-
- Future<void> test_subprocessWorksViaParallelSubprocessLimit() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessWorksViaParallelSubprocessLimit');
-
- await launcher.runStreamed(Platform.resolvedExecutable, ['--version'],
- perLine: outputCallback);
- expect(output, anyElement(contains('Dart')));
- }
-}
diff --git a/pkg/nnbd_migration/test/utilities/test_all.dart b/pkg/nnbd_migration/test/utilities/test_all.dart
index 9c04ec1e..dc5758e 100644
--- a/pkg/nnbd_migration/test/utilities/test_all.dart
+++ b/pkg/nnbd_migration/test/utilities/test_all.dart
@@ -8,7 +8,6 @@
import 'scoped_set_test.dart' as scoped_set_test;
import 'source_edit_diff_formatter_test.dart'
as source_edit_diff_formatter_test;
-import 'subprocess_launcher_test.dart' as subprocess_launcher_test;
import 'where_not_null_transformer_test.dart'
as where_not_null_transformer_test;
import 'where_or_null_transformer_test.dart' as where_or_null_transformer_test;
@@ -18,7 +17,6 @@
multi_future_tracker_test.main();
scoped_set_test.main();
source_edit_diff_formatter_test.main();
- subprocess_launcher_test.main();
where_not_null_transformer_test.main();
where_or_null_transformer_test.main();
});
diff --git a/pkg/nnbd_migration/tool/src/package.dart b/pkg/nnbd_migration/tool/src/package.dart
deleted file mode 100644
index 0fc154b..0000000
--- a/pkg/nnbd_migration/tool/src/package.dart
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2019, 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.
-
-/// Abstractions for the different sources of truth for different packages.
-library;
-
-import 'dart:io';
-
-import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
-import 'package:path/path.dart' as path;
-
-final String defaultPlaygroundPath =
- Platform.environment['TRIAL_MIGRATION_PLAYGROUND'] ??
- resolveTildePath('~/.nnbd_trial_migration');
-
-/// The pub cache inherited by this process.
-final String defaultPubCache =
- Platform.environment['PUB_CACHE'] ?? resolveTildePath('~/.pub-cache');
-
-/// Returns the path to the SDK repository this script is a part of.
-final String thisSdkRepo = () {
- var maybeSdkRepoDir = Platform.script.toFilePath();
- while (maybeSdkRepoDir != path.dirname(maybeSdkRepoDir)) {
- maybeSdkRepoDir = path.dirname(maybeSdkRepoDir);
- if (File(path.join(maybeSdkRepoDir, 'README.dart-sdk')).existsSync()) {
- return maybeSdkRepoDir;
- }
- }
- throw UnsupportedError(
- 'Script ${Platform.script} using this library must be within the SDK repository');
-}();
-Uri get thisSdkUri => Uri.file(thisSdkRepo);
-
-/// Return a resolved path including the home directory in place of tilde
-/// references.
-String resolveTildePath(String originalPath) {
- if (!originalPath.startsWith('~/')) {
- return originalPath;
- }
-
- String homeDir;
-
- if (Platform.isWindows) {
- homeDir = path.absolute(Platform.environment['USERPROFILE']!);
- } else {
- homeDir = path.absolute(Platform.environment['HOME']!);
- }
-
- return path.join(homeDir, originalPath.substring(2));
-}
-
-/// Abstraction for a package fetched via Git.
-class GitPackage extends Package {
- static final RegExp _pathAndPeriodSplitter = RegExp('[\\/.]');
- final String _clonePath;
- final bool? _keepUpdated;
- final String label;
-
- final Playground _playground;
-
- SubprocessLauncher? _launcher;
-
- String? _packagePath;
-
- GitPackage._(this._clonePath, this._playground, this._keepUpdated,
- {String? name, this.label = 'master'})
- : super(name ?? _buildName(_clonePath));
-
- SubprocessLauncher get launcher =>
- _launcher ??= SubprocessLauncher('$name-$label', _playground.env);
-
- @override
- List<String?> get migrationPaths => [_packagePath];
- String get packagePath =>
- // TODO(jcollins-g): allow packages from subdirectories of clones
- _packagePath ??= path.join(_playground.playgroundPath, '$name-$label');
-
- @override
- String toString() {
- return '$_clonePath ($label)${_keepUpdated! ? ' [synced]' : ''}';
- }
-
- /// Initialize the package with a shallow clone. Run only once per
- /// [GitPackage] instance.
- Future<void> _init() async {
- if (_keepUpdated! || !await Directory(packagePath).exists()) {
- // Clone or update.
- if (await Directory(packagePath).exists()) {
- await launcher.runStreamed('git', ['pull'],
- workingDirectory: packagePath);
- } else {
- await launcher.runStreamed('git',
- ['clone', '--branch=$label', '--depth=1', _clonePath, packagePath],
- workingDirectory: _playground.playgroundPath);
- await launcher.runStreamed('git', ['checkout', '-b', '_test_migration'],
- workingDirectory: packagePath);
- await launcher.runStreamed(
- 'git', ['branch', '--set-upstream-to', 'origin/$label'],
- workingDirectory: packagePath);
- // TODO(jcollins-g): allow for migrating dependencies?
- }
- await pubTracker.runFutureFromClosure(() =>
- launcher.runStreamed('pub', ['get'], workingDirectory: packagePath));
- }
- }
-
- static Future<GitPackage> gitPackageFactory(
- String clonePath, Playground playground, bool? keepUpdated,
- {String? name, String label = 'master'}) async {
- GitPackage gitPackage = GitPackage._(clonePath, playground, keepUpdated,
- name: name, label: label);
- await gitPackage._init();
- return gitPackage;
- }
-
- /// Calculate the "humanish" name of the clone (see `git help clone`).
- static String _buildName(String clonePath) {
- if (Directory(clonePath).existsSync()) {
- // assume we are cloning locally
- return path.basename(clonePath);
- }
- List<String> pathParts = clonePath.split(_pathAndPeriodSplitter);
- int indexOfName = pathParts.lastIndexOf('git') - 1;
- if (indexOfName < 0) {
- throw ArgumentError(
- 'GitPackage can not figure out the name for $clonePath, pass it in manually?');
- }
- return pathParts[indexOfName];
- }
-}
-
-/// Abstraction for an unmanaged package.
-class ManualPackage extends Package {
- final String _packagePath;
- ManualPackage(this._packagePath) : super(_packagePath);
-
- @override
- List<String> get migrationPaths => [_packagePath];
-}
-
-/// Base class for pub, github, SDK, or possibly other package sources.
-abstract class Package {
- final String name;
-
- Package(this.name);
-
- /// Returns the set of directories for this package.
- List<String?> get migrationPaths;
-
- @override
- String toString() => name;
-}
-
-class Playground {
- final String playgroundPath;
-
- /// If [clean] is true, this will delete the playground. Otherwise,
- /// if it exists it will assume it is properly constructed.
- Playground(this.playgroundPath, bool clean) {
- Directory playground = Directory(playgroundPath);
- if (clean) {
- if (playground.existsSync()) {
- playground.deleteSync(recursive: true);
- }
- }
- if (!playground.existsSync()) playground.createSync();
- }
-
- /// Build an environment for subprocesses.
- Map<String, String> get env => {'PUB_CACHE': pubCachePath};
-
- String get pubCachePath => path.join(playgroundPath, '.pub-cache');
-}
-
-/// Abstraction for a package fetched via pub.
-class PubPackage extends Package {
- PubPackage(super.name, [String? version]) {
- throw UnimplementedError();
- }
-
- @override
- // TODO: implement packagePath
- List<String> get migrationPaths => throw UnimplementedError();
-}
-
-/// Abstraction for compiled Dart SDKs (not this repository).
-class Sdk {
- /// The root of the compiled SDK.
- late final String sdkPath;
-
- Sdk(String sdkPath) {
- this.sdkPath = path.canonicalize(sdkPath);
- }
-}
-
-/// Abstraction for a package located within pkg or third_party/pkg.
-class SdkPackage extends Package {
- /// Where to find packages. Constructor searches in-order.
- static final List<String> _searchPaths = [
- 'pkg',
- path.join('third_party', 'pkg'),
- ];
-
- late final String _packagePath;
-
- SdkPackage(String name) : super(name) {
- for (String potentialPath
- in _searchPaths.map((p) => path.join(thisSdkRepo, p, name))) {
- if (Directory(potentialPath).existsSync()) {
- _packagePath = potentialPath;
- }
- }
- }
- @override
- List<String> get migrationPaths => [_packagePath];
-
- @override
- String toString() => path.relative(_packagePath, from: thisSdkRepo);
-}
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
deleted file mode 100644
index d4f9d61..0000000
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright (c) 2019, 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.
-
-// This is a hacked-together client of the NNBD migration API, intended for
-// early testing of the migration process. It runs a small hardcoded set of
-// packages through the migration engine and outputs statistics about the
-// result of migration, as well as categories (and counts) of exceptions that
-// occurred.
-
-import 'dart:io';
-
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/diagnostic/diagnostic.dart';
-import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:args/args.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:path/path.dart' as path;
-
-import 'src/package.dart';
-
-void main(List<String> args) async {
- ArgResults parsedArgs = parseArguments(args)!;
-
- Sdk sdk = Sdk(parsedArgs['sdk'] as String);
-
- warnOnNoAssertions();
-
- Playground playground =
- Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool);
-
- List<Package> packages = [
- for (String package in parsedArgs['packages'] as Iterable<String>)
- SdkPackage(package),
- for (String package in parsedArgs['manual_packages'] as Iterable<String>)
- ManualPackage(package),
- ];
-
- var packageNames = parsedArgs['git_packages'] as Iterable<String>;
- await Future.wait(packageNames.map((n) async => packages.add(
- await GitPackage.gitPackageFactory(
- n, playground, parsedArgs['update'] as bool?))));
-
- String? categoryOfInterest =
- parsedArgs.rest.isEmpty ? null : parsedArgs.rest.single;
-
- var listener = _Listener(categoryOfInterest,
- printExceptionNodeOnly: parsedArgs['exception_node_only'] as bool?);
- assert(listener.numExceptions == 0);
- var overallStartTime = DateTime.now();
- for (var package in packages) {
- print('Migrating $package');
- var startTime = DateTime.now();
- listener.currentPackage = package.name;
- var contextCollection = AnalysisContextCollectionImpl(
- includedPaths: package.migrationPaths as List<String>,
- sdkPath: sdk.sdkPath);
-
- var files = <String>{};
- var previousExceptionCount = listener.numExceptions;
- for (var context in contextCollection.contexts) {
- var localFiles =
- context.contextRoot.analyzedFiles().where((s) => s.endsWith('.dart'));
- files.addAll(localFiles);
- var session = context.currentSession;
- var migration = NullabilityMigration(listener, permissive: true);
- for (var file in localFiles) {
- var resolvedUnit =
- await session.getResolvedUnit(file) as ResolvedUnitResult;
- if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
- migration.prepareInput(resolvedUnit);
- } else {
- print(' Skipping $file; it has errors.');
- }
- }
- for (var file in localFiles) {
- var resolvedUnit =
- await session.getResolvedUnit(file) as ResolvedUnitResult;
- if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
- migration.processInput(resolvedUnit);
- }
- }
- for (var file in localFiles) {
- var resolvedUnit =
- await session.getResolvedUnit(file) as ResolvedUnitResult;
- if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
- migration.finalizeInput(resolvedUnit);
- }
- }
- migration.finish();
- }
-
- var endTime = DateTime.now();
- print(' Migrated $package in ${endTime.difference(startTime).inSeconds} '
- 'seconds');
- print(' ${files.length} files found');
- var exceptionCount = listener.numExceptions - previousExceptionCount;
- print(' $exceptionCount exceptions in this package');
- }
-
- var overallDuration = DateTime.now().difference(overallStartTime);
- print('${packages.length} packages migrated in ${overallDuration.inSeconds} '
- 'seconds');
- print('${listener.numTypesMadeNullable} types made nullable');
- print('${listener.numNullChecksAdded} null checks added');
- print('${listener.numVariablesMarkedLate} variables marked late');
- print('${listener.numInsertedCasts} casts inserted');
- print('${listener.numInsertedParenthesis} parenthesis groupings inserted');
- print('${listener.numMetaImportsAdded} meta imports added');
- print('${listener.numRequiredAnnotationsAdded} required annotations added');
- print('${listener.numDeadCodeSegmentsFound} dead code segments found');
- print('and ${listener.numOtherEdits} other edits not categorized');
- print('${listener.numExceptions} exceptions in '
- '${listener.groupedExceptions.length} categories');
-
- var sortedExceptions = [
- for (var entry in listener.groupedExceptions.entries)
- ExceptionCategory(entry.key, entry.value)
- ]..sort((category1, category2) => category2.count.compareTo(category1.count));
- var exceptionalPackages =
- sortedExceptions.expand((category) => category.packageNames).toSet();
- print('Packages with exceptions: $exceptionalPackages');
- print('Exception categories:');
- for (var category in sortedExceptions) {
- print(' $category');
- }
-
- if (categoryOfInterest == null) {
- print('\n(Note: to show stack traces & nodes for a particular failure,'
- ' rerun with a search string as an argument.)');
- }
-}
-
-ArgResults? parseArguments(List<String> args) {
- ArgParser argParser = ArgParser();
- ArgResults? parsedArgs;
-
- argParser.addFlag('clean',
- abbr: 'c',
- defaultsTo: false,
- help: 'Recursively delete the playground directory before beginning.');
-
- argParser.addFlag('help', abbr: 'h', help: 'Display options');
-
- argParser.addFlag('exception_node_only',
- defaultsTo: false,
- negatable: true,
- help: 'Only print the exception node instead of the full stack trace.');
-
- argParser.addFlag('update',
- abbr: 'u',
- defaultsTo: false,
- negatable: true,
- help: 'Auto-update fetched packages in the playground.');
-
- argParser.addOption('sdk',
- abbr: 's',
- defaultsTo: path.dirname(path.dirname(Platform.resolvedExecutable)),
- help: 'Select the root of the SDK to analyze against for this run '
- '(compiled with --nnbd). For example: ../../xcodebuild/DebugX64NNBD/dart-sdk');
-
- argParser.addMultiOption(
- 'git_packages',
- abbr: 'g',
- defaultsTo: [],
- help: 'Shallow-clone the given git repositories into a playground area,'
- ' run pub get on them, and migrate them.',
- );
-
- argParser.addMultiOption(
- 'manual_packages',
- abbr: 'm',
- defaultsTo: [],
- help: 'Run migration against packages in these directories. Does not '
- 'run pub get, any git commands, or any other preparation.',
- );
-
- argParser.addMultiOption(
- 'packages',
- abbr: 'p',
- defaultsTo: [],
- help: 'The list of SDK packages to run the migration against.',
- );
-
- try {
- parsedArgs = argParser.parse(args);
- } on ArgParserException {
- stderr.writeln(argParser.usage);
- exit(1);
- }
- if (parsedArgs['help'] as bool) {
- print(argParser.usage);
- exit(0);
- }
-
- if (parsedArgs.rest.length > 1) {
- throw 'invalid args. Specify *one* argument to get exceptions of interest.';
- }
- return parsedArgs;
-}
-
-void printWarning(String warn) {
- stderr.writeln('''
-!!!
-!!! Warning! $warn
-!!!
-''');
-}
-
-void warnOnNoAssertions() {
- try {
- assert(false);
- } catch (e) {
- return;
- }
-
- printWarning("You didn't --enable-asserts!");
-}
-
-class ExceptionCategory {
- final String topOfStack;
- final List<MapEntry<String?, int>> exceptionCountPerPackage;
-
- ExceptionCategory(this.topOfStack, Map<String?, int> exceptions)
- : exceptionCountPerPackage = exceptions.entries.toList()
- ..sort((e1, e2) => e2.value.compareTo(e1.value));
-
- int get count => exceptionCountPerPackage.length;
-
- List<String?> get packageNames =>
- [for (var entry in exceptionCountPerPackage) entry.key];
-
- Iterable<String> get packageNamesAndCounts =>
- exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
-
- String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
-}
-
-class _Listener implements NullabilityMigrationListener {
- /// Set this to `true` to cause just the exception nodes to be printed when
- /// `_Listener.categoryOfInterest` is non-null. Set this to `false` to cause
- /// the full stack trace to be printed.
- final bool? printExceptionNodeOnly;
-
- /// Set this to a non-null value to cause any exception to be printed in full
- /// if its category contains the string.
- final String? categoryOfInterest;
-
- /// Exception mapped to a map of packages & exception counts.
- final groupedExceptions = <String, Map<String?, int>>{};
-
- int numExceptions = 0;
-
- int numTypesMadeNullable = 0;
-
- int numVariablesMarkedLate = 0;
-
- int numInsertedCasts = 0;
-
- int numInsertedParenthesis = 0;
-
- int numNullChecksAdded = 0;
-
- int numMetaImportsAdded = 0;
-
- int numRequiredAnnotationsAdded = 0;
-
- int numDeadCodeSegmentsFound = 0;
-
- int numOtherEdits = 0;
-
- String? currentPackage;
-
- _Listener(this.categoryOfInterest, {this.printExceptionNodeOnly = false});
-
- @override
- void addEdit(Source source, SourceEdit edit) {
- if (edit.replacement == '') {
- return;
- }
-
- if (edit.replacement.contains('!')) {
- ++numNullChecksAdded;
- }
-
- if (edit.replacement.contains('(')) {
- ++numInsertedParenthesis;
- }
-
- if (edit.replacement == '?' && edit.length == 0) {
- ++numTypesMadeNullable;
- } else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
- edit.length == 0) {
- ++numMetaImportsAdded;
- } else if (edit.replacement == 'required ' && edit.length == 0) {
- ++numRequiredAnnotationsAdded;
- } else if (edit.replacement == 'late ' && edit.length == 0) {
- ++numVariablesMarkedLate;
- } else if (edit.replacement.startsWith(' as ') && edit.length == 0) {
- ++numInsertedCasts;
- } else if ((edit.replacement == '/* ' ||
- edit.replacement == ' /*' ||
- edit.replacement == '; /*') &&
- edit.length == 0) {
- ++numDeadCodeSegmentsFound;
- } else if ((edit.replacement == '*/ ' ||
- edit.replacement == ' */' ||
- edit.replacement == ')' ||
- edit.replacement == '!' ||
- edit.replacement == '(') &&
- edit.length == 0) {
- } else {
- numOtherEdits++;
- }
- }
-
- @override
- void addSuggestion(String descriptions, Location location) {}
-
- @override
- void reportException(
- Source? source, AstNode? node, Object exception, StackTrace stackTrace) {
- var category = _classifyStackTrace(stackTrace.toString().split('\n'));
- String detail = '''
-In file $source
-While processing $node
-Exception $exception
-$stackTrace
-''';
- if (categoryOfInterest != null && category.contains(categoryOfInterest!)) {
- if (printExceptionNodeOnly!) {
- print('$node');
- } else {
- print(detail);
- }
- }
- (groupedExceptions[category] ??= <String?, int>{})
- .update(currentPackage, (value) => ++value, ifAbsent: () => 1);
- ++numExceptions;
- }
-
- String _classifyStackTrace(List<String> stackTrace) {
- for (var entry in stackTrace) {
- if (entry.contains('EdgeBuilder._unimplemented')) continue;
- if (entry.contains('_AssertionError._doThrowNew')) continue;
- if (entry.contains('_AssertionError._throwNew')) continue;
- if (entry.contains('NodeBuilder._unimplemented')) continue;
- if (entry.contains('Object.noSuchMethod')) continue;
- if (entry.contains('List.[] (dart:core-patch/growable_array.dart')) {
- continue;
- }
- return entry;
- }
- return '???';
- }
-}
diff --git a/pkg/nnbd_migration/tool/trial_migration.sh b/pkg/nnbd_migration/tool/trial_migration.sh
deleted file mode 100755
index 4db1c2b..0000000
--- a/pkg/nnbd_migration/tool/trial_migration.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019, 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.
-#
-
-TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
-
-# Priority One, Group One, as defined at go/dart-null-safety-migration-order.
-p1g1 () {
- for n in charcode collection logging path pedantic term_glyph typed_data ; do
- echo "-g https://dart.googlesource.com/${n}.git"
- done
- # Some packages do not have googlesource mirrors; use GitHub directly.
- echo "-g https://github.com/google/vector_math.dart.git"
- # SDK-only packages.
- echo "-p meta"
-}
-
-
-# The current "official" set of parameters for the trial_migration script.
-set -x
-dart --enable-asserts ${TRIAL_MIGRATION} \
- $(p1g1) \
- "$@"
diff --git a/pkg/nnbd_migration/tool/trial_migration_p2.sh b/pkg/nnbd_migration/tool/trial_migration_p2.sh
deleted file mode 100755
index bca1231..0000000
--- a/pkg/nnbd_migration/tool/trial_migration_p2.sh
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-#
-
-TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
-
-# Priority Two, Group One, as defined at go/dart-null-safety-migration-order.
-p2g1 () {
- echo "-g https://github.com/google/ansicolor-dart.git"
- echo "-g https://dart.googlesource.com/args.git"
- echo "-p dart_internal"
- echo "-g https://dart.googlesource.com/fixnum.git"
- echo "-g https://github.com/google/inject.dart.git"
- echo "-p js"
- echo "-g https://github.com/a14n/dart-js-wrapping.git"
- echo "-g https://dart.googlesource.com/mime.git"
- echo "-g https://github.com/xxgreg/mustache.git"
- echo "-g https://github.com/leonsenft/path_to_regexp.git"
- echo "-g https://github.com/petitparser/dart-petitparser.git"
- echo "-g https://github.com/google/platform.dart.git"
- echo "-g https://github.com/dart-lang/stream_transform.git"
- echo "-g https://github.com/dart-lang/sync_http.git"
- echo "-g https://github.com/srawlins/timezone.git"
-}
-
-# Priority Two, Group Two, as defined at go/dart-null-safety-migration-order.
-p2g2 () {
- echo "-g https://github.com/google/ansicolor-dart.git"
- echo "-g https://dart.googlesource.com/cli_util.git"
- echo "-g https://github.com/dart-lang/clock.git"
- echo "-g https://github.com/kevmoo/completion.dart.git"
- echo "-g https://dart.googlesource.com/convert.git"
- echo "-g https://github.com/a14n/dart-google-maps.git"
- echo "-g https://github.com/dart-lang/http_server.git"
- echo "-g https://dart.googlesource.com/intl.git"
- echo "-p kernel"
- echo "-g https://dart.googlesource.com/package_config.git"
- # TODO(srawlins): Add protobuf, from monorepo
- # https://github.com/dart-lang/protobuf.
- echo "-g https://dart.googlesource.com/pub_semver.git"
- echo "-g https://github.com/google/quiver-dart.git"
-}
-
-# Priority Two, Group Three, as defined at go/dart-null-safety-migration-order.
-p2g3 () {
- # TODO(srawlins): Add android_intent, from monorepo
- # https://github.com/flutter/plugins/tree/master/packages/android_intent.
- # SDK-only packages.
- echo "-g https://dart.googlesource.com/bazel_worker.git"
- echo "-g https://github.com/google/built_collection.dart.git"
- # TODO(srawlins): Add charts_common, from monorepo
- # https://github.com/google/charts/tree/master/charts_common.
- echo "-g https://github.com/jathak/cli_repl.git"
- echo "-g https://dart.googlesource.com/crypto.git"
- echo "-g https://dart.googlesource.com/csslib.git"
- echo "-g https://github.com/google/file.dart.git"
- # TODO(srawlins): Add front_end, which currently crashes.
- echo "-g https://github.com/reyerstudio/google-maps-markerclusterer.git"
- # TODO(srawlins): Add google_sign_in, from monorepo
- # https://github.com/flutter/plugins/tree/master/packages/google_sign_in.
- echo "-g https://dart.googlesource.com/http_multi_server.git"
- echo "-g https://github.com/dart-lang/observable.git"
- # TODO(srawlins): Add package_info, from monorepo
- # https://github.com/flutter/plugins/tree/master/packages/package_info.
- echo "-g https://dart.googlesource.com/pool.git"
- # TODO(srawlins): Add protoc_plugin, from monorepo
- # https://github.com/dart-lang/protobuf.
- echo "-g https://github.com/google/quiver-log.git"
- # TODO(srawlins): Add shared_preferences, from monorepo
- # https://github.com/flutter/plugins/tree/master/packages/shared_preferences.
- echo "-g https://dart.googlesource.com/source_maps.git"
- echo "-g https://dart.googlesource.com/string_scanner.git"
- echo "-g https://github.com/renggli/dart-xml.git"
-}
-
-# Priority Two, Group Four, as defined at go/dart-null-safety-migration-order.
-p2g4 () {
- echo "-g https://github.com/brendan-duncan/archive.git"
- # TODO(srawlins): Add built_value, from monorepo
- # https://github.com/google/built_value.dart
- # Not including charted; concern is internal copy; not old published copy.
- echo "-g https://dart.googlesource.com/glob.git"
- echo "-g https://dart.googlesource.com/html.git"
- echo "-g https://dart.googlesource.com/http_parser.git"
- echo "-g https://dart.googlesource.com/json_rpc_2.git"
- # Not including observe; concern is internal copy; not old published copy.
- echo "-g https://github.com/google/process.dart.git"
- # Not including scissors; concern is internal copy; not old published copy.
-}
-
-# Priority Two, Group Five, as defined at go/dart-null-safety-migration-order.
-p2g5 () {
- echo "-p analyzer"
- # Not including angular_forms; concern is internal copy; not old published copy.
- # Not including angular_router; concern is internal copy; not old published copy.
- # Not including angular_test; concern is internal copy; not old published copy.
- echo "-g https://github.com/dart-lang/code_builder.git"
- echo "-g https://dart.googlesource.com/http.git"
- echo "-g https://github.com/brendan-duncan/image.git"
- echo "-g https://dart.googlesource.com/shelf.git"
-}
-
-# Priority Two, Group Six, as defined at go/dart-null-safety-migration-order.
-p2g6 () {
- echo "-p analyzer_plugin"
- # TODO(srawlins): Add build, from monorepo
- # https://github.com/dart-lang/build/tree/master/build.
- echo "-g https://github.com/dart-lang/coverage.git"
- echo "-g https://dart.googlesource.com/dart_style.git"
- # TODO(srawlins): Add flutter_test.
- echo "-g https://github.com/dart-lang/googleapis_auth.git"
- echo "-g https://github.com/dart-lang/intl_translation.git"
- echo "-g https://dart.googlesource.com/mockito.git"
- echo "-g https://dart.googlesource.com/package_resolver.git"
- # Not including pageloader ("2"); concern is internal copy; not old published copy.
- echo "-g https://dart.googlesource.com/shelf_static.git"
- echo "-g https://dart.googlesource.com/shelf_web_socket.git"
-}
-
-# Priority Two, Group Seven, as defined at go/dart-null-safety-migration-order.
-p2g7 () {
- echo "-g https://github.com/dart-lang/grpc-dart.git"
- echo "-g https://github.com/google/pageloader.git" # This is pageloader3.
- echo "-g https://github.com/sass/dart-sass.git"
- echo "-g https://dart.googlesource.com/shelf_packages_handler.git"
- # TODO(srawlins): Add source_gen.
- echo "-g https://dart.googlesource.com/source_map_stack_trace.git"
-}
-
-# Priority Two, Group Eight, as defined at go/dart-null-safety-migration-order.
-p2g8 () {
- # Not including angular_compiler; concern is internal copy; not old published copy.
- # TODO(srawlins): Add built_value_generator, from monorepo
- # https://github.com/google/built_value.dart.
- # TODO(srawlins): Add flutter_tools, from monorepo
- # https://github.com/flutter/flutter.
- # TODO(srawlins): Locate and add rpc_client.
- echo ""
-}
-
-# The current "official" set of parameters for the trial_migration script.
-set -x
-dart --enable-asserts ${TRIAL_MIGRATION} \
- $(p2g1) $(p2g2) $(p2g3) $(p2g4) $(p2g5) $(p2g6) $(p2g7) $(p2g8) \
- "$@"