Chromium Code Reviews| 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.source.analysis_options_provider; | 5 library analyzer.source.analysis_options_provider; |
| 6 | 6 |
| 7 import 'dart:core'; | 7 import 'dart:core'; |
| 8 | 8 |
| 9 import 'package:analyzer/file_system/file_system.dart'; | 9 import 'package:analyzer/file_system/file_system.dart'; |
| 10 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| 11 import 'package:analyzer/src/generated/source.dart'; | |
| 12 import 'package:analyzer/src/source/source_resource.dart'; | |
| 11 import 'package:analyzer/src/util/yaml.dart'; | 13 import 'package:analyzer/src/util/yaml.dart'; |
| 12 import 'package:source_span/source_span.dart'; | 14 import 'package:source_span/source_span.dart'; |
| 13 import 'package:yaml/yaml.dart'; | 15 import 'package:yaml/yaml.dart'; |
| 14 | 16 |
| 15 /// Provide the options found in the analysis options file. | 17 /// Provide the options found in the analysis options file. |
| 16 class AnalysisOptionsProvider { | 18 class AnalysisOptionsProvider { |
| 19 /// The source factory used to resolve include declarations | |
| 20 /// in analysis options files or `null` if include is not supported. | |
| 21 SourceFactory sourceFactory; | |
| 22 | |
| 23 AnalysisOptionsProvider([this.sourceFactory]); | |
| 24 | |
| 17 /// Provide the options found in either | 25 /// Provide the options found in either |
| 18 /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or | 26 /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or |
| 19 /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE]. | 27 /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE]. |
| 20 /// Return an empty options map if the file does not exist. | 28 /// Return an empty options map if the file does not exist. |
| 21 Map<String, YamlNode> getOptions(Folder root, {bool crawlUp: false}) { | 29 Map<String, YamlNode> getOptions(Folder root, {bool crawlUp: false}) { |
| 22 Resource resource; | 30 Resource resource; |
| 23 for (Folder folder = root; folder != null; folder = folder.parent) { | 31 for (Folder folder = root; folder != null; folder = folder.parent) { |
| 24 resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE); | 32 resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE); |
| 25 if (resource.exists) { | 33 if (resource.exists) { |
| 26 break; | 34 break; |
| 27 } | 35 } |
| 28 resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE); | 36 resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE); |
| 29 if (resource.exists || !crawlUp) { | 37 if (resource.exists || !crawlUp) { |
| 30 break; | 38 break; |
| 31 } | 39 } |
| 32 } | 40 } |
| 33 String optionsText = _readAnalysisOptionsFile(resource); | 41 return getOptionsFromFile(resource); |
| 34 return getOptionsFromString(optionsText); | |
| 35 } | 42 } |
| 36 | 43 |
| 37 /// Provide the options found in [file]. | 44 /// Provide the options found in [file]. |
| 38 /// Return an empty options map if the file does not exist. | 45 /// Return an empty options map if the file does not exist. |
| 39 Map<String, YamlNode> getOptionsFromFile(File file) { | 46 Map<String, YamlNode> getOptionsFromFile(File file) { |
| 40 var optionsSource = _readAnalysisOptionsFile(file); | 47 return getOptionsFromSource(new FileSource(file)); |
| 41 return getOptionsFromString(optionsSource); | 48 } |
| 49 | |
| 50 /// Provide the options found in [source]. | |
| 51 /// Return an empty options map if the file does not exist. | |
| 52 Map<String, YamlNode> getOptionsFromSource(Source source) { | |
| 53 Map<String, YamlNode> options = | |
| 54 getOptionsFromString(_readAnalysisOptions(source)); | |
| 55 YamlNode node = options.remove('include'); | |
|
Brian Wilkerson
2016/11/11 19:37:47
Given that "participants" are able to look at the
danrubel
2016/11/14 20:39:33
I don't think the "include" directive makes sense
| |
| 56 if (sourceFactory != null && node is YamlScalar) { | |
| 57 var path = node.value; | |
| 58 if (path is String) { | |
| 59 Source parent = sourceFactory.resolveUri(source, path); | |
| 60 options = merge(getOptionsFromSource(parent), options); | |
| 61 } | |
| 62 } | |
| 63 return options; | |
| 42 } | 64 } |
| 43 | 65 |
| 44 /// Provide the options found in [optionsSource]. | 66 /// Provide the options found in [optionsSource]. |
| 45 /// Return an empty options map if the source is null. | 67 /// Return an empty options map if the source is null. |
| 46 Map<String, YamlNode> getOptionsFromString(String optionsSource) { | 68 Map<String, YamlNode> getOptionsFromString(String optionsSource) { |
| 47 Map<String, YamlNode> options = <String, YamlNode>{}; | 69 Map<String, YamlNode> options = <String, YamlNode>{}; |
| 48 if (optionsSource == null) { | 70 if (optionsSource == null) { |
| 49 return options; | 71 return options; |
| 50 } | 72 } |
| 51 | 73 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 /// * lists of scalar values can be promoted to simple maps when merged with | 125 /// * lists of scalar values can be promoted to simple maps when merged with |
| 104 /// maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes | 126 /// maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes |
| 105 /// {'opt1': true, 'opt2': true}. | 127 /// {'opt1': true, 'opt2': true}. |
| 106 /// * maps are merged recursively. | 128 /// * maps are merged recursively. |
| 107 /// * if map values cannot be merged, the overriding value is taken. | 129 /// * if map values cannot be merged, the overriding value is taken. |
| 108 /// | 130 /// |
| 109 Map<String, YamlNode> merge( | 131 Map<String, YamlNode> merge( |
| 110 Map<String, YamlNode> defaults, Map<String, YamlNode> overrides) => | 132 Map<String, YamlNode> defaults, Map<String, YamlNode> overrides) => |
| 111 new Merger().merge(defaults, overrides) as Map<String, YamlNode>; | 133 new Merger().merge(defaults, overrides) as Map<String, YamlNode>; |
| 112 | 134 |
| 113 /// Read the contents of [file] as a string. | 135 /// Read the contents of [source] as a string. |
| 114 /// Returns null if file does not exist. | 136 /// Returns null if source is null or does not exist. |
| 115 String _readAnalysisOptionsFile(File file) { | 137 String _readAnalysisOptions(Source source) { |
| 116 try { | 138 try { |
| 117 return file.readAsStringSync(); | 139 return source.contents.data; |
| 118 } on FileSystemException { | 140 } catch (e) { |
| 119 // File can't be read. | 141 // Source can't be read. |
| 120 return null; | 142 return null; |
|
Brian Wilkerson
2016/11/11 19:37:47
There is linter support for linting options files.
danrubel
2016/11/14 20:39:33
Good idea. https://github.com/dart-lang/sdk/issues
| |
| 121 } | 143 } |
| 122 } | 144 } |
| 123 } | 145 } |
| 124 | 146 |
| 125 /// Thrown on options format exceptions. | 147 /// Thrown on options format exceptions. |
| 126 class OptionsFormatException implements Exception { | 148 class OptionsFormatException implements Exception { |
| 127 final String message; | 149 final String message; |
| 128 final SourceSpan span; | 150 final SourceSpan span; |
| 129 OptionsFormatException(this.message, [this.span]); | 151 OptionsFormatException(this.message, [this.span]); |
| 130 | 152 |
| 131 @override | 153 @override |
| 132 String toString() => | 154 String toString() => |
| 133 'OptionsFormatException: ${message?.toString()}, ${span?.toString()}'; | 155 'OptionsFormatException: ${message?.toString()}, ${span?.toString()}'; |
| 134 } | 156 } |
| OLD | NEW |