Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 54adfeb

Browse files
devoncarewcommit-bot@chromium.org
authored andcommitted
[nnbd_migration] handle multiple contexts
Bug: dart-lang/sdk#42141 Change-Id: I64179cd3fa0389397a8a9b3a763fbb1a3719294e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149664 Commit-Queue: Devon Carew <[email protected]> Reviewed-by: Paul Berry <[email protected]>
1 parent ba25fd1 commit 54adfeb

File tree

2 files changed

+73
-9
lines changed

2 files changed

+73
-9
lines changed

pkg/nnbd_migration/lib/migration_cli.dart

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66
import 'dart:convert' show jsonDecode;
77
import 'dart:io' hide File;
88

9+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
910
import 'package:analyzer/dart/analysis/results.dart';
1011
import 'package:analyzer/diagnostic/diagnostic.dart';
1112
import 'package:analyzer/error/error.dart';
@@ -155,8 +156,8 @@ class DependencyChecker {
155156
_logger.stderr('Visit https://dart.dev/tools/pub/cmd/pub-outdated for '
156157
'more information.');
157158
_logger.stderr('');
158-
_logger.stderr('Force migration with '
159-
'--${CommandLineOptions.skipPubOutdatedFlag} (not recommended)');
159+
_logger.stderr('You can force migration with '
160+
"'--${CommandLineOptions.skipPubOutdatedFlag}' (not recommended).");
160161
return false;
161162
}
162163
return true;
@@ -235,6 +236,8 @@ class MigrationCli {
235236

236237
_FixCodeProcessor _fixCodeProcessor;
237238

239+
AnalysisContextCollection _contextCollection;
240+
238241
MigrationCli(
239242
{@required this.binaryName,
240243
@visibleForTesting this.loggerFactory = _defaultLoggerFactory,
@@ -316,6 +319,12 @@ class MigrationCli {
316319
argResults[CommandLineOptions.skipPubOutdatedFlag] as bool,
317320
summary: argResults[CommandLineOptions.summaryOption] as String,
318321
webPreview: webPreview);
322+
323+
_contextCollection = AnalysisContextCollectionImpl(
324+
includedPaths: [options.directory],
325+
resourceProvider: resourceProvider,
326+
sdkPath: pathContext.normalize(options.sdkPath));
327+
319328
if (isVerbose) {
320329
logger = loggerFactory(true);
321330
}
@@ -352,16 +361,19 @@ class MigrationCli {
352361
logger.stdout('Migrating ${options.directory}');
353362
logger.stdout('');
354363

364+
if (hasMultipleAnalysisContext) {
365+
logger.stdout(
366+
'Note: more than one project found; migrating the top-level project.');
367+
logger.stdout('');
368+
}
369+
370+
DriverBasedAnalysisContext context = analysisContext;
371+
355372
List<String> previewUrls;
356373
NonNullableFix nonNullableFix;
374+
357375
await _withProgress(
358376
'${ansi.emphasized('Generating migration suggestions')}', () async {
359-
var contextCollection = AnalysisContextCollectionImpl(
360-
includedPaths: [options.directory],
361-
resourceProvider: resourceProvider,
362-
sdkPath: options.sdkPath);
363-
DriverBasedAnalysisContext context =
364-
contextCollection.contexts.single as DriverBasedAnalysisContext;
365377
_fixCodeProcessor = _FixCodeProcessor(context, this);
366378
_dartFixListener =
367379
DartFixListener(DriverProviderImpl(resourceProvider, context));
@@ -376,6 +388,8 @@ class MigrationCli {
376388
_fixCodeProcessor.nonNullableFixTask = nonNullableFix;
377389

378390
try {
391+
// TODO(devoncarew): The progress written by the fix processor conflicts
392+
// with the progress written by the ansi logger above.
379393
await _fixCodeProcessor.runFirstPhase();
380394
_fixCodeProcessor._progressBar.clear();
381395
_checkForErrors();
@@ -437,6 +451,23 @@ Use this interactive web view to review, improve, or apply the results.
437451
exitCode = 0;
438452
}
439453

454+
@visibleForTesting
455+
DriverBasedAnalysisContext get analysisContext {
456+
// Handle the case of more than one analysis context being found (typically,
457+
// the current directory and one or more sub-directories).
458+
if (hasMultipleAnalysisContext) {
459+
return _contextCollection.contextFor(options.directory)
460+
as DriverBasedAnalysisContext;
461+
} else {
462+
return _contextCollection.contexts.single as DriverBasedAnalysisContext;
463+
}
464+
}
465+
466+
@visibleForTesting
467+
bool get hasMultipleAnalysisContext {
468+
return _contextCollection.contexts.length > 1;
469+
}
470+
440471
/// Perform the indicated source edits to the given source, returning the
441472
/// resulting transformed text.
442473
String _applyEdits(SourceFileEdit sourceFileEdit, String source) {

pkg/nnbd_migration/test/migration_cli_test.dart

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,39 @@ int${migrated ? '?' : ''} f() => null;
362362
assertProjectContents(projectDir, simpleProject(migrated: true));
363363
}
364364

365+
test_lifecycle_contextdiscovery_handles_multiple() async {
366+
var projectContents = simpleProject();
367+
var subProject = simpleProject();
368+
for (var filePath in subProject.keys) {
369+
projectContents['example/$filePath'] = subProject[filePath];
370+
}
371+
projectContents['example/analysis_options.yaml'] = '''
372+
analyzer:
373+
strong-mode:
374+
implicit-casts: false
375+
linter:
376+
rules:
377+
- empty_constructor_bodies
378+
''';
379+
380+
var projectDir = await createProjectDir(projectContents);
381+
var cli = _createCli();
382+
await cli.run(_parseArgs(['--no-web-preview', projectDir]));
383+
expect(cli.hasMultipleAnalysisContext, true);
384+
expect(cli.analysisContext, isNotNull);
385+
var output = logger.stdoutBuffer.toString();
386+
expect(output, contains('more than one project found'));
387+
}
388+
389+
test_lifecycle_contextdiscovery_handles_single() async {
390+
var projectContents = simpleProject();
391+
var projectDir = await createProjectDir(projectContents);
392+
var cli = _createCli();
393+
await cli.run(_parseArgs(['--no-web-preview', projectDir]));
394+
expect(cli.hasMultipleAnalysisContext, false);
395+
expect(cli.analysisContext, isNotNull);
396+
}
397+
365398
test_lifecycle_ignore_errors_disable() async {
366399
var projectContents = simpleProject(sourceText: '''
367400
int f() => null
@@ -918,7 +951,7 @@ int f() => null;
918951
}
919952

920953
test_migrate_path_normalized() {
921-
expect(assertParseArgsSuccess(['..']).directory, isNot(contains('..')));
954+
expect(assertParseArgsSuccess(['foo/..']).directory, isNot(contains('..')));
922955
}
923956

924957
test_migrate_path_one() {

0 commit comments

Comments
 (0)