| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import 'package:yaml/yaml.dart'; | |
| 6 | |
| 7 /** | |
| 8 * Parse the given map into a lint config. | |
| 9 */ | |
| 10 LintConfig parseConfig(Map optionsMap) { | |
| 11 if (optionsMap != null) { | |
| 12 var options = optionsMap['linter']; | |
| 13 // Quick check of basic contract. | |
| 14 if (options is Map) { | |
| 15 return new LintConfig.parseMap(options); | |
| 16 } | |
| 17 } | |
| 18 return null; | |
| 19 } | |
| 20 | |
| 21 /** | |
| 22 * Process the given option [fileContents] and produce a corresponding | |
| 23 * [LintConfig]. | |
| 24 */ | |
| 25 LintConfig processAnalysisOptionsFile(String fileContents, {String fileUrl}) { | |
| 26 var yaml = loadYamlNode(fileContents, sourceUrl: fileUrl); | |
| 27 if (yaml is YamlMap) { | |
| 28 return parseConfig(yaml); | |
| 29 } | |
| 30 return null; | |
| 31 } | |
| 32 | |
| 33 /** | |
| 34 * The configuration of lint rules within an analysis options file. | |
| 35 */ | |
| 36 abstract class LintConfig { | |
| 37 factory LintConfig.parse(String source, {String sourceUrl}) => | |
| 38 new _LintConfig().._parse(source, sourceUrl: sourceUrl); | |
| 39 | |
| 40 factory LintConfig.parseMap(Map map) => new _LintConfig().._parseMap(map); | |
| 41 | |
| 42 List<String> get fileExcludes; | |
| 43 List<String> get fileIncludes; | |
| 44 List<RuleConfig> get ruleConfigs; | |
| 45 } | |
| 46 | |
| 47 /** | |
| 48 * The configuration of a single lint rule within an analysis options file. | |
| 49 */ | |
| 50 abstract class RuleConfig { | |
| 51 Map<String, dynamic> args = <String, dynamic>{}; | |
| 52 String get group; | |
| 53 String get name; | |
| 54 | |
| 55 // Provisional | |
| 56 bool disables(String ruleName) => | |
| 57 ruleName == name && args['enabled'] == false; | |
| 58 | |
| 59 bool enables(String ruleName) => ruleName == name && args['enabled'] == true; | |
| 60 } | |
| 61 | |
| 62 class _LintConfig implements LintConfig { | |
| 63 @override | |
| 64 final fileIncludes = <String>[]; | |
| 65 @override | |
| 66 final fileExcludes = <String>[]; | |
| 67 @override | |
| 68 final ruleConfigs = <RuleConfig>[]; | |
| 69 | |
| 70 void addAsListOrString(value, List<String> list) { | |
| 71 if (value is List) { | |
| 72 value.forEach((v) => list.add(v)); | |
| 73 } else if (value is String) { | |
| 74 list.add(value); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 bool asBool(scalar) { | |
| 79 if (scalar is bool) { | |
| 80 return scalar; | |
| 81 } | |
| 82 if (scalar is String) { | |
| 83 if (scalar == 'true') { | |
| 84 return true; | |
| 85 } | |
| 86 if (scalar == 'false') { | |
| 87 return false; | |
| 88 } | |
| 89 } | |
| 90 return null; | |
| 91 } | |
| 92 | |
| 93 String asString(scalar) { | |
| 94 if (scalar is String) { | |
| 95 return scalar; | |
| 96 } | |
| 97 return null; | |
| 98 } | |
| 99 | |
| 100 Map<String, dynamic> parseArgs(args) { | |
| 101 bool enabled = asBool(args); | |
| 102 if (enabled != null) { | |
| 103 return {'enabled': enabled}; | |
| 104 } | |
| 105 return null; | |
| 106 } | |
| 107 | |
| 108 void _parse(String src, {String sourceUrl}) { | |
| 109 var yaml = loadYamlNode(src, sourceUrl: sourceUrl); | |
| 110 if (yaml is YamlMap) { | |
| 111 _parseYaml(yaml); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 void _parseMap(Map options) { | |
| 116 //TODO(pq): unify map parsing. | |
| 117 if (options is YamlMap) { | |
| 118 _parseYaml(options); | |
| 119 } else { | |
| 120 _parseRawMap(options); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 void _parseRawMap(Map options) { | |
| 125 options.forEach((k, v) { | |
| 126 if (k is! String) { | |
| 127 return; | |
| 128 } | |
| 129 String key = k; | |
| 130 switch (key) { | |
| 131 case 'files': | |
| 132 if (v is Map) { | |
| 133 addAsListOrString(v['include'], fileIncludes); | |
| 134 addAsListOrString(v['exclude'], fileExcludes); | |
| 135 } | |
| 136 break; | |
| 137 | |
| 138 case 'rules': | |
| 139 // - unnecessary_getters | |
| 140 // - camel_case_types | |
| 141 if (v is List) { | |
| 142 v.forEach((rule) { | |
| 143 var config = new _RuleConfig(); | |
| 144 config.name = asString(rule); | |
| 145 config.args = {'enabled': true}; | |
| 146 ruleConfigs.add(config); | |
| 147 }); | |
| 148 } | |
| 149 | |
| 150 // {unnecessary_getters: false, camel_case_types: true} | |
| 151 if (v is Map) { | |
| 152 v.forEach((key, value) { | |
| 153 // style_guide: {unnecessary_getters: false, camel_case_types: tru
e} | |
| 154 if (value is Map) { | |
| 155 value.forEach((rule, args) { | |
| 156 // unnecessary_getters: false | |
| 157 var config = new _RuleConfig(); | |
| 158 config.group = key; | |
| 159 config.name = asString(rule); | |
| 160 config.args = parseArgs(args); | |
| 161 ruleConfigs.add(config); | |
| 162 }); | |
| 163 } else { | |
| 164 //{unnecessary_getters: false} | |
| 165 value = asBool(value); | |
| 166 if (value != null) { | |
| 167 var config = new _RuleConfig(); | |
| 168 config.name = asString(key); | |
| 169 config.args = {'enabled': value}; | |
| 170 ruleConfigs.add(config); | |
| 171 } | |
| 172 } | |
| 173 }); | |
| 174 } | |
| 175 break; | |
| 176 } | |
| 177 }); | |
| 178 } | |
| 179 | |
| 180 void _parseYaml(YamlMap yaml) { | |
| 181 yaml.nodes.forEach((k, v) { | |
| 182 if (k is! YamlScalar) { | |
| 183 return; | |
| 184 } | |
| 185 YamlScalar key = k; | |
| 186 switch (key.toString()) { | |
| 187 case 'files': | |
| 188 if (v is YamlMap) { | |
| 189 addAsListOrString(v['include'], fileIncludes); | |
| 190 addAsListOrString(v['exclude'], fileExcludes); | |
| 191 } | |
| 192 break; | |
| 193 | |
| 194 case 'rules': | |
| 195 | |
| 196 // - unnecessary_getters | |
| 197 // - camel_case_types | |
| 198 if (v is List) { | |
| 199 (v as List).forEach((rule) { | |
| 200 var config = new _RuleConfig(); | |
| 201 config.name = asString(rule); | |
| 202 config.args = {'enabled': true}; | |
| 203 ruleConfigs.add(config); | |
| 204 }); | |
| 205 } | |
| 206 | |
| 207 // style_guide: {unnecessary_getters: false, camel_case_types: true} | |
| 208 if (v is YamlMap) { | |
| 209 v.forEach((key, value) { | |
| 210 //{unnecessary_getters: false} | |
| 211 if (value is bool) { | |
| 212 var config = new _RuleConfig(); | |
| 213 config.name = asString(key); | |
| 214 config.args = {'enabled': value}; | |
| 215 ruleConfigs.add(config); | |
| 216 } | |
| 217 | |
| 218 // style_guide: {unnecessary_getters: false, camel_case_types: tru
e} | |
| 219 if (value is YamlMap) { | |
| 220 value.forEach((rule, args) { | |
| 221 // TODO: verify format | |
| 222 // unnecessary_getters: false | |
| 223 var config = new _RuleConfig(); | |
| 224 config.group = key; | |
| 225 config.name = asString(rule); | |
| 226 config.args = parseArgs(args); | |
| 227 ruleConfigs.add(config); | |
| 228 }); | |
| 229 } | |
| 230 }); | |
| 231 } | |
| 232 break; | |
| 233 } | |
| 234 }); | |
| 235 } | |
| 236 } | |
| 237 | |
| 238 class _RuleConfig extends RuleConfig { | |
| 239 @override | |
| 240 String group; | |
| 241 @override | |
| 242 String name; | |
| 243 } | |
| OLD | NEW |