Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: pkg/analyzer_cli/lib/src/driver.dart

Issue 1805533005: Directory support for the analyzer CLI (#25129). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer_cli.src.driver; 5 library analyzer_cli.src.driver;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 10
(...skipping 15 matching lines...) Expand all
26 import 'package:analyzer/src/generated/java_engine.dart'; 26 import 'package:analyzer/src/generated/java_engine.dart';
27 import 'package:analyzer/src/generated/java_io.dart'; 27 import 'package:analyzer/src/generated/java_io.dart';
28 import 'package:analyzer/src/generated/sdk_io.dart'; 28 import 'package:analyzer/src/generated/sdk_io.dart';
29 import 'package:analyzer/src/generated/source.dart'; 29 import 'package:analyzer/src/generated/source.dart';
30 import 'package:analyzer/src/generated/source_io.dart'; 30 import 'package:analyzer/src/generated/source_io.dart';
31 import 'package:analyzer/src/generated/utilities_general.dart' 31 import 'package:analyzer/src/generated/utilities_general.dart'
32 show PerformanceTag; 32 show PerformanceTag;
33 import 'package:analyzer/src/services/lint.dart'; 33 import 'package:analyzer/src/services/lint.dart';
34 import 'package:analyzer/src/task/options.dart'; 34 import 'package:analyzer/src/task/options.dart';
35 import 'package:analyzer_cli/src/analyzer_impl.dart'; 35 import 'package:analyzer_cli/src/analyzer_impl.dart';
36 import 'package:analyzer_cli/src/error_formatter.dart';
36 import 'package:analyzer_cli/src/options.dart'; 37 import 'package:analyzer_cli/src/options.dart';
37 import 'package:analyzer_cli/src/package_analyzer.dart'; 38 import 'package:analyzer_cli/src/package_analyzer.dart';
38 import 'package:analyzer_cli/src/perf_report.dart'; 39 import 'package:analyzer_cli/src/perf_report.dart';
39 import 'package:analyzer_cli/starter.dart'; 40 import 'package:analyzer_cli/starter.dart';
40 import 'package:linter/src/plugin/linter_plugin.dart'; 41 import 'package:linter/src/plugin/linter_plugin.dart';
41 import 'package:package_config/discovery.dart' as pkgDiscovery; 42 import 'package:package_config/discovery.dart' as pkgDiscovery;
42 import 'package:package_config/packages.dart' show Packages; 43 import 'package:package_config/packages.dart' show Packages;
43 import 'package:package_config/packages_file.dart' as pkgfile show parse; 44 import 'package:package_config/packages_file.dart' as pkgfile show parse;
44 import 'package:package_config/src/packages_impl.dart' show MapPackages; 45 import 'package:package_config/src/packages_impl.dart' show MapPackages;
45 import 'package:path/path.dart' as path; 46 import 'package:path/path.dart' as path;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 /// If [_context] is not `null`, the [CommandLineOptions] that guided its 83 /// If [_context] is not `null`, the [CommandLineOptions] that guided its
83 /// creation. 84 /// creation.
84 CommandLineOptions _previousOptions; 85 CommandLineOptions _previousOptions;
85 86
86 @override 87 @override
87 EmbeddedResolverProvider embeddedUriResolverProvider; 88 EmbeddedResolverProvider embeddedUriResolverProvider;
88 89
89 @override 90 @override
90 ResolverProvider packageResolverProvider; 91 ResolverProvider packageResolverProvider;
91 92
93 /// Collected analysis statistics.
94 final AnalysisStats stats = new AnalysisStats();
95
92 /// This Driver's current analysis context. 96 /// This Driver's current analysis context.
93 /// 97 ///
94 /// *Visible for testing.* 98 /// *Visible for testing.*
95 AnalysisContext get context => _context; 99 AnalysisContext get context => _context;
96 100
97 @override 101 @override
98 void set userDefinedPlugins(List<Plugin> plugins) { 102 void set userDefinedPlugins(List<Plugin> plugins) {
99 _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins; 103 _userDefinedPlugins = plugins ?? <Plugin>[];
100 } 104 }
101 105
102 @override 106 @override
103 void start(List<String> args) { 107 void start(List<String> args) {
104 int startTime = new DateTime.now().millisecondsSinceEpoch; 108 int startTime = new DateTime.now().millisecondsSinceEpoch;
105 109
106 StringUtilities.INTERNER = new MappedInterner(); 110 StringUtilities.INTERNER = new MappedInterner();
107 111
108 _processPlugins(); 112 _processPlugins();
109 113
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 try { 159 try {
156 _createAnalysisContext(options); 160 _createAnalysisContext(options);
157 } on _DriverError catch (error) { 161 } on _DriverError catch (error) {
158 outSink.writeln(error.msg); 162 outSink.writeln(error.msg);
159 return ErrorSeverity.ERROR; 163 return ErrorSeverity.ERROR;
160 } 164 }
161 165
162 // Add all the files to be analyzed en masse to the context. Skip any 166 // Add all the files to be analyzed en masse to the context. Skip any
163 // files that were added earlier (whether explicitly or implicitly) to 167 // files that were added earlier (whether explicitly or implicitly) to
164 // avoid causing those files to be unnecessarily re-read. 168 // avoid causing those files to be unnecessarily re-read.
165 Set<Source> knownSources = _context.sources.toSet(); 169 Set<Source> knownSources = context.sources.toSet();
166 List<Source> sourcesToAnalyze = <Source>[]; 170 List<Source> sourcesToAnalyze = <Source>[];
167 ChangeSet changeSet = new ChangeSet(); 171 ChangeSet changeSet = new ChangeSet();
168 for (String sourcePath in options.sourceFiles) { 172 for (String sourcePath in options.sourceFiles) {
169 sourcePath = sourcePath.trim(); 173 sourcePath = sourcePath.trim();
170 // Check that file exists. 174
171 if (!new File(sourcePath).existsSync()) { 175 // Collect files for analysis.
172 errorSink.writeln('File not found: $sourcePath'); 176 // Note that these files will all be analyzed in the same context.
177 // This should be updated when the ContextManager re-work is complete
178 // (See: https://github.com/dart-lang/sdk/issues/24133)
179 Iterable<File> files = _collectFiles(sourcePath);
180 if (files.isEmpty) {
181 errorSink.writeln('No dart files found at: $sourcePath');
173 exitCode = ErrorSeverity.ERROR.ordinal; 182 exitCode = ErrorSeverity.ERROR.ordinal;
174 //Fail fast; don't analyze more files
175 return ErrorSeverity.ERROR; 183 return ErrorSeverity.ERROR;
176 } 184 }
177 // Check that file is Dart file. 185
178 if (!AnalysisEngine.isDartFileName(sourcePath)) { 186 for (File file in files) {
179 errorSink.writeln('$sourcePath is not a Dart file'); 187 Source source = _computeLibrarySource(file.absolute.path);
180 exitCode = ErrorSeverity.ERROR.ordinal; 188 if (!knownSources.contains(source)) {
181 // Fail fast; don't analyze more files. 189 changeSet.addedSource(source);
182 return ErrorSeverity.ERROR; 190 sourcesToAnalyze.add(source);
191 }
183 } 192 }
184 Source source = _computeLibrarySource(sourcePath);
185 if (!knownSources.contains(source)) {
186 changeSet.addedSource(source);
187 }
188 sourcesToAnalyze.add(source);
189 } 193 }
190 _context.applyChanges(changeSet); 194 context.applyChanges(changeSet);
191 195
192 // Analyze the libraries. 196 // Analyze the libraries.
193 ErrorSeverity allResult = ErrorSeverity.NONE; 197 ErrorSeverity allResult = ErrorSeverity.NONE;
194 var libUris = <Uri>[]; 198 var libUris = <Uri>[];
195 var parts = <Source>[]; 199 var parts = <Source>[];
196 for (Source source in sourcesToAnalyze) { 200 for (Source source in sourcesToAnalyze) {
197 if (context.computeKindOf(source) == SourceKind.PART) { 201 if (context.computeKindOf(source) == SourceKind.PART) {
198 parts.add(source); 202 parts.add(source);
199 continue; 203 continue;
200 } 204 }
(...skipping 11 matching lines...) Expand all
212 } 216 }
213 } 217 }
214 if (!found) { 218 if (!found) {
215 errorSink.writeln("${part.fullName} is a part and cannot be analyzed."); 219 errorSink.writeln("${part.fullName} is a part and cannot be analyzed.");
216 errorSink.writeln("Please pass in a library that contains this part."); 220 errorSink.writeln("Please pass in a library that contains this part.");
217 exitCode = ErrorSeverity.ERROR.ordinal; 221 exitCode = ErrorSeverity.ERROR.ordinal;
218 allResult = allResult.max(ErrorSeverity.ERROR); 222 allResult = allResult.max(ErrorSeverity.ERROR);
219 } 223 }
220 } 224 }
221 225
226 if (!options.machineFormat) {
227 stats.print(outSink);
228 }
229
222 return allResult; 230 return allResult;
223 } 231 }
224 232
225 /// Perform package analysis according to the given [options]. 233 /// Perform package analysis according to the given [options].
226 ErrorSeverity _analyzePackage(CommandLineOptions options) { 234 ErrorSeverity _analyzePackage(CommandLineOptions options) {
227 return _analyzeAllTag.makeCurrentWhile(() { 235 return _analyzeAllTag.makeCurrentWhile(() {
228 return new PackageAnalyzer(options).analyze(); 236 return new PackageAnalyzer(options, stats).analyze();
229 }); 237 });
230 } 238 }
231 239
232 /// Determine whether the context created during a previous call to 240 /// Determine whether the context created during a previous call to
233 /// [_analyzeAll] can be re-used in order to analyze using [options]. 241 /// [_analyzeAll] can be re-used in order to analyze using [options].
234 bool _canContextBeReused(CommandLineOptions options) { 242 bool _canContextBeReused(CommandLineOptions options) {
235 // TODO(paulberry): add a command-line option that disables context re-use. 243 // TODO(paulberry): add a command-line option that disables context re-use.
236 if (_context == null) { 244 if (_context == null) {
237 return false; 245 return false;
238 } 246 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 if (packageUriResolver != null) { 452 if (packageUriResolver != null) {
445 resolvers.add(packageUriResolver); 453 resolvers.add(packageUriResolver);
446 } 454 }
447 455
448 // Finally files. 456 // Finally files.
449 resolvers.add(new FileUriResolver()); 457 resolvers.add(new FileUriResolver());
450 458
451 return new SourceFactory(resolvers, packages); 459 return new SourceFactory(resolvers, packages);
452 } 460 }
453 461
462 /// Collect all analyzable files at [filePath], recursively if it's a
463 /// directory, ignoring links.
464 Iterable<File> _collectFiles(String filePath) {
465 List<File> files = <File>[];
466 File file = new File(filePath);
467 if (file.existsSync()) {
468 files.add(file);
469 } else {
470 Directory directory = new Directory(filePath);
471 if (directory.existsSync()) {
472 for (FileSystemEntity entry
473 in directory.listSync(recursive: true, followLinks: false)) {
474 String relative = path.relative(entry.path, from: directory.path);
475 if (AnalysisEngine.isDartFileName(entry.path) &&
476 !_isInHiddenDir(relative)) {
477 files.add(entry);
478 }
479 }
480 }
481 }
482 return files;
483 }
484
454 /// Convert the given [sourcePath] (which may be relative to the current 485 /// Convert the given [sourcePath] (which may be relative to the current
455 /// working directory) to a [Source] object that can be fed to the analysis 486 /// working directory) to a [Source] object that can be fed to the analysis
456 /// context. 487 /// context.
457 Source _computeLibrarySource(String sourcePath) { 488 Source _computeLibrarySource(String sourcePath) {
458 sourcePath = _normalizeSourcePath(sourcePath); 489 sourcePath = _normalizeSourcePath(sourcePath);
459 JavaFile sourceFile = new JavaFile(sourcePath); 490 JavaFile sourceFile = new JavaFile(sourcePath);
460 Source source = sdk.fromFileUri(sourceFile.toURI()); 491 Source source = sdk.fromFileUri(sourceFile.toURI());
461 if (source != null) { 492 if (source != null) {
462 return source; 493 return source;
463 } 494 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 Map<String, List<fileSystem.Folder>> folderMap = 549 Map<String, List<fileSystem.Folder>> folderMap =
519 new Map<String, List<fileSystem.Folder>>(); 550 new Map<String, List<fileSystem.Folder>>();
520 packages.asMap().forEach((String packagePath, Uri uri) { 551 packages.asMap().forEach((String packagePath, Uri uri) {
521 folderMap[packagePath] = [ 552 folderMap[packagePath] = [
522 PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri)) 553 PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri))
523 ]; 554 ];
524 }); 555 });
525 return folderMap; 556 return folderMap;
526 } 557 }
527 558
559 /// Returns `true` if this relative path is a hidden directory.
560 bool _isInHiddenDir(String relative) =>
561 path.split(relative).any((part) => part.startsWith("."));
Brian Wilkerson 2016/03/16 20:42:52 Does this need to worry about having ".." as a par
pquitslund 2016/03/16 20:55:41 Good eye. In general maybe, but I think we're saf
562
528 void _processPlugins() { 563 void _processPlugins() {
529 List<Plugin> plugins = <Plugin>[]; 564 List<Plugin> plugins = <Plugin>[];
530 plugins.addAll(AnalysisEngine.instance.requiredPlugins); 565 plugins.addAll(AnalysisEngine.instance.requiredPlugins);
531 plugins.add(AnalysisEngine.instance.commandLinePlugin); 566 plugins.add(AnalysisEngine.instance.commandLinePlugin);
532 plugins.add(AnalysisEngine.instance.optionsPlugin); 567 plugins.add(AnalysisEngine.instance.optionsPlugin);
533 plugins.add(linterPlugin); 568 plugins.add(linterPlugin);
534 plugins.addAll(_userDefinedPlugins); 569 plugins.addAll(_userDefinedPlugins);
535 570
536 ExtensionManager manager = new ExtensionManager(); 571 ExtensionManager manager = new ExtensionManager();
537 manager.processPlugins(plugins); 572 manager.processPlugins(plugins);
538 } 573 }
539 574
540 /// Analyze a single source. 575 /// Analyze a single source.
541 ErrorSeverity _runAnalyzer(Source source, CommandLineOptions options) { 576 ErrorSeverity _runAnalyzer(Source source, CommandLineOptions options) {
542 int startTime = currentTimeMillis(); 577 int startTime = currentTimeMillis();
543 AnalyzerImpl analyzer = 578 AnalyzerImpl analyzer =
544 new AnalyzerImpl(_context, source, options, startTime); 579 new AnalyzerImpl(_context, source, options, stats, startTime);
545 var errorSeverity = analyzer.analyzeSync(); 580 var errorSeverity = analyzer.analyzeSync();
546 if (errorSeverity == ErrorSeverity.ERROR) { 581 if (errorSeverity == ErrorSeverity.ERROR) {
547 exitCode = errorSeverity.ordinal; 582 exitCode = errorSeverity.ordinal;
548 } 583 }
549 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { 584 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) {
550 exitCode = errorSeverity.ordinal; 585 exitCode = errorSeverity.ordinal;
551 } 586 }
552 return errorSeverity; 587 return errorSeverity;
553 } 588 }
554 589
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 for (var package in packages) { 777 for (var package in packages) {
743 var packageName = path.basename(package.path); 778 var packageName = path.basename(package.path);
744 var realPath = package.resolveSymbolicLinksSync(); 779 var realPath = package.resolveSymbolicLinksSync();
745 result[packageName] = [ 780 result[packageName] = [
746 PhysicalResourceProvider.INSTANCE.getFolder(realPath) 781 PhysicalResourceProvider.INSTANCE.getFolder(realPath)
747 ]; 782 ];
748 } 783 }
749 return result; 784 return result;
750 } 785 }
751 } 786 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/lib/src/analyzer_impl.dart ('k') | pkg/analyzer_cli/lib/src/error_formatter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698