Refactoring / comments

This commit is contained in:
XeroOl 2022-08-29 10:10:09 -05:00
parent 9b25d09bcd
commit 2c47e61f2c
No known key found for this signature in database
GPG Key ID: 9DD4B4B4DAED0322
2 changed files with 55 additions and 38 deletions

View File

@ -39,10 +39,11 @@ later by fennel-ls.language to answer requests from the client."
"Compile the file, and record all the useful information from the compiler into the file object"
;; The useful information being recorded:
(let [definitions-by-scope (doto {} (setmetatable has-tables-mt))
definitions {}
diagnostics {}
references {}
require-calls {}]
definitions {} ; symbol -> definition
diagnostics {} ; [diagnostic]
references {} ; symbol -> references
scopes {} ; ast -> scope
require-calls {}]; ast -> boolean (does this ast start with the symbol `require)
(λ find-definition [name ?scope]
(when ?scope
@ -106,7 +107,7 @@ later by fennel-ls.language to answer requests from the client."
(define-function-args ast scope))
(λ call [ast scope]
;; handles every function call
(tset scopes ast scope)
;; Most calls aren't interesting, but here's the list of the ones that are:
(match ast
;; This cannot be done through the :fn feature of the compiler plugin system
@ -114,10 +115,6 @@ later by fennel-ls.language to answer requests from the client."
;; TODO check if hashfn needs to be here
[-fn-]
(define-function ast scope)
[-λ-]
(define-function ast scope)
[-lambda-]
(define-function ast scope)
[-require- modname]
(tset require-calls ast true)))
@ -144,6 +141,8 @@ later by fennel-ls.language to answer requests from the client."
:codeDescription "compiler error"}))
(error "__NOT_AN_ERROR"))
(local allowed-globals (icollect [k v (pairs _G)] k))
;; TODO clean up this code. It's awful now that there is error handling
(let
[plugin
@ -157,7 +156,7 @@ later by fennel-ls.language to answer requests from the client."
scope (fennel.scope)
opts {:filename file.uri
:plugins [plugin]
:allowedGlobals (icollect [k v (pairs _G)] k)
:allowedGlobals allowed-globals
:requireAsInclude false
: scope}
parser (partial pcall (fennel.parser file.text file.uri opts))
@ -168,14 +167,14 @@ later by fennel-ls.language to answer requests from the client."
(table.insert diagnostics
{:range (message.pos->range 0 0 0 0)
:message err})))]
(set file.ast ast)
;; write things back to the file object
;; (set file.definitions-by-scope definitions-by-scope) ;; not needed yet
(set file.ast ast)
(set file.scopes scopes)
(set file.definitions definitions)
(set file.diagnostics diagnostics)
(set file.references references)
(set file.require-calls require-calls))))
;; (set file.compiled? true))
(set file.require-calls require-calls)
(set file.allowed-globals allowed-globals))))
{: compile}

View File

@ -3,13 +3,14 @@ You finally made it. Here is the main code that implements the language server p
Every time the client sends a message, it gets handled by a function in the corresponding table type.
(ie, a textDocument/didChange notification will call notifications.textDocument/didChange
and a textDocument/defintion request will call requests.textDocument/didChange)"
and a textDocument/defintion request will call requests.textDocument/definition)"
(local {: pos->byte : apply-changes} (require :fennel-ls.utils))
(local message (require :fennel-ls.message))
(local state (require :fennel-ls.state))
(local language (require :fennel-ls.language))
(local formatter (require :fennel-ls.formatter))
(local utils (require :fennel-ls.utils))
(local {: view} (require :fennel))
@ -19,8 +20,11 @@ Every time the client sends a message, it gets handled by a function in the corr
(local capabilities
{:textDocumentSync 1 ;; FIXME: upgrade to 2
;; :notebookDocumentSync nil
;; :completionProvider nil
:hoverProvider {:workDoneProgress false}
:completionProvider {:workDoneProgress false} ;; TODO
:hoverProvider {:workDoneProgress false
:resolveProvider false
:triggerCharacters ["(" "[" "{" "." ":" "\""]
:completionItem {:labelDetailsSupport false}}
;; :signatureHelpProvider nil
;; :declarationProvider nil
:definitionProvider {:workDoneProgress false}
@ -63,29 +67,43 @@ Every time the client sends a message, it gets handled by a function in the corr
:serverInfo {:name "fennel-ls" :version "0.0.0"}})
(λ requests.textDocument/definition [self send {: position :textDocument {: uri}}]
(local file (state.get-by-uri self uri))
(local byte (pos->byte file.text position.line position.character))
(match-try (language.find-symbol file.ast byte)
(symbol parents)
(match-try
(let [parent (. parents (length parents))]
(if (. file.require-calls parent)
(language.search self file parent [])))
nil
(language.search-main self file symbol))
(result result-file)
(message.range-and-uri
(or result.binding result.?definition)
result-file)
(catch _ nil)))
(let [file (state.get-by-uri self uri)
byte (pos->byte file.text position.line position.character)]
(match-try (language.find-symbol file.ast byte)
(symbol parents)
(match-try
(let [parent (. parents (length parents))]
(if (. file.require-calls parent)
(language.search self file parent [])))
nil
(language.search-main self file symbol))
(result result-file)
(message.range-and-uri
(or result.binding result.?definition)
result-file)
(catch _ nil))))
(λ requests.textDocument/hover [self send {: position :textDocument {: uri}}]
(local file (state.get-by-uri self uri))
(local byte (pos->byte file.text position.line position.character))
(match-try (language.find-symbol file.ast byte)
symbol (language.search-main self file symbol)
result {:contents {:kind "markdown"
:value (formatter.hover-format result)}}))
(let [file (state.get-by-uri self uri)
byte (pos->byte file.text position.line position.character)]
(match-try (language.find-symbol file.ast byte)
symbol (language.search-main self file symbol)
result {:contents {:kind "markdown"
:value (formatter.hover-format result)}})))
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]
(let [file (state.get-by-uri self uri)
byte (pos->byte file.text position.line position.character)
(?symbol parents) (language.find-symbol file.ast byte)]
;; TODO build a recursive searcher,
;; store file scopes parents length parents as an intermediate
;; potentially reverse parents order so it's only (. parents 1)
(let [begin (if (?. file.scopes (. parents (length parents)))
(icollect [k (pairs (. file.scopes (. parents (length parents)) :manglings))]
{:label k})
[])]
(icollect [_ k (ipairs file.allowed-globals) &into begin] {:label k}))))
(λ notifications.textDocument/didChange [self send {: contentChanges :textDocument {: uri}}]
(local file (state.get-by-uri self uri))