Skip to content

Commit 6275b4c

Browse files
committed
Created analysis_options.yaml rules parser
1 parent 04a0112 commit 6275b4c

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import 'dart:io';
2+
import 'package:yaml/yaml.dart';
3+
4+
/// Loads and parses analysis options from a Dart project's YAML file.
5+
class AnalysisOptionsLoader {
6+
final Map<String, dynamic> _cache = {};
7+
8+
/// Loads analysis options from a YAML file at the given [yamlPath].
9+
Map<String, dynamic> loadAnalysisOptions(String yamlPath) {
10+
if (_cache.containsKey(yamlPath)) {
11+
return _cache[yamlPath] as Map<String, dynamic>;
12+
}
13+
14+
final file = File(yamlPath);
15+
if (!file.existsSync()) {
16+
_cache[yamlPath] = {};
17+
return {};
18+
}
19+
20+
try {
21+
final content = file.readAsStringSync();
22+
final yamlMap = loadYaml(content);
23+
final parsedYaml = _convertYaml(yamlMap);
24+
final result =
25+
parsedYaml is Map<String, dynamic> ? parsedYaml : <String, dynamic>{};
26+
27+
_cache[yamlPath] = result;
28+
return result;
29+
} on YamlException {
30+
_cache[yamlPath] = {};
31+
return {};
32+
}
33+
}
34+
35+
/// Extracts custom lint rules from the provided YAML map.
36+
Map<String, dynamic> extractLintRules(
37+
Map<String, dynamic> yaml, {
38+
String lintName = 'custom_lint',
39+
}) {
40+
final customLint = yaml[lintName];
41+
42+
if (customLint is! Map) return {};
43+
44+
final rules = customLint['rules'];
45+
46+
if (rules is! List) return {};
47+
48+
final result = <String, dynamic>{};
49+
50+
for (final item in rules) {
51+
final rule = _extractRuleEntry(item);
52+
if (rule == null) continue;
53+
54+
result[rule.$1] = rule.$2;
55+
}
56+
57+
return result;
58+
}
59+
60+
dynamic _convertYaml(dynamic yaml) {
61+
if (yaml is YamlMap) {
62+
return _yamlMapToDartMap(yaml);
63+
}
64+
65+
if (yaml is YamlList) {
66+
return yaml.map(_convertRuleItem).toList();
67+
}
68+
69+
return yaml;
70+
}
71+
72+
dynamic _convertRuleItem(dynamic item) {
73+
if (item is! YamlMap) return item;
74+
75+
final map = _yamlMapToDartMap(item);
76+
77+
final keys = map.keys.toList();
78+
79+
if (keys.length >= 2 && map[keys.first] == null) {
80+
final ruleName = keys.first;
81+
final config = Map<String, dynamic>.from(map)..remove(ruleName);
82+
83+
return {ruleName: config.isEmpty ? null : config};
84+
}
85+
86+
return map;
87+
}
88+
89+
Map<String, dynamic> _yamlMapToDartMap(YamlMap yamlMap) {
90+
return Map<String, dynamic>.fromEntries(
91+
yamlMap.entries.map(
92+
(e) => MapEntry(e.key.toString(), _convertYaml(e.value)),
93+
),
94+
);
95+
}
96+
97+
(String, Map<String, dynamic>)? _extractRuleEntry(dynamic item) {
98+
if (item is String) return (item, {});
99+
if (item is! Map || item.isEmpty) return null;
100+
101+
final entry = item.entries.first;
102+
final ruleName = entry.key.toString();
103+
final config = entry.value;
104+
105+
if (config is Map<String, dynamic>) {
106+
return (ruleName, config);
107+
}
108+
109+
if (config is Map) {
110+
return (ruleName, Map<String, dynamic>.from(config));
111+
}
112+
113+
return (ruleName, {});
114+
}
115+
}

0 commit comments

Comments
 (0)