Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 | 66 |
| 67 typedef ErrorSeverity _BatchRunnerHandler(List<String> args); | 67 typedef ErrorSeverity _BatchRunnerHandler(List<String> args); |
| 68 | 68 |
| 69 class Driver implements CommandLineStarter { | 69 class Driver implements CommandLineStarter { |
| 70 static final PerformanceTag _analyzeAllTag = | 70 static final PerformanceTag _analyzeAllTag = |
| 71 new PerformanceTag("Driver._analyzeAll"); | 71 new PerformanceTag("Driver._analyzeAll"); |
| 72 | 72 |
| 73 /// The plugins that are defined outside the `analyzer_cli` package. | 73 /// The plugins that are defined outside the `analyzer_cli` package. |
| 74 List<Plugin> _userDefinedPlugins = <Plugin>[]; | 74 List<Plugin> _userDefinedPlugins = <Plugin>[]; |
| 75 | 75 |
| 76 /// Indicates whether the analyzer is running in batch mode. | |
| 77 bool _isBatch; | |
| 78 | |
| 79 /// The context that was most recently created by a call to [_analyzeAll], or | 76 /// The context that was most recently created by a call to [_analyzeAll], or |
| 80 /// `null` if [_analyzeAll] hasn't been called yet. | 77 /// `null` if [_analyzeAll] hasn't been called yet. |
| 81 AnalysisContext _context; | 78 AnalysisContext _context; |
| 82 | 79 |
| 83 /// The total number of source files loaded by an AnalysisContext. | 80 /// The total number of source files loaded by an AnalysisContext. |
| 84 int _analyzedFileCount = 0; | 81 int _analyzedFileCount = 0; |
| 85 | 82 |
| 86 /// If [_context] is not `null`, the [CommandLineOptions] that guided its | 83 /// If [_context] is not `null`, the [CommandLineOptions] that guided its |
| 87 /// creation. | 84 /// creation. |
| 88 CommandLineOptions _previousOptions; | 85 CommandLineOptions _previousOptions; |
| 89 | 86 |
| 90 @override | 87 @override |
| 91 EmbeddedResolverProvider embeddedUriResolverProvider; | 88 EmbeddedResolverProvider embeddedUriResolverProvider; |
| 92 | 89 |
| 93 @override | 90 @override |
| 94 ResolverProvider packageResolverProvider; | 91 ResolverProvider packageResolverProvider; |
| 95 | 92 |
| 93 /// SDK instance. | |
| 94 DirectoryBasedDartSdk sdk; | |
| 95 | |
| 96 /// Collected analysis statistics. | 96 /// Collected analysis statistics. |
| 97 final AnalysisStats stats = new AnalysisStats(); | 97 final AnalysisStats stats = new AnalysisStats(); |
| 98 | 98 |
| 99 /// This Driver's current analysis context. | 99 /// This Driver's current analysis context. |
| 100 /// | 100 /// |
| 101 /// *Visible for testing.* | 101 /// *Visible for testing.* |
| 102 AnalysisContext get context => _context; | 102 AnalysisContext get context => _context; |
| 103 | 103 |
| 104 @override | 104 @override |
| 105 void set userDefinedPlugins(List<Plugin> plugins) { | 105 void set userDefinedPlugins(List<Plugin> plugins) { |
| 106 _userDefinedPlugins = plugins ?? <Plugin>[]; | 106 _userDefinedPlugins = plugins ?? <Plugin>[]; |
| 107 } | 107 } |
| 108 | 108 |
| 109 @override | 109 @override |
| 110 void start(List<String> args) { | 110 void start(List<String> args) { |
| 111 if (_context != null) { | 111 if (_context != null) { |
| 112 throw new StateError("start() can only be called once"); | 112 throw new StateError("start() can only be called once"); |
| 113 } | 113 } |
| 114 int startTime = new DateTime.now().millisecondsSinceEpoch; | 114 int startTime = new DateTime.now().millisecondsSinceEpoch; |
| 115 | 115 |
| 116 StringUtilities.INTERNER = new MappedInterner(); | 116 StringUtilities.INTERNER = new MappedInterner(); |
| 117 | 117 |
| 118 _processPlugins(); | 118 _processPlugins(); |
| 119 | 119 |
| 120 // Parse commandline options. | 120 // Parse commandline options. |
| 121 CommandLineOptions options = CommandLineOptions.parse(args); | 121 CommandLineOptions options = CommandLineOptions.parse(args); |
| 122 | 122 |
| 123 // Cache options of interest to inform analysis. | |
| 124 _setupEnv(options); | |
| 125 | |
| 126 // Do analysis. | 123 // Do analysis. |
| 127 if (options.buildMode) { | 124 if (options.buildMode) { |
| 128 ErrorSeverity severity = _buildModeAnalyze(options); | 125 ErrorSeverity severity = _buildModeAnalyze(options); |
| 129 // In case of error propagate exit code. | 126 // In case of error propagate exit code. |
| 130 if (severity == ErrorSeverity.ERROR) { | 127 if (severity == ErrorSeverity.ERROR) { |
| 131 exitCode = severity.ordinal; | 128 exitCode = severity.ordinal; |
| 132 } | 129 } |
| 133 } else if (_isBatch) { | 130 } else if (options.shouldBatch) { |
| 134 _BatchRunner.runAsBatch(args, (List<String> args) { | 131 _BatchRunner.runAsBatch(args, (List<String> args) { |
| 135 CommandLineOptions options = CommandLineOptions.parse(args); | 132 CommandLineOptions options = CommandLineOptions.parse(args); |
| 136 return _analyzeAll(options); | 133 return _analyzeAll(options); |
| 137 }); | 134 }); |
| 138 } else { | 135 } else { |
| 139 ErrorSeverity severity = _analyzeAll(options); | 136 ErrorSeverity severity = _analyzeAll(options); |
| 140 // In case of error propagate exit code. | 137 // In case of error propagate exit code. |
| 141 if (severity == ErrorSeverity.ERROR) { | 138 if (severity == ErrorSeverity.ERROR) { |
| 142 exitCode = severity.ordinal; | 139 exitCode = severity.ordinal; |
| 143 } | 140 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 return false; | 296 return false; |
| 300 } | 297 } |
| 301 return true; | 298 return true; |
| 302 } | 299 } |
| 303 | 300 |
| 304 /// Decide on the appropriate policy for which files need to be fully parsed | 301 /// Decide on the appropriate policy for which files need to be fully parsed |
| 305 /// and which files need to be diet parsed, based on [options], and return an | 302 /// and which files need to be diet parsed, based on [options], and return an |
| 306 /// [AnalyzeFunctionBodiesPredicate] that implements this policy. | 303 /// [AnalyzeFunctionBodiesPredicate] that implements this policy. |
| 307 AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy( | 304 AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy( |
| 308 CommandLineOptions options) { | 305 CommandLineOptions options) { |
| 309 if (_isBatch) { | 306 if (options.shouldBatch) { |
| 310 // As analyzer is currently implemented, once a file has been diet | 307 // As analyzer is currently implemented, once a file has been diet |
| 311 // parsed, it can't easily be un-diet parsed without creating a brand new | 308 // parsed, it can't easily be un-diet parsed without creating a brand new |
| 312 // context and losing caching. In batch mode, we can't predict which | 309 // context and losing caching. In batch mode, we can't predict which |
| 313 // files we'll need to generate errors and warnings for in the future, so | 310 // files we'll need to generate errors and warnings for in the future, so |
| 314 // we can't safely diet parse anything. | 311 // we can't safely diet parse anything. |
| 315 return (Source source) => true; | 312 return (Source source) => true; |
| 316 } | 313 } |
| 317 | 314 |
| 318 return (Source source) { | 315 return (Source source) { |
| 319 if (options.sourceFiles.contains(source.fullName)) { | 316 if (options.sourceFiles.contains(source.fullName)) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 _previousOptions = options; | 497 _previousOptions = options; |
| 501 | 498 |
| 502 // Save stats from previous context before clobbering it. | 499 // Save stats from previous context before clobbering it. |
| 503 if (_context != null) { | 500 if (_context != null) { |
| 504 _analyzedFileCount += _context.sources.length; | 501 _analyzedFileCount += _context.sources.length; |
| 505 } | 502 } |
| 506 | 503 |
| 507 // Create a context. | 504 // Create a context. |
| 508 _context = AnalysisEngine.instance.createAnalysisContext(); | 505 _context = AnalysisEngine.instance.createAnalysisContext(); |
| 509 | 506 |
| 507 AnalyzeFunctionBodiesPredicate dietParsingPolicy = | |
| 508 _chooseDietParsingPolicy(options); | |
| 509 setAnalysisContextOptions(_context, options, | |
| 510 (AnalysisOptionsImpl contextOptions) { | |
| 511 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; | |
| 512 }); | |
| 513 | |
| 514 // Once options are processed, setup the SDK. | |
| 515 _setupSdk(path: options.dartSdkPath); | |
| 516 | |
| 510 // Choose a package resolution policy and a diet parsing policy based on | 517 // Choose a package resolution policy and a diet parsing policy based on |
| 511 // the command-line options. | 518 // the command-line options. |
| 512 SourceFactory sourceFactory = _chooseUriResolutionPolicy( | 519 SourceFactory sourceFactory = _chooseUriResolutionPolicy( |
| 513 options, (_context as InternalAnalysisContext).embedderYamlLocator); | 520 options, (_context as InternalAnalysisContext).embedderYamlLocator); |
| 514 AnalyzeFunctionBodiesPredicate dietParsingPolicy = | |
| 515 _chooseDietParsingPolicy(options); | |
| 516 | 521 |
| 517 _context.sourceFactory = sourceFactory; | 522 _context.sourceFactory = sourceFactory; |
| 518 | |
| 519 setAnalysisContextOptions(_context, options, | |
| 520 (AnalysisOptionsImpl contextOptions) { | |
| 521 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; | |
| 522 }); | |
| 523 } | 523 } |
| 524 | 524 |
| 525 /// Return discovered packagespec, or `null` if none is found. | 525 /// Return discovered packagespec, or `null` if none is found. |
| 526 Packages _discoverPackagespec(Uri root) { | 526 Packages _discoverPackagespec(Uri root) { |
| 527 try { | 527 try { |
| 528 Packages packages = pkgDiscovery.findPackagesFromFile(root); | 528 Packages packages = pkgDiscovery.findPackagesFromFile(root); |
| 529 if (packages != Packages.noPackages) { | 529 if (packages != Packages.noPackages) { |
| 530 return packages; | 530 return packages; |
| 531 } | 531 } |
| 532 } catch (_) { | 532 } catch (_) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 var errorSeverity = analyzer.analyzeSync(); | 575 var errorSeverity = analyzer.analyzeSync(); |
| 576 if (errorSeverity == ErrorSeverity.ERROR) { | 576 if (errorSeverity == ErrorSeverity.ERROR) { |
| 577 exitCode = errorSeverity.ordinal; | 577 exitCode = errorSeverity.ordinal; |
| 578 } | 578 } |
| 579 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { | 579 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { |
| 580 exitCode = errorSeverity.ordinal; | 580 exitCode = errorSeverity.ordinal; |
| 581 } | 581 } |
| 582 return errorSeverity; | 582 return errorSeverity; |
| 583 } | 583 } |
| 584 | 584 |
| 585 void _setupEnv(CommandLineOptions options) { | 585 void _setupSdk({String path}) { |
|
Paul Berry
2016/05/10 18:33:24
Nit: it seems weird for [path] to be an optional p
pquitslund
2016/05/10 21:22:39
Yeah. I just really like named params! Would that
| |
| 586 // In batch mode, SDK is specified on the main command line rather than in | |
| 587 // the command lines sent to stdin. So process it before deciding whether | |
| 588 // to activate batch mode. | |
| 589 if (sdk == null) { | 586 if (sdk == null) { |
| 590 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); | 587 sdk = new DirectoryBasedDartSdk(new JavaFile(path)); |
| 591 sdk.useSummary = true; | 588 sdk.useSummary = true; |
| 592 sdk.analysisOptions = createAnalysisOptionsForCommandLineOptions(options); | 589 sdk.analysisOptions = context.analysisOptions; |
| 593 } | 590 } |
| 594 _isBatch = options.shouldBatch; | |
| 595 } | 591 } |
| 596 | 592 |
| 597 static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions( | 593 static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions( |
| 598 CommandLineOptions options) { | 594 CommandLineOptions options) { |
| 599 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); | 595 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); |
| 600 contextOptions.hint = !options.disableHints; | 596 contextOptions.hint = !options.disableHints; |
| 601 contextOptions.enableStrictCallChecks = options.enableStrictCallChecks; | 597 contextOptions.enableStrictCallChecks = options.enableStrictCallChecks; |
| 602 contextOptions.enableSuperMixins = options.enableSuperMixins; | 598 contextOptions.enableSuperMixins = options.enableSuperMixins; |
| 603 contextOptions.generateImplicitErrors = options.showPackageWarnings; | 599 contextOptions.generateImplicitErrors = options.showPackageWarnings; |
| 604 contextOptions.generateSdkErrors = options.showSdkWarnings; | 600 contextOptions.generateSdkErrors = options.showSdkWarnings; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 for (var package in packages) { | 774 for (var package in packages) { |
| 779 var packageName = path.basename(package.path); | 775 var packageName = path.basename(package.path); |
| 780 var realPath = package.resolveSymbolicLinksSync(); | 776 var realPath = package.resolveSymbolicLinksSync(); |
| 781 result[packageName] = [ | 777 result[packageName] = [ |
| 782 PhysicalResourceProvider.INSTANCE.getFolder(realPath) | 778 PhysicalResourceProvider.INSTANCE.getFolder(realPath) |
| 783 ]; | 779 ]; |
| 784 } | 780 } |
| 785 return result; | 781 return result; |
| 786 } | 782 } |
| 787 } | 783 } |
| OLD | NEW |