src/check.bend
bolt@1.26.0.0 · 118 lines · 14 definitions
1
2
3
4
5
6
7
8import Base
9import bolt@1.26.0.0/src/status.bend as Status
10import bolt@1.26.0.0/src/lsp/report.bend as Rep
11import bolt@1.26.0.0/src/lsp/checker/answer.bend as Checker
12
13
14def rest_lines(ls: List<&2, String>) -> String:
15 match ls:
16 case Nil{}:
17 ""
18 case Con{l, t}:
19 "\n " ++ l ++ rest_lines(t)
20
21
22def message.of(ls: List<&2, String>) -> String:
23 match ls:
24 case Nil{}:
25 ""
26 case Con{h, t}:
27 h ++ rest_lines(t)
28
29
30def message(msg: String) -> String:
31 message.of(String.lines(msg))
32
33
34def show_all(ds: List<&2, Rep.Diag>, +path: String) -> List<&2, String>:
35 match ds:
36 case Nil{}:
37 Nil{}
38 case Con{Rep.Diag{line, msg}, rest}:
39 (path ++ ":" ++ U32.show((line + 1 : U32)) ++ ":1: error: " ++ message(msg)) <> show_all(rest, path)
40
41
42
43type Run is Data:
44 Run{path: String, ds: List<&2, Rep.Diag>}
45 Failed{path: String}
46
47
48type Out is Data:
49 Out{lines: List<&2, String>, code: U32}
50
51
52def lines_of(runs: List<&2, Run>) -> List<&2, String>:
53 match runs:
54 case Nil{}:
55 Nil{}
56 case Con{Run{path, ds}, rest}:
57 List.append(&2, String, show_all(ds, path), lines_of(rest))
58 case Con{Failed{path}, rest}:
59 (path ++ ":1:1: error: could not run bend") <> lines_of(rest)
60
61
62
63def out.at(ls: List<&2, String>, count: Nat) -> Out:
64 match count:
65 case 0n:
66 Out{List.append(&2, String, ls, ["clean"]), 0}
67 case 1n:
68 Out{List.append(&2, String, ls, ["1 error, 0 warnings"]), 1}
69 case 2n+more:
70 Out{List.append(&2, String, ls, [U32.show(U32.from_nat(2n+more)) ++ " errors, 0 warnings"]), 1}
71
72
73def out(runs: List<&2, Run>) -> Out:
74 +ls = lines_of(runs)
75 out.at(ls, List.length(&2, String, ls))
76
77
78def print_all(lines: List<&2, String>) -> IO(Unit):
79 match lines:
80 case Nil{}:
81 IO.pure(Unit, Unit{})
82 case Con{l, t}:
83 do IO<Unit>:
84 IO.print(l)
85 print_all(t)
86
87
88def run_of(path: String, aa: Checker.Answer) -> Run:
89 match aa:
90 case Checker.Checked{ds}:
91 Run{path, ds}
92 case Checker.Unrun{}:
93 Failed{path}
94
95
96def check_all(~ck: Checker.Checker, paths: List<&2, String>) -> IO(List<&2, Run>):
97 match paths:
98 case Nil{}:
99 IO.pure(List<&2, Run>, [])
100 case Con{+path, rest}:
101 do IO<List<&2, Run>>:
102 aa : Checker.Answer <- Checker.check(ck, path)
103 more : List<&2, Run> <- check_all(~ck, rest)
104 return run_of(path, aa) <> more
105
106
107def perform(oo: Out) -> IO(Unit):
108 Out{lines, code} = oo
109 do IO<Unit>:
110 print_all(lines)
111 Status.stop(U32.is_gt(code, 0))
112
113
114
115def run(~ck: Checker.Checker, paths: List<&2, String>) -> IO(Unit):
116 do IO<Unit>:
117 runs : List<&2, Run> <- check_all(~ck, paths)
118 perform(out(runs))