| 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' as io; | 9 import 'dart:io' as io; |
| 10 | 10 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 /// | 61 /// |
| 62 /// *Visible for testing.* | 62 /// *Visible for testing.* |
| 63 StringSink outSink = io.stdout; | 63 StringSink outSink = io.stdout; |
| 64 | 64 |
| 65 /// Test this option map to see if it specifies lint rules. | 65 /// Test this option map to see if it specifies lint rules. |
| 66 bool containsLintRuleEntry(Map<String, YamlNode> options) { | 66 bool containsLintRuleEntry(Map<String, YamlNode> options) { |
| 67 var linterNode = options['linter']; | 67 var linterNode = options['linter']; |
| 68 return linterNode is YamlMap && linterNode.containsKey('rules'); | 68 return linterNode is YamlMap && linterNode.containsKey('rules'); |
| 69 } | 69 } |
| 70 | 70 |
| 71 typedef ErrorSeverity _BatchRunnerHandler(List<String> args); | 71 typedef Future<ErrorSeverity> _BatchRunnerHandler(List<String> args); |
| 72 | 72 |
| 73 class Driver implements CommandLineStarter { | 73 class Driver implements CommandLineStarter { |
| 74 static final PerformanceTag _analyzeAllTag = | 74 static final PerformanceTag _analyzeAllTag = |
| 75 new PerformanceTag("Driver._analyzeAll"); | 75 new PerformanceTag("Driver._analyzeAll"); |
| 76 | 76 |
| 77 /// The plugins that are defined outside the `analyzer_cli` package. | 77 /// The plugins that are defined outside the `analyzer_cli` package. |
| 78 List<Plugin> _userDefinedPlugins = <Plugin>[]; | 78 List<Plugin> _userDefinedPlugins = <Plugin>[]; |
| 79 | 79 |
| 80 /// The context that was most recently created by a call to [_analyzeAll], or | 80 /// The context that was most recently created by a call to [_analyzeAll], or |
| 81 /// `null` if [_analyzeAll] hasn't been called yet. | 81 /// `null` if [_analyzeAll] hasn't been called yet. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 107 /// | 107 /// |
| 108 /// *Visible for testing.* | 108 /// *Visible for testing.* |
| 109 AnalysisContext get context => _context; | 109 AnalysisContext get context => _context; |
| 110 | 110 |
| 111 @override | 111 @override |
| 112 void set userDefinedPlugins(List<Plugin> plugins) { | 112 void set userDefinedPlugins(List<Plugin> plugins) { |
| 113 _userDefinedPlugins = plugins ?? <Plugin>[]; | 113 _userDefinedPlugins = plugins ?? <Plugin>[]; |
| 114 } | 114 } |
| 115 | 115 |
| 116 @override | 116 @override |
| 117 void start(List<String> args) { | 117 Future<Null> start(List<String> args) async { |
| 118 if (_context != null) { | 118 if (_context != null) { |
| 119 throw new StateError("start() can only be called once"); | 119 throw new StateError("start() can only be called once"); |
| 120 } | 120 } |
| 121 int startTime = new DateTime.now().millisecondsSinceEpoch; | 121 int startTime = new DateTime.now().millisecondsSinceEpoch; |
| 122 | 122 |
| 123 StringUtilities.INTERNER = new MappedInterner(); | 123 StringUtilities.INTERNER = new MappedInterner(); |
| 124 | 124 |
| 125 _processPlugins(); | 125 _processPlugins(); |
| 126 | 126 |
| 127 // Parse commandline options. | 127 // Parse commandline options. |
| 128 CommandLineOptions options = CommandLineOptions.parse(args); | 128 CommandLineOptions options = CommandLineOptions.parse(args); |
| 129 | 129 |
| 130 // Do analysis. | 130 // Do analysis. |
| 131 if (options.buildMode) { | 131 if (options.buildMode) { |
| 132 ErrorSeverity severity = _buildModeAnalyze(options); | 132 ErrorSeverity severity = _buildModeAnalyze(options); |
| 133 // In case of error propagate exit code. | 133 // In case of error propagate exit code. |
| 134 if (severity == ErrorSeverity.ERROR) { | 134 if (severity == ErrorSeverity.ERROR) { |
| 135 io.exitCode = severity.ordinal; | 135 io.exitCode = severity.ordinal; |
| 136 } | 136 } |
| 137 } else if (options.shouldBatch) { | 137 } else if (options.shouldBatch) { |
| 138 _BatchRunner.runAsBatch(args, (List<String> args) { | 138 _BatchRunner.runAsBatch(args, (List<String> args) { |
| 139 CommandLineOptions options = CommandLineOptions.parse(args); | 139 CommandLineOptions options = CommandLineOptions.parse(args); |
| 140 return _analyzeAll(options); | 140 return _analyzeAll(options); |
| 141 }); | 141 }); |
| 142 } else { | 142 } else { |
| 143 ErrorSeverity severity = _analyzeAll(options); | 143 ErrorSeverity severity = await _analyzeAll(options); |
| 144 // In case of error propagate exit code. | 144 // In case of error propagate exit code. |
| 145 if (severity == ErrorSeverity.ERROR) { | 145 if (severity == ErrorSeverity.ERROR) { |
| 146 io.exitCode = severity.ordinal; | 146 io.exitCode = severity.ordinal; |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 if (_context != null) { | 150 if (_context != null) { |
| 151 _analyzedFileCount += _context.sources.length; | 151 _analyzedFileCount += _context.sources.length; |
| 152 } | 152 } |
| 153 | 153 |
| 154 if (options.perfReport != null) { | 154 if (options.perfReport != null) { |
| 155 String json = makePerfReport( | 155 String json = makePerfReport( |
| 156 startTime, currentTimeMillis(), options, _analyzedFileCount, stats); | 156 startTime, currentTimeMillis(), options, _analyzedFileCount, stats); |
| 157 new io.File(options.perfReport).writeAsStringSync(json); | 157 new io.File(options.perfReport).writeAsStringSync(json); |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 ErrorSeverity _analyzeAll(CommandLineOptions options) { | 161 Future<ErrorSeverity> _analyzeAll(CommandLineOptions options) async { |
| 162 return _analyzeAllTag.makeCurrentWhile(() { | 162 PerformanceTag previous = _analyzeAllTag.makeCurrent(); |
| 163 return _analyzeAllImpl(options); | 163 try { |
| 164 }); | 164 return await _analyzeAllImpl(options); |
| 165 } finally { |
| 166 previous.makeCurrent(); |
| 167 } |
| 165 } | 168 } |
| 166 | 169 |
| 167 /// Perform analysis according to the given [options]. | 170 /// Perform analysis according to the given [options]. |
| 168 ErrorSeverity _analyzeAllImpl(CommandLineOptions options) { | 171 Future<ErrorSeverity> _analyzeAllImpl(CommandLineOptions options) async { |
| 169 if (!options.machineFormat) { | 172 if (!options.machineFormat) { |
| 170 outSink.writeln("Analyzing ${options.sourceFiles}..."); | 173 outSink.writeln("Analyzing ${options.sourceFiles}..."); |
| 171 } | 174 } |
| 172 | 175 |
| 173 // Create a context, or re-use the previous one. | 176 // Create a context, or re-use the previous one. |
| 174 try { | 177 try { |
| 175 _createAnalysisContext(options); | 178 _createAnalysisContext(options); |
| 176 } on _DriverError catch (error) { | 179 } on _DriverError catch (error) { |
| 177 outSink.writeln(error.msg); | 180 outSink.writeln(error.msg); |
| 178 return ErrorSeverity.ERROR; | 181 return ErrorSeverity.ERROR; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 | 213 |
| 211 // Analyze the libraries. | 214 // Analyze the libraries. |
| 212 ErrorSeverity allResult = ErrorSeverity.NONE; | 215 ErrorSeverity allResult = ErrorSeverity.NONE; |
| 213 var libUris = <Uri>[]; | 216 var libUris = <Uri>[]; |
| 214 var parts = <Source>[]; | 217 var parts = <Source>[]; |
| 215 for (Source source in sourcesToAnalyze) { | 218 for (Source source in sourcesToAnalyze) { |
| 216 if (context.computeKindOf(source) == SourceKind.PART) { | 219 if (context.computeKindOf(source) == SourceKind.PART) { |
| 217 parts.add(source); | 220 parts.add(source); |
| 218 continue; | 221 continue; |
| 219 } | 222 } |
| 220 ErrorSeverity status = _runAnalyzer(source, options); | 223 ErrorSeverity status = await _runAnalyzer(source, options); |
| 221 allResult = allResult.max(status); | 224 allResult = allResult.max(status); |
| 222 libUris.add(source.uri); | 225 libUris.add(source.uri); |
| 223 } | 226 } |
| 224 | 227 |
| 225 // Check that each part has a corresponding source in the input list. | 228 // Check that each part has a corresponding source in the input list. |
| 226 for (Source part in parts) { | 229 for (Source part in parts) { |
| 227 bool found = false; | 230 bool found = false; |
| 228 for (var lib in context.getLibrariesContaining(part)) { | 231 for (var lib in context.getLibrariesContaining(part)) { |
| 229 if (libUris.contains(lib.uri)) { | 232 if (libUris.contains(lib.uri)) { |
| 230 found = true; | 233 found = true; |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 532 |
| 530 AnalyzeFunctionBodiesPredicate dietParsingPolicy = | 533 AnalyzeFunctionBodiesPredicate dietParsingPolicy = |
| 531 _chooseDietParsingPolicy(options); | 534 _chooseDietParsingPolicy(options); |
| 532 setAnalysisContextOptions( | 535 setAnalysisContextOptions( |
| 533 resourceProvider, sourceFactory, _context, options, | 536 resourceProvider, sourceFactory, _context, options, |
| 534 (AnalysisOptionsImpl contextOptions) { | 537 (AnalysisOptionsImpl contextOptions) { |
| 535 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; | 538 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; |
| 536 }); | 539 }); |
| 537 | 540 |
| 538 _context.sourceFactory = sourceFactory; | 541 _context.sourceFactory = sourceFactory; |
| 542 |
| 539 if (sdkBundle != null) { | 543 if (sdkBundle != null) { |
| 540 _context.resultProvider = | 544 _context.resultProvider = |
| 541 new InputPackagesResultProvider(_context, summaryDataStore); | 545 new InputPackagesResultProvider(_context, summaryDataStore); |
| 542 } | 546 } |
| 543 } | 547 } |
| 544 | 548 |
| 545 /// Return discovered packagespec, or `null` if none is found. | 549 /// Return discovered packagespec, or `null` if none is found. |
| 546 Packages _discoverPackagespec(Uri root) { | 550 Packages _discoverPackagespec(Uri root) { |
| 547 try { | 551 try { |
| 548 Packages packages = pkg_discovery.findPackagesFromFile(root); | 552 Packages packages = pkg_discovery.findPackagesFromFile(root); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 plugins.addAll(AnalysisEngine.instance.requiredPlugins); | 630 plugins.addAll(AnalysisEngine.instance.requiredPlugins); |
| 627 plugins.addAll(_userDefinedPlugins); | 631 plugins.addAll(_userDefinedPlugins); |
| 628 | 632 |
| 629 ExtensionManager manager = new ExtensionManager(); | 633 ExtensionManager manager = new ExtensionManager(); |
| 630 manager.processPlugins(plugins); | 634 manager.processPlugins(plugins); |
| 631 | 635 |
| 632 linter.registerLintRules(); | 636 linter.registerLintRules(); |
| 633 } | 637 } |
| 634 | 638 |
| 635 /// Analyze a single source. | 639 /// Analyze a single source. |
| 636 ErrorSeverity _runAnalyzer(Source source, CommandLineOptions options) { | 640 Future<ErrorSeverity> _runAnalyzer( |
| 641 Source source, CommandLineOptions options) async { |
| 637 int startTime = currentTimeMillis(); | 642 int startTime = currentTimeMillis(); |
| 638 AnalyzerImpl analyzer = | 643 AnalyzerImpl analyzer = new AnalyzerImpl( |
| 639 new AnalyzerImpl(_context, source, options, stats, startTime); | 644 _context.analysisOptions, _context, source, options, stats, startTime); |
| 640 var errorSeverity = analyzer.analyzeSync(); | 645 ErrorSeverity errorSeverity = await analyzer.analyze(); |
| 641 if (errorSeverity == ErrorSeverity.ERROR) { | 646 if (errorSeverity == ErrorSeverity.ERROR) { |
| 642 io.exitCode = errorSeverity.ordinal; | 647 io.exitCode = errorSeverity.ordinal; |
| 643 } | 648 } |
| 644 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { | 649 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { |
| 645 io.exitCode = errorSeverity.ordinal; | 650 io.exitCode = errorSeverity.ordinal; |
| 646 } | 651 } |
| 647 return errorSeverity; | 652 return errorSeverity; |
| 648 } | 653 } |
| 649 | 654 |
| 650 void _setupSdk(CommandLineOptions options, bool useSummaries) { | 655 void _setupSdk(CommandLineOptions options, bool useSummaries) { |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 static void runAsBatch(List<String> sharedArgs, _BatchRunnerHandler handler) { | 807 static void runAsBatch(List<String> sharedArgs, _BatchRunnerHandler handler) { |
| 803 outSink.writeln('>>> BATCH START'); | 808 outSink.writeln('>>> BATCH START'); |
| 804 Stopwatch stopwatch = new Stopwatch(); | 809 Stopwatch stopwatch = new Stopwatch(); |
| 805 stopwatch.start(); | 810 stopwatch.start(); |
| 806 int testsFailed = 0; | 811 int testsFailed = 0; |
| 807 int totalTests = 0; | 812 int totalTests = 0; |
| 808 ErrorSeverity batchResult = ErrorSeverity.NONE; | 813 ErrorSeverity batchResult = ErrorSeverity.NONE; |
| 809 // Read line from stdin. | 814 // Read line from stdin. |
| 810 Stream cmdLine = | 815 Stream cmdLine = |
| 811 io.stdin.transform(UTF8.decoder).transform(new LineSplitter()); | 816 io.stdin.transform(UTF8.decoder).transform(new LineSplitter()); |
| 812 cmdLine.listen((String line) { | 817 cmdLine.listen((String line) async { |
| 813 // Maybe finish. | 818 // Maybe finish. |
| 814 if (line.isEmpty) { | 819 if (line.isEmpty) { |
| 815 var time = stopwatch.elapsedMilliseconds; | 820 var time = stopwatch.elapsedMilliseconds; |
| 816 outSink.writeln( | 821 outSink.writeln( |
| 817 '>>> BATCH END (${totalTests - testsFailed}/$totalTests) ${time}ms')
; | 822 '>>> BATCH END (${totalTests - testsFailed}/$totalTests) ${time}ms')
; |
| 818 io.exitCode = batchResult.ordinal; | 823 io.exitCode = batchResult.ordinal; |
| 819 } | 824 } |
| 820 // Prepare arguments. | 825 // Prepare arguments. |
| 821 var lineArgs = line.split(new RegExp('\\s+')); | 826 var lineArgs = line.split(new RegExp('\\s+')); |
| 822 var args = new List<String>(); | 827 var args = new List<String>(); |
| 823 args.addAll(sharedArgs); | 828 args.addAll(sharedArgs); |
| 824 args.addAll(lineArgs); | 829 args.addAll(lineArgs); |
| 825 args.remove('-b'); | 830 args.remove('-b'); |
| 826 args.remove('--batch'); | 831 args.remove('--batch'); |
| 827 // Analyze single set of arguments. | 832 // Analyze single set of arguments. |
| 828 try { | 833 try { |
| 829 totalTests++; | 834 totalTests++; |
| 830 ErrorSeverity result = handler(args); | 835 ErrorSeverity result = await handler(args); |
| 831 bool resultPass = result != ErrorSeverity.ERROR; | 836 bool resultPass = result != ErrorSeverity.ERROR; |
| 832 if (!resultPass) { | 837 if (!resultPass) { |
| 833 testsFailed++; | 838 testsFailed++; |
| 834 } | 839 } |
| 835 batchResult = batchResult.max(result); | 840 batchResult = batchResult.max(result); |
| 836 // Write stderr end token and flush. | 841 // Write stderr end token and flush. |
| 837 errorSink.writeln('>>> EOF STDERR'); | 842 errorSink.writeln('>>> EOF STDERR'); |
| 838 String resultPassString = resultPass ? 'PASS' : 'FAIL'; | 843 String resultPassString = resultPass ? 'PASS' : 'FAIL'; |
| 839 outSink.writeln( | 844 outSink.writeln( |
| 840 '>>> TEST $resultPassString ${stopwatch.elapsedMilliseconds}ms'); | 845 '>>> TEST $resultPassString ${stopwatch.elapsedMilliseconds}ms'); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 for (var package in packages) { | 882 for (var package in packages) { |
| 878 var packageName = path.basename(package.path); | 883 var packageName = path.basename(package.path); |
| 879 var realPath = package.resolveSymbolicLinksSync(); | 884 var realPath = package.resolveSymbolicLinksSync(); |
| 880 result[packageName] = [ | 885 result[packageName] = [ |
| 881 PhysicalResourceProvider.INSTANCE.getFolder(realPath) | 886 PhysicalResourceProvider.INSTANCE.getFolder(realPath) |
| 882 ]; | 887 ]; |
| 883 } | 888 } |
| 884 return result; | 889 return result; |
| 885 } | 890 } |
| 886 } | 891 } |
| OLD | NEW |