src/lsp/checker/names.bend

bolt@1.27.0.0 · 61 lines · 7 definitions

1# checker/names: pure. The names bend gives the items of the file it
2# checks, so a report's Location can be told apart as this file's or an
3# import's (report.bend's mine). bend keys a def by its name, and a def
4# whose name opens with an import alias (`def Laws.x` filling a law of
5# `./LAWS.bend`) by that import's namespace: its path, `./` and `.bend`
6# dropped (`LAWS.x`). A def of an import beside the file is keyed the same
7# way (`m.g`), which is why the file's own keys are needed at all.
8import Base
9import bolt@1.27.0.0/src/syntax/outline.bend as Outline
10import bolt@1.27.0.0/src/lazy/lazy.bend as Lazy
11
12# a path without its leading `./`s
13def ns.lead(ss: String) -> String:
14  match ss:
15    case SCon{'.', SCon{'/', tt}}:
16      ns.lead(tt)
17    case other:
18      other
19
20# an import's namespace: its path, without a leading `./` or its `.bend`
21def ns(path: String) -> String:
22  +pp = ns.lead(path)
23  Bool.pick(String, String.ends_with(pp, ".bend"), String.take(pp, Nat.sub(String.length(pp), 5n)), pp)
24
25# the key of a name that opens with `head.`: through the import aliased head
26# when there is one, else the name as written
27def key.of(alias: Maybe<&2, String>, +name: String, +rest: String) -> String:
28  match alias:
29    case None{}:
30      name
31    case Some{path}:
32      ns(path) ++ "." ++ rest
33
34# an item's key, among the file's items
35def key.parts(items: List<&2, Outline.Item>, +name: String, parts: List<&2, String>) -> String:
36  match parts:
37    case Con{+head, Con{rr, more}}:
38      key.of(Outline.import_path(items, head), name, String.join(rr <> more, "."))
39    case other:
40      name
41
42# an item's key: bend's name for it
43def key(items: List<&2, Outline.Item>, +name: String) -> String:
44  key.parts(items, name, String.split(name, '.'))
45
46# the keys of the items, imports aside, onto acc (in no particular order)
47def keys(its: List<&2, Outline.Item>, +items: List<&2, Outline.Item>, +acc: List<&2, String>) -> List<&2, String>:
48  match its:
49    case Nil{}:
50      acc
51    case Con{Outline.Item{+kk, +nn, _line, _sig, _doc, _path}, rest}:
52      keys(rest, items, Lazy.stop(List<&2, String>, Outline.is_import(kk), acc, _u => key(items, nn) <> acc))
53
54# the names bend gives a file's items, when its text could be read
55def of(mm: Maybe<&2, String>) -> Maybe<&2, List<&2, String>>:
56  match mm:
57    case None{}:
58      None{}
59    case Some{text}:
60      +items = Outline.items(text)
61      Some{keys(items, items, [])}