compiler environment docs

This commit is contained in:
XeroOl 2025-07-30 00:24:43 -05:00
parent 27a7548453
commit 1733cbab94
4 changed files with 209 additions and 30 deletions

View File

@ -4,7 +4,8 @@ LUA ?= lua
FENNEL=$(if $(wildcard fennel),$(LUA) fennel,fennel)
EXE=fennel-ls
SRC:=$(shell find src -name "*.fnl")
SRC:=$(shell find src -name "*.fnl" | grep -v "/generated/")
TOOLS:=$(shell find tools -name "*.fnl")
DESTDIR ?=
PREFIX ?= /usr/local
@ -41,12 +42,18 @@ install: $(EXE) build/fennel-ls.1
docs: src/fennel-ls/docs/generated/lua51.fnl \
src/fennel-ls/docs/generated/lua52.fnl \
src/fennel-ls/docs/generated/lua53.fnl \
src/fennel-ls/docs/generated/lua54.fnl
src/fennel-ls/docs/generated/lua54.fnl \
src/fennel-ls/docs/generated/compiler-env.fnl
src/fennel-ls/docs/generated/%.fnl:
src/fennel-ls/docs/generated/lua%.fnl: $(TOOLS)
mkdir -p build/
mkdir -p src/fennel-ls/docs/generated/
$(FENNEL) $(FENNELFLAGS) tools/generate-lua-docs.fnl ${*} > $@
$(FENNEL) $(FENNELFLAGS) tools/generate-lua-docs.fnl lua${*} > $@
src/fennel-ls/docs/generated/compiler-env.fnl: $(TOOLS)
mkdir -p build/
mkdir -p src/fennel-ls/docs/generated/
$(FENNEL) $(FENNELFLAGS) tools/generate-compiler-env-docs.fnl ${*} > $@
docs/lints.md: src/fennel-ls/lint.fnl
$(FENNEL) $(FENNELFLAGS) tools/extract-lint-docs.fnl > $@

View File

@ -0,0 +1,116 @@
{:assert-compile {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["condition"
"msg"
"ast"
"?fallback-ast"]
:fnl/docstring "Assert a condition and raise a compile error with line numbers.
The ast arg should be unmodified so that its first element is the form called."}}
:ast-source {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["ast"]
:fnl/docstring "Get a table for the given ast which includes file/line info, if possible."}}
:comment {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["contents" "?source"]}}
:comment? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x"]}}
:fennel-module-name {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist []}}
:gensym {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["base"]}}
:get-scope {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist []}}
:in-scope? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["symbol"]}}
:list {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist [...]
:fnl/docstring "Create a new list. Lists are a compile-time construct in Fennel; they are
represented as tables with a special marker metatable. They only come from
the parser, and they represent code which comes from reading a paren form;
they are specifically not cons cells."}}
:list? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x"]
:fnl/docstring "Checks if an object is a list. Returns the object if is."}}
:macro-loaded {:fields {}}
:macroexpand {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["form"]}}
:multi-sym? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["str"]
:fnl/docstring "Returns a table containing the symbol's segments if passed a multi-sym.
A multi-sym refers to a table field reference like tbl.x or access.channel:deny.
Returns nil if passed something other than a multi-sym."}}
:pack {}
:sequence {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist [...]
:fnl/docstring "Create a new sequence. Sequences are tables that come from the parser when
it encounters a form with square brackets. They are treated as regular tables
except when certain macros need to look for binding forms, etc specifically."}}
:sequence? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x"]
:fnl/docstring "Checks if an object is a sequence (created with a [] literal)"}}
:sym {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["str" "?source"]
:fnl/docstring "Create a new symbol. Symbols are a compile-time construct in Fennel and are
not exposed outside the compiler. Second optional argument is a table describing
where the symbol came from; should be a table with filename, line, bytestart,
and byteend fields."}}
:sym? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x" "?name"]
:fnl/docstring "Checks if an object is a symbol. Returns the object if it is.
When given a second string argument, will check that the sym's name matches it."}}
:table? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x"]
:fnl/docstring "Checks if an object any kind of table, EXCEPT list/symbol/varg/comment."}}
:unpack {}
:varg? {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x"]
:fnl/docstring "Checks if an object is the varg symbol. Returns the object if is."}}
:version {:definition "1.5.3"}
:view {:metadata {:fls/fntype "fn"
:fls/itemKind "Function"
:fnl/arglist ["x" "?options"]
:fnl/docstring "Return a string representation of x.
Can take an options table with the following keys:
* :one-line? (default: false) keep the output string as a one-liner
* :depth (number, default: 128) limit how many levels to go (default: 128)
* :detect-cycles? (default: true) don't try to traverse a looping table
* :metamethod? (default: true) use the __fennelview metamethod if found
* :empty-as-sequence? (default: false) render empty tables as []
* :line-length (number, default: 80) length of the line at which
multi-line output for tables is forced
* :escape-newlines? (default: false) emit strings with \\n instead of newline
* :prefer-colon? (default: false) emit strings in colon notation when possible
* :utf8? (default: true) whether to use the utf8 module to compute string lengths
* :max-sparse-gap: maximum gap to fill in with nils in sparse sequential tables
* :preprocess (function) if present, called on x (and recursively on each value
in x), and the result is used for pretty printing; takes the same arguments as
`fennel.view`
* :infinity, :negative-infinity - how to serialize infinity and negative infinity
* :nan, :negative-nan - how to serialize NaN and negative NaN values
All options can be set to `{:once some-value}` to force their value to be
`some-value` but only for the current level. After that, the option is reset
to its default value. Alternatively, `{:once value :after other-value}` can
be used, with the difference that after the first use, the options will be set to
`other-value` instead of the default value.
You can set a `__fennelview` metamethod on a table to override its serialization
behavior; see the API reference for details."}}}

View File

@ -0,0 +1,40 @@
(local fennel (require :fennel))
(local files (require :fennel-ls.files))
(local analyzer (require :fennel-ls.analyzer))
(local navigate (require :fennel-ls.navigate))
(local docs (require :fennel-ls.docs))
(local {: create-client} (require :test.utils))
(local get-deps (require :tools.get-deps))
;; ensure fennel source is present
(get-deps.get-fennel)
;; use fennel-ls to observe fennel/specials.fnl (make-compiler-env)
(local {: server : uri}
(create-client {:main.fnl "(local {: make-compiler-env} (require :fennel.specials))
(make-compiler-env)"
:flsproject.fnl "{:fennel-path \"build/fennel/src/?.fnl\"}"}))
(set server.root-uri "file://.")
(local file (files.get-by-uri server uri))
(local result (analyzer.search server file (. file.ast (length file.ast)) {} {}))
;; convert results into a doc file
(tset (getmetatable (fennel.sym "x")) :__fennelview #(fennel.view (. $ 1)))
(fn into-doc [result]
(if (= (type result.definition) :string)
{:definition result.definition}
{:metadata (navigate.getmetadata server result)
:fields (if (navigate.has-fields server result)
(collect [key field (navigate.iter-fields server result)]
key (into-doc field)))}))
(print (fennel.view (collect [key field (navigate.iter-fields server result)]
(if (and (not (docs.get-global server nil key))
(not (key:find "^_")))
(values key (into-doc field))))))

View File

@ -15,34 +15,50 @@
(local dkjson-sha1sum "19b27918b411b52b1c2b0061dd479672cb746687 build/dkjson.lua")
;; get fennel
(sh :mkdir :-p "build/")
(when (not (io.open "build/fennel/fennel"))
(git-clone "build/fennel"
"https://git.sr.ht/~technomancy/fennel"
fennel-version)
(sh :make :-C "build/fennel"))
(fn get-fennel []
(sh :mkdir :-p "build/")
(when (not (io.open "build/fennel/fennel"))
(git-clone "build/fennel"
"https://git.sr.ht/~technomancy/fennel"
fennel-version)
(sh :make :-C "build/fennel")))
;; get faith
(when (not (io.open "build/faith/faith.fnl"))
(git-clone "build/faith" "https://git.sr.ht/~technomancy/faith" faith-version))
(fn get-faith []
(when (not (io.open "build/faith/faith.fnl"))
(git-clone "build/faith" "https://git.sr.ht/~technomancy/faith" faith-version)))
;; get penlight.stringio
(when (not (io.open "build/penlight/lua/pl/stringio.lua"))
(git-clone "build/penlight" "https://github.com/lunarmodules/Penlight" penlight-version))
;; we clone all of penlight, but only stringio.lua will be installed
(fn get-penlight-stringio []
(when (not (io.open "build/penlight/lua/pl/stringio.lua"))
(git-clone "build/penlight" "https://github.com/lunarmodules/Penlight" penlight-version)))
;; get dkjson
(when (not (io.open "build/dkjson.lua"))
(sh :curl (.. "http://dkolf.de/dkjson-lua/dkjson-" dkjson-version ".lua") [:>] "build/dkjson.lua")
(assert (sh :echo dkjson-md5sum [:|] :md5sum "--check" "--status"))
(assert (sh :echo dkjson-sha1sum [:|] :sha1sum "--check" "--status")))
(fn get-dkjson []
(when (not (io.open "build/dkjson.lua"))
(sh :curl (.. "http://dkolf.de/dkjson-lua/dkjson-" dkjson-version ".lua") [:>] "build/dkjson.lua")
(assert (sh :echo dkjson-md5sum [:|] :md5sum "--check" "--status"))
(assert (sh :echo dkjson-sha1sum [:|] :sha1sum "--check" "--status"))))
;; copy to the "deps" folder
(sh :mkdir :-p "deps/")
(sh :cp "build/fennel/fennel" ".")
(sh :cp "build/fennel/fennel.lua" "deps/")
(sh :cp "build/faith/faith.fnl" "deps/")
(sh :mkdir :-p "deps/pl")
(sh :cp "build/penlight/lua/pl/stringio.lua" "deps/pl/")
(sh :cp "build/penlight/LICENSE.md" "deps/pl/")
(sh :cp "build/dkjson.lua" "deps/")
(fn install []
;; installing just means copying to the "deps" folder
(sh :mkdir :-p "deps/")
(sh :cp "build/fennel/fennel" ".")
(sh :cp "build/fennel/fennel.lua" "deps/")
(sh :cp "build/faith/faith.fnl" "deps/")
(sh :mkdir :-p "deps/pl")
(sh :cp "build/penlight/lua/pl/stringio.lua" "deps/pl/")
(sh :cp "build/penlight/LICENSE.md" "deps/pl/")
(sh :cp "build/dkjson.lua" "deps/"))
(when (not ...)
(get-fennel)
(get-faith)
(get-penlight-stringio)
(get-dkjson)
(install))
{: get-fennel
: get-faith
: get-penlight-stringio
: get-dkjson
: install}