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 /// New Compiler API. This API is under construction, use only internally or | 5 /// New Compiler API. This API is under construction, use only internally or |
6 /// in unittests. | 6 /// in unittests. |
7 | 7 |
8 library compiler_new; | 8 library compiler_new; |
9 | 9 |
10 import 'dart:async'; | 10 import 'dart:async'; |
11 import 'src/apiimpl.dart'; | 11 import 'src/apiimpl.dart'; |
12 import 'src/commandline_options.dart'; | 12 import 'src/options.dart' show CompilerOptions; |
13 import 'src/diagnostics/diagnostic_listener.dart' show DiagnosticOptions; | |
14 | 13 |
15 import 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider; | 14 import 'compiler.dart' show Diagnostic; |
16 export 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider; | 15 export 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider; |
17 | 16 |
18 // Unless explicitly allowed, passing `null` for any argument to the | 17 // Unless explicitly allowed, passing `null` for any argument to the |
19 // methods of library will result in an Error being thrown. | 18 // methods of library will result in an Error being thrown. |
20 | 19 |
21 /// Interface for providing the compiler with input. That is, Dart source files, | 20 /// Interface for providing the compiler with input. That is, Dart source files, |
22 /// package config files, etc. | 21 /// package config files, etc. |
23 abstract class CompilerInput { | 22 abstract class CompilerInput { |
24 /// Returns a future that completes to the source corresponding to [uri]. | 23 /// Returns a future that completes to the source corresponding to [uri]. |
25 /// If an exception occurs, the future completes with this exception. | 24 /// If an exception occurs, the future completes with this exception. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 85 |
87 /// The compiler object used for the compilation. | 86 /// The compiler object used for the compilation. |
88 /// | 87 /// |
89 /// Note: The type of [compiler] is implementation dependent and may vary. | 88 /// Note: The type of [compiler] is implementation dependent and may vary. |
90 /// Use only for debugging and testing. | 89 /// Use only for debugging and testing. |
91 final compiler; | 90 final compiler; |
92 | 91 |
93 CompilationResult(this.compiler, {this.isSuccess: true}); | 92 CompilationResult(this.compiler, {this.isSuccess: true}); |
94 } | 93 } |
95 | 94 |
96 /// Object for passing options to the compiler. | |
97 class CompilerOptions { | |
98 /// The entry point of the application that is being compiled. | |
99 final Uri entryPoint; | |
100 | |
101 /// Root location where SDK libraries are found. | |
102 final Uri libraryRoot; | |
103 | |
104 /// Package root location. | |
105 /// | |
106 /// If not null then [packageConfig] should be null. | |
107 final Uri packageRoot; | |
108 | |
109 /// Location of the package configuration file. | |
110 /// | |
111 /// If not null then [packageRoot] should be null. | |
112 final Uri packageConfig; | |
113 | |
114 // TODO(sigmund): Move out of here, maybe to CompilerInput. Options should not | |
115 // hold code, just configuration options. | |
116 final PackagesDiscoveryProvider packagesDiscoveryProvider; | |
117 | |
118 /// Resolved constant "environment" values passed to the compiler via the `-D` | |
119 /// flags. | |
120 final Map<String, dynamic> environment; | |
121 | |
122 /// Whether we allow mocking compilation of libraries such as dart:io and | |
123 /// dart:html for unit testing purposes. | |
124 final bool allowMockCompilation; | |
125 | |
126 /// Whether the native extension syntax is supported by the frontend. | |
127 final bool allowNativeExtensions; | |
128 | |
129 /// Whether to resolve all functions in the program, not just those reachable | |
130 /// from main. This implies [analyzeOnly] is true as well. | |
131 final bool analyzeAll; | |
132 | |
133 /// Whether to disable tree-shaking for the main script. This marks all | |
134 /// functions in the main script as reachable (not just a function named | |
135 /// `main`). | |
136 // TODO(sigmund): rename. The current name seems to indicate that only the | |
137 // main function is retained, which is the opposite of what this does. | |
138 final bool analyzeMain; | |
139 | |
140 /// Whether to run the compiler just for the purpose of analysis. That is, to | |
141 /// run resolution and type-checking alone, but otherwise do not generate any | |
142 /// code. | |
143 final bool analyzeOnly; | |
144 | |
145 /// Whether to skip analysis of method bodies and field initializers. Implies | |
146 /// [analyzeOnly]. | |
147 final bool analyzeSignaturesOnly; | |
148 | |
149 /// ID associated with this sdk build. | |
150 final String buildId; | |
151 | |
152 /// Whether there is a build-id available so we can use it on error messages | |
153 /// and in the emitted output of the compiler. | |
154 bool get hasBuildId => buildId != _UNDETERMINED_BUILD_ID; | |
155 | |
156 /// Location where to generate a map containing details of how deferred | |
157 /// libraries are subdivided. | |
158 final Uri deferredMapUri; | |
159 | |
160 /// Whether to disable inlining during the backend optimizations. | |
161 // TODO(sigmund): negate, so all flags are positive | |
162 final bool disableInlining; | |
163 | |
164 /// Several options to configure diagnostic messages. | |
165 // TODO(sigmund): should we simply embed those options here? | |
166 final DiagnosticOptions diagnosticOptions; | |
167 | |
168 /// Whether to disable global type inference. | |
169 final bool disableTypeInference; | |
170 | |
171 /// Whether to emit a .json file with a summary of the information used by the | |
172 /// compiler during optimization. This includes resolution details, | |
173 /// dependencies between elements, results of type inference, and the output | |
174 /// code for each function. | |
175 final bool dumpInfo; | |
176 | |
177 /// Whether we allow passing an extra argument to `assert`, containing a | |
178 /// reason for why an assertion fails. (experimental) | |
179 final bool enableAssertMessage; | |
180 | |
181 /// Whether to enable the experimental conditional directives feature. | |
182 final bool enableConditionalDirectives; | |
183 | |
184 /// Whether the user specified a flag to allow the use of dart:mirrors. This | |
185 /// silences a warning produced by the compiler. | |
186 final bool enableExperimentalMirrors; | |
187 | |
188 /// Whether to enable minification | |
189 // TODO(sigmund): rename to minify | |
190 final bool enableMinification; | |
191 | |
192 /// Whether to model which native classes are live based on annotations on the | |
193 /// core libraries. If false, all native classes will be included by default. | |
194 final bool enableNativeLiveTypeAnalysis; | |
195 | |
196 /// Whether to generate code containing checked-mode assignability checks. | |
197 final bool enableTypeAssertions; | |
198 | |
199 /// Whether to generate code containing user's `assert` statements. | |
200 final bool enableUserAssertions; | |
201 | |
202 /// Whether to generate output even when there are compile-time errors. | |
203 final bool generateCodeWithCompileTimeErrors; | |
204 | |
205 /// Whether to generate a source-map file together with the output program. | |
206 final bool generateSourceMap; | |
207 | |
208 /// Whether some values are cached for reuse in incremental compilation. | |
209 /// Incremental compilation allows calling `Compiler.run` more than once | |
210 /// (experimental). | |
211 final bool hasIncrementalSupport; | |
212 | |
213 /// URI of the main output if the compiler is generating source maps. | |
214 final Uri outputUri; | |
215 | |
216 /// Location of the platform configuration file. | |
217 final Uri platformConfigUri; | |
218 | |
219 /// Whether to emit URIs in the reflection metadata. | |
220 final bool preserveUris; | |
221 | |
222 /// URI where the compiler should generate the output source map file. | |
223 final Uri sourceMapUri; | |
224 | |
225 /// The compiler is run from the build bot. | |
226 final bool testMode; | |
227 | |
228 /// Whether to trust JS-interop annotations. (experimental) | |
229 final bool trustJSInteropTypeAnnotations; | |
230 | |
231 /// Whether to trust primitive types during inference and optimizations. | |
232 final bool trustPrimitives; | |
233 | |
234 /// Whether to trust type annotations during inference and optimizations. | |
235 final bool trustTypeAnnotations; | |
236 | |
237 /// Whether to generate code compliant with content security policy (CSP). | |
238 final bool useContentSecurityPolicy; | |
239 | |
240 /// Use the experimental CPS based backend. | |
241 final bool useCpsIr; | |
242 | |
243 /// When obfuscating for minification, whether to use the frequency of a name | |
244 /// as an heuristic to pick shorter names. | |
245 final bool useFrequencyNamer; | |
246 | |
247 /// Whether to use the new source-information implementation for source-maps. | |
248 /// (experimental) | |
249 final bool useNewSourceInfo; | |
250 | |
251 /// Whether the user requested to use the fast startup emitter. The full | |
252 /// emitter might still be used if the program uses dart:mirrors. | |
253 final bool useStartupEmitter; | |
254 | |
255 /// Enable verbose printing during compilation. Includes progress messages | |
256 /// during each phase and a time-breakdown between phases at the end. | |
257 final bool verbose; | |
258 | |
259 | |
260 // ------------------------------------------------- | |
261 // Options for deprecated features | |
262 // ------------------------------------------------- | |
263 // TODO(sigmund): delete these as we delete the underlying features | |
264 | |
265 /// Whether to preserve comments while scanning (only use for dart:mirrors). | |
266 final bool preserveComments; | |
267 | |
268 /// Whether to emit JavaScript (false enables dart2dart). | |
269 final bool emitJavaScript; | |
270 | |
271 /// When using dart2dart, whether to use the multi file format. | |
272 final bool dart2dartMultiFile; | |
273 | |
274 /// Strip option used by dart2dart. | |
275 final List<String> strips; | |
276 | |
277 /// Create an options object by parsing flags from [options]. | |
278 factory CompilerOptions.parse( | |
279 {Uri entryPoint, | |
280 Uri libraryRoot, | |
281 Uri packageRoot, | |
282 Uri packageConfig, | |
283 PackagesDiscoveryProvider packagesDiscoveryProvider, | |
284 Map<String, dynamic> environment: const <String, dynamic>{}, | |
285 List<String> options}) { | |
286 return new CompilerOptions( | |
287 entryPoint: entryPoint, | |
288 libraryRoot: libraryRoot, | |
289 packageRoot: packageRoot, | |
290 packageConfig: packageConfig, | |
291 packagesDiscoveryProvider: packagesDiscoveryProvider, | |
292 environment: environment, | |
293 allowMockCompilation: _hasOption(options, Flags.allowMockCompilation), | |
294 allowNativeExtensions: _hasOption(options, Flags.allowNativeExtensions), | |
295 analyzeAll: _hasOption(options, Flags.analyzeAll), | |
296 analyzeMain: _hasOption(options, Flags.analyzeMain), | |
297 analyzeOnly: _hasOption(options, Flags.analyzeOnly), | |
298 analyzeSignaturesOnly: _hasOption(options, Flags.analyzeSignaturesOnly), | |
299 buildId: _extractStringOption( | |
300 options, '--build-id=', _UNDETERMINED_BUILD_ID), | |
301 dart2dartMultiFile: _hasOption(options, '--output-type=dart-multi'), | |
302 deferredMapUri: _extractUriOption(options, '--deferred-map='), | |
303 diagnosticOptions: new DiagnosticOptions( | |
304 suppressWarnings: _hasOption(options, Flags.suppressWarnings), | |
305 fatalWarnings: _hasOption(options, Flags.fatalWarnings), | |
306 suppressHints: _hasOption(options, Flags.suppressHints), | |
307 terseDiagnostics: _hasOption(options, Flags.terse), | |
308 shownPackageWarnings: | |
309 _extractOptionalCsvOption(options, Flags.showPackageWarnings)), | |
310 disableInlining: _hasOption(options, Flags.disableInlining), | |
311 disableTypeInference: _hasOption(options, Flags.disableTypeInference), | |
312 dumpInfo: _hasOption(options, Flags.dumpInfo), | |
313 emitJavaScript: !(_hasOption(options, '--output-type=dart') || | |
314 _hasOption(options, '--output-type=dart-multi')), | |
315 enableAssertMessage: _hasOption(options, Flags.enableAssertMessage), | |
316 enableConditionalDirectives: | |
317 _hasOption(options, Flags.conditionalDirectives), | |
318 enableExperimentalMirrors: | |
319 _hasOption(options, Flags.enableExperimentalMirrors), | |
320 enableMinification: _hasOption(options, Flags.minify), | |
321 enableNativeLiveTypeAnalysis: | |
322 !_hasOption(options, Flags.disableNativeLiveTypeAnalysis), | |
323 enableTypeAssertions: _hasOption(options, Flags.enableCheckedMode), | |
324 enableUserAssertions: _hasOption(options, Flags.enableCheckedMode), | |
325 generateCodeWithCompileTimeErrors: | |
326 _hasOption(options, Flags.generateCodeWithCompileTimeErrors), | |
327 generateSourceMap: !_hasOption(options, Flags.noSourceMaps), | |
328 hasIncrementalSupport: _forceIncrementalSupport || | |
329 _hasOption(options, Flags.incrementalSupport), | |
330 outputUri: _extractUriOption(options, '--out='), | |
331 platformConfigUri: _resolvePlatformConfigFromOptions( | |
332 libraryRoot, options), | |
333 preserveComments: _hasOption(options, Flags.preserveComments), | |
334 preserveUris: _hasOption(options, Flags.preserveUris), | |
335 sourceMapUri: _extractUriOption(options, '--source-map='), | |
336 strips: _extractCsvOption(options, '--force-strip='), | |
337 testMode: _hasOption(options, Flags.testMode), | |
338 trustJSInteropTypeAnnotations: | |
339 _hasOption(options, Flags.trustJSInteropTypeAnnotations), | |
340 trustPrimitives: _hasOption(options, Flags.trustPrimitives), | |
341 trustTypeAnnotations: _hasOption(options, Flags.trustTypeAnnotations), | |
342 useContentSecurityPolicy: | |
343 _hasOption(options, Flags.useContentSecurityPolicy), | |
344 useCpsIr: _hasOption(options, Flags.useCpsIr), | |
345 useFrequencyNamer: | |
346 !_hasOption(options, Flags.noFrequencyBasedMinification), | |
347 useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo), | |
348 useStartupEmitter: _hasOption(options, Flags.fastStartup), | |
349 verbose: _hasOption(options, Flags.verbose)); | |
350 } | |
351 | |
352 /// Creates an option object for the compiler. | |
353 /// | |
354 /// This validates and normalizes dependent options to be consistent. For | |
355 /// example, if [analyzeAll] is true, the resulting options object will also | |
356 /// have [analyzeOnly] as true. | |
357 factory CompilerOptions( | |
358 {Uri entryPoint, | |
359 Uri libraryRoot, | |
360 Uri packageRoot, | |
361 Uri packageConfig, | |
362 PackagesDiscoveryProvider packagesDiscoveryProvider, | |
363 Map<String, dynamic> environment: const <String, dynamic>{}, | |
364 bool allowMockCompilation: false, | |
365 bool allowNativeExtensions: false, | |
366 bool analyzeAll: false, | |
367 bool analyzeMain: false, | |
368 bool analyzeOnly: false, | |
369 bool analyzeSignaturesOnly: false, | |
370 String buildId: _UNDETERMINED_BUILD_ID, | |
371 bool dart2dartMultiFile: false, | |
372 Uri deferredMapUri: null, | |
373 DiagnosticOptions diagnosticOptions: const DiagnosticOptions(), | |
374 bool disableInlining: false, | |
375 bool disableTypeInference: false, | |
376 bool dumpInfo: false, | |
377 bool emitJavaScript: true, | |
378 bool enableAssertMessage: false, | |
379 bool enableConditionalDirectives: false, | |
380 bool enableExperimentalMirrors: false, | |
381 bool enableMinification: false, | |
382 bool enableNativeLiveTypeAnalysis: true, | |
383 bool enableTypeAssertions: false, | |
384 bool enableUserAssertions: false, | |
385 bool generateCodeWithCompileTimeErrors: false, | |
386 bool generateSourceMap: true, | |
387 bool hasIncrementalSupport: false, | |
388 Uri outputUri: null, | |
389 Uri platformConfigUri: null, | |
390 bool preserveComments: false, | |
391 bool preserveUris: false, | |
392 Uri sourceMapUri: null, | |
393 List<String> strips: const [], | |
394 bool testMode: false, | |
395 bool trustJSInteropTypeAnnotations: false, | |
396 bool trustPrimitives: false, | |
397 bool trustTypeAnnotations: false, | |
398 bool useContentSecurityPolicy: false, | |
399 bool useCpsIr: false, | |
400 bool useFrequencyNamer: true, | |
401 bool useNewSourceInfo: false, | |
402 bool useStartupEmitter: false, | |
403 bool verbose: false}) { | |
404 // TODO(sigmund): should entrypoint be here? should we validate it is not | |
405 // null? In unittests we use the same compiler to analyze or build multiple | |
406 // entrypoints. | |
407 if (libraryRoot == null) { | |
408 throw new ArgumentError("[libraryRoot] is null."); | |
409 } | |
410 if (!libraryRoot.path.endsWith("/")) { | |
411 throw new ArgumentError("[libraryRoot] must end with a /"); | |
412 } | |
413 if (packageRoot != null && packageConfig != null) { | |
414 throw new ArgumentError("Only one of [packageRoot] or [packageConfig] " | |
415 "may be given."); | |
416 } | |
417 if (packageRoot != null && !packageRoot.path.endsWith("/")) { | |
418 throw new ArgumentError("[packageRoot] must end with a /"); | |
419 } | |
420 if (!analyzeOnly) { | |
421 if (allowNativeExtensions) { | |
422 throw new ArgumentError( | |
423 "${Flags.allowNativeExtensions} is only supported in combination " | |
424 "with ${Flags.analyzeOnly}"); | |
425 } | |
426 } | |
427 return new CompilerOptions._(entryPoint, libraryRoot, packageRoot, | |
428 packageConfig, packagesDiscoveryProvider, environment, | |
429 allowMockCompilation: allowMockCompilation, | |
430 allowNativeExtensions: allowNativeExtensions, | |
431 analyzeAll: analyzeAll, | |
432 analyzeMain: analyzeMain, | |
433 analyzeOnly: analyzeOnly || analyzeSignaturesOnly || analyzeAll, | |
434 analyzeSignaturesOnly: analyzeSignaturesOnly, | |
435 buildId: buildId, | |
436 dart2dartMultiFile: dart2dartMultiFile, | |
437 deferredMapUri: deferredMapUri, | |
438 diagnosticOptions: diagnosticOptions, | |
439 disableInlining: disableInlining || hasIncrementalSupport, | |
440 disableTypeInference: disableTypeInference || !emitJavaScript, | |
441 dumpInfo: dumpInfo, | |
442 emitJavaScript: emitJavaScript, | |
443 enableAssertMessage: enableAssertMessage, | |
444 enableConditionalDirectives: enableConditionalDirectives, | |
445 enableExperimentalMirrors: enableExperimentalMirrors, | |
446 enableMinification: enableMinification, | |
447 enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis, | |
448 enableTypeAssertions: enableTypeAssertions, | |
449 enableUserAssertions: enableUserAssertions, | |
450 generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors, | |
451 generateSourceMap: generateSourceMap, | |
452 hasIncrementalSupport: hasIncrementalSupport, | |
453 outputUri: outputUri, | |
454 platformConfigUri: platformConfigUri ?? _resolvePlatformConfig( | |
455 libraryRoot, null, !emitJavaScript, const []), | |
456 preserveComments: preserveComments, | |
457 preserveUris: preserveUris, | |
458 sourceMapUri: sourceMapUri, | |
459 strips: strips, | |
460 testMode: testMode, | |
461 trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations, | |
462 trustPrimitives: trustPrimitives, | |
463 trustTypeAnnotations: trustTypeAnnotations, | |
464 useContentSecurityPolicy: useContentSecurityPolicy, | |
465 useCpsIr: useCpsIr, | |
466 useFrequencyNamer: useFrequencyNamer, | |
467 useNewSourceInfo: useNewSourceInfo, | |
468 useStartupEmitter: useStartupEmitter, | |
469 verbose: verbose); | |
470 } | |
471 | |
472 CompilerOptions._(this.entryPoint, this.libraryRoot, this.packageRoot, | |
473 this.packageConfig, this.packagesDiscoveryProvider, this.environment, | |
474 {this.allowMockCompilation: false, | |
475 this.allowNativeExtensions: false, | |
476 this.analyzeAll: false, | |
477 this.analyzeMain: false, | |
478 this.analyzeOnly: false, | |
479 this.analyzeSignaturesOnly: false, | |
480 this.buildId: _UNDETERMINED_BUILD_ID, | |
481 this.dart2dartMultiFile: false, | |
482 this.deferredMapUri: null, | |
483 this.diagnosticOptions: null, | |
484 this.disableInlining: false, | |
485 this.disableTypeInference: false, | |
486 this.dumpInfo: false, | |
487 this.emitJavaScript: true, | |
488 this.enableAssertMessage: false, | |
489 this.enableConditionalDirectives: false, | |
490 this.enableExperimentalMirrors: false, | |
491 this.enableMinification: false, | |
492 this.enableNativeLiveTypeAnalysis: false, | |
493 this.enableTypeAssertions: false, | |
494 this.enableUserAssertions: false, | |
495 this.generateCodeWithCompileTimeErrors: false, | |
496 this.generateSourceMap: true, | |
497 this.hasIncrementalSupport: false, | |
498 this.outputUri: null, | |
499 this.platformConfigUri: null, | |
500 this.preserveComments: false, | |
501 this.preserveUris: false, | |
502 this.sourceMapUri: null, | |
503 this.strips: const [], | |
504 this.testMode: false, | |
505 this.trustJSInteropTypeAnnotations: false, | |
506 this.trustPrimitives: false, | |
507 this.trustTypeAnnotations: false, | |
508 this.useContentSecurityPolicy: false, | |
509 this.useCpsIr: false, | |
510 this.useFrequencyNamer: false, | |
511 this.useNewSourceInfo: false, | |
512 this.useStartupEmitter: false, | |
513 this.verbose: false}); | |
514 } | |
515 | |
516 /// Returns a future that completes to a [CompilationResult] when the Dart | 95 /// Returns a future that completes to a [CompilationResult] when the Dart |
517 /// sources in [options] have been compiled. | 96 /// sources in [options] have been compiled. |
518 /// | 97 /// |
519 /// The generated compiler output is obtained by providing a [compilerOutput]. | 98 /// The generated compiler output is obtained by providing a [compilerOutput]. |
520 /// | 99 /// |
521 /// If the compilation fails, the future's `CompilationResult.isSuccess` is | 100 /// If the compilation fails, the future's `CompilationResult.isSuccess` is |
522 /// `false` and [CompilerDiagnostics.report] on [compilerDiagnostics] | 101 /// `false` and [CompilerDiagnostics.report] on [compilerDiagnostics] |
523 /// is invoked at least once with `kind == Diagnostic.ERROR` or | 102 /// is invoked at least once with `kind == Diagnostic.ERROR` or |
524 /// `kind == Diagnostic.CRASH`. | 103 /// `kind == Diagnostic.CRASH`. |
525 Future<CompilationResult> compile( | 104 Future<CompilationResult> compile( |
(...skipping 14 matching lines...) Expand all Loading... |
540 throw new ArgumentError("compilerOutput must be non-null"); | 119 throw new ArgumentError("compilerOutput must be non-null"); |
541 } | 120 } |
542 | 121 |
543 CompilerImpl compiler = new CompilerImpl( | 122 CompilerImpl compiler = new CompilerImpl( |
544 compilerInput, compilerOutput, compilerDiagnostics, compilerOptions); | 123 compilerInput, compilerOutput, compilerDiagnostics, compilerOptions); |
545 return compiler.run(compilerOptions.entryPoint).then((bool success) { | 124 return compiler.run(compilerOptions.entryPoint).then((bool success) { |
546 return new CompilationResult(compiler, isSuccess: success); | 125 return new CompilationResult(compiler, isSuccess: success); |
547 }); | 126 }); |
548 } | 127 } |
549 | 128 |
550 String _extractStringOption( | |
551 List<String> options, String prefix, String defaultValue) { | |
552 for (String option in options) { | |
553 if (option.startsWith(prefix)) { | |
554 return option.substring(prefix.length); | |
555 } | |
556 } | |
557 return defaultValue; | |
558 } | |
559 | |
560 Uri _extractUriOption(List<String> options, String prefix) { | |
561 var option = _extractStringOption(options, prefix, null); | |
562 return (option == null) ? null : Uri.parse(option); | |
563 } | |
564 | |
565 // CSV: Comma separated values. | |
566 List<String> _extractCsvOption(List<String> options, String prefix) { | |
567 for (String option in options) { | |
568 if (option.startsWith(prefix)) { | |
569 return option.substring(prefix.length).split(','); | |
570 } | |
571 } | |
572 return const <String>[]; | |
573 } | |
574 | |
575 /// Extract list of comma separated values provided for [flag]. Returns an | |
576 /// empty list if [option] contain [flag] without arguments. Returns `null` if | |
577 /// [option] doesn't contain [flag] with or without arguments. | |
578 List<String> _extractOptionalCsvOption(List<String> options, String flag) { | |
579 String prefix = '$flag='; | |
580 for (String option in options) { | |
581 if (option == flag) { | |
582 return const <String>[]; | |
583 } | |
584 if (option.startsWith(flag)) { | |
585 return option.substring(prefix.length).split(','); | |
586 } | |
587 } | |
588 return null; | |
589 } | |
590 | |
591 Uri _resolvePlatformConfigFromOptions(Uri libraryRoot, List<String> options) { | |
592 return _resolvePlatformConfig(libraryRoot, | |
593 _extractStringOption(options, "--platform-config=", null), | |
594 _hasOption(options, '--output-type=dart'), | |
595 _extractCsvOption(options, '--categories=')); | |
596 } | |
597 | |
598 Uri _resolvePlatformConfig(Uri libraryRoot, | |
599 String platformConfigPath, bool isDart2Dart, Iterable<String> categories) { | |
600 if (platformConfigPath != null) { | |
601 return libraryRoot.resolve(platformConfigPath); | |
602 } else if (isDart2Dart) { | |
603 return libraryRoot.resolve(_dart2dartPlatform); | |
604 } else { | |
605 if (categories.length == 0) { | |
606 return libraryRoot.resolve(_clientPlatform); | |
607 } | |
608 assert(categories.length <= 2); | |
609 if (categories.contains("Client")) { | |
610 if (categories.contains("Server")) { | |
611 return libraryRoot.resolve(_sharedPlatform); | |
612 } | |
613 return libraryRoot.resolve(_clientPlatform); | |
614 } | |
615 assert(categories.contains("Server")); | |
616 return libraryRoot.resolve(_serverPlatform); | |
617 } | |
618 } | |
619 | |
620 bool _hasOption(List<String> options, String option) { | |
621 return options.indexOf(option) >= 0; | |
622 } | |
623 | |
624 /// Locations of the platform descriptor files relative to the library root. | |
625 const String _clientPlatform = "lib/dart_client.platform"; | |
626 const String _serverPlatform = "lib/dart_server.platform"; | |
627 const String _sharedPlatform = "lib/dart_shared.platform"; | |
628 const String _dart2dartPlatform = "lib/dart2dart.platform"; | |
629 | |
630 const String _UNDETERMINED_BUILD_ID = "build number could not be determined"; | |
631 const bool _forceIncrementalSupport = | |
632 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | |
OLD | NEW |