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. 8 import Base 9 import ../../syntax/outline.bend as Outline 10 import ../../lazy/lazy.bend as Lazy 11 12 # a path without its leading `./`s 13 def 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` 21 def 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 27 def 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 35 def 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 43 def 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) 47 def 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 55 def 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, [])}