| Index: pkg/analyzer/lib/src/command_line/arguments.dart
|
| diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..147ade7b300d9608be90d0bed7dad97f18752b05
|
| --- /dev/null
|
| +++ b/pkg/analyzer/lib/src/command_line/arguments.dart
|
| @@ -0,0 +1,256 @@
|
| +// 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 analyzer.src.command_line.arguments;
|
| +
|
| +import 'dart:collection';
|
| +
|
| +import 'package:analyzer/file_system/file_system.dart';
|
| +import 'package:analyzer/src/context/builder.dart';
|
| +import 'package:analyzer/src/dart/sdk/sdk.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/sdk.dart';
|
| +import 'package:args/args.dart';
|
| +import 'package:path/path.dart';
|
| +
|
| +const String analysisOptionsFileOption = 'options';
|
| +const String defineVariableOption = 'D';
|
| +const String enableInitializingFormalAccessFlag = 'initializing-formal-access';
|
| +const String enableStrictCallChecksFlag = 'enable-strict-call-checks';
|
| +const String enableSuperInMixinFlag = 'supermixin';
|
| +const String ignoreUnrecognizedFlagsFlag = 'ignore_unrecognized_flags';
|
| +const String noImplicitCastsFlag = 'no-implicit-casts';
|
| +const String noImplicitDynamicFlag = 'no-implicit-dynamic';
|
| +const String packageRootOption = 'package-root';
|
| +const String packagesOption = 'packages';
|
| +const String sdkPathOption = 'dart-sdk';
|
| +const String sdkSummaryPathOption = 'dart-sdk-summary';
|
| +const String strongModeFlag = 'strong';
|
| +
|
| +/**
|
| + * Use the given [resourceProvider], [contentCache] and command-line [args] to
|
| + * create a context builder.
|
| + */
|
| +ContextBuilderOptions createContextBuilderOptions(ArgResults args) {
|
| + ContextBuilderOptions builderOptions = new ContextBuilderOptions();
|
| + //
|
| + // File locations.
|
| + //
|
| + builderOptions.dartSdkSummaryPath = args[sdkSummaryPathOption];
|
| + builderOptions.defaultAnalysisOptionsFilePath =
|
| + args[analysisOptionsFileOption];
|
| + builderOptions.defaultPackageFilePath = args[packagesOption];
|
| + builderOptions.defaultPackagesDirectoryPath = args[packageRootOption];
|
| + //
|
| + // Analysis options.
|
| + //
|
| + AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
|
| + defaultOptions.enableInitializingFormalAccess =
|
| + args[enableInitializingFormalAccessFlag];
|
| + defaultOptions.enableStrictCallChecks = args[enableStrictCallChecksFlag];
|
| + defaultOptions.enableSuperMixins = args[enableSuperInMixinFlag];
|
| + defaultOptions.implicitCasts = !args[noImplicitCastsFlag];
|
| + defaultOptions.implicitDynamic = !args[noImplicitDynamicFlag];
|
| + defaultOptions.strongMode = args[strongModeFlag];
|
| + builderOptions.defaultOptions = defaultOptions;
|
| + //
|
| + // Declared variables.
|
| + //
|
| + Map<String, String> declaredVariables = <String, String>{};
|
| + List<String> variables = args[defineVariableOption] as List<String>;
|
| + for (String variable in variables) {
|
| + int index = variable.indexOf('=');
|
| + if (index < 0) {
|
| + // TODO (brianwilkerson) Decide the semantics we want in this case.
|
| + // The VM prints "No value given to -D option", then tries to load '-Dfoo'
|
| + // as a file and dies. Unless there was nothing after the '-D', in which
|
| + // case it prints the warning and ignores the option.
|
| + } else {
|
| + String name = variable.substring(0, index);
|
| + if (name.isNotEmpty) {
|
| + // TODO (brianwilkerson) Decide the semantics we want in the case where
|
| + // there is no name. If there is no name, the VM tries to load a file
|
| + // named '-D' and dies.
|
| + declaredVariables[name] = variable.substring(index + 1);
|
| + }
|
| + }
|
| + }
|
| + builderOptions.declaredVariables = declaredVariables;
|
| +
|
| + return builderOptions;
|
| +}
|
| +
|
| +/**
|
| + * Use the given [resourceProvider] and command-line [args] to create a Dart SDK
|
| + * manager. The manager will use summary information if [useSummaries] is `true`
|
| + * and if the summary information exists.
|
| + */
|
| +DartSdkManager createDartSdkManager(
|
| + ResourceProvider resourceProvider, bool useSummaries, ArgResults args) {
|
| + String sdkPath = args[sdkPathOption];
|
| +
|
| + bool canUseSummaries = useSummaries &&
|
| + args.rest.every((String sourcePath) {
|
| + sourcePath = context.absolute(sourcePath);
|
| + sourcePath = context.normalize(sourcePath);
|
| + return !context.isWithin(sdkPath, sourcePath);
|
| + });
|
| + return new DartSdkManager(
|
| + sdkPath ?? FolderBasedDartSdk.defaultSdkDirectory(resourceProvider),
|
| + canUseSummaries);
|
| +}
|
| +
|
| +/**
|
| + * Add the standard flags and options to the given [parser]. The standard flags
|
| + * are those that are typically used to control the way in which the code is
|
| + * analyzed.
|
| + */
|
| +void defineAnalysisArguments(ArgParser parser) {
|
| + parser.addOption(defineVariableOption,
|
| + abbr: 'D',
|
| + allowMultiple: true,
|
| + help: 'Define environment variables. For example, "-Dfoo=bar" defines an '
|
| + 'environment variable named "foo" whose value is "bar".');
|
| + parser.addOption(sdkPathOption, help: 'The path to the Dart SDK.');
|
| + parser.addOption(sdkSummaryPathOption,
|
| + help: 'The path to the Dart SDK summary file.', hide: true);
|
| + parser.addOption(analysisOptionsFileOption,
|
| + help: 'Path to an analysis options file.');
|
| + parser.addOption(packagesOption,
|
| + help: 'The path to the package resolution configuration file, which '
|
| + 'supplies a mapping of package names to paths. This option cannot be '
|
| + 'used with --package-root.');
|
| + parser.addOption(packageRootOption,
|
| + abbr: 'p',
|
| + help: 'The path to a package root directory (deprecated). This option '
|
| + 'cannot be used with --packages.');
|
| +
|
| + parser.addFlag(strongModeFlag,
|
| + help: 'Enable strong static checks (https://goo.gl/DqcBsw)');
|
| + parser.addFlag(noImplicitCastsFlag,
|
| + negatable: false,
|
| + help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40)');
|
| + parser.addFlag(noImplicitDynamicFlag,
|
| + negatable: false,
|
| + help: 'Disable implicit dynamic (https://goo.gl/m0UgXD)');
|
| + //
|
| + // Hidden flags and options.
|
| + //
|
| +// parser.addFlag(enableNullAwareOperatorsFlag, // 'enable-null-aware-operators'
|
| +// help: 'Enable support for null-aware operators (DEP 9).',
|
| +// defaultsTo: false,
|
| +// negatable: false,
|
| +// hide: true);
|
| + parser.addFlag(enableStrictCallChecksFlag,
|
| + help: 'Fix issue 21938.',
|
| + defaultsTo: false,
|
| + negatable: false,
|
| + hide: true);
|
| + parser.addFlag(enableInitializingFormalAccessFlag,
|
| + help:
|
| + 'Enable support for allowing access to field formal parameters in a '
|
| + 'constructor\'s initializer list',
|
| + defaultsTo: false,
|
| + negatable: false,
|
| + hide: true);
|
| + parser.addFlag(enableSuperInMixinFlag,
|
| + help: 'Relax restrictions on mixins (DEP 34).',
|
| + defaultsTo: false,
|
| + negatable: false,
|
| + hide: true);
|
| +// parser.addFlag('enable_type_checks',
|
| +// help: 'Check types in constant evaluation.',
|
| +// defaultsTo: false,
|
| +// negatable: false,
|
| +// hide: true);
|
| +}
|
| +
|
| +/**
|
| + * Return a list of command-line arguments containing all of the given [args]
|
| + * that are defined by the given [parser]. An argument is considered to be
|
| + * defined by the parser if
|
| + * - it starts with '--' and the rest of the argument (minus any value
|
| + * introduced by '=') is the name of a known option,
|
| + * - it starts with '-' and the rest of the argument (minus any value
|
| + * introduced by '=') is the name of a known abbreviation, or
|
| + * - it starts with something other than '--' or '-'.
|
| + *
|
| + * This function allows command-line tools to implement the
|
| + * '--ignore_unrecognized_flags' option.
|
| + */
|
| +List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
|
| + Set<String> knownOptions = new HashSet<String>();
|
| + Set<String> knownAbbreviations = new HashSet<String>();
|
| + parser.options.forEach((String name, Option option) {
|
| + knownOptions.add(name);
|
| + String abbreviation = option.abbreviation;
|
| + if (abbreviation != null) {
|
| + knownAbbreviations.add(abbreviation);
|
| + }
|
| + });
|
| + String optionName(int prefixLength, String argument) {
|
| + int equalsOffset = argument.lastIndexOf('=');
|
| + if (equalsOffset < 0) {
|
| + return argument.substring(prefixLength);
|
| + }
|
| + return argument.substring(prefixLength, equalsOffset);
|
| + }
|
| +
|
| + List<String> filtered = <String>[];
|
| + for (int i = 0; i < args.length; i++) {
|
| + String argument = args[i];
|
| + if (argument.startsWith('--') && argument.length > 2) {
|
| + if (knownOptions.contains(optionName(2, argument))) {
|
| + filtered.add(argument);
|
| + }
|
| + } else if (argument.startsWith('-') && argument.length > 1) {
|
| + if (knownAbbreviations.contains(optionName(1, argument))) {
|
| + filtered.add(argument);
|
| + }
|
| + } else {
|
| + filtered.add(argument);
|
| + }
|
| + }
|
| + return filtered;
|
| +}
|
| +
|
| +/**
|
| + * Use the given [parser] to parse the given command-line [args], and return the
|
| + * result.
|
| + */
|
| +ArgResults parse(
|
| + ResourceProvider provider, ArgParser parser, List<String> args) {
|
| + args = preprocessArgs(provider, args);
|
| + if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
|
| + args = filterUnknownArguments(args, parser);
|
| + }
|
| + return parser.parse(args);
|
| +}
|
| +
|
| +/**
|
| + * Preprocess the given list of command line [args] by checking whether the real
|
| + * arguments are in a file (Bazel worker mode).
|
| + */
|
| +List<String> preprocessArgs(ResourceProvider provider, List<String> args) {
|
| + if (args.isEmpty) {
|
| + return args;
|
| + }
|
| + String lastArg = args.last;
|
| + if (lastArg.startsWith('@')) {
|
| + File argsFile = provider.getFile(lastArg.substring(1));
|
| + try {
|
| + List<String> newArgs = args.sublist(0, args.length - 1).toList();
|
| + newArgs.addAll(argsFile
|
| + .readAsStringSync()
|
| + .replaceAll('\r\n', '\n')
|
| + .replaceAll('\r', '\n')
|
| + .split('\n')
|
| + .where((String line) => line.isNotEmpty));
|
| + return newArgs;
|
| + } on FileSystemException {
|
| + // Don't modify args if the file does not exist or cannot be read.
|
| + }
|
| + }
|
| + return args;
|
| +}
|
|
|