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 |
11 import 'package:analyzer/file_system/file_system.dart' as fileSystem; | 11 import 'package:analyzer/file_system/file_system.dart' as fileSystem; |
12 import 'package:analyzer/file_system/physical_file_system.dart'; | 12 import 'package:analyzer/file_system/physical_file_system.dart'; |
13 import 'package:analyzer/plugin/options.dart'; | 13 import 'package:analyzer/plugin/options.dart'; |
14 import 'package:analyzer/source/analysis_options_provider.dart'; | 14 import 'package:analyzer/source/analysis_options_provider.dart'; |
15 import 'package:analyzer/source/package_map_provider.dart'; | 15 import 'package:analyzer/source/package_map_provider.dart'; |
16 import 'package:analyzer/source/package_map_resolver.dart'; | 16 import 'package:analyzer/source/package_map_resolver.dart'; |
17 import 'package:analyzer/source/pub_package_map_provider.dart'; | 17 import 'package:analyzer/source/pub_package_map_provider.dart'; |
18 import 'package:analyzer/source/sdk_ext.dart'; | 18 import 'package:analyzer/source/sdk_ext.dart'; |
19 import 'package:analyzer/src/generated/constant.dart'; | 19 import 'package:analyzer/src/generated/constant.dart'; |
20 import 'package:analyzer/src/generated/engine.dart'; | 20 import 'package:analyzer/src/generated/engine.dart'; |
21 import 'package:analyzer/src/generated/error.dart'; | 21 import 'package:analyzer/src/generated/error.dart'; |
22 import 'package:analyzer/src/generated/interner.dart'; | 22 import 'package:analyzer/src/generated/interner.dart'; |
23 import 'package:analyzer/src/generated/java_engine.dart'; | 23 import 'package:analyzer/src/generated/java_engine.dart'; |
24 import 'package:analyzer/src/generated/java_io.dart'; | 24 import 'package:analyzer/src/generated/java_io.dart'; |
25 import 'package:analyzer/src/generated/sdk_io.dart'; | 25 import 'package:analyzer/src/generated/sdk_io.dart'; |
26 import 'package:analyzer/src/generated/source.dart'; | 26 import 'package:analyzer/src/generated/source.dart'; |
27 import 'package:analyzer/src/generated/source_io.dart'; | 27 import 'package:analyzer/src/generated/source_io.dart'; |
28 import 'package:analyzer/src/generated/utilities_general.dart' | |
29 show PerformanceTag; | |
28 import 'package:analyzer/src/services/lint.dart'; | 30 import 'package:analyzer/src/services/lint.dart'; |
29 import 'package:analyzer/src/task/options.dart'; | 31 import 'package:analyzer/src/task/options.dart'; |
30 import 'package:analyzer_cli/src/analyzer_impl.dart'; | 32 import 'package:analyzer_cli/src/analyzer_impl.dart'; |
31 import 'package:analyzer_cli/src/options.dart'; | 33 import 'package:analyzer_cli/src/options.dart'; |
32 import 'package:linter/src/plugin/linter_plugin.dart'; | 34 import 'package:linter/src/plugin/linter_plugin.dart'; |
33 import 'package:package_config/discovery.dart' as pkgDiscovery; | 35 import 'package:package_config/discovery.dart' as pkgDiscovery; |
34 import 'package:package_config/packages.dart' show Packages; | 36 import 'package:package_config/packages.dart' show Packages; |
35 import 'package:package_config/packages_file.dart' as pkgfile show parse; | 37 import 'package:package_config/packages_file.dart' as pkgfile show parse; |
36 import 'package:package_config/src/packages_impl.dart' show MapPackages; | 38 import 'package:package_config/src/packages_impl.dart' show MapPackages; |
37 import 'package:path/path.dart' as path; | 39 import 'package:path/path.dart' as path; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 /// *Visible for testing.* | 83 /// *Visible for testing.* |
82 AnalysisContext get context => _context; | 84 AnalysisContext get context => _context; |
83 | 85 |
84 /// Set the [plugins] that are defined outside the `analyzer_cli` package. | 86 /// Set the [plugins] that are defined outside the `analyzer_cli` package. |
85 void set userDefinedPlugins(List<Plugin> plugins) { | 87 void set userDefinedPlugins(List<Plugin> plugins) { |
86 _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins; | 88 _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins; |
87 } | 89 } |
88 | 90 |
89 /// Use the given command-line [args] to start this analysis driver. | 91 /// Use the given command-line [args] to start this analysis driver. |
90 void start(List<String> args) { | 92 void start(List<String> args) { |
93 int startTime = new DateTime.now().millisecondsSinceEpoch; | |
94 | |
91 StringUtilities.INTERNER = new MappedInterner(); | 95 StringUtilities.INTERNER = new MappedInterner(); |
92 | 96 |
93 _processPlugins(); | 97 _processPlugins(); |
94 | 98 |
95 // Parse commandline options. | 99 // Parse commandline options. |
96 CommandLineOptions options = CommandLineOptions.parse(args); | 100 CommandLineOptions options = CommandLineOptions.parse(args); |
97 | 101 |
98 // Cache options of interest to inform analysis. | 102 // Cache options of interest to inform analysis. |
99 _setupEnv(options); | 103 _setupEnv(options); |
100 | 104 |
101 // Do analysis. | 105 // Do analysis. |
102 if (_isBatch) { | 106 if (_isBatch) { |
103 _BatchRunner.runAsBatch(args, (List<String> args) { | 107 _BatchRunner.runAsBatch(args, (List<String> args) { |
104 CommandLineOptions options = CommandLineOptions.parse(args); | 108 CommandLineOptions options = CommandLineOptions.parse(args); |
105 return _analyzeAll(options); | 109 return _analyzeAll(options); |
106 }); | 110 }); |
107 } else { | 111 } else { |
108 ErrorSeverity severity = _analyzeAll(options); | 112 ErrorSeverity severity = _analyzeAll(options); |
109 // In case of error propagate exit code. | 113 // In case of error propagate exit code. |
110 if (severity == ErrorSeverity.ERROR) { | 114 if (severity == ErrorSeverity.ERROR) { |
111 exitCode = severity.ordinal; | 115 exitCode = severity.ordinal; |
112 } | 116 } |
113 } | 117 } |
118 | |
119 if (options.perfLog != null) { | |
120 _writePerfLog(options.perfLog, startTime); | |
121 } | |
114 } | 122 } |
115 | 123 |
124 ErrorSeverity _analyzeAll(CommandLineOptions options) { | |
125 return _analyzeAllTag.makeCurrentWhile(() { | |
126 return _analyzeAllImpl(options); | |
127 }); | |
128 } | |
129 | |
130 static final PerformanceTag _analyzeAllTag = | |
131 new PerformanceTag("Driver._analyzeAll"); | |
132 | |
116 /// Perform analysis according to the given [options]. | 133 /// Perform analysis according to the given [options]. |
117 ErrorSeverity _analyzeAll(CommandLineOptions options) { | 134 ErrorSeverity _analyzeAllImpl(CommandLineOptions options) { |
118 if (!options.machineFormat) { | 135 if (!options.machineFormat) { |
119 outSink.writeln("Analyzing ${options.sourceFiles}..."); | 136 outSink.writeln("Analyzing ${options.sourceFiles}..."); |
120 } | 137 } |
121 | 138 |
122 // Create a context, or re-use the previous one. | 139 // Create a context, or re-use the previous one. |
123 try { | 140 try { |
124 _createAnalysisContext(options); | 141 _createAnalysisContext(options); |
125 } on _DriverError catch (error) { | 142 } on _DriverError catch (error) { |
126 outSink.writeln(error.msg); | 143 outSink.writeln(error.msg); |
127 return ErrorSeverity.ERROR; | 144 return ErrorSeverity.ERROR; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 errorSink.writeln("${part.fullName} is a part and cannot be analyzed."); | 200 errorSink.writeln("${part.fullName} is a part and cannot be analyzed."); |
184 errorSink.writeln("Please pass in a library that contains this part."); | 201 errorSink.writeln("Please pass in a library that contains this part."); |
185 exitCode = ErrorSeverity.ERROR.ordinal; | 202 exitCode = ErrorSeverity.ERROR.ordinal; |
186 allResult = allResult.max(ErrorSeverity.ERROR); | 203 allResult = allResult.max(ErrorSeverity.ERROR); |
187 } | 204 } |
188 } | 205 } |
189 | 206 |
190 return allResult; | 207 return allResult; |
191 } | 208 } |
192 | 209 |
210 static _writePerfLog(String filename, int startTime) { | |
211 int totalTime = currentTimeMillis() - startTime; | |
212 int otherTime = totalTime; | |
213 | |
214 // Convert performance tags to JSON representation. | |
215 var json = <String, dynamic>{}; | |
216 for (PerformanceTag tag in PerformanceTag.all) { | |
217 if (tag != PerformanceTag.UNKNOWN) { | |
218 int tagTime = tag.elapsedMs; | |
219 json[tag.label] = tagTime; | |
220 otherTime -= tagTime; | |
221 } | |
222 } | |
223 json['other'] = otherTime; | |
224 json['total'] = totalTime; | |
225 | |
226 // Pretty-print the JSON, one line per value for readability. | |
227 var buf = new StringBuffer(); | |
Paul Berry
2015/12/16 15:11:26
There's already library code available to pretty-p
skybrian
2015/12/16 18:48:10
Thanks!
| |
228 buf.writeln("{"); | |
229 var firstLine = true; | |
230 for (var key in json.keys) { | |
231 if (!firstLine) buf.writeln(","); | |
Brian Wilkerson
2015/12/16 15:08:43
style nit: we always use blocks for 'if's.
| |
232 var val = json[key]; | |
233 buf.write(' "$key": ${JSON.encode(val)}'); | |
234 firstLine = false; | |
235 } | |
236 buf.writeln("\n}"); | |
Brian Wilkerson
2015/12/16 15:08:43
nit: seems strange to have a newline explicitly in
| |
237 | |
238 // Save to disk. | |
239 new File(filename).writeAsStringSync(buf.toString()); | |
240 } | |
241 | |
193 /// Determine whether the context created during a previous call to | 242 /// Determine whether the context created during a previous call to |
194 /// [_analyzeAll] can be re-used in order to analyze using [options]. | 243 /// [_analyzeAll] can be re-used in order to analyze using [options]. |
195 bool _canContextBeReused(CommandLineOptions options) { | 244 bool _canContextBeReused(CommandLineOptions options) { |
196 // TODO(paulberry): add a command-line option that disables context re-use. | 245 // TODO(paulberry): add a command-line option that disables context re-use. |
197 if (_context == null) { | 246 if (_context == null) { |
198 return false; | 247 return false; |
199 } | 248 } |
200 if (options.packageRootPath != _previousOptions.packageRootPath) { | 249 if (options.packageRootPath != _previousOptions.packageRootPath) { |
201 return false; | 250 return false; |
202 } | 251 } |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 for (var package in packages) { | 684 for (var package in packages) { |
636 var packageName = path.basename(package.path); | 685 var packageName = path.basename(package.path); |
637 var realPath = package.resolveSymbolicLinksSync(); | 686 var realPath = package.resolveSymbolicLinksSync(); |
638 result[packageName] = [ | 687 result[packageName] = [ |
639 PhysicalResourceProvider.INSTANCE.getFolder(realPath) | 688 PhysicalResourceProvider.INSTANCE.getFolder(realPath) |
640 ]; | 689 ]; |
641 } | 690 } |
642 return result; | 691 return result; |
643 } | 692 } |
644 } | 693 } |
OLD | NEW |