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 |
|
Brian Wilkerson
2017/04/24 20:26:47
I don't understand why the name of the file was ch
devoncarew
2017/04/24 22:10:00
I can change this name back to 'driver.dart'. It w
| |
| 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; | |
| 6 | |
| 7 import 'dart:async'; | 5 import 'dart:async'; |
| 8 import 'dart:convert'; | |
| 9 import 'dart:io' as io; | 6 import 'dart:io' as io; |
| 10 | 7 |
| 11 import 'package:analyzer/error/error.dart'; | 8 import 'package:analyzer/error/error.dart'; |
| 12 import 'package:analyzer/file_system/file_system.dart' as file_system; | 9 import 'package:analyzer/file_system/file_system.dart' as file_system; |
| 13 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| 14 import 'package:analyzer/file_system/physical_file_system.dart'; | 11 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 15 import 'package:analyzer/plugin/resolver_provider.dart'; | 12 import 'package:analyzer/plugin/resolver_provider.dart'; |
| 16 import 'package:analyzer/source/package_map_provider.dart'; | 13 import 'package:analyzer/source/package_map_provider.dart'; |
| 17 import 'package:analyzer/source/package_map_resolver.dart'; | 14 import 'package:analyzer/source/package_map_resolver.dart'; |
| 18 import 'package:analyzer/source/pub_package_map_provider.dart'; | 15 import 'package:analyzer/source/pub_package_map_provider.dart'; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 29 import 'package:analyzer/src/generated/sdk.dart'; | 26 import 'package:analyzer/src/generated/sdk.dart'; |
| 30 import 'package:analyzer/src/generated/source.dart'; | 27 import 'package:analyzer/src/generated/source.dart'; |
| 31 import 'package:analyzer/src/generated/source_io.dart'; | 28 import 'package:analyzer/src/generated/source_io.dart'; |
| 32 import 'package:analyzer/src/generated/utilities_general.dart' | 29 import 'package:analyzer/src/generated/utilities_general.dart' |
| 33 show PerformanceTag; | 30 show PerformanceTag; |
| 34 import 'package:analyzer/src/source/source_resource.dart'; | 31 import 'package:analyzer/src/source/source_resource.dart'; |
| 35 import 'package:analyzer/src/summary/idl.dart'; | 32 import 'package:analyzer/src/summary/idl.dart'; |
| 36 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | 33 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
| 37 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk; | 34 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk; |
| 38 import 'package:analyzer_cli/src/analyzer_impl.dart'; | 35 import 'package:analyzer_cli/src/analyzer_impl.dart'; |
| 36 import 'package:analyzer_cli/src/analyzer_options.dart'; | |
| 37 import 'package:analyzer_cli/src/batch_mode.dart'; | |
| 39 import 'package:analyzer_cli/src/build_mode.dart'; | 38 import 'package:analyzer_cli/src/build_mode.dart'; |
| 40 import 'package:analyzer_cli/src/error_formatter.dart'; | 39 import 'package:analyzer_cli/src/error_formatter.dart'; |
| 41 import 'package:analyzer_cli/src/error_severity.dart'; | 40 import 'package:analyzer_cli/src/error_severity.dart'; |
| 42 import 'package:analyzer_cli/src/options.dart'; | |
| 43 import 'package:analyzer_cli/src/perf_report.dart'; | 41 import 'package:analyzer_cli/src/perf_report.dart'; |
| 44 import 'package:analyzer_cli/starter.dart' show CommandLineStarter; | 42 import 'package:analyzer_cli/starter.dart' show CommandLineStarter; |
| 45 import 'package:linter/src/rules.dart' as linter; | 43 import 'package:linter/src/rules.dart' as linter; |
| 46 import 'package:package_config/discovery.dart' as pkg_discovery; | 44 import 'package:package_config/discovery.dart' as pkg_discovery; |
| 47 import 'package:package_config/packages.dart' show Packages; | 45 import 'package:package_config/packages.dart' show Packages; |
| 48 import 'package:package_config/packages_file.dart' as pkgfile show parse; | 46 import 'package:package_config/packages_file.dart' as pkgfile show parse; |
| 49 import 'package:package_config/src/packages_impl.dart' show MapPackages; | 47 import 'package:package_config/src/packages_impl.dart' show MapPackages; |
| 50 import 'package:path/path.dart' as path; | 48 import 'package:path/path.dart' as path; |
| 51 import 'package:plugin/manager.dart'; | 49 import 'package:plugin/manager.dart'; |
| 52 import 'package:plugin/plugin.dart'; | 50 import 'package:plugin/plugin.dart'; |
| 53 import 'package:yaml/yaml.dart'; | 51 import 'package:yaml/yaml.dart'; |
| 54 | 52 |
| 55 /// Shared IO sink for standard error reporting. | 53 /// Shared IO sink for standard error reporting. |
| 56 /// | 54 /// |
| 57 /// *Visible for testing.* | 55 /// *Visible for testing.* |
| 58 StringSink errorSink = io.stderr; | 56 StringSink errorSink = io.stderr; |
| 59 | 57 |
| 60 /// Shared IO sink for standard out reporting. | 58 /// Shared IO sink for standard out reporting. |
| 61 /// | 59 /// |
| 62 /// *Visible for testing.* | 60 /// *Visible for testing.* |
| 63 StringSink outSink = io.stdout; | 61 StringSink outSink = io.stdout; |
| 64 | 62 |
| 65 /// Test this option map to see if it specifies lint rules. | 63 /// Test this option map to see if it specifies lint rules. |
| 66 bool containsLintRuleEntry(Map<String, YamlNode> options) { | 64 bool containsLintRuleEntry(Map<String, YamlNode> options) { |
| 67 var linterNode = options['linter']; | 65 var linterNode = options['linter']; |
| 68 return linterNode is YamlMap && linterNode.containsKey('rules'); | 66 return linterNode is YamlMap && linterNode.containsKey('rules'); |
| 69 } | 67 } |
| 70 | 68 |
| 71 typedef Future<ErrorSeverity> _BatchRunnerHandler(List<String> args); | |
| 72 | |
| 73 class Driver implements CommandLineStarter { | 69 class Driver implements CommandLineStarter { |
| 74 static final PerformanceTag _analyzeAllTag = | 70 static final PerformanceTag _analyzeAllTag = |
| 75 new PerformanceTag("Driver._analyzeAll"); | 71 new PerformanceTag("Driver._analyzeAll"); |
| 76 | 72 |
| 77 static ByteStore analysisDriverMemoryByteStore = new MemoryByteStore(); | 73 static ByteStore analysisDriverMemoryByteStore = new MemoryByteStore(); |
| 78 | 74 |
| 79 /// The plugins that are defined outside the `analyzer_cli` package. | 75 /// The plugins that are defined outside the `analyzer_cli` package. |
| 80 List<Plugin> _userDefinedPlugins = <Plugin>[]; | 76 List<Plugin> _userDefinedPlugins = <Plugin>[]; |
| 81 | 77 |
| 82 /// The context that was most recently created by a call to [_analyzeAll], or | 78 /// The context that was most recently created by a call to [_analyzeAll], or |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 CommandLineOptions options = CommandLineOptions.parse(args); | 128 CommandLineOptions options = CommandLineOptions.parse(args); |
| 133 | 129 |
| 134 // Do analysis. | 130 // Do analysis. |
| 135 if (options.buildMode) { | 131 if (options.buildMode) { |
| 136 ErrorSeverity severity = _buildModeAnalyze(options); | 132 ErrorSeverity severity = _buildModeAnalyze(options); |
| 137 // In case of error propagate exit code. | 133 // In case of error propagate exit code. |
| 138 if (severity == ErrorSeverity.ERROR) { | 134 if (severity == ErrorSeverity.ERROR) { |
| 139 io.exitCode = severity.ordinal; | 135 io.exitCode = severity.ordinal; |
| 140 } | 136 } |
| 141 } else if (options.shouldBatch) { | 137 } else if (options.shouldBatch) { |
| 142 _BatchRunner.runAsBatch(args, (List<String> args) async { | 138 BatchRunner batchRunner = new BatchRunner(outSink, errorSink); |
| 139 batchRunner.runAsBatch(args, (List<String> args) async { | |
| 143 CommandLineOptions options = CommandLineOptions.parse(args); | 140 CommandLineOptions options = CommandLineOptions.parse(args); |
| 144 return await _analyzeAll(options); | 141 return await _analyzeAll(options); |
| 145 }); | 142 }); |
| 146 } else { | 143 } else { |
| 147 ErrorSeverity severity = await _analyzeAll(options); | 144 ErrorSeverity severity = await _analyzeAll(options); |
| 148 // In case of error propagate exit code. | 145 // In case of error propagate exit code. |
| 149 if (severity == ErrorSeverity.ERROR) { | 146 if (severity == ErrorSeverity.ERROR) { |
| 150 io.exitCode = severity.ordinal; | 147 io.exitCode = severity.ordinal; |
| 151 } | 148 } |
| 152 } | 149 } |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 } | 844 } |
| 848 } | 845 } |
| 849 return true; | 846 return true; |
| 850 } | 847 } |
| 851 | 848 |
| 852 /// Convert [sourcePath] into an absolute path. | 849 /// Convert [sourcePath] into an absolute path. |
| 853 static String _normalizeSourcePath(String sourcePath) => | 850 static String _normalizeSourcePath(String sourcePath) => |
| 854 path.normalize(new io.File(sourcePath).absolute.path); | 851 path.normalize(new io.File(sourcePath).absolute.path); |
| 855 } | 852 } |
| 856 | 853 |
| 857 /// Provides a framework to read command line options from stdin and feed them | |
| 858 /// to a callback. | |
| 859 class _BatchRunner { | |
| 860 /// Run the tool in 'batch' mode, receiving command lines through stdin and | |
| 861 /// returning pass/fail status through stdout. This feature is intended for | |
| 862 /// use in unit testing. | |
| 863 static void runAsBatch(List<String> sharedArgs, _BatchRunnerHandler handler) { | |
| 864 outSink.writeln('>>> BATCH START'); | |
| 865 Stopwatch stopwatch = new Stopwatch(); | |
| 866 stopwatch.start(); | |
| 867 int testsFailed = 0; | |
| 868 int totalTests = 0; | |
| 869 ErrorSeverity batchResult = ErrorSeverity.NONE; | |
| 870 // Read line from stdin. | |
| 871 Stream cmdLine = | |
| 872 io.stdin.transform(UTF8.decoder).transform(new LineSplitter()); | |
| 873 cmdLine.listen((String line) async { | |
| 874 // Maybe finish. | |
| 875 if (line.isEmpty) { | |
| 876 var time = stopwatch.elapsedMilliseconds; | |
| 877 outSink.writeln( | |
| 878 '>>> BATCH END (${totalTests - testsFailed}/$totalTests) ${time}ms') ; | |
| 879 io.exitCode = batchResult.ordinal; | |
| 880 } | |
| 881 // Prepare arguments. | |
| 882 var lineArgs = line.split(new RegExp('\\s+')); | |
| 883 var args = new List<String>(); | |
| 884 args.addAll(sharedArgs); | |
| 885 args.addAll(lineArgs); | |
| 886 args.remove('-b'); | |
| 887 args.remove('--batch'); | |
| 888 // Analyze single set of arguments. | |
| 889 try { | |
| 890 totalTests++; | |
| 891 ErrorSeverity result = await handler(args); | |
| 892 bool resultPass = result != ErrorSeverity.ERROR; | |
| 893 if (!resultPass) { | |
| 894 testsFailed++; | |
| 895 } | |
| 896 batchResult = batchResult.max(result); | |
| 897 // Write stderr end token and flush. | |
| 898 errorSink.writeln('>>> EOF STDERR'); | |
| 899 String resultPassString = resultPass ? 'PASS' : 'FAIL'; | |
| 900 outSink.writeln( | |
| 901 '>>> TEST $resultPassString ${stopwatch.elapsedMilliseconds}ms'); | |
| 902 } catch (e, stackTrace) { | |
| 903 errorSink.writeln(e); | |
| 904 errorSink.writeln(stackTrace); | |
| 905 errorSink.writeln('>>> EOF STDERR'); | |
| 906 outSink.writeln('>>> TEST CRASH'); | |
| 907 } | |
| 908 }); | |
| 909 } | |
| 910 } | |
| 911 | |
| 912 class _DriverError implements Exception { | 854 class _DriverError implements Exception { |
| 913 String msg; | 855 String msg; |
| 914 _DriverError(this.msg); | 856 _DriverError(this.msg); |
| 915 } | 857 } |
| 916 | 858 |
| 917 class _PackageInfo { | 859 class _PackageInfo { |
| 918 Packages packages; | 860 Packages packages; |
| 919 Map<String, List<file_system.Folder>> packageMap; | 861 Map<String, List<file_system.Folder>> packageMap; |
| 920 _PackageInfo(this.packages, this.packageMap); | 862 _PackageInfo(this.packages, this.packageMap); |
| 921 } | 863 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 938 for (var package in packages) { | 880 for (var package in packages) { |
| 939 var packageName = path.basename(package.path); | 881 var packageName = path.basename(package.path); |
| 940 var realPath = package.resolveSymbolicLinksSync(); | 882 var realPath = package.resolveSymbolicLinksSync(); |
| 941 result[packageName] = [ | 883 result[packageName] = [ |
| 942 PhysicalResourceProvider.INSTANCE.getFolder(realPath) | 884 PhysicalResourceProvider.INSTANCE.getFolder(realPath) |
| 943 ]; | 885 ]; |
| 944 } | 886 } |
| 945 return result; | 887 return result; |
| 946 } | 888 } |
| 947 } | 889 } |
| OLD | NEW |