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

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

Issue 2659463003: Make analyzer_cli batch mode asynchronous. (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « pkg/analyzer_cli/lib/src/build_mode.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/lib/src/build_mode.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698