Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: pkg/analyzer/lib/src/task/options.dart

Issue 1411053003: Error code validation for error filters. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Name tweaks. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 library analyzer.src.task.options; 5 library analyzer.src.task.options;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/plugin/options.dart'; 8 import 'package:analyzer/plugin/options.dart';
9 import 'package:analyzer/source/analysis_options_provider.dart'; 9 import 'package:analyzer/source/analysis_options_provider.dart';
10 import 'package:analyzer/src/generated/engine.dart'; 10 import 'package:analyzer/src/generated/engine.dart';
11 import 'package:analyzer/src/generated/java_engine.dart'; 11 import 'package:analyzer/src/generated/java_engine.dart';
12 import 'package:analyzer/src/generated/source.dart'; 12 import 'package:analyzer/src/generated/source.dart';
13 import 'package:analyzer/src/task/general.dart'; 13 import 'package:analyzer/src/task/general.dart';
14 import 'package:analyzer/task/general.dart'; 14 import 'package:analyzer/task/general.dart';
15 import 'package:analyzer/task/model.dart'; 15 import 'package:analyzer/task/model.dart';
16 import 'package:source_span/source_span.dart'; 16 import 'package:source_span/source_span.dart';
17 import 'package:yaml/yaml.dart'; 17 import 'package:yaml/yaml.dart';
18 18
19 /// The errors produced while parsing `.analysis_options` files. 19 /// The errors produced while parsing `.analysis_options` files.
20 /// 20 ///
21 /// The list will be empty if there were no errors, but will not be `null`. 21 /// The list will be empty if there were no errors, but will not be `null`.
22 final ListResultDescriptor<AnalysisError> ANALYSIS_OPTIONS_ERRORS = 22 final ListResultDescriptor<AnalysisError> ANALYSIS_OPTIONS_ERRORS =
23 new ListResultDescriptor<AnalysisError>( 23 new ListResultDescriptor<AnalysisError>(
24 'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS); 24 'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS);
25 25
26 /// `analyzer` analysis options constants. 26 /// `analyzer` analysis options constants.
27 class AnalyzerOptions { 27 class AnalyzerOptions {
28 static const String analyzer = 'analyzer';
28 static const String errors = 'errors'; 29 static const String errors = 'errors';
29 static const String exclude = 'exclude'; 30 static const String exclude = 'exclude';
30 static const String plugins = 'plugins'; 31 static const String plugins = 'plugins';
31 static const String strong_mode = 'strong-mode'; 32 static const String strong_mode = 'strong-mode';
32 33
33 /// Ways to say `ignore`. 34 /// Ways to say `ignore`.
34 static const List<String> ignoreSynonyms = const ['ignore', 'false']; 35 static const List<String> ignoreSynonyms = const ['ignore', 'false'];
35 36
37 /// Ways to say `include`.
38 static const List<String> includeSynonyms = const ['include', 'true'];
39
36 /// Supported top-level `analyzer` options. 40 /// Supported top-level `analyzer` options.
37 static const List<String> top_level = const [ 41 static const List<String> top_level = const [
38 errors, 42 errors,
39 exclude, 43 exclude,
40 plugins, 44 plugins,
41 strong_mode 45 strong_mode
42 ]; 46 ];
43 } 47 }
44 48
49 /// Validates `analyzer` error filter options.
50 class ErrorFilterOptionValidator extends OptionsValidator {
51 /// Pretty list of legal includes.
52 static final String legalIncludes = StringUtilities.printListOfQuotedNames(
53 new List.from(AnalyzerOptions.ignoreSynonyms)
54 ..addAll(AnalyzerOptions.includeSynonyms));
55
56 @override
57 void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
58 YamlMap analyzer = options[AnalyzerOptions.analyzer];
59 if (analyzer == null) {
60 // No options for analyzer.
61 return;
62 }
63
64 YamlNode filters = analyzer[AnalyzerOptions.errors];
65
66 if (filters is YamlMap) {
67 String value;
68 filters.nodes.forEach((k, v) {
69 if (k is YamlScalar) {
70 value = k.value?.toString()?.toUpperCase();
71 if (!ErrorCode.values.any((ErrorCode code) => code.name == value)) {
72 reporter.reportErrorForSpan(
73 AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
74 k.span,
75 [k.value?.toString()]);
76 }
77 }
78 if (v is YamlScalar) {
79 value = v.value?.toString()?.toLowerCase();
80 if (!AnalyzerOptions.ignoreSynonyms.contains(value) &&
81 !AnalyzerOptions.includeSynonyms.contains(value)) {
82 reporter.reportErrorForSpan(
83 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
84 v.span,
85 [AnalyzerOptions.errors, v.value?.toString(), legalIncludes]);
86 }
87
88 value = v.value?.toString()?.toLowerCase();
89 }
90 });
91 }
92 }
93 }
94
45 /// Validates `analyzer` top-level options. 95 /// Validates `analyzer` top-level options.
46 class AnalyzerOptionsValidator extends TopLevelOptionValidator { 96 class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator {
47 AnalyzerOptionsValidator() : super('analyzer', AnalyzerOptions.top_level); 97 TopLevelAnalyzerOptionsValidator()
98 : super(AnalyzerOptions.analyzer, AnalyzerOptions.top_level);
99 }
100
101 /// Validates `analyzer` options.
102 class AnalyzerOptionsValidator extends CompositeValidator {
103 AnalyzerOptionsValidator()
104 : super([
105 new TopLevelAnalyzerOptionsValidator(),
106 new ErrorFilterOptionValidator()
107 ]);
48 } 108 }
49 109
50 /// Convenience class for composing validators. 110 /// Convenience class for composing validators.
51 class CompositeValidator extends OptionsValidator { 111 class CompositeValidator extends OptionsValidator {
52 final List<OptionsValidator> validators; 112 final List<OptionsValidator> validators;
53 CompositeValidator(this.validators); 113 CompositeValidator(this.validators);
54 114
55 @override 115 @override
56 void validate(ErrorReporter reporter, Map<String, YamlNode> options) => 116 void validate(ErrorReporter reporter, Map<String, YamlNode> options) =>
57 validators.forEach((v) => v.validate(reporter, options)); 117 validators.forEach((v) => v.validate(reporter, options));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 return recorder.errors; 210 return recorder.errors;
151 } 211 }
152 } 212 }
153 213
154 /// Validates top-level options. For example, 214 /// Validates top-level options. For example,
155 /// plugin: 215 /// plugin:
156 /// top-level-option: true 216 /// top-level-option: true
157 class TopLevelOptionValidator extends OptionsValidator { 217 class TopLevelOptionValidator extends OptionsValidator {
158 final String pluginName; 218 final String pluginName;
159 final List<String> supportedOptions; 219 final List<String> supportedOptions;
220 String _valueProposal;
221 AnalysisOptionsWarningCode _warningCode;
222 TopLevelOptionValidator(this.pluginName, this.supportedOptions) {
223 assert(supportedOptions != null && !supportedOptions.isEmpty);
224 if (supportedOptions.length > 1) {
225 _valueProposal = StringUtilities.printListOfQuotedNames(supportedOptions);
226 _warningCode =
227 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
228 } else {
229 _valueProposal = "'${supportedOptions.join()}'";
230 _warningCode =
231 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
232 }
233 }
160 234
161 TopLevelOptionValidator(this.pluginName, this.supportedOptions);
162 @override 235 @override
163 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { 236 void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
164 YamlNode node = options[pluginName]; 237 YamlNode node = options[pluginName];
165 if (node is YamlMap) { 238 if (node is YamlMap) {
166 node.nodes.forEach((k, v) { 239 node.nodes.forEach((k, v) {
167 if (k is YamlScalar) { 240 if (k is YamlScalar) {
168 if (!supportedOptions.contains(k.value)) { 241 if (!supportedOptions.contains(k.value)) {
169 reporter.reportErrorForSpan( 242 reporter.reportErrorForSpan(
170 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION, 243 _warningCode, k.span, [pluginName, k.value, _valueProposal]);
171 k.span,
172 [pluginName, k.value]);
173 } 244 }
174 } 245 }
175 //TODO(pq): consider an error if the node is not a Scalar. 246 //TODO(pq): consider an error if the node is not a Scalar.
176 }); 247 });
177 } 248 }
178 } 249 }
179 } 250 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/all_the_rest_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698