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

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

Issue 1459683003: `analyzer_cli` move to SDK. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: master merge Created 5 years, 1 month 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/analyzer_impl.dart ('k') | pkg/analyzer_cli/lib/src/driver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer_cli.src.bootloader;
6
7 import 'dart:async';
8 import 'dart:isolate';
9
10 import 'package:analyzer/file_system/physical_file_system.dart';
11 import 'package:analyzer/source/analysis_options_provider.dart';
12 import 'package:analyzer/src/context/context.dart';
13 import 'package:analyzer/src/generated/engine.dart' as engine;
14 import 'package:analyzer/src/plugin/plugin_configuration.dart';
15 import 'package:analyzer_cli/src/driver.dart';
16 import 'package:analyzer_cli/src/options.dart';
17 import 'package:source_span/source_span.dart';
18 import 'package:yaml/src/yaml_node.dart';
19
20 const _analyzerPackageName = 'analyzer';
21
22 /// Return non-null if there is a validation issue with this plugin.
23 String validate(PluginInfo plugin) {
24 var missing = <String>[];
25 if (plugin.className == null) {
26 missing.add('class name');
27 }
28 if (plugin.libraryUri == null) {
29 missing.add('library uri');
30 }
31 if (missing.isEmpty) {
32 // All good.
33 return null;
34 }
35 return 'Plugin ${plugin.name} skipped, config missing: ${missing.join(", ")}';
36 }
37
38 List<PluginInfo> _validate(Iterable<PluginInfo> plugins) {
39 List<PluginInfo> validated = <PluginInfo>[];
40 plugins.forEach((PluginInfo plugin) {
41 String validation = validate(plugin);
42 if (validation != null) {
43 errorSink.writeln(validation);
44 } else {
45 validated.add(plugin);
46 }
47 });
48 return validated;
49 }
50
51 /// Source code assembler.
52 class Assembler {
53 /// Plugins to configure.
54 final Iterable<PluginInfo> plugins;
55
56 /// Create an assembler for the given plugin [config].
57 Assembler(this.plugins);
58
59 /// A string enumerating required package `import`s.
60 String get enumerateImports =>
61 plugins.map((PluginInfo p) => "import '${p.libraryUri}';").join('\n');
62
63 /// A string listing initialized plugin instances.
64 String get pluginList =>
65 plugins.map((PluginInfo p) => 'new ${p.className}()').join(', ');
66
67 /// Create a file containing a `main()` suitable for loading in spawned
68 /// isolate.
69 String createMain() => _generateMain();
70
71 String _generateMain() => """
72 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
73 // for details. All rights reserved. Use of this source code is governed by a
74 // BSD-style license that can be found in the LICENSE file.
75
76 // This code was auto-generated, is not intended to be edited, and is subject to
77 // significant change. Please see the README file for more information.
78
79 import 'package:analyzer_cli/src/driver.dart';
80
81 $enumerateImports
82
83 void main(List<String> args) {
84 var starter = new Driver();
85 starter.userDefinedPlugins = [$pluginList];
86 starter.start(args);
87 }
88 """;
89 }
90
91 /// Given environment information extracted from command-line `args`, creates a
92 /// a loadable analyzer "image".
93 class BootLoader {
94 /// Emits an error message to [errorSink] if plugin config can't be read.
95 static final ErrorHandler _pluginConfigErrorHandler = (Exception e) {
96 String details;
97 if (e is PluginConfigFormatException) {
98 details = e.message;
99 var node = e.yamlNode;
100 if (node is YamlNode) {
101 SourceLocation location = node.span.start;
102 details += ' (line ${location.line}, column ${location.column})';
103 }
104 } else {
105 details = e.toString();
106 }
107
108 errorSink.writeln('Plugin configuration skipped: $details');
109 };
110
111 /// Reads plugin config info from `.analysis_options`.
112 PluginConfigOptionsProcessor _pluginOptionsProcessor =
113 new PluginConfigOptionsProcessor(_pluginConfigErrorHandler);
114
115 /// Create a loadable analyzer image configured with plugins derived from
116 /// the given analyzer command-line `args`.
117 Image createImage(List<String> args) {
118 // Parse commandline options.
119 CommandLineOptions options = CommandLineOptions.parse(args);
120
121 // Process analysis options file (and notify all interested parties).
122 _processAnalysisOptions(options);
123
124 // TODO(pquitslund): Pass in .packages info
125 return new Image(_pluginOptionsProcessor.config,
126 args: args, packageRootPath: options.packageRootPath);
127 }
128
129 void _processAnalysisOptions(CommandLineOptions options) {
130 // Determine options file path.
131 var filePath = options.analysisOptionsFile ??
132 engine.AnalysisEngine.ANALYSIS_OPTIONS_FILE;
133 try {
134 var file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
135 AnalysisOptionsProvider analysisOptionsProvider =
136 new AnalysisOptionsProvider();
137 Map<String, YamlNode> options =
138 analysisOptionsProvider.getOptionsFromFile(file);
139 //TODO(pq): thread in proper context.
140 var temporaryContext = new AnalysisContextImpl();
141 _pluginOptionsProcessor.optionsProcessed(temporaryContext, options);
142 } on Exception catch (e) {
143 _pluginOptionsProcessor.onError(e);
144 }
145 }
146 }
147
148 /// A loadable "image" of a a configured analyzer instance.
149 class Image {
150 /// (Optional) package root path.
151 final String packageRootPath;
152
153 /// (Optional) package map.
154 final Map<String, Uri> packages;
155
156 /// (Optional) args to be passed on to the loaded main.
157 final List<String> args;
158
159 /// Plugin configuration.
160 final PluginConfig config;
161
162 /// Create an image with the given [config] and optionally [packages],
163 /// [packageRootPath], and command line [args].
164 Image(this.config, {this.packages, this.packageRootPath, this.args});
165
166 /// Load this image.
167 ///
168 /// Loading an image consists in assembling an analyzer `main()`, configured
169 /// to include the appropriate analyzer plugins as specified in
170 /// `.analyzer_options` which is then run in a spawned isolate.
171 Future load() {
172 List<PluginInfo> plugins = _validate(config.plugins);
173 String mainSource = new Assembler(plugins).createMain();
174
175 Completer completer = new Completer();
176 ReceivePort exitListener = new ReceivePort();
177 exitListener.listen((data) {
178 completer.complete();
179 exitListener.close();
180 });
181
182 Uri uri =
183 Uri.parse('data:application/dart;charset=utf-8,${Uri.encodeComponent(
184 mainSource)}');
185
186 // TODO(pquitslund): update once .packages are supported.
187 String packageRoot =
188 packageRootPath != null ? packageRootPath : './packages';
189 Uri packageUri = new Uri.file(packageRoot);
190
191 Isolate.spawnUri(uri, args, null /* msg */,
192 packageRoot: packageUri, onExit: exitListener.sendPort);
193
194 return completer.future;
195 }
196 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/lib/src/analyzer_impl.dart ('k') | pkg/analyzer_cli/lib/src/driver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698