src/syntax/outline.bend checks
raw source on the hub · import 0x013e0f9a479bbebad5ed196725eede95/src/syntax/outline.bend as Outline
src/syntax/outline: a source's top-level items, read line by line. A top-level item starts at column 0, so a line the outline does not understand costs nothing: it is skipped, and the items around it still stand. That tolerance is the point: an editor asks about files that are half-written.
A line that starts inside a string literal (the lexer's, which runs across newlines as bend's does) is text, not a line of code: it is never an item, a comment or a blank, and it joins a pending header as one more line.
3 imports
import Base import ../lazy/lazy.bend as Lazy import ./lex.bend as Lex
Types
type ItemKind source · line 15 · raw
Data
what an item is; ILocal is not read from a source, it is how the server offers a binder as a candidate
IImportItemKind
IDefItemKind
ILawItemKind
ITypeItemKind
ICtorItemKind
ILocalItemKind
type Item source · line 26 · raw
Data
line is 0-based; sig is the header text (a def's through its :, a law's
whole block, a constructor's line); doc is the comment block right above;
path is an import's target
Item@kind:ItemKind -> @name:String -> @line:U32 -> @sig:String -> @doc:String -> @path:String -> Item
type Cls source · line 30 · raw
Data
what a line is, by its first chars
LBlankCls
LComment@text:String -> Cls
LIndent@text:String -> Cls
LImportCls
LDefCls
LLawCls
LTypeCls
LOtherCls
type Mode source · line 41 · raw
Data
Pending: a def's header that has not reached its :, or a law's block
TopMode
InTypeMode
Pending@kind:ItemKind -> @name:String -> @line:U32 -> @doc:String -> @sig:List<&2, String> -> Mode
type St source · line 47 · raw
Data
doc and out are reversed
St@mode:Mode -> @n:U32 -> @doc:List<&2, String> -> @out:List<&2, Item> -> St
Definitions
def classify.kw source · line 51 · raw
@hit:Bool -> @yes:Cls -> Cls
the class when the prefix matches, else other
def classify.rebuild source · line 59 · raw
@acc:List<&2, Char> -> @rest:String -> String
leading spaces (reversed) in front of the rest of the line
def classify.white.hit source · line 67 · raw
@indent:Bool -> @acc:List<&2, Char> -> @hh:Char -> @rest:String -> Cls
an indented line when the first char is a space, else other
def classify.white source · line 77 · raw
@tt:String -> @space:Bool -> @hh:Char -> @indent:Bool -> @acc:List<&2, Char> -> Cls
whitespace after a leading space-class char. space says h is whitespace;
acc is the whitespace before h, reversed; indent when that line opened
with a space
def classify.white.enter source · line 89 · raw
@tt:String -> @+xx:U32 -> Cls
a line whose first char is whitespace
def classify.ktype source · line 93 · raw
@hit:Bool -> @tt:String -> Cls
type , once the t is known
def classify.klaw source · line 101 · raw
@hit:Bool -> @+xx:U32 -> @tt:String -> Cls
law , else type
def classify.kat source · line 109 · raw
@hit:Bool -> @+xx:U32 -> @tt:String -> Cls
@unsafe def , else law
def classify.kdef source · line 117 · raw
@hit:Bool -> @+xx:U32 -> @tt:String -> Cls
def , else @unsafe def
def classify.kimp source · line 125 · raw
@hit:Bool -> @+xx:U32 -> @tt:String -> Cls
import , else def
def classify.keys source · line 133 · raw
@+xx:U32 -> @tt:String -> Cls
a column-0 keyword, from the first character's code
def classify.hold.keys source · line 137 · raw
@+xx:U32 -> @cc:Char -> @+tt:String -> Pair(Cls, String)
a column-0 keyword keeps the line; the class comes from its first character
def classify.hold.gap.keep source · line 141 · raw
@+xx:U32 -> @cc:Char -> @+tt:String -> Pair(Cls, String)
whitespace that is not a leading space keeps the line: the class may not
def classify.hold.gap source · line 145 · raw
@indent:Bool -> @xx:U32 -> @cc:Char -> @tt:String -> Pair(Cls, String)
a leading space is blank or indented, and that class already carries the line
def classify.hold.space source · line 153 · raw
@space:Bool -> @+xx:U32 -> @cc:Char -> @tt:String -> Pair(Cls, String)
whitespace, else a keyword
def classify.hold.hash source · line 161 · raw
@is_hash:Bool -> @space:Bool -> @xx:U32 -> @cc:Char -> @tt:String -> Pair(Cls, String)
a comment keeps its text; anything else is whitespace or a keyword
def classify.hold.open source · line 169 · raw
@+xx:U32 -> @+cc:Char -> @tt:String -> Pair(Cls, String)
the first character, then the rest of the line
def classify.hold source · line 173 · raw
@ss:String -> Pair(Cls, String)
the class, and the line when the class does not already carry it
def name.stop source · line 181 · raw
@+hh:Char -> Bool
(, <, :, { or a space ends a name
def name.push source · line 188 · raw
@stop:Bool -> @hh:Char -> @acc:String -> String
a delimiter is not part of the name
def name.go source · line 196 · raw
@ss:String -> @acc:String -> @stop:Bool -> String
the name, reversed into acc, up to a delimiter
def name source · line 206 · raw
@ss:String -> String
the name that starts a header: up to (, <, :, { or a space
def lstrip.go source · line 209 · raw
@cs:List<&2, Char> -> List<&2, Char>
def lstrip source · line 217 · raw
@ss:String -> String
leading spaces dropped
def nonempty source · line 221 · raw
@ss:String -> Bool
not ""?
def words source · line 225 · raw
@ss:String -> List<&2, String>
the words of a line
def undoc source · line 229 · raw
@+ss:String -> String
a comment line without its #
def undoc.all source · line 233 · raw
@doc:List<&2, String> -> @acc:List<&2, String> -> List<&2, String>
def doc_text source · line 241 · raw
@doc:List<&2, String> -> String
the comment block (reversed) as text
def sig_text source · line 245 · raw
@sig:List<&2, String> -> String
the pending header lines (reversed) as one text
def add source · line 249 · raw
@mm:Maybe<&2, Item> -> @out:List<&2, Item> -> List<&2, Item>
an item, when there is one, onto the items
def import_item.of source · line 257 · raw
@ws:List<&2, String> -> @ss:String -> @nn:U32 -> @doc:String -> Maybe<&2, Item>
import <path> as <Alias> is named by its alias; import Base by its path
def import_item source · line 267 · raw
@+ss:String -> @nn:U32 -> @doc:String -> Maybe<&2, Item>
an import line as an item: import Base, or import <path> as <Alias>
def def_name source · line 271 · raw
@+ss:String -> String
the name of a def or @unsafe def line
def starts_upper.of source · line 274 · raw
@cs:List<&2, Char> -> Bool
def starts_upper source · line 282 · raw
@ss:String -> Bool
does the text start with a capital?
def ctor.of source · line 286 · raw
@+tt:String -> @nn:U32 -> Maybe<&2, Item>
an indented line of a type block: Ctor{..}
def ctor source · line 291 · raw
@text:String -> @nn:U32 -> Maybe<&2, Item>
an indented line of a type block as a constructor item, when it is one
def is_def source · line 295 · raw
@kk:ItemKind -> Bool
a def?
def flush source · line 303 · raw
@mode:Mode -> @out:List<&2, Item> -> List<&2, Item>
what was pending becomes an item
def ends_colon.is source · line 311 · raw
@kk:0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.TokKind -> Bool
a : token?
def ends_colon.go source · line 319 · raw
@toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> @prev:Bool -> Bool
the tokens walked so far ended in :; a space or a comment keeps that
def ends_colon source · line 328 · raw
@ss:String -> Bool
the line's last token that is not a space or a comment is :, so a header
ends at its : though a comment follows it (def f() -> U32: # note)
def pend_more.closed source · line 332 · raw
@colon:Bool -> @nm:String -> @ll:U32 -> @dd:String -> @sig:List<&2, String> -> @text:String -> @nn:U32 -> @out:List<&2, Item> -> St
a def continuation that does or does not end in :
def pend_more.def source · line 349 · raw
@nm:String -> @ll:U32 -> @dd:String -> @sig:List<&2, String> -> @+text:String -> @nn:U32 -> @out:List<&2, Item> -> St
one more line of a def header
def pend_more source · line 361 · raw
@kk:ItemKind -> @nm:String -> @ll:U32 -> @dd:String -> @sig:List<&2, String> -> @text:String -> @nn:U32 -> @out:List<&2, Item> -> St
one more line of a pending header; a def's ends at the line that ends in :
def indent source · line 379 · raw
@mode:Mode -> @text:String -> @+nn:U32 -> @out:List<&2, Item> -> St
an indented line: more of a pending header, a constructor of an open type, or nothing
def stray source · line 390 · raw
@+mode:Mode -> @text:String -> @+nn:U32 -> @+out:List<&2, Item> -> St
a column-0 line that starts nothing: ) -> T: closing a def's header that
broke across lines; anywhere else it is junk, and ends what was pending
def start_def.on source · line 398 · raw
@colon:Bool -> @+ss:String -> @+nn:U32 -> @doc:String -> @out:List<&2, Item> -> St
a finished def, or a header that is still open
def start_def source · line 406 · raw
@+ss:String -> @+nn:U32 -> @doc:String -> @out:List<&2, Item> -> St
a def line: an item at once when it ends in :, else a pending header
def doc_above source · line 410 · raw
@mode:Mode -> @doc:List<&2, String> -> List<&2, String>
a comment continues the block above it only at the top level
def step.law source · line 418 · raw
@+ss:String -> @+nn:U32 -> @doc:String -> @mode:Mode -> @out:List<&2, Item> -> St
a law header, pending the block under it
def step.ty source · line 422 · raw
@+ss:String -> @+nn:U32 -> @doc:String -> @mode:Mode -> @out:List<&2, Item> -> St
a type header, and the block that follows it
def step.go source · line 426 · raw
@cls:Cls -> @+mode:Mode -> @ss:String -> @+nn:U32 -> @doc:List<&2, String> -> @out:List<&2, Item> -> St
def step.use source · line 446 · raw
@pp:Pair(Cls, String) -> @mode:Mode -> @+nn:U32 -> @doc:List<&2, String> -> @out:List<&2, Item> -> St
the class and the line, applied to the outline
def step.text.go source · line 451 · raw
@mode:Mode -> @ss:String -> @+nn:U32 -> @doc:List<&2, String> -> @out:List<&2, Item> -> St
a line inside a string: more of a pending header, else nothing
def step.text source · line 459 · raw
@ss:String -> @st:St -> St
a line inside a string, applied to the outline
def step.code source · line 464 · raw
@ss:String -> @st:St -> St
a line of code, by its class
def step source · line 469 · raw
@within:Bool -> @ss:String -> @st:St -> St
one line, by its class, or as text when within says it starts inside a string
def breaks source · line 478 · raw
@tt:String -> @+str:Bool -> @+acc:List<&2, Bool> -> List<&2, Bool>
one flag per line break in a text, onto acc (reversed), each str: whether the text is a string's
def inside.go source · line 485 · raw
@toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> @acc:List<&2, Bool> -> List<&2, Bool>
def inside source · line 494 · raw
@toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, Bool>
one flag per line, in order: does it start inside a string? Line 0 does not; the line after a line break does when the break sits in a string token
def inside.hit source · line 499 · raw
@ins:List<&2, Bool> -> Bool
does the line start inside a string? ins are the flags of it and the lines after it; none left is no
def inside.rest source · line 507 · raw
@ins:List<&2, Bool> -> List<&2, Bool>
the flags of the lines after this one
def run source · line 515 · raw
@lines:List<&2, String> -> @st:St -> @+ins:List<&2, Bool> -> St
every line, in order; ins flags the lines ahead that start inside a string
def finish source · line 523 · raw
@st:St -> List<&2, Item>
the items once the lines are over, a pending header flushed
def of_tokens source · line 528 · raw
@text:String -> @toks:List<&2, 0x013e0f9a479bbebad5ed196725eede95/src/syntax/lex.Tok> -> List<&2, Item>
the top-level items of a source whose tokens are already lexed, in order
def items source · line 532 · raw
@+text:String -> List<&2, Item>
the top-level items of a source, in order
def is_import source · line 539 · raw
@kk:ItemKind -> Bool
an import?
def find source · line 547 · raw
@items:List<&2, Item> -> @+name:String -> Maybe<&2, Item>
the item of that name; imports are not names of the module
def import_path source · line 556 · raw
@items:List<&2, Item> -> @+alias:String -> Maybe<&2, String>
the path behind an import alias
def has source · line 565 · raw
@names:List<&2, String> -> @+name:String -> Bool
is the name among these?
def starting.go source · line 572 · raw
@items:List<&2, Item> -> @+prefix:String -> @+qual:String -> @+seen:List<&2, String> -> List<&2, Item>
def starting source · line 585 · raw
@items:List<&2, Item> -> @prefix:String -> @qual:String -> List<&2, Item>
the named items whose name starts with prefix, each renamed qual ++ name (the text to insert). A law and the def that fills it share a name: the first stands for both.
def aliases source · line 589 · raw
@items:List<&2, Item> -> @+prefix:String -> List<&2, Item>
the import aliases that start with prefix (import Base has none)