OLD | NEW |
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 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
10 import 'package:analyzer/plugin/options.dart'; | 10 import 'package:analyzer/plugin/options.dart'; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name)); | 161 _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name)); |
162 // Strong-mode codes. | 162 // Strong-mode codes. |
163 _errorCodes.addAll(StaticInfo.names); | 163 _errorCodes.addAll(StaticInfo.names); |
164 } | 164 } |
165 return _errorCodes; | 165 return _errorCodes; |
166 } | 166 } |
167 | 167 |
168 @override | 168 @override |
169 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { | 169 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { |
170 var analyzer = options[AnalyzerOptions.analyzer]; | 170 var analyzer = options[AnalyzerOptions.analyzer]; |
171 if (analyzer is! YamlMap) { | 171 if (analyzer is YamlMap) { |
172 return; | 172 var filters = analyzer[AnalyzerOptions.errors]; |
173 } | 173 if (filters is YamlMap) { |
174 | 174 String value; |
175 var filters = analyzer[AnalyzerOptions.errors]; | 175 filters.nodes.forEach((k, v) { |
176 if (filters is YamlMap) { | 176 if (k is YamlScalar) { |
177 String value; | 177 value = toUpperCase(k.value); |
178 filters.nodes.forEach((k, v) { | 178 if (!errorCodes.contains(value)) { |
179 if (k is YamlScalar) { | 179 reporter.reportErrorForSpan( |
180 value = toUpperCase(k.value); | 180 AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE, |
181 if (!errorCodes.contains(value)) { | 181 k.span, |
182 reporter.reportErrorForSpan( | 182 [k.value?.toString()]); |
183 AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE, | 183 } |
184 k.span, | |
185 [k.value?.toString()]); | |
186 } | 184 } |
187 } | 185 if (v is YamlScalar) { |
188 if (v is YamlScalar) { | 186 value = toLowerCase(v.value); |
189 value = toLowerCase(v.value); | 187 if (!legalValues.contains(value)) { |
190 if (!legalValues.contains(value)) { | 188 reporter.reportErrorForSpan( |
191 reporter.reportErrorForSpan( | 189 AnalysisOptionsWarningCode |
192 AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES, | 190 .UNSUPPORTED_OPTION_WITH_LEGAL_VALUES, |
193 v.span, [ | 191 v.span, |
194 AnalyzerOptions.errors, | 192 [ |
195 v.value?.toString(), | 193 AnalyzerOptions.errors, |
196 legalValueString | 194 v.value?.toString(), |
197 ]); | 195 legalValueString |
| 196 ]); |
| 197 } |
198 } | 198 } |
199 } | 199 }); |
200 }); | 200 } |
201 } | 201 } |
202 } | 202 } |
203 } | 203 } |
204 | 204 |
205 /// A task that generates errors for an `.analysis_options` file. | 205 /// A task that generates errors for an `.analysis_options` file. |
206 class GenerateOptionsErrorsTask extends SourceBasedAnalysisTask { | 206 class GenerateOptionsErrorsTask extends SourceBasedAnalysisTask { |
207 /// The name of the input whose value is the content of the file. | 207 /// The name of the input whose value is the content of the file. |
208 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; | 208 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; |
209 | 209 |
210 /// The task descriptor describing this kind of task. | 210 /// The task descriptor describing this kind of task. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 outputs[ANALYSIS_OPTIONS_ERRORS] = errors; | 248 outputs[ANALYSIS_OPTIONS_ERRORS] = errors; |
249 outputs[LINE_INFO] = computeLineInfo(content); | 249 outputs[LINE_INFO] = computeLineInfo(content); |
250 } | 250 } |
251 | 251 |
252 List<AnalysisError> _validate(Map<String, YamlNode> options) => | 252 List<AnalysisError> _validate(Map<String, YamlNode> options) => |
253 new OptionsFileValidator(source).validate(options); | 253 new OptionsFileValidator(source).validate(options); |
254 | 254 |
255 /// Return a map from the names of the inputs of this kind of task to the | 255 /// Return a map from the names of the inputs of this kind of task to the |
256 /// task input descriptors describing those inputs for a task with the | 256 /// task input descriptors describing those inputs for a task with the |
257 /// given [target]. | 257 /// given [target]. |
258 static Map<String, TaskInput> buildInputs(Source source) => | 258 static Map<String, TaskInput> buildInputs(AnalysisTarget source) => |
259 <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)}; | 259 <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)}; |
260 | 260 |
261 /// Compute [LineInfo] for the given [content]. | 261 /// Compute [LineInfo] for the given [content]. |
262 static LineInfo computeLineInfo(String content) { | 262 static LineInfo computeLineInfo(String content) { |
263 List<int> lineStarts = StringUtilities.computeLineStarts(content); | 263 List<int> lineStarts = StringUtilities.computeLineStarts(content); |
264 return new LineInfo(lineStarts); | 264 return new LineInfo(lineStarts); |
265 } | 265 } |
266 | 266 |
267 /// Create a task based on the given [target] in the given [context]. | 267 /// Create a task based on the given [target] in the given [context]. |
268 static GenerateOptionsErrorsTask createTask( | 268 static GenerateOptionsErrorsTask createTask( |
(...skipping 13 matching lines...) Expand all Loading... |
282 } | 282 } |
283 | 283 |
284 /// Validates `analyzer` language configuration options. | 284 /// Validates `analyzer` language configuration options. |
285 class LanguageOptionValidator extends OptionsValidator { | 285 class LanguageOptionValidator extends OptionsValidator { |
286 ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions); | 286 ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions); |
287 ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder(); | 287 ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder(); |
288 | 288 |
289 @override | 289 @override |
290 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { | 290 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { |
291 var analyzer = options[AnalyzerOptions.analyzer]; | 291 var analyzer = options[AnalyzerOptions.analyzer]; |
292 if (analyzer is! YamlMap) { | 292 if (analyzer is YamlMap) { |
293 return; | 293 var language = analyzer[AnalyzerOptions.language]; |
294 } | 294 if (language is YamlMap) { |
295 | 295 language.nodes.forEach((k, v) { |
296 var language = analyzer[AnalyzerOptions.language]; | 296 String key, value; |
297 if (language is YamlMap) { | 297 bool validKey = false; |
298 language.nodes.forEach((k, v) { | 298 if (k is YamlScalar) { |
299 String key, value; | 299 key = k.value?.toString(); |
300 bool validKey = false; | 300 if (!AnalyzerOptions.languageOptions.contains(key)) { |
301 if (k is YamlScalar) { | 301 builder.reportError(reporter, AnalyzerOptions.language, k); |
302 key = k.value?.toString(); | 302 } else { |
303 if (!AnalyzerOptions.languageOptions.contains(key)) { | 303 // If we have a valid key, go on and check the value. |
304 builder.reportError(reporter, AnalyzerOptions.language, k); | 304 validKey = true; |
305 } else { | 305 } |
306 // If we have a valid key, go on and check the value. | |
307 validKey = true; | |
308 } | 306 } |
309 } | 307 if (validKey && v is YamlScalar) { |
310 if (validKey && v is YamlScalar) { | 308 value = toLowerCase(v.value); |
311 value = toLowerCase(v.value); | 309 if (!AnalyzerOptions.trueOrFalse.contains(value)) { |
312 if (!AnalyzerOptions.trueOrFalse.contains(value)) { | 310 trueOrFalseBuilder.reportError(reporter, key, v); |
313 trueOrFalseBuilder.reportError(reporter, key, v); | 311 } |
314 } | 312 } |
315 } | 313 }); |
316 }); | 314 } |
317 } | 315 } |
318 } | 316 } |
319 } | 317 } |
320 | 318 |
321 /// Validates `linter` top-level options. | 319 /// Validates `linter` top-level options. |
322 /// TODO(pq): move into `linter` package and plugin. | 320 /// TODO(pq): move into `linter` package and plugin. |
323 class LinterOptionsValidator extends TopLevelOptionValidator { | 321 class LinterOptionsValidator extends TopLevelOptionValidator { |
324 LinterOptionsValidator() : super('linter', const ['rules']); | 322 LinterOptionsValidator() : super('linter', const ['rules']); |
325 } | 323 } |
326 | 324 |
(...skipping 18 matching lines...) Expand all Loading... |
345 } | 343 } |
346 } | 344 } |
347 | 345 |
348 /// Validates `analyzer` strong-mode value configuration options. | 346 /// Validates `analyzer` strong-mode value configuration options. |
349 class StrongModeOptionValueValidator extends OptionsValidator { | 347 class StrongModeOptionValueValidator extends OptionsValidator { |
350 ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder(); | 348 ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder(); |
351 | 349 |
352 @override | 350 @override |
353 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { | 351 void validate(ErrorReporter reporter, Map<String, YamlNode> options) { |
354 var analyzer = options[AnalyzerOptions.analyzer]; | 352 var analyzer = options[AnalyzerOptions.analyzer]; |
355 if (analyzer is! YamlMap) { | 353 if (analyzer is YamlMap) { |
356 return; | 354 var v = analyzer.nodes[AnalyzerOptions.strong_mode]; |
357 } | 355 if (v is YamlScalar) { |
358 | 356 var value = toLowerCase(v.value); |
359 var v = analyzer.nodes[AnalyzerOptions.strong_mode]; | 357 if (!AnalyzerOptions.trueOrFalse.contains(value)) { |
360 if (v is YamlScalar) { | 358 trueOrFalseBuilder.reportError( |
361 var value = toLowerCase(v.value); | 359 reporter, AnalyzerOptions.strong_mode, v); |
362 if (!AnalyzerOptions.trueOrFalse.contains(value)) { | 360 } |
363 trueOrFalseBuilder.reportError( | |
364 reporter, AnalyzerOptions.strong_mode, v); | |
365 } | 361 } |
366 } | 362 } |
367 } | 363 } |
368 } | 364 } |
369 | 365 |
370 /// Validates `analyzer` top-level options. | 366 /// Validates `analyzer` top-level options. |
371 class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator { | 367 class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator { |
372 TopLevelAnalyzerOptionsValidator() | 368 TopLevelAnalyzerOptionsValidator() |
373 : super(AnalyzerOptions.analyzer, AnalyzerOptions.topLevel); | 369 : super(AnalyzerOptions.analyzer, AnalyzerOptions.topLevel); |
374 } | 370 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 | 420 |
425 /** | 421 /** |
426 * Apply the options in the given [optionMap] to the given analysis [options]. | 422 * Apply the options in the given [optionMap] to the given analysis [options]. |
427 */ | 423 */ |
428 void applyToAnalysisOptions( | 424 void applyToAnalysisOptions( |
429 AnalysisOptionsImpl options, Map<String, Object> optionMap) { | 425 AnalysisOptionsImpl options, Map<String, Object> optionMap) { |
430 if (optionMap == null) { | 426 if (optionMap == null) { |
431 return; | 427 return; |
432 } | 428 } |
433 var analyzer = optionMap[AnalyzerOptions.analyzer]; | 429 var analyzer = optionMap[AnalyzerOptions.analyzer]; |
434 if (analyzer is! Map) { | 430 if (analyzer is Map) { |
435 return; | 431 // Process strong mode option. |
| 432 var strongMode = analyzer[AnalyzerOptions.strong_mode]; |
| 433 if (strongMode is bool) { |
| 434 options.strongMode = strongMode; |
| 435 } |
| 436 // Process language options. |
| 437 var language = analyzer[AnalyzerOptions.language]; |
| 438 _applyLanguageOptions(options, language); |
436 } | 439 } |
437 // Process strong mode option. | |
438 var strongMode = analyzer[AnalyzerOptions.strong_mode]; | |
439 if (strongMode is bool) { | |
440 options.strongMode = strongMode; | |
441 } | |
442 // Process language options. | |
443 var language = analyzer[AnalyzerOptions.language]; | |
444 _applyLanguageOptions(options, language); | |
445 } | 440 } |
446 | 441 |
447 /// Configure [context] based on the given [options] (which can be `null` | 442 /// Configure [context] based on the given [options] (which can be `null` |
448 /// to restore [defaults]). | 443 /// to restore [defaults]). |
449 void configure(AnalysisContext context, Map<String, Object> options) { | 444 void configure(AnalysisContext context, Map<String, Object> options) { |
450 if (options == null) { | 445 if (options == null) { |
451 options = defaults; | 446 options = defaults; |
452 } | 447 } |
453 | 448 |
454 var analyzer = options[AnalyzerOptions.analyzer]; | 449 var analyzer = options[AnalyzerOptions.analyzer]; |
455 if (analyzer is! Map) { | 450 if (analyzer is Map) { |
456 return; | 451 // Set strong mode (default is false). |
| 452 var strongMode = analyzer[AnalyzerOptions.strong_mode]; |
| 453 setStrongMode(context, strongMode); |
| 454 |
| 455 // Set filters. |
| 456 var filters = analyzer[AnalyzerOptions.errors]; |
| 457 setProcessors(context, filters); |
| 458 |
| 459 // Process language options. |
| 460 var language = analyzer[AnalyzerOptions.language]; |
| 461 setLanguageOptions(context, language); |
457 } | 462 } |
458 | |
459 // Set strong mode (default is false). | |
460 var strongMode = analyzer[AnalyzerOptions.strong_mode]; | |
461 setStrongMode(context, strongMode); | |
462 | |
463 // Set filters. | |
464 var filters = analyzer[AnalyzerOptions.errors]; | |
465 setProcessors(context, filters); | |
466 | |
467 // Process language options. | |
468 var language = analyzer[AnalyzerOptions.language]; | |
469 setLanguageOptions(context, language); | |
470 } | 463 } |
471 | 464 |
472 void setLanguageOption( | 465 void setLanguageOption( |
473 AnalysisContext context, Object feature, Object value) { | 466 AnalysisContext context, Object feature, Object value) { |
474 if (feature == AnalyzerOptions.enableAsync) { | 467 if (feature == AnalyzerOptions.enableAsync) { |
475 if (isFalse(value)) { | 468 if (isFalse(value)) { |
476 AnalysisOptionsImpl options = | 469 AnalysisOptionsImpl options = |
477 new AnalysisOptionsImpl.from(context.analysisOptions); | 470 new AnalysisOptionsImpl.from(context.analysisOptions); |
478 options.enableAsync = false; | 471 options.enableAsync = false; |
479 context.analysisOptions = options; | 472 context.analysisOptions = options; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 String feature = key.value?.toString(); | 558 String feature = key.value?.toString(); |
566 _applyLanguageOption(options, feature, value.value); | 559 _applyLanguageOption(options, feature, value.value); |
567 } | 560 } |
568 }); | 561 }); |
569 } else if (configs is Map) { | 562 } else if (configs is Map) { |
570 configs | 563 configs |
571 .forEach((key, value) => _applyLanguageOption(options, key, value)); | 564 .forEach((key, value) => _applyLanguageOption(options, key, value)); |
572 } | 565 } |
573 } | 566 } |
574 } | 567 } |
OLD | NEW |