| Index: packages/analyzer/lib/src/task/options.dart
|
| diff --git a/packages/analyzer/lib/src/task/options.dart b/packages/analyzer/lib/src/task/options.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4047b3b84c244a407b79b3e8e82179c711eed3dd
|
| --- /dev/null
|
| +++ b/packages/analyzer/lib/src/task/options.dart
|
| @@ -0,0 +1,621 @@
|
| +// Copyright (c) 2015, 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.task.options;
|
| +
|
| +import 'dart:collection';
|
| +
|
| +import 'package:analyzer/analyzer.dart';
|
| +import 'package:analyzer/plugin/options.dart';
|
| +import 'package:analyzer/source/analysis_options_provider.dart';
|
| +import 'package:analyzer/source/error_processor.dart';
|
| +import 'package:analyzer/src/context/context.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/java_engine.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/generated/utilities_general.dart';
|
| +import 'package:analyzer/src/task/general.dart';
|
| +import 'package:analyzer/src/util/yaml.dart';
|
| +import 'package:analyzer/task/general.dart';
|
| +import 'package:analyzer/task/model.dart';
|
| +import 'package:source_span/source_span.dart';
|
| +import 'package:yaml/yaml.dart';
|
| +
|
| +/// The errors produced while parsing an analysis options file.
|
| +///
|
| +/// The list will be empty if there were no errors, but will not be `null`.
|
| +final ListResultDescriptor<AnalysisError> ANALYSIS_OPTIONS_ERRORS =
|
| + new ListResultDescriptor<AnalysisError>(
|
| + 'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS);
|
| +
|
| +/**
|
| + * The descriptor used to associate error processors with analysis contexts in
|
| + * configuration data.
|
| + */
|
| +final ListResultDescriptor<ErrorProcessor> CONFIGURED_ERROR_PROCESSORS =
|
| + new ListResultDescriptor<ErrorProcessor>(
|
| + 'configured.errors', const <ErrorProcessor>[]);
|
| +
|
| +final _OptionsProcessor _processor = new _OptionsProcessor();
|
| +
|
| +void applyToAnalysisOptions(
|
| + AnalysisOptionsImpl options, Map<String, Object> optionMap) {
|
| + _processor.applyToAnalysisOptions(options, optionMap);
|
| +}
|
| +
|
| +/// Configure this [context] based on configuration details specified in
|
| +/// the given [options]. If [options] is `null`, default values are applied.
|
| +void configureContextOptions(
|
| + AnalysisContext context, Map<String, Object> options) =>
|
| + _processor.configure(context, options);
|
| +
|
| +/// `analyzer` analysis options constants.
|
| +class AnalyzerOptions {
|
| + static const String analyzer = 'analyzer';
|
| + static const String enableAssertInitializer = 'enableAssertInitializer';
|
| + static const String enableAsync = 'enableAsync';
|
| + static const String enableGenericMethods = 'enableGenericMethods';
|
| + static const String enableInitializingFormalAccess =
|
| + 'enableInitializingFormalAccess';
|
| + static const String enableStrictCallChecks = 'enableStrictCallChecks';
|
| + static const String enableSuperMixins = 'enableSuperMixins';
|
| +
|
| + static const String errors = 'errors';
|
| + static const String exclude = 'exclude';
|
| + static const String language = 'language';
|
| + static const String plugins = 'plugins';
|
| + static const String strong_mode = 'strong-mode';
|
| +
|
| + // Strong mode options, see AnalysisOptionsImpl for documentation.
|
| + static const String implicitCasts = 'implicit-casts';
|
| + static const String implicitDynamic = 'implicit-dynamic';
|
| +
|
| + /// Ways to say `ignore`.
|
| + static const List<String> ignoreSynonyms = const ['ignore', 'false'];
|
| +
|
| + /// Valid error `severity`s.
|
| + static final List<String> severities =
|
| + new List.unmodifiable(severityMap.keys);
|
| +
|
| + /// Ways to say `include`.
|
| + static const List<String> includeSynonyms = const ['include', 'true'];
|
| +
|
| + /// Ways to say `true` or `false`.
|
| + static const List<String> trueOrFalse = const ['true', 'false'];
|
| +
|
| + /// Supported top-level `analyzer` options.
|
| + static const List<String> topLevel = const [
|
| + errors,
|
| + exclude,
|
| + language,
|
| + plugins,
|
| + strong_mode
|
| + ];
|
| +
|
| + /// Supported `analyzer` language configuration options.
|
| + static const List<String> languageOptions = const [
|
| + enableAssertInitializer,
|
| + enableAsync,
|
| + enableGenericMethods,
|
| + enableStrictCallChecks,
|
| + enableSuperMixins
|
| + ];
|
| +}
|
| +
|
| +/// Validates `analyzer` options.
|
| +class AnalyzerOptionsValidator extends CompositeValidator {
|
| + AnalyzerOptionsValidator()
|
| + : super([
|
| + new TopLevelAnalyzerOptionsValidator(),
|
| + new StrongModeOptionValueValidator(),
|
| + new ErrorFilterOptionValidator(),
|
| + new LanguageOptionValidator()
|
| + ]);
|
| +}
|
| +
|
| +/// Convenience class for composing validators.
|
| +class CompositeValidator extends OptionsValidator {
|
| + final List<OptionsValidator> validators;
|
| + CompositeValidator(this.validators);
|
| +
|
| + @override
|
| + void validate(ErrorReporter reporter, Map<String, YamlNode> options) =>
|
| + validators.forEach((v) => v.validate(reporter, options));
|
| +}
|
| +
|
| +/// Builds error reports with value proposals.
|
| +class ErrorBuilder {
|
| + String proposal;
|
| + AnalysisOptionsWarningCode code;
|
| +
|
| + /// Create a builder for the given [supportedOptions].
|
| + ErrorBuilder(List<String> supportedOptions) {
|
| + assert(supportedOptions != null && !supportedOptions.isEmpty);
|
| + if (supportedOptions.length > 1) {
|
| + proposal = StringUtilities.printListOfQuotedNames(supportedOptions);
|
| + code = pluralProposalCode;
|
| + } else {
|
| + proposal = "'${supportedOptions.join()}'";
|
| + code = singularProposalCode;
|
| + }
|
| + }
|
| + AnalysisOptionsWarningCode get pluralProposalCode =>
|
| + AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
|
| +
|
| + AnalysisOptionsWarningCode get singularProposalCode =>
|
| + AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
|
| +
|
| + /// Report an unsupported [node] value, defined in the given [scopeName].
|
| + void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
|
| + reporter
|
| + .reportErrorForSpan(code, node.span, [scopeName, node.value, proposal]);
|
| + }
|
| +}
|
| +
|
| +/// Validates `analyzer` error filter options.
|
| +class ErrorFilterOptionValidator extends OptionsValidator {
|
| + /// Legal values.
|
| + static final List<String> legalValues =
|
| + new List.from(AnalyzerOptions.ignoreSynonyms)
|
| + ..addAll(AnalyzerOptions.includeSynonyms)
|
| + ..addAll(AnalyzerOptions.severities);
|
| +
|
| + /// Pretty String listing legal values.
|
| + static final String legalValueString =
|
| + StringUtilities.printListOfQuotedNames(legalValues);
|
| +
|
| + /// Lazily populated set of error codes (hashed for speedy lookup).
|
| + static HashSet<String> _errorCodes;
|
| +
|
| + /// Legal error code names.
|
| + static Set<String> get errorCodes {
|
| + if (_errorCodes == null) {
|
| + _errorCodes = new HashSet<String>();
|
| + // Engine codes.
|
| + _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name));
|
| + }
|
| + return _errorCodes;
|
| + }
|
| +
|
| + @override
|
| + void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
|
| + var analyzer = options[AnalyzerOptions.analyzer];
|
| + if (analyzer is YamlMap) {
|
| + var filters = analyzer[AnalyzerOptions.errors];
|
| + if (filters is YamlMap) {
|
| + String value;
|
| + filters.nodes.forEach((k, v) {
|
| + if (k is YamlScalar) {
|
| + value = toUpperCase(k.value);
|
| + if (!errorCodes.contains(value)) {
|
| + reporter.reportErrorForSpan(
|
| + AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
|
| + k.span,
|
| + [k.value?.toString()]);
|
| + }
|
| + }
|
| + if (v is YamlScalar) {
|
| + value = toLowerCase(v.value);
|
| + if (!legalValues.contains(value)) {
|
| + reporter.reportErrorForSpan(
|
| + AnalysisOptionsWarningCode
|
| + .UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
|
| + v.span,
|
| + [
|
| + AnalyzerOptions.errors,
|
| + v.value?.toString(),
|
| + legalValueString
|
| + ]);
|
| + }
|
| + }
|
| + });
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// A task that generates errors for an analysis options file.
|
| +class GenerateOptionsErrorsTask extends SourceBasedAnalysisTask {
|
| + /// The name of the input whose value is the content of the file.
|
| + static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME';
|
| +
|
| + /// The task descriptor describing this kind of task.
|
| + static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
|
| + 'GenerateOptionsErrorsTask',
|
| + createTask,
|
| + buildInputs,
|
| + <ResultDescriptor>[ANALYSIS_OPTIONS_ERRORS, LINE_INFO],
|
| + suitabilityFor: suitabilityFor);
|
| +
|
| + final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
|
| +
|
| + GenerateOptionsErrorsTask(AnalysisContext context, AnalysisTarget target)
|
| + : super(context, target);
|
| +
|
| + @override
|
| + TaskDescriptor get descriptor => DESCRIPTOR;
|
| +
|
| + Source get source => target.source;
|
| +
|
| + @override
|
| + void internalPerform() {
|
| + String content = getRequiredInput(CONTENT_INPUT_NAME);
|
| +
|
| + List<AnalysisError> errors = <AnalysisError>[];
|
| +
|
| + try {
|
| + Map<String, YamlNode> options =
|
| + optionsProvider.getOptionsFromString(content);
|
| + errors.addAll(_validate(options));
|
| + } on OptionsFormatException catch (e) {
|
| + SourceSpan span = e.span;
|
| + var error = new AnalysisError(source, span.start.column + 1, span.length,
|
| + AnalysisOptionsErrorCode.PARSE_ERROR, [e.message]);
|
| + errors.add(error);
|
| + }
|
| +
|
| + //
|
| + // Record outputs.
|
| + //
|
| + outputs[ANALYSIS_OPTIONS_ERRORS] = errors;
|
| + outputs[LINE_INFO] = computeLineInfo(content);
|
| + }
|
| +
|
| + List<AnalysisError> _validate(Map<String, YamlNode> options) =>
|
| + new OptionsFileValidator(source).validate(options);
|
| +
|
| + /// Return a map from the names of the inputs of this kind of task to the
|
| + /// task input descriptors describing those inputs for a task with the
|
| + /// given [target].
|
| + static Map<String, TaskInput> buildInputs(AnalysisTarget source) =>
|
| + <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
|
| +
|
| + /// Compute [LineInfo] for the given [content].
|
| + static LineInfo computeLineInfo(String content) {
|
| + List<int> lineStarts = StringUtilities.computeLineStarts(content);
|
| + return new LineInfo(lineStarts);
|
| + }
|
| +
|
| + /// Create a task based on the given [target] in the given [context].
|
| + static GenerateOptionsErrorsTask createTask(
|
| + AnalysisContext context, AnalysisTarget target) =>
|
| + new GenerateOptionsErrorsTask(context, target);
|
| +
|
| + /**
|
| + * Return an indication of how suitable this task is for the given [target].
|
| + */
|
| + static TaskSuitability suitabilityFor(AnalysisTarget target) {
|
| + if (target is Source &&
|
| + (target.shortName == AnalysisEngine.ANALYSIS_OPTIONS_FILE ||
|
| + target.shortName == AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE)) {
|
| + return TaskSuitability.HIGHEST;
|
| + }
|
| + return TaskSuitability.NONE;
|
| + }
|
| +}
|
| +
|
| +/// Validates `analyzer` language configuration options.
|
| +class LanguageOptionValidator extends OptionsValidator {
|
| + ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions);
|
| + ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
|
| +
|
| + @override
|
| + void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
|
| + var analyzer = options[AnalyzerOptions.analyzer];
|
| + if (analyzer is YamlMap) {
|
| + var language = analyzer[AnalyzerOptions.language];
|
| + if (language is YamlMap) {
|
| + language.nodes.forEach((k, v) {
|
| + String key, value;
|
| + bool validKey = false;
|
| + if (k is YamlScalar) {
|
| + key = k.value?.toString();
|
| + if (!AnalyzerOptions.languageOptions.contains(key)) {
|
| + builder.reportError(reporter, AnalyzerOptions.language, k);
|
| + } else {
|
| + // If we have a valid key, go on and check the value.
|
| + validKey = true;
|
| + }
|
| + }
|
| + if (validKey && v is YamlScalar) {
|
| + value = toLowerCase(v.value);
|
| + if (!AnalyzerOptions.trueOrFalse.contains(value)) {
|
| + trueOrFalseBuilder.reportError(reporter, key, v);
|
| + }
|
| + }
|
| + });
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// Validates `linter` top-level options.
|
| +/// TODO(pq): move into `linter` package and plugin.
|
| +class LinterOptionsValidator extends TopLevelOptionValidator {
|
| + LinterOptionsValidator() : super('linter', const ['rules']);
|
| +}
|
| +
|
| +/// Validates options defined in an analysis options file.
|
| +class OptionsFileValidator {
|
| + // TODO(pq): move to an extension point.
|
| + final List<OptionsValidator> _validators = [
|
| + new AnalyzerOptionsValidator(),
|
| + new LinterOptionsValidator()
|
| + ];
|
| +
|
| + final Source source;
|
| + OptionsFileValidator(this.source) {
|
| + _validators.addAll(AnalysisEngine.instance.optionsPlugin.optionsValidators);
|
| + }
|
| +
|
| + List<AnalysisError> validate(Map<String, YamlNode> options) {
|
| + RecordingErrorListener recorder = new RecordingErrorListener();
|
| + ErrorReporter reporter = new ErrorReporter(recorder, source);
|
| + _validators.forEach((OptionsValidator v) => v.validate(reporter, options));
|
| + return recorder.errors;
|
| + }
|
| +}
|
| +
|
| +/// Validates `analyzer` strong-mode value configuration options.
|
| +class StrongModeOptionValueValidator extends OptionsValidator {
|
| + ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
|
| +
|
| + @override
|
| + void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
|
| + var analyzer = options[AnalyzerOptions.analyzer];
|
| + if (analyzer is YamlMap) {
|
| + var v = analyzer.nodes[AnalyzerOptions.strong_mode];
|
| + if (v is YamlScalar) {
|
| + var value = toLowerCase(v.value);
|
| + if (!AnalyzerOptions.trueOrFalse.contains(value)) {
|
| + trueOrFalseBuilder.reportError(
|
| + reporter, AnalyzerOptions.strong_mode, v);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// Validates `analyzer` top-level options.
|
| +class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator {
|
| + TopLevelAnalyzerOptionsValidator()
|
| + : super(AnalyzerOptions.analyzer, AnalyzerOptions.topLevel);
|
| +}
|
| +
|
| +/// Validates top-level options. For example,
|
| +/// plugin:
|
| +/// top-level-option: true
|
| +class TopLevelOptionValidator extends OptionsValidator {
|
| + final String pluginName;
|
| + final List<String> supportedOptions;
|
| + String _valueProposal;
|
| + AnalysisOptionsWarningCode _warningCode;
|
| + TopLevelOptionValidator(this.pluginName, this.supportedOptions) {
|
| + assert(supportedOptions != null && !supportedOptions.isEmpty);
|
| + if (supportedOptions.length > 1) {
|
| + _valueProposal = StringUtilities.printListOfQuotedNames(supportedOptions);
|
| + _warningCode =
|
| + AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
|
| + } else {
|
| + _valueProposal = "'${supportedOptions.join()}'";
|
| + _warningCode =
|
| + AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
|
| + YamlNode node = options[pluginName];
|
| + if (node is YamlMap) {
|
| + node.nodes.forEach((k, v) {
|
| + if (k is YamlScalar) {
|
| + if (!supportedOptions.contains(k.value)) {
|
| + reporter.reportErrorForSpan(
|
| + _warningCode, k.span, [pluginName, k.value, _valueProposal]);
|
| + }
|
| + }
|
| + //TODO(pq): consider an error if the node is not a Scalar.
|
| + });
|
| + }
|
| + }
|
| +}
|
| +
|
| +/// An error-builder that knows about `true` and `false` legal values.
|
| +class TrueOrFalseValueErrorBuilder extends ErrorBuilder {
|
| + TrueOrFalseValueErrorBuilder() : super(AnalyzerOptions.trueOrFalse);
|
| + @override
|
| + AnalysisOptionsWarningCode get pluralProposalCode =>
|
| + AnalysisOptionsWarningCode.UNSUPPORTED_VALUE;
|
| +}
|
| +
|
| +class _OptionsProcessor {
|
| + static final Map<String, Object> defaults = {'analyzer': {}};
|
| +
|
| + /**
|
| + * Apply the options in the given [optionMap] to the given analysis [options].
|
| + */
|
| + void applyToAnalysisOptions(
|
| + AnalysisOptionsImpl options, Map<String, Object> optionMap) {
|
| + if (optionMap == null) {
|
| + return;
|
| + }
|
| + var analyzer = optionMap[AnalyzerOptions.analyzer];
|
| + if (analyzer is Map) {
|
| + // Process strong mode option.
|
| + var strongMode = analyzer[AnalyzerOptions.strong_mode];
|
| + _applyStrongOptions(options, strongMode);
|
| +
|
| + // Process language options.
|
| + var language = analyzer[AnalyzerOptions.language];
|
| + _applyLanguageOptions(options, language);
|
| + }
|
| + }
|
| +
|
| + /// Configure [context] based on the given [options] (which can be `null`
|
| + /// to restore [defaults]).
|
| + void configure(AnalysisContext context, Map<String, Object> options) {
|
| + if (options == null) {
|
| + options = defaults;
|
| + }
|
| +
|
| + var analyzer = options[AnalyzerOptions.analyzer];
|
| + if (analyzer is Map) {
|
| + // Set strong mode (default is false).
|
| + var strongMode = analyzer[AnalyzerOptions.strong_mode];
|
| + setStrongMode(context, strongMode);
|
| +
|
| + // Set filters.
|
| + var filters = analyzer[AnalyzerOptions.errors];
|
| + setProcessors(context, filters);
|
| +
|
| + // Process language options.
|
| + var language = analyzer[AnalyzerOptions.language];
|
| + setLanguageOptions(context, language);
|
| +
|
| + // Process excludes.
|
| + var excludes = analyzer[AnalyzerOptions.exclude];
|
| + setExcludes(context, excludes);
|
| + }
|
| + }
|
| +
|
| + void setExcludes(AnalysisContext context, Object excludes) {
|
| + if (excludes is YamlList) {
|
| + List<String> excludeList = toStringList(excludes);
|
| + if (excludeList != null) {
|
| + context.setConfigurationData(CONTEXT_EXCLUDES, excludeList);
|
| + }
|
| + }
|
| + }
|
| +
|
| + void setLanguageOption(
|
| + AnalysisContext context, Object feature, Object value) {
|
| + if (feature == AnalyzerOptions.enableAssertInitializer) {
|
| + if (isTrue(value)) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + options.enableAssertInitializer = true;
|
| + context.analysisOptions = options;
|
| + }
|
| + }
|
| + if (feature == AnalyzerOptions.enableStrictCallChecks) {
|
| + if (isTrue(value)) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + options.enableStrictCallChecks = true;
|
| + context.analysisOptions = options;
|
| + }
|
| + }
|
| + if (feature == AnalyzerOptions.enableSuperMixins) {
|
| + if (isTrue(value)) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + options.enableSuperMixins = true;
|
| + context.analysisOptions = options;
|
| + }
|
| + }
|
| + if (feature == AnalyzerOptions.enableGenericMethods) {
|
| + if (isTrue(value)) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + options.enableGenericMethods = true;
|
| + context.analysisOptions = options;
|
| + }
|
| + }
|
| + }
|
| +
|
| + void setLanguageOptions(AnalysisContext context, Object configs) {
|
| + if (configs is YamlMap) {
|
| + configs.nodes.forEach((k, v) {
|
| + if (k is YamlScalar && v is YamlScalar) {
|
| + String feature = k.value?.toString();
|
| + setLanguageOption(context, feature, v.value);
|
| + }
|
| + });
|
| + } else if (configs is Map) {
|
| + configs.forEach((k, v) => setLanguageOption(context, k, v));
|
| + }
|
| + }
|
| +
|
| + void setProcessors(AnalysisContext context, Object codes) {
|
| + ErrorConfig config = new ErrorConfig(codes);
|
| + context.setConfigurationData(
|
| + CONFIGURED_ERROR_PROCESSORS, config.processors);
|
| + }
|
| +
|
| + void setStrongMode(AnalysisContext context, Object strongMode) {
|
| + if (strongMode is Map) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + _applyStrongOptions(options, strongMode);
|
| + context.analysisOptions = options;
|
| + } else {
|
| + strongMode = strongMode is bool ? strongMode : false;
|
| + if (context.analysisOptions.strongMode != strongMode) {
|
| + AnalysisOptionsImpl options =
|
| + new AnalysisOptionsImpl.from(context.analysisOptions);
|
| + options.strongMode = strongMode;
|
| + context.analysisOptions = options;
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _applyLanguageOption(
|
| + AnalysisOptionsImpl options, Object feature, Object value) {
|
| + bool boolValue = toBool(value);
|
| + if (boolValue != null) {
|
| + if (feature == AnalyzerOptions.enableAssertInitializer) {
|
| + options.enableAssertInitializer = boolValue;
|
| + } else if (feature == AnalyzerOptions.enableInitializingFormalAccess) {
|
| + options.enableInitializingFormalAccess = boolValue;
|
| + } else if (feature == AnalyzerOptions.enableSuperMixins) {
|
| + options.enableSuperMixins = boolValue;
|
| + } else if (feature == AnalyzerOptions.enableGenericMethods) {
|
| + options.enableGenericMethods = boolValue;
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _applyLanguageOptions(AnalysisOptionsImpl options, Object configs) {
|
| + if (configs is YamlMap) {
|
| + configs.nodes.forEach((key, value) {
|
| + if (key is YamlScalar && value is YamlScalar) {
|
| + String feature = key.value?.toString();
|
| + _applyLanguageOption(options, feature, value.value);
|
| + }
|
| + });
|
| + } else if (configs is Map) {
|
| + configs
|
| + .forEach((key, value) => _applyLanguageOption(options, key, value));
|
| + }
|
| + }
|
| +
|
| + void _applyStrongModeOption(
|
| + AnalysisOptionsImpl options, Object feature, Object value) {
|
| + bool boolValue = toBool(value);
|
| + if (boolValue != null) {
|
| + if (feature == AnalyzerOptions.implicitCasts) {
|
| + options.implicitCasts = boolValue;
|
| + }
|
| + if (feature == AnalyzerOptions.implicitDynamic) {
|
| + options.implicitDynamic = boolValue;
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _applyStrongOptions(AnalysisOptionsImpl options, Object config) {
|
| + if (config is YamlMap) {
|
| + options.strongMode = true;
|
| + config.nodes.forEach((k, v) {
|
| + if (k is YamlScalar && v is YamlScalar) {
|
| + _applyStrongModeOption(options, k.value?.toString(), v.value);
|
| + }
|
| + });
|
| + } else if (config is Map) {
|
| + options.strongMode = true;
|
| + config.forEach((k, v) => _applyStrongModeOption(options, k, v));
|
| + } else {
|
| + options.strongMode = config is bool ? config : false;
|
| + }
|
| + }
|
| +}
|
|
|