| 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 |