| Index: packages/analyzer/lib/source/error_processor.dart
|
| diff --git a/packages/analyzer/lib/source/error_processor.dart b/packages/analyzer/lib/source/error_processor.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b5fe38f3c7a2bf47d955ebd1932ebeeff90b7ed3
|
| --- /dev/null
|
| +++ b/packages/analyzer/lib/source/error_processor.dart
|
| @@ -0,0 +1,137 @@
|
| +// 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.source.error_processor;
|
| +
|
| +import 'package:analyzer/error/error.dart';
|
| +import 'package:analyzer/src/error/codes.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/utilities_general.dart';
|
| +import 'package:analyzer/src/task/options.dart'
|
| + show CONFIGURED_ERROR_PROCESSORS;
|
| +import 'package:analyzer/src/task/options.dart';
|
| +import 'package:yaml/yaml.dart';
|
| +
|
| +/// String identifiers mapped to associated severities.
|
| +const Map<String, ErrorSeverity> severityMap = const {
|
| + 'error': ErrorSeverity.ERROR,
|
| + 'info': ErrorSeverity.INFO,
|
| + 'warning': ErrorSeverity.WARNING
|
| +};
|
| +
|
| +/// Error processor configuration derived from analysis (or embedder) options.
|
| +class ErrorConfig {
|
| + /// The processors in this config.
|
| + final List<ErrorProcessor> processors = <ErrorProcessor>[];
|
| +
|
| + /// Create an error config for the given error code map.
|
| + /// For example:
|
| + /// new ErrorConfig({'missing_return' : 'error'});
|
| + /// will create a processor config that turns `missing_return` hints into
|
| + /// errors.
|
| + ErrorConfig(Object codeMap) {
|
| + _processMap(codeMap);
|
| + }
|
| +
|
| + void _process(String code, Object action) {
|
| + action = toLowerCase(action);
|
| + code = toUpperCase(code);
|
| + if (AnalyzerOptions.ignoreSynonyms.contains(action)) {
|
| + processors.add(new ErrorProcessor.ignore(code));
|
| + } else {
|
| + ErrorSeverity severity = _toSeverity(action);
|
| + if (severity != null) {
|
| + processors.add(new ErrorProcessor(code, severity));
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _processMap(Object codes) {
|
| + if (codes is YamlMap) {
|
| + // TODO(pq): stop traversing nodes and unify w/ standard map handling
|
| + codes.nodes.forEach((k, v) {
|
| + if (k is YamlScalar && v is YamlScalar) {
|
| + _process(k.value, v.value);
|
| + }
|
| + });
|
| + } else if (codes is Map) {
|
| + codes.forEach((k, v) {
|
| + if (k is String) {
|
| + _process(k, v);
|
| + }
|
| + });
|
| + }
|
| + }
|
| +
|
| + ErrorSeverity _toSeverity(String severity) => severityMap[severity];
|
| +}
|
| +
|
| +/// Process errors by filtering or changing associated [ErrorSeverity].
|
| +class ErrorProcessor {
|
| + /// The code name of the associated error.
|
| + final String code;
|
| +
|
| + /// The desired severity of the processed error.
|
| + ///
|
| + /// If `null`, this processor will "filter" the associated error code.
|
| + final ErrorSeverity severity;
|
| +
|
| + /// Create an error processor that assigns errors with this [code] the
|
| + /// given [severity].
|
| + ///
|
| + /// If [severity] is `null`, matching errors will be filtered.
|
| + ErrorProcessor(this.code, [this.severity]);
|
| +
|
| + /// Create an error processor that ignores the given error by [code].
|
| + factory ErrorProcessor.ignore(String code) => new ErrorProcessor(code);
|
| +
|
| + /// Check if this processor applies to the given [error].
|
| + bool appliesTo(AnalysisError error) => code == error.errorCode.name;
|
| +
|
| + /// Return an error processor associated with this [context] for the given
|
| + /// [error], or `null` if none is found.
|
| + static ErrorProcessor getProcessor(
|
| + AnalysisContext context, AnalysisError error) {
|
| + if (context == null) {
|
| + return null;
|
| + }
|
| +
|
| + // Let the user configure how specific errors are processed.
|
| + List<ErrorProcessor> processors =
|
| + context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
|
| +
|
| + // Give strong mode a chance to upgrade it.
|
| + if (context.analysisOptions.strongMode) {
|
| + processors = processors.toList();
|
| + processors.add(_StrongModeTypeErrorProcessor.instance);
|
| + }
|
| + return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
|
| + orElse: () => null);
|
| + }
|
| +}
|
| +
|
| +/// In strong mode, this upgrades static type warnings to errors.
|
| +class _StrongModeTypeErrorProcessor implements ErrorProcessor {
|
| + static final instance = new _StrongModeTypeErrorProcessor();
|
| +
|
| + // TODO(rnystrom): As far as I know, this is only used to implement
|
| + // appliesTo(). Consider making it private in ErrorProcessor if possible.
|
| + String get code => throw new UnsupportedError(
|
| + "_StrongModeTypeErrorProcessor is not specific to an error code.");
|
| +
|
| + /// In strong mode, type warnings are upgraded to errors.
|
| + ErrorSeverity get severity => ErrorSeverity.ERROR;
|
| +
|
| + /// Check if this processor applies to the given [error].
|
| + bool appliesTo(AnalysisError error) {
|
| + ErrorCode errorCode = error.errorCode;
|
| + if (errorCode is StaticTypeWarningCode) {
|
| + return true;
|
| + }
|
| + if (errorCode is StaticWarningCode) {
|
| + return errorCode.isStrongModeError;
|
| + }
|
| + return false;
|
| + }
|
| +}
|
|
|