src/rules.bend
bolt@1.27.0.0 · 188 lines · 14 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import Base
18import bolt@1.27.0.0/src/finding.bend as F
19import bolt@1.27.0.0/src/codes.bend as Codes
20import bolt@1.27.0.0/src/src.bend as Src
21import bolt@1.27.0.0/src/role.bend as Role
22import bolt@1.27.0.0/src/rules/digest.bend as Digest
23import bolt@1.27.0.0/src/rules/imports.bend as Imports
24import bolt@1.27.0.0/src/lazy/lazy.bend as Lazy
25import bolt@1.27.0.0/src/config.bend as Config
26import bolt@1.27.0.0/src/rules/style/doc.bend as Doc
27import bolt@1.27.0.0/src/rules/suspicious/unused.bend as Unused
28import bolt@1.27.0.0/src/rules/correctness/hole.bend as Hole
29import bolt@1.27.0.0/src/rules/style/space.bend as Space
30import bolt@1.27.0.0/src/rules/style/wrap.bend as Wrap
31import bolt@1.27.0.0/src/rules/style/param.bend as Param
32import bolt@1.27.0.0/src/rules/style/transcong.bend as Transcong
33import bolt@1.27.0.0/src/rules/correctness/pick.bend as Pick
34import bolt@1.27.0.0/src/rules/laws/law.bend as Law
35import bolt@1.27.0.0/src/rules/pedantic/strict.bend as Strict
36import bolt@1.27.0.0/src/rules/suspicious/eager.bend as Eager
37import bolt@1.27.0.0/src/rules/pedantic/tail.bend as Tail
38import bolt@1.27.0.0/src/rules/suspicious/concat.bend as Concat
39import bolt@1.27.0.0/src/rules/pedantic/index.bend as Index
40import bolt@1.27.0.0/src/rules/pedantic/rewalk.bend as Rewalk
41import bolt@1.27.0.0/src/rules/suspicious/thunk.bend as Thunk
42import bolt@1.27.0.0/src/rules/suspicious/fromrev.bend as Fromrev
43import bolt@1.27.0.0/src/rules/suspicious/prefix.bend as Prefix
44import bolt@1.27.0.0/src/rules/suspicious/empty.bend as Empty
45import bolt@1.27.0.0/src/rules/correctness/put.bend as Put
46import bolt@1.27.0.0/src/rules/correctness/escape.bend as Escape
47import bolt@1.27.0.0/src/rules/perf/strings.bend as Strings
48import bolt@1.27.0.0/src/rules/perf/chars.bend as Chars
49import bolt@1.27.0.0/src/rules/correctness/twice.bend as Twice
50import bolt@1.27.0.0/src/rules/correctness/arms.bend as Arms
51import bolt@1.27.0.0/src/rules/pedantic/foreign.bend as Foreign
52import bolt@1.27.0.0/src/rules/pedantic/fuel.bend as Fuel
53import bolt@1.27.0.0/src/rules/laws/closed.bend as Closed
54
55
56def on.path(ss: Src.Src) -> String:
57 Src.Src{path, _text, _toks, _tree, _bound, _items} = ss
58 path
59
60
61
62def on.at(+path: String, fs: List<&2, F.Finding>) -> List<&2, F.Finding>:
63 match fs:
64 case Nil{}:
65 Nil{}
66 case Con{F.Finding{_path, line, col, len, rule, msg}, rest}:
67 F.Finding{path, line, col, len, rule, msg} <> on.at(path, rest)
68
69
70
71
72
73def on.rules.role(+rr: Role.Role, +ss: Src.Src) -> List<&2, F.Finding>:
74 List.concat(&2, F.Finding, [
75 Doc.check.role(rr, ss),
76 Unused.check(ss),
77 Hole.check.role(rr, ss),
78 Space.check(ss),
79 Wrap.check(ss),
80 Param.check.role(rr, ss),
81 Role.skip(rr, _u => Pick.check(ss)),
82 Role.skip(rr, _u => Pick.search(ss)),
83 Role.skip(rr, _u => Strict.check(ss)),
84 Role.skip(rr, _u => Eager.check(ss)),
85 Role.skip(rr, _u => Tail.check(ss)),
86 Role.skip(rr, _u => Concat.check(ss)),
87 Role.skip(rr, _u => Concat.cont(ss)),
88 Role.skip(rr, _u => Index.check(ss)),
89 Role.skip(rr, _u => Rewalk.check(ss)),
90 Role.skip(rr, _u => Thunk.check(ss)),
91 Fromrev.check.role(rr, ss),
92 Prefix.check.role(rr, ss),
93 Empty.check.role(rr, ss),
94 Put.check(ss),
95 Escape.check(ss),
96 Strings.check(ss),
97 Chars.check(ss),
98 Twice.check(ss),
99 Arms.check(ss),
100 Foreign.check(ss),
101 Fuel.check(ss),
102 Closed.check.role(rr, ss),
103 Transcong.check(ss)])
104
105
106def on.role(+rr: Role.Role, +ss: Src.Src) -> List<&2, F.Finding>:
107 on.at(on.path(ss), on.rules.role(rr, ss))
108
109
110
111
112
113
114
115
116def has(ds: List<&2, String>, +dd: String) -> Bool:
117 match ds:
118 case Nil{}:
119 False{}
120 case Con{d, rest}:
121 Lazy.or_else(String.eq(d, dd), _u => has(rest, dd))
122
123def ups.go(rs: List<&2, String>) -> List<&2, String>:
124 match rs:
125 case Nil{}:
126 Nil{}
127 case Con{s, +rest}:
128 (String.join(List.reverse(&2, String, s <> rest), "/") ++ "/") <> ups.go(rest)
129
130
131
132def ups(dir: String) -> List<&2, String>:
133 ups.go(List.reverse(&2, String, Imports.init(String.split(dir, '/'))))
134
135
136def owner.go(us: List<&2, String>, +roots: List<&2, String>) -> String:
137 match us:
138 case Nil{}:
139 ""
140 case Con{+u, rest}:
141 Lazy.stop(String, has(roots, u), u, _u => owner.go(rest, roots))
142
143
144def owner(+roots: List<&2, String>, dir: String) -> String:
145 owner.go(ups(dir), roots)
146
147
148def members(ds: List<&2, Digest.Digest>, +roots: List<&2, String>, +pkg: String) -> List<&2, Digest.Digest>:
149 match ds:
150 case Nil{}:
151 Nil{}
152 case Con{Digest.Digest{path, norm, +dir, is_laws, is_law_file, exempt, tops, says, deps, laws}, rest}:
153 +more = members(rest, roots, pkg)
154 Bool.pick(List<&2, Digest.Digest>, String.eq(owner(roots, dir), pkg),
155 Digest.Digest{path, norm, dir, is_laws, is_law_file, exempt, tops, says, deps, laws} <> more, more)
156
157
158def covers(rs: List<&2, String>, +ds: List<&2, Digest.Digest>, +roots: List<&2, String>) -> List<&2, F.Finding>:
159 match rs:
160 case Nil{}:
161 Nil{}
162 case Con{+dir, rest}:
163 List.append(&2, F.Finding, Law.check(members(ds, roots, dir)), covers(rest, ds, roots))
164
165
166
167
168
169def project(+srcs: List<&2, Src.Src>, +rs: List<&2, String>) -> List<&2, F.Finding>:
170 +ds = Digest.all.role(Role.marks(srcs), srcs)
171 List.concat(&2, F.Finding, [Law.check(members(ds, rs, "")), covers(rs, ds, rs)])
172
173
174def group(+rule: String) -> String:
175 +named = Codes.group(rule)
176 Bool.pick(String, String.is_empty(named), "correctness", named)
177
178
179
180def graded(+cfg: Config.Config, fs: List<&2, F.Finding>) -> List<&2, F.Graded>:
181 match fs:
182 case Nil{}:
183 Nil{}
184 case Con{F.Finding{path, line, col, len, +rule, msg}, rest}:
185 +more = graded(cfg, rest)
186 +l = Config.level(cfg, group(rule), rule)
187 Bool.pick(List<&2, F.Graded>, Config.is_off(l), more,
188 F.Graded{l, F.Finding{path, line, col, len, rule, msg}} <> more)