blob: ec4b54c41b3a5744f355c1a17e0e88bd4e55add4 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library dart2js.src.options;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import '../compiler.dart' show PackagesDiscoveryProvider;
import 'commandline_options.dart' show Flags;
/// Options used for controlling diagnostic messages.
abstract class DiagnosticOptions {
const DiagnosticOptions();
/// If `true`, warnings cause the compilation to fail.
bool get fatalWarnings;
/// Emit terse diagnostics without howToFix.
bool get terseDiagnostics;
/// If `true`, warnings are not reported.
bool get suppressWarnings;
/// If `true`, hints are not reported.
bool get suppressHints;
/// Returns `true` if warnings and hints are shown for all packages.
bool get showAllPackageWarnings;
/// Returns `true` if warnings and hints are hidden for all packages.
bool get hidePackageWarnings;
/// Returns `true` if warnings should be should for [uri].
bool showPackageWarningsFor(Uri uri);
}
/// Object for passing options to the compiler. Superclasses are used to select
/// subsets of these options, enabling each part of the compiler to depend on
/// as few as possible.
class CompilerOptions implements DiagnosticOptions {
/// The entry point of the application that is being compiled.
final Uri entryPoint;
/// Root location where SDK libraries are found.
final Uri libraryRoot;
/// Package root location.
///
/// If not null then [packageConfig] should be null.
final Uri packageRoot;
/// Location of the package configuration file.
///
/// If not null then [packageRoot] should be null.
final Uri packageConfig;
// TODO(sigmund): Move out of here, maybe to CompilerInput. Options should not
// hold code, just configuration options.
final PackagesDiscoveryProvider packagesDiscoveryProvider;
/// Resolved constant "environment" values passed to the compiler via the `-D`
/// flags.
final Map<String, dynamic> environment;
/// A possibly null state object for kernel compilation.
fe.InitializedCompilerState kernelInitializedCompilerState;
/// Whether we allow mocking compilation of libraries such as dart:io and
/// dart:html for unit testing purposes.
final bool allowMockCompilation;
/// Whether the native extension syntax is supported by the frontend.
final bool allowNativeExtensions;
/// Whether to resolve all functions in the program, not just those reachable
/// from main. This implies [analyzeOnly] is true as well.
final bool analyzeAll;
/// Whether to disable tree-shaking for the main script. This marks all
/// functions in the main script as reachable (not just a function named
/// `main`).
// TODO(sigmund): rename. The current name seems to indicate that only the
// main function is retained, which is the opposite of what this does.
final bool analyzeMain;
/// Whether to run the compiler just for the purpose of analysis. That is, to
/// run resolution and type-checking alone, but otherwise do not generate any
/// code.
final bool analyzeOnly;
/// Whether to skip analysis of method bodies and field initializers. Implies
/// [analyzeOnly].
final bool analyzeSignaturesOnly;
/// ID associated with this sdk build.
final String buildId;
/// Whether there is a build-id available so we can use it on error messages
/// and in the emitted output of the compiler.
bool get hasBuildId => buildId != _UNDETERMINED_BUILD_ID;
/// Location where to generate a map containing details of how deferred
/// libraries are subdivided.
final Uri deferredMapUri;
/// Whether to disable inlining during the backend optimizations.
// TODO(sigmund): negate, so all flags are positive
final bool disableInlining;
/// Disable deferred loading, instead generate everything in one output unit.
/// Note: the resulting program still correctly checks that loadLibrary &
/// checkLibrary calls are correct.
final bool disableProgramSplit;
/// Diagnostic option: If `true`, warnings cause the compilation to fail.
final bool fatalWarnings;
/// Diagnostic option: Emit terse diagnostics without howToFix.
final bool terseDiagnostics;
/// Diagnostic option: If `true`, warnings are not reported.
final bool suppressWarnings;
/// Diagnostic option: If `true`, hints are not reported.
final bool suppressHints;
/// Diagnostic option: List of packages for which warnings and hints are
/// reported. If `null`, no package warnings or hints are reported. If
/// empty, all warnings and hints are reported.
final List<String> _shownPackageWarnings;
/// Whether to disable global type inference.
final bool disableTypeInference;
/// Whether to disable optimization for need runtime type information.
final bool disableRtiOptimization;
/// Whether to emit a .json file with a summary of the information used by the
/// compiler during optimization. This includes resolution details,
/// dependencies between elements, results of type inference, and the output
/// code for each function.
final bool dumpInfo;
/// Whether we allow passing an extra argument to `assert`, containing a
/// reason for why an assertion fails. (experimental)
///
/// This is only included so that tests can pass the --assert-message flag
/// without causing dart2js to crash. The flag has no effect.
final bool enableAssertMessage;
/// Whether the user specified a flag to allow the use of dart:mirrors. This
/// silences a warning produced by the compiler.
final bool enableExperimentalMirrors;
/// Whether to enable minification
// TODO(sigmund): rename to minify
final bool enableMinification;
/// Whether to model which native classes are live based on annotations on the
/// core libraries. If false, all native classes will be included by default.
final bool enableNativeLiveTypeAnalysis;
/// Whether to generate code containing checked-mode assignability checks.
final bool enableTypeAssertions;
/// Whether to generate code containing user's `assert` statements.
final bool enableUserAssertions;
/// Whether to generate output even when there are compile-time errors.
final bool generateCodeWithCompileTimeErrors;
/// Whether to generate a source-map file together with the output program.
final bool generateSourceMap;
/// URI of the main output if the compiler is generating source maps.
final Uri outputUri;
/// Location of the platform configuration file.
final Uri platformConfigUri;
/// Location of the kernel platform `.dill` files.
final Uri platformBinaries;
/// Whether to emit URIs in the reflection metadata.
final bool preserveUris;
/// The locations of serialized data used for resolution.
final List<Uri> resolutionInputs;
/// The location of the serialized data from resolution.
final Uri resolutionOutput;
/// If `true`, sources are resolved and serialized.
final bool resolveOnly;
/// If `true`, sources are only available from serialized data.
final bool compileOnly;
/// URI where the compiler should generate the output source map file.
final Uri sourceMapUri;
/// The compiler is run from the build bot.
final bool testMode;
/// Whether to trust JS-interop annotations. (experimental)
final bool trustJSInteropTypeAnnotations;
/// Whether to trust primitive types during inference and optimizations.
final bool trustPrimitives;
/// Whether to trust type annotations during inference and optimizations.
final bool trustTypeAnnotations;
/// Whether to generate code compliant with content security policy (CSP).
final bool useContentSecurityPolicy;
/// Preview the unified front-end and compilation from kernel.
///
/// When enabled the compiler will use the unified front-end to compile
/// sources to kernel, and then continue compilation from the kernel
/// representation.
///
/// When this flag is on, the compiler also accepts reading .dill files from
/// disk. The compiler reads the sources differently depending on the
/// extension format.
final bool useKernel;
/// Enables strong mode in dart2js.
///
/// This is work-in-progress and will only be supported for [useKernel].
final bool strongMode;
/// When obfuscating for minification, whether to use the frequency of a name
/// as an heuristic to pick shorter names.
final bool useFrequencyNamer;
/// Whether to generate source-information from both the old and the new
/// source-information engines. (experimental)
final bool useMultiSourceInfo;
/// Whether to use the new source-information implementation for source-maps.
/// (experimental)
final bool useNewSourceInfo;
/// Whether the user requested to use the fast startup emitter. The full
/// emitter might still be used if the program uses dart:mirrors.
final bool useStartupEmitter;
/// Enable verbose printing during compilation. Includes progress messages
/// during each phase and a time-breakdown between phases at the end.
final bool verbose;
/// Track allocations in the JS output.
///
/// This is an experimental feature.
final bool experimentalTrackAllocations;
/// The path to the file that contains the profiled allocations.
///
/// The file must contain the Map that was produced by using
/// [experimentalTrackAllocations] encoded as a JSON map.
///
/// This is an experimental feature.
final String experimentalAllocationsPath;
// -------------------------------------------------
// Options for deprecated features
// -------------------------------------------------
// TODO(sigmund): delete these as we delete the underlying features
/// Whether to preserve comments while scanning (only use for dart:mirrors).
final bool preserveComments;
/// Strip option used by dart2dart.
final List<String> strips;
/// Whether to start `async` functions synchronously.
final bool startAsyncSynchronously;
/// Create an options object by parsing flags from [options].
factory CompilerOptions.parse(
{Uri entryPoint,
Uri libraryRoot,
Uri packageRoot,
Uri packageConfig,
Uri platformBinaries,
List<Uri> resolutionInputs,
Uri resolutionOutput,
PackagesDiscoveryProvider packagesDiscoveryProvider,
Map<String, dynamic> environment: const <String, dynamic>{},
List<String> options}) {
return new CompilerOptions(
entryPoint: entryPoint,
libraryRoot: libraryRoot,
packageRoot: packageRoot,
packageConfig: packageConfig,
packagesDiscoveryProvider: packagesDiscoveryProvider,
environment: environment,
allowMockCompilation: _hasOption(options, Flags.allowMockCompilation),
allowNativeExtensions: _hasOption(options, Flags.allowNativeExtensions),
analyzeAll: _hasOption(options, Flags.analyzeAll),
analyzeMain: _hasOption(options, Flags.analyzeMain),
analyzeOnly: _hasOption(options, Flags.analyzeOnly),
analyzeSignaturesOnly: _hasOption(options, Flags.analyzeSignaturesOnly),
buildId: _extractStringOption(
options, '--build-id=', _UNDETERMINED_BUILD_ID),
deferredMapUri: _extractUriOption(options, '--deferred-map='),
fatalWarnings: _hasOption(options, Flags.fatalWarnings),
terseDiagnostics: _hasOption(options, Flags.terse),
suppressWarnings: _hasOption(options, Flags.suppressWarnings),
suppressHints: _hasOption(options, Flags.suppressHints),
shownPackageWarnings:
_extractOptionalCsvOption(options, Flags.showPackageWarnings),
disableInlining: _hasOption(options, Flags.disableInlining),
disableProgramSplit: _hasOption(options, Flags.disableProgramSplit),
disableTypeInference: _hasOption(options, Flags.disableTypeInference),
disableRtiOptimization:
_hasOption(options, Flags.disableRtiOptimization),
dumpInfo: _hasOption(options, Flags.dumpInfo),
enableExperimentalMirrors:
_hasOption(options, Flags.enableExperimentalMirrors),
enableMinification: _hasOption(options, Flags.minify),
enableNativeLiveTypeAnalysis:
!_hasOption(options, Flags.disableNativeLiveTypeAnalysis),
enableTypeAssertions: _hasOption(options, Flags.enableCheckedMode),
enableUserAssertions: _hasOption(options, Flags.enableCheckedMode) ||
_hasOption(options, Flags.enableAsserts),
experimentalTrackAllocations:
_hasOption(options, Flags.experimentalTrackAllocations),
experimentalAllocationsPath: _extractStringOption(
options, "${Flags.experimentalAllocationsPath}=", null),
generateCodeWithCompileTimeErrors:
_hasOption(options, Flags.generateCodeWithCompileTimeErrors),
generateSourceMap: !_hasOption(options, Flags.noSourceMaps),
outputUri: _extractUriOption(options, '--out='),
platformConfigUri:
_resolvePlatformConfigFromOptions(libraryRoot, options),
platformBinaries: platformBinaries ??
_extractUriOption(options, '--platform-binaries='),
preserveComments: _hasOption(options, Flags.preserveComments),
preserveUris: _hasOption(options, Flags.preserveUris),
resolutionInputs: resolutionInputs,
resolutionOutput: resolutionOutput,
resolveOnly: _hasOption(options, Flags.resolveOnly),
sourceMapUri: _extractUriOption(options, '--source-map='),
strips: _extractCsvOption(options, '--force-strip='),
strongMode: _hasOption(options, Flags.strongMode),
testMode: _hasOption(options, Flags.testMode),
trustJSInteropTypeAnnotations:
_hasOption(options, Flags.trustJSInteropTypeAnnotations),
trustPrimitives: _hasOption(options, Flags.trustPrimitives),
trustTypeAnnotations: _hasOption(options, Flags.trustTypeAnnotations),
useContentSecurityPolicy:
_hasOption(options, Flags.useContentSecurityPolicy),
useKernel: !_hasOption(options, Flags.useOldFrontend),
useFrequencyNamer:
!_hasOption(options, Flags.noFrequencyBasedMinification),
useMultiSourceInfo: _hasOption(options, Flags.useMultiSourceInfo),
useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo),
useStartupEmitter: _hasOption(options, Flags.fastStartup),
startAsyncSynchronously: _hasOption(options, Flags.syncAsync),
verbose: _hasOption(options, Flags.verbose));
}
/// Creates an option object for the compiler.
///
/// This validates and normalizes dependent options to be consistent. For
/// example, if [analyzeAll] is true, the resulting options object will also
/// have [analyzeOnly] as true.
factory CompilerOptions(
{Uri entryPoint,
Uri libraryRoot,
Uri packageRoot,
Uri packageConfig,
PackagesDiscoveryProvider packagesDiscoveryProvider,
Map<String, dynamic> environment: const <String, dynamic>{},
bool allowMockCompilation: false,
bool allowNativeExtensions: false,
bool analyzeAll: false,
bool analyzeMain: false,
bool analyzeOnly: false,
bool analyzeSignaturesOnly: false,
String buildId: _UNDETERMINED_BUILD_ID,
Uri deferredMapUri: null,
bool fatalWarnings: false,
bool terseDiagnostics: false,
bool suppressWarnings: false,
bool suppressHints: false,
List<String> shownPackageWarnings: null,
bool disableInlining: false,
bool disableProgramSplit: false,
bool disableTypeInference: false,
bool disableRtiOptimization: false,
bool dumpInfo: false,
bool enableAssertMessage: true,
bool enableExperimentalMirrors: false,
bool enableMinification: false,
bool enableNativeLiveTypeAnalysis: true,
bool enableTypeAssertions: false,
bool enableUserAssertions: false,
bool experimentalTrackAllocations: false,
String experimentalAllocationsPath: null,
bool generateCodeWithCompileTimeErrors: false,
bool generateSourceMap: true,
bool kernelGlobalInference: false,
Uri outputUri: null,
Uri platformConfigUri: null,
Uri platformBinaries: null,
bool preserveComments: false,
bool preserveUris: false,
List<Uri> resolutionInputs: null,
Uri resolutionOutput: null,
bool resolveOnly: false,
Uri sourceMapUri: null,
List<String> strips: const [],
bool strongMode: false,
bool testMode: false,
bool trustJSInteropTypeAnnotations: false,
bool trustPrimitives: false,
bool trustTypeAnnotations: false,
bool useContentSecurityPolicy: false,
bool useKernel: true,
bool useFrequencyNamer: true,
bool useMultiSourceInfo: false,
bool useNewSourceInfo: false,
bool useStartupEmitter: false,
bool startAsyncSynchronously: false,
bool verbose: false}) {
// TODO(sigmund): should entrypoint be here? should we validate it is not
// null? In unittests we use the same compiler to analyze or build multiple
// entrypoints.
if (libraryRoot == null) {
throw new ArgumentError("[libraryRoot] is null.");
}
if (!libraryRoot.path.endsWith("/")) {
throw new ArgumentError("[libraryRoot] must end with a /");
}
if (packageRoot != null && packageConfig != null) {
throw new ArgumentError("Only one of [packageRoot] or [packageConfig] "
"may be given.");
}
if (packageRoot != null && !packageRoot.path.endsWith("/")) {
throw new ArgumentError("[packageRoot] must end with a /");
}
if (!analyzeOnly) {
if (allowNativeExtensions) {
throw new ArgumentError(
"${Flags.allowNativeExtensions} is only supported in combination "
"with ${Flags.analyzeOnly}");
}
}
if (useKernel && platformBinaries == null) {
throw new ArgumentError("Missing required ${Flags.platformBinaries}");
}
return new CompilerOptions._(entryPoint, libraryRoot, packageRoot,
packageConfig, packagesDiscoveryProvider, environment,
allowMockCompilation: allowMockCompilation,
allowNativeExtensions: allowNativeExtensions,
analyzeAll: analyzeAll || resolveOnly,
analyzeMain: analyzeMain,
analyzeOnly:
analyzeOnly || analyzeSignaturesOnly || analyzeAll || resolveOnly,
analyzeSignaturesOnly: analyzeSignaturesOnly,
buildId: buildId,
deferredMapUri: deferredMapUri,
fatalWarnings: fatalWarnings,
terseDiagnostics: terseDiagnostics,
suppressWarnings: suppressWarnings,
suppressHints: suppressHints,
shownPackageWarnings: shownPackageWarnings,
disableInlining: disableInlining,
disableProgramSplit: disableProgramSplit,
disableTypeInference: disableTypeInference,
disableRtiOptimization: disableRtiOptimization,
dumpInfo: dumpInfo,
enableAssertMessage: enableAssertMessage,
enableExperimentalMirrors: enableExperimentalMirrors,
enableMinification: enableMinification,
enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
enableTypeAssertions: enableTypeAssertions,
enableUserAssertions: enableUserAssertions,
experimentalTrackAllocations: experimentalTrackAllocations,
experimentalAllocationsPath: experimentalAllocationsPath,
generateCodeWithCompileTimeErrors:
generateCodeWithCompileTimeErrors && !useKernel,
generateSourceMap: generateSourceMap,
outputUri: outputUri,
platformConfigUri: platformConfigUri ??
_resolvePlatformConfig(libraryRoot, null, const []),
platformBinaries: platformBinaries,
preserveComments: preserveComments,
preserveUris: preserveUris,
resolutionInputs: resolutionInputs,
resolutionOutput: resolutionOutput,
resolveOnly: resolveOnly,
sourceMapUri: sourceMapUri,
strips: strips,
strongMode: strongMode,
testMode: testMode,
trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
trustPrimitives: trustPrimitives,
trustTypeAnnotations: trustTypeAnnotations,
useContentSecurityPolicy: useContentSecurityPolicy,
useKernel: useKernel,
useFrequencyNamer: useFrequencyNamer,
useMultiSourceInfo: useMultiSourceInfo,
useNewSourceInfo: useNewSourceInfo,
useStartupEmitter: useStartupEmitter,
startAsyncSynchronously: startAsyncSynchronously,
verbose: verbose);
}
CompilerOptions._(this.entryPoint, this.libraryRoot, this.packageRoot,
this.packageConfig, this.packagesDiscoveryProvider, this.environment,
{this.allowMockCompilation: false,
this.allowNativeExtensions: false,
this.analyzeAll: false,
this.analyzeMain: false,
this.analyzeOnly: false,
this.analyzeSignaturesOnly: false,
this.buildId: _UNDETERMINED_BUILD_ID,
this.deferredMapUri: null,
this.fatalWarnings: false,
this.terseDiagnostics: false,
this.suppressWarnings: false,
this.suppressHints: false,
List<String> shownPackageWarnings: null,
this.disableInlining: false,
this.disableProgramSplit: false,
this.disableTypeInference: false,
this.disableRtiOptimization: false,
this.dumpInfo: false,
this.enableAssertMessage: true,
this.enableExperimentalMirrors: false,
this.enableMinification: false,
this.enableNativeLiveTypeAnalysis: false,
this.enableTypeAssertions: false,
this.enableUserAssertions: false,
this.experimentalTrackAllocations: false,
this.experimentalAllocationsPath: null,
this.generateCodeWithCompileTimeErrors: false,
this.generateSourceMap: true,
this.outputUri: null,
this.platformConfigUri: null,
this.platformBinaries: null,
this.preserveComments: false,
this.preserveUris: false,
this.resolutionInputs: null,
this.resolutionOutput: null,
this.resolveOnly: false,
this.compileOnly: false,
this.sourceMapUri: null,
this.strips: const [],
this.strongMode: false,
this.testMode: false,
this.trustJSInteropTypeAnnotations: false,
this.trustPrimitives: false,
this.trustTypeAnnotations: false,
this.useContentSecurityPolicy: false,
this.useKernel: true,
this.useFrequencyNamer: false,
this.useMultiSourceInfo: false,
this.useNewSourceInfo: false,
this.useStartupEmitter: false,
this.startAsyncSynchronously: false,
this.verbose: false})
: _shownPackageWarnings = shownPackageWarnings;
/// Creates a copy of the [CompilerOptions] where the provided non-null
/// option values replace existing.
static CompilerOptions copy(CompilerOptions options,
{entryPoint,
libraryRoot,
packageRoot,
packageConfig,
packagesDiscoveryProvider,
environment,
allowMockCompilation,
allowNativeExtensions,
analyzeAll,
analyzeMain,
analyzeOnly,
analyzeSignaturesOnly,
buildId,
deferredMapUri,
fatalWarnings,
terseDiagnostics,
suppressWarnings,
suppressHints,
List<String> shownPackageWarnings,
disableInlining,
disableProgramSplit,
disableTypeInference,
disableRtiOptimization,
dumpInfo,
enableAssertMessage,
enableExperimentalMirrors,
enableMinification,
enableNativeLiveTypeAnalysis,
enableTypeAssertions,
enableUserAssertions,
experimentalTrackAllocations,
experimentalAllocationsPath,
generateCodeWithCompileTimeErrors,
generateSourceMap,
kernelGlobalInference,
outputUri,
platformConfigUri,
platformBinaries,
preserveComments,
preserveUris,
resolutionInputs,
resolutionOutput,
resolveOnly,
compileOnly,
sourceMapUri,
strips,
strongMode,
testMode,
trustJSInteropTypeAnnotations,
trustPrimitives,
trustTypeAnnotations,
useContentSecurityPolicy,
useKernel,
useFrequencyNamer,
useMultiSourceInfo,
useNewSourceInfo,
useStartupEmitter,
verbose}) {
return new CompilerOptions._(
entryPoint ?? options.entryPoint,
libraryRoot ?? options.libraryRoot,
packageRoot ?? options.packageRoot,
packageConfig ?? options.packageConfig,
packagesDiscoveryProvider ?? options.packagesDiscoveryProvider,
environment ?? options.environment,
allowMockCompilation:
allowMockCompilation ?? options.allowMockCompilation,
allowNativeExtensions:
allowNativeExtensions ?? options.allowNativeExtensions,
analyzeAll: analyzeAll ?? options.analyzeAll,
analyzeMain: analyzeMain ?? options.analyzeMain,
analyzeOnly: analyzeOnly ?? options.analyzeOnly,
analyzeSignaturesOnly:
analyzeSignaturesOnly ?? options.analyzeSignaturesOnly,
buildId: buildId ?? options.buildId,
deferredMapUri: deferredMapUri ?? options.deferredMapUri,
fatalWarnings: fatalWarnings ?? options.fatalWarnings,
terseDiagnostics: terseDiagnostics ?? options.terseDiagnostics,
suppressWarnings: suppressWarnings ?? options.suppressWarnings,
suppressHints: suppressHints ?? options.suppressHints,
shownPackageWarnings:
shownPackageWarnings ?? options._shownPackageWarnings,
disableInlining: disableInlining ?? options.disableInlining,
disableProgramSplit: disableProgramSplit ?? options.disableProgramSplit,
disableTypeInference:
disableTypeInference ?? options.disableTypeInference,
disableRtiOptimization:
disableRtiOptimization ?? options.disableRtiOptimization,
dumpInfo: dumpInfo ?? options.dumpInfo,
enableAssertMessage: enableAssertMessage ?? options.enableAssertMessage,
enableExperimentalMirrors:
enableExperimentalMirrors ?? options.enableExperimentalMirrors,
enableMinification: enableMinification ?? options.enableMinification,
enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis ??
options.enableNativeLiveTypeAnalysis,
enableTypeAssertions:
enableTypeAssertions ?? options.enableTypeAssertions,
enableUserAssertions:
enableUserAssertions ?? options.enableUserAssertions,
experimentalTrackAllocations: experimentalTrackAllocations ??
options.experimentalTrackAllocations,
experimentalAllocationsPath:
experimentalAllocationsPath ?? options.experimentalAllocationsPath,
generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors ??
options.generateCodeWithCompileTimeErrors,
generateSourceMap: generateSourceMap ?? options.generateSourceMap,
outputUri: outputUri ?? options.outputUri,
platformConfigUri: platformConfigUri ?? options.platformConfigUri,
platformBinaries: platformBinaries ?? options.platformBinaries,
preserveComments: preserveComments ?? options.preserveComments,
preserveUris: preserveUris ?? options.preserveUris,
resolutionInputs: resolutionInputs ?? options.resolutionInputs,
resolutionOutput: resolutionOutput ?? options.resolutionOutput,
resolveOnly: resolveOnly ?? options.resolveOnly,
compileOnly: compileOnly ?? options.compileOnly,
sourceMapUri: sourceMapUri ?? options.sourceMapUri,
strips: strips ?? options.strips,
strongMode: strongMode ?? options.strongMode,
testMode: testMode ?? options.testMode,
trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations ??
options.trustJSInteropTypeAnnotations,
trustPrimitives: trustPrimitives ?? options.trustPrimitives,
trustTypeAnnotations:
trustTypeAnnotations ?? options.trustTypeAnnotations,
useContentSecurityPolicy:
useContentSecurityPolicy ?? options.useContentSecurityPolicy,
useKernel: useKernel ?? options.useKernel,
useFrequencyNamer: useFrequencyNamer ?? options.useFrequencyNamer,
useMultiSourceInfo: useMultiSourceInfo ?? options.useMultiSourceInfo,
useNewSourceInfo: useNewSourceInfo ?? options.useNewSourceInfo,
useStartupEmitter: useStartupEmitter ?? options.useStartupEmitter,
verbose: verbose ?? options.verbose);
}
/// Returns `true` if warnings and hints are shown for all packages.
bool get showAllPackageWarnings {
return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
}
/// Returns `true` if warnings and hints are hidden for all packages.
bool get hidePackageWarnings => _shownPackageWarnings == null;
/// Returns `true` if warnings should be should for [uri].
bool showPackageWarningsFor(Uri uri) {
if (showAllPackageWarnings) {
return true;
}
if (_shownPackageWarnings != null) {
return uri.scheme == 'package' &&
_shownPackageWarnings.contains(uri.pathSegments.first);
}
return false;
}
}
String _extractStringOption(
List<String> options, String prefix, String defaultValue) {
for (String option in options) {
if (option.startsWith(prefix)) {
return option.substring(prefix.length);
}
}
return defaultValue;
}
Uri _extractUriOption(List<String> options, String prefix) {
var option = _extractStringOption(options, prefix, null);
return (option == null) ? null : Uri.parse(option);
}
// CSV: Comma separated values.
List<String> _extractCsvOption(List<String> options, String prefix) {
for (String option in options) {
if (option.startsWith(prefix)) {
return option.substring(prefix.length).split(',');
}
}
return const <String>[];
}
bool _hasOption(List<String> options, String option) {
return options.indexOf(option) >= 0;
}
/// Extract list of comma separated values provided for [flag]. Returns an
/// empty list if [option] contain [flag] without arguments. Returns `null` if
/// [option] doesn't contain [flag] with or without arguments.
List<String> _extractOptionalCsvOption(List<String> options, String flag) {
String prefix = '$flag=';
for (String option in options) {
if (option == flag) {
return const <String>[];
}
if (option.startsWith(flag)) {
return option.substring(prefix.length).split(',');
}
}
return null;
}
Uri _resolvePlatformConfig(
Uri libraryRoot, String platformConfigPath, Iterable<String> categories) {
if (platformConfigPath != null) {
return libraryRoot.resolve(platformConfigPath);
} else {
if (categories.length == 0) {
return libraryRoot.resolve(_clientPlatform);
}
assert(categories.length <= 2);
if (categories.contains("Client")) {
if (categories.contains("Server")) {
return libraryRoot.resolve(_sharedPlatform);
}
return libraryRoot.resolve(_clientPlatform);
}
assert(categories.contains("Server"));
return libraryRoot.resolve(_serverPlatform);
}
}
Uri _resolvePlatformConfigFromOptions(Uri libraryRoot, List<String> options) {
return _resolvePlatformConfig(
libraryRoot,
_extractStringOption(options, "--platform-config=", null),
_extractCsvOption(options, '--categories='));
}
/// Locations of the platform descriptor files relative to the library root.
const String _clientPlatform = "lib/dart_client.platform";
const String _serverPlatform = "lib/dart_server.platform";
const String _sharedPlatform = "lib/dart_shared.platform";
const String _UNDETERMINED_BUILD_ID = "build number could not be determined";