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

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

Issue 2704103002: Some improvements to the command-line analyzer's output. (Closed)
Patch Set: Created 3 years, 10 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' as io; 9 import 'dart:io' as io;
10 10
(...skipping 20 matching lines...) Expand all
31 import 'package:analyzer/src/generated/source.dart'; 31 import 'package:analyzer/src/generated/source.dart';
32 import 'package:analyzer/src/generated/source_io.dart'; 32 import 'package:analyzer/src/generated/source_io.dart';
33 import 'package:analyzer/src/generated/utilities_general.dart' 33 import 'package:analyzer/src/generated/utilities_general.dart'
34 show PerformanceTag; 34 show PerformanceTag;
35 import 'package:analyzer/src/lint/registry.dart'; 35 import 'package:analyzer/src/lint/registry.dart';
36 import 'package:analyzer/src/source/source_resource.dart'; 36 import 'package:analyzer/src/source/source_resource.dart';
37 import 'package:analyzer/src/summary/idl.dart'; 37 import 'package:analyzer/src/summary/idl.dart';
38 import 'package:analyzer/src/summary/package_bundle_reader.dart'; 38 import 'package:analyzer/src/summary/package_bundle_reader.dart';
39 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk; 39 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
40 import 'package:analyzer/src/task/options.dart'; 40 import 'package:analyzer/src/task/options.dart';
41 import 'package:analyzer_cli/src/analyzer_impl.dart';
42 import 'package:analyzer_cli/src/build_mode.dart';
43 import 'package:analyzer_cli/src/error_formatter.dart';
44 import 'package:analyzer_cli/src/options.dart';
45 import 'package:analyzer_cli/src/perf_report.dart';
46 import 'package:analyzer_cli/starter.dart';
47 import 'package:linter/src/rules.dart' as linter; 41 import 'package:linter/src/rules.dart' as linter;
48 import 'package:package_config/discovery.dart' as pkg_discovery; 42 import 'package:package_config/discovery.dart' as pkg_discovery;
49 import 'package:package_config/packages.dart' show Packages; 43 import 'package:package_config/packages.dart' show Packages;
50 import 'package:package_config/packages_file.dart' as pkgfile show parse; 44 import 'package:package_config/packages_file.dart' as pkgfile show parse;
51 import 'package:package_config/src/packages_impl.dart' show MapPackages; 45 import 'package:package_config/src/packages_impl.dart' show MapPackages;
52 import 'package:path/path.dart' as path; 46 import 'package:path/path.dart' as path;
53 import 'package:plugin/manager.dart'; 47 import 'package:plugin/manager.dart';
54 import 'package:plugin/plugin.dart'; 48 import 'package:plugin/plugin.dart';
55 import 'package:yaml/yaml.dart'; 49 import 'package:yaml/yaml.dart';
56 50
51 import '../starter.dart' show CommandLineStarter;
52 import 'analyzer_impl.dart';
53 import 'build_mode.dart';
54 import 'error_formatter.dart';
55 import 'options.dart';
56 import 'perf_report.dart';
57
57 /// Shared IO sink for standard error reporting. 58 /// Shared IO sink for standard error reporting.
58 /// 59 ///
59 /// *Visible for testing.* 60 /// *Visible for testing.*
60 StringSink errorSink = io.stderr; 61 StringSink errorSink = io.stderr;
61 62
62 /// Shared IO sink for standard out reporting. 63 /// Shared IO sink for standard out reporting.
63 /// 64 ///
64 /// *Visible for testing.* 65 /// *Visible for testing.*
65 StringSink outSink = io.stdout; 66 StringSink outSink = io.stdout;
66 67
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 io.exitCode = severity.ordinal; 153 io.exitCode = severity.ordinal;
153 } 154 }
154 } 155 }
155 156
156 if (_context != null) { 157 if (_context != null) {
157 _analyzedFileCount += _context.sources.length; 158 _analyzedFileCount += _context.sources.length;
158 } 159 }
159 160
160 if (options.perfReport != null) { 161 if (options.perfReport != null) {
161 String json = makePerfReport( 162 String json = makePerfReport(
162 startTime, currentTimeMillis(), options, _analyzedFileCount, stats); 163 startTime, currentTimeMillis, options, _analyzedFileCount, stats);
163 new io.File(options.perfReport).writeAsStringSync(json); 164 new io.File(options.perfReport).writeAsStringSync(json);
164 } 165 }
165 } 166 }
166 167
167 Future<ErrorSeverity> _analyzeAll(CommandLineOptions options) async { 168 Future<ErrorSeverity> _analyzeAll(CommandLineOptions options) async {
168 PerformanceTag previous = _analyzeAllTag.makeCurrent(); 169 PerformanceTag previous = _analyzeAllTag.makeCurrent();
169 try { 170 try {
170 return await _analyzeAllImpl(options); 171 return await _analyzeAllImpl(options);
171 } finally { 172 } finally {
172 previous.makeCurrent(); 173 previous.makeCurrent();
173 } 174 }
174 } 175 }
175 176
176 /// Perform analysis according to the given [options]. 177 /// Perform analysis according to the given [options].
177 Future<ErrorSeverity> _analyzeAllImpl(CommandLineOptions options) async { 178 Future<ErrorSeverity> _analyzeAllImpl(CommandLineOptions options) async {
178 if (!options.machineFormat) { 179 if (!options.machineFormat) {
179 outSink.writeln("Analyzing ${options.sourceFiles}..."); 180 List<String> fileNames = options.sourceFiles.map((String file) {
181 file = path.normalize(file);
182 if (file == '.') {
183 file = path.basename(path.current);
184 } else if (file == '..') {
185 file = path.basename(path.normalize(path.absolute(file)));
186 }
187 return file;
188 }).toList();
189
190 outSink.writeln("Analyzing ${fileNames.join(', ')}...");
180 } 191 }
181 192
182 // Create a context, or re-use the previous one. 193 // Create a context, or re-use the previous one.
183 try { 194 try {
184 _createAnalysisContext(options); 195 _createAnalysisContext(options);
185 } on _DriverError catch (error) { 196 } on _DriverError catch (error) {
186 outSink.writeln(error.msg); 197 outSink.writeln(error.msg);
187 return ErrorSeverity.ERROR; 198 return ErrorSeverity.ERROR;
188 } 199 }
189 200
190 // Add all the files to be analyzed en masse to the context. Skip any 201 // Add all the files to be analyzed en masse to the context. Skip any
191 // files that were added earlier (whether explicitly or implicitly) to 202 // files that were added earlier (whether explicitly or implicitly) to
192 // avoid causing those files to be unnecessarily re-read. 203 // avoid causing those files to be unnecessarily re-read.
193 Set<Source> knownSources = context.sources.toSet(); 204 Set<Source> knownSources = context.sources.toSet();
194 List<Source> sourcesToAnalyze = <Source>[]; 205 Set<Source> sourcesToAnalyze = new Set<Source>();
195 ChangeSet changeSet = new ChangeSet(); 206 ChangeSet changeSet = new ChangeSet();
196 for (String sourcePath in options.sourceFiles) { 207 for (String sourcePath in options.sourceFiles) {
197 sourcePath = sourcePath.trim(); 208 sourcePath = sourcePath.trim();
198 209
199 // Collect files for analysis. 210 // Collect files for analysis.
200 // Note that these files will all be analyzed in the same context. 211 // Note that these files will all be analyzed in the same context.
201 // This should be updated when the ContextManager re-work is complete 212 // This should be updated when the ContextManager re-work is complete
202 // (See: https://github.com/dart-lang/sdk/issues/24133) 213 // (See: https://github.com/dart-lang/sdk/issues/24133)
203 Iterable<io.File> files = _collectFiles(sourcePath); 214 Iterable<io.File> files = _collectFiles(sourcePath);
204 if (files.isEmpty) { 215 if (files.isEmpty) {
205 errorSink.writeln('No dart files found at: $sourcePath'); 216 errorSink.writeln('No dart files found at: $sourcePath');
206 io.exitCode = ErrorSeverity.ERROR.ordinal; 217 io.exitCode = ErrorSeverity.ERROR.ordinal;
207 return ErrorSeverity.ERROR; 218 return ErrorSeverity.ERROR;
208 } 219 }
209 220
210 for (io.File file in files) { 221 for (io.File file in files) {
211 Source source = _computeLibrarySource(file.absolute.path); 222 Source source = _computeLibrarySource(file.absolute.path);
212 if (!knownSources.contains(source)) { 223 if (!knownSources.contains(source)) {
213 changeSet.addedSource(source); 224 changeSet.addedSource(source);
214 } 225 }
215 sourcesToAnalyze.add(source); 226 sourcesToAnalyze.add(source);
216 } 227 }
217 228
218 if (analysisDriver != null) { 229 files.forEach((file) {
Brian Wilkerson 2017/02/19 22:52:17 It looks like this CL is also removing the non-dri
devoncarew 2017/02/21 04:30:47 No - it's unintentional. I had a fair amount of ch
219 files.forEach((file) { 230 analysisDriver.addFile(file.path);
220 analysisDriver.addFile(file.path); 231 });
221 });
222 } else {
223 context.applyChanges(changeSet);
224 }
225 } 232 }
226 233
227 // Analyze the libraries. 234 // Analyze the libraries.
228 ErrorSeverity allResult = ErrorSeverity.NONE; 235 ErrorSeverity allResult = ErrorSeverity.NONE;
229 var libUris = <Uri>[]; 236 List<Uri> libUris = <Uri>[];
230 var parts = <Source>[]; 237 Set<Source> partSources = new Set<Source>();
238
231 for (Source source in sourcesToAnalyze) { 239 for (Source source in sourcesToAnalyze) {
232 SourceKind sourceKind = analysisDriver != null 240 SourceKind sourceKind = analysisDriver != null
233 ? await analysisDriver.getSourceKind(source.fullName) 241 ? await analysisDriver.getSourceKind(source.fullName)
234 : context.computeKindOf(source); 242 : context.computeKindOf(source);
235 if (sourceKind == SourceKind.PART) { 243 if (sourceKind == SourceKind.PART) {
236 parts.add(source); 244 partSources.add(source);
237 continue; 245 continue;
238 } 246 }
247 // TODO(devoncarew): Analyzing each source individually causes errors to
248 // be reported multiple times (#25697).
239 ErrorSeverity status = await _runAnalyzer(source, options); 249 ErrorSeverity status = await _runAnalyzer(source, options);
240 allResult = allResult.max(status); 250 allResult = allResult.max(status);
241 libUris.add(source.uri); 251 libUris.add(source.uri);
242 } 252 }
243 253
244 // Check that each part has a corresponding source in the input list. 254 // Check that each part has a corresponding source in the input list.
245 for (Source part in parts) { 255 for (Source partSource in partSources) {
246 bool found = false; 256 bool found = false;
247 if (analysisDriver != null) { 257 if (analysisDriver != null) {
248 var partFile = analysisDriver.fsState.getFileForPath(part.fullName); 258 var partFile =
259 analysisDriver.fsState.getFileForPath(partSource.fullName);
249 if (libUris.contains(partFile.library?.uri)) { 260 if (libUris.contains(partFile.library?.uri)) {
250 found = true; 261 found = true;
251 } 262 }
252 } else { 263 } else {
253 for (var lib in context.getLibrariesContaining(part)) { 264 for (var lib in context.getLibrariesContaining(partSource)) {
254 if (libUris.contains(lib.uri)) { 265 if (libUris.contains(lib.uri)) {
255 found = true; 266 found = true;
256 } 267 }
257 } 268 }
258 } 269 }
259 if (!found) { 270 if (!found) {
260 errorSink.writeln("${part.fullName} is a part and cannot be analyzed."); 271 errorSink.writeln(
272 "${partSource.fullName} is a part and cannot be analyzed.");
261 errorSink.writeln("Please pass in a library that contains this part."); 273 errorSink.writeln("Please pass in a library that contains this part.");
262 io.exitCode = ErrorSeverity.ERROR.ordinal; 274 io.exitCode = ErrorSeverity.ERROR.ordinal;
263 allResult = allResult.max(ErrorSeverity.ERROR); 275 allResult = allResult.max(ErrorSeverity.ERROR);
264 } 276 }
265 } 277 }
266 278
267 if (!options.machineFormat) { 279 if (!options.machineFormat) {
268 stats.print(outSink); 280 stats.print(outSink);
269 } 281 }
270 282
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 if (packageUriResolver != null) { 473 if (packageUriResolver != null) {
462 resolvers.add(packageUriResolver); 474 resolvers.add(packageUriResolver);
463 } 475 }
464 476
465 // Finally files. 477 // Finally files.
466 resolvers.add(new file_system.ResourceUriResolver(resourceProvider)); 478 resolvers.add(new file_system.ResourceUriResolver(resourceProvider));
467 479
468 return new SourceFactory(resolvers, packageInfo.packages); 480 return new SourceFactory(resolvers, packageInfo.packages);
469 } 481 }
470 482
483 // TODO(devoncarew): This needs to respect analysis_options excludes.
484
471 /// Collect all analyzable files at [filePath], recursively if it's a 485 /// Collect all analyzable files at [filePath], recursively if it's a
472 /// directory, ignoring links. 486 /// directory, ignoring links.
473 Iterable<io.File> _collectFiles(String filePath) { 487 Iterable<io.File> _collectFiles(String filePath) {
474 List<io.File> files = <io.File>[]; 488 List<io.File> files = <io.File>[];
475 io.File file = new io.File(filePath); 489 io.File file = new io.File(filePath);
476 if (file.existsSync()) { 490 if (file.existsSync()) {
477 files.add(file); 491 files.add(file);
478 } else { 492 } else {
479 io.Directory directory = new io.Directory(filePath); 493 io.Directory directory = new io.Directory(filePath);
480 if (directory.existsSync()) { 494 if (directory.existsSync()) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 695
682 ExtensionManager manager = new ExtensionManager(); 696 ExtensionManager manager = new ExtensionManager();
683 manager.processPlugins(plugins); 697 manager.processPlugins(plugins);
684 698
685 linter.registerLintRules(); 699 linter.registerLintRules();
686 } 700 }
687 701
688 /// Analyze a single source. 702 /// Analyze a single source.
689 Future<ErrorSeverity> _runAnalyzer( 703 Future<ErrorSeverity> _runAnalyzer(
690 Source source, CommandLineOptions options) async { 704 Source source, CommandLineOptions options) async {
691 int startTime = currentTimeMillis(); 705 int startTime = currentTimeMillis;
692 AnalyzerImpl analyzer = new AnalyzerImpl(_context.analysisOptions, _context, 706 AnalyzerImpl analyzer = new AnalyzerImpl(_context.analysisOptions, _context,
693 analysisDriver, source, options, stats, startTime); 707 analysisDriver, source, options, stats, startTime);
694 ErrorSeverity errorSeverity = await analyzer.analyze(); 708 ErrorSeverity errorSeverity = await analyzer.analyze();
695 if (errorSeverity == ErrorSeverity.ERROR) { 709 if (errorSeverity == ErrorSeverity.ERROR) {
696 io.exitCode = errorSeverity.ordinal; 710 io.exitCode = errorSeverity.ordinal;
697 } 711 }
698 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { 712 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) {
699 io.exitCode = errorSeverity.ordinal; 713 io.exitCode = errorSeverity.ordinal;
700 } 714 }
701 return errorSeverity; 715 return errorSeverity;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 for (var package in packages) { 959 for (var package in packages) {
946 var packageName = path.basename(package.path); 960 var packageName = path.basename(package.path);
947 var realPath = package.resolveSymbolicLinksSync(); 961 var realPath = package.resolveSymbolicLinksSync();
948 result[packageName] = [ 962 result[packageName] = [
949 PhysicalResourceProvider.INSTANCE.getFolder(realPath) 963 PhysicalResourceProvider.INSTANCE.getFolder(realPath)
950 ]; 964 ];
951 } 965 }
952 return result; 966 return result;
953 } 967 }
954 } 968 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698