Skip to content

Lsp #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 291 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
291 commits
Select commit Hold shift + click to select a range
8893f50
readds build all on start
roryc89 Sep 26, 2024
2621a98
types showing on hover
roryc89 Sep 26, 2024
376197f
hovering works
roryc89 Sep 27, 2024
fc3fa88
IDE: don't force state results (#4546)
roryc89 Sep 29, 2024
287fb33
remove ed instance extern changes
roryc89 Sep 30, 2024
7eff2a9
adds corefn inserting
roryc89 Sep 30, 2024
ce27550
clean up
roryc89 Oct 1, 2024
5e56301
fix queries
roryc89 Oct 1, 2024
b89aa29
remove noisy logs
roryc89 Oct 1, 2024
e8f504d
snake case cols
roryc89 Oct 1, 2024
1b663a8
fixes decoding for core fn queries
roryc89 Oct 1, 2024
bcbf7e6
adds type on hover
roryc89 Oct 1, 2024
7f0c30e
go to definition for by source pos working
roryc89 Oct 1, 2024
7284928
adds environment and decl indexing
roryc89 Oct 1, 2024
707f6c8
adds docs lookup
roryc89 Oct 1, 2024
55c11a3
hover over typeclasses showing kind
roryc89 Oct 2, 2024
0d4a271
get more docs on hover
roryc89 Oct 2, 2024
bfab3d3
type class go to definition working
roryc89 Oct 2, 2024
0238024
adds logs for no found decl
roryc89 Oct 2, 2024
454a1d8
get smallest declarations first
roryc89 Oct 2, 2024
39e1d90
Effect and Unit go to def working
roryc89 Oct 2, 2024
8313d3a
stop unneeded indexing
roryc89 Oct 2, 2024
65e3741
suggestions looking decent
roryc89 Oct 2, 2024
4200bff
start SMethod_CompletionItemResolve
roryc89 Oct 2, 2024
5c2b17b
adds json decl to code complete
roryc89 Oct 2, 2024
6e839aa
use same monad for lsp logic and handlers
roryc89 Oct 3, 2024
02a92ee
move handlers to own module
roryc89 Oct 3, 2024
d115503
better log labels
roryc89 Oct 3, 2024
f82eb75
add reactor to lsp server
roryc89 Oct 3, 2024
d687616
remove comments
roryc89 Oct 3, 2024
1395565
removes diagnostics ref
roryc89 Oct 3, 2024
28d2498
unqualified imports working
roryc89 Oct 3, 2024
7e0a3e6
starts lsp test setup
roryc89 Oct 4, 2024
31bfc8d
remove init state
roryc89 Oct 4, 2024
f41abcd
adds compile custom command to lsp
roryc89 Oct 4, 2024
2683d11
adds compile command and test scaffold
roryc89 Oct 4, 2024
66251b0
only fetch needed externs
roryc89 Oct 4, 2024
55ccd1e
adds time logs
roryc89 Oct 4, 2024
6485911
get definition test passing
roryc89 Oct 5, 2024
e99728f
add lsp desugar
roryc89 Oct 5, 2024
783fc63
adds EnvironmentFn
roryc89 Oct 5, 2024
a1b6de8
start rebuildModuleUsingDbEnv
roryc89 Oct 5, 2024
1b5208f
faster completion
roryc89 Oct 6, 2024
9067b50
use typechecked module
roryc89 Oct 6, 2024
e54dd0c
Async env: start
roryc89 Oct 6, 2024
0366387
Revert "Async env: start"
roryc89 Oct 6, 2024
943d4e8
adds desugarLsp
roryc89 Oct 7, 2024
8ae18c4
get externs from sqlite ordered
roryc89 Oct 7, 2024
9f33f18
adds rebuildModuleWithProvidedEnv
roryc89 Oct 7, 2024
6dfbafe
remove comments
roryc89 Oct 7, 2024
71b25d2
adds perf logs
roryc89 Oct 7, 2024
08a4613
only search in available srcs
roryc89 Oct 7, 2024
17a490d
add ast modules for paths
roryc89 Oct 7, 2024
8a18899
update available srcs on init
roryc89 Oct 7, 2024
f56f1df
add update available srcs function
roryc89 Oct 7, 2024
8c493a3
find definitions is fast
roryc89 Oct 7, 2024
e054cb2
remove perf log
roryc89 Oct 7, 2024
2ca741d
adds cancellation to request
roryc89 Oct 7, 2024
abc381d
search for module names on type
roryc89 Oct 8, 2024
5eaa17f
put each request on a separate thread and catch errors
roryc89 Oct 8, 2024
a800bfc
fix imports length
roryc89 Oct 8, 2024
1003e09
better type displays
roryc89 Oct 8, 2024
6da5ce6
adds method to errors
roryc89 Oct 8, 2024
e6e4d0e
delete comment
roryc89 Oct 8, 2024
0162ad8
remove logs
roryc89 Oct 8, 2024
e45665f
remove unused import
roryc89 Oct 8, 2024
d7cedc9
move to map env
roryc89 Oct 8, 2024
821b355
only load required files into export env
roryc89 Oct 8, 2024
de49453
fast cached rebuilds
roryc89 Oct 8, 2024
2fd6d19
remove open and save rebuild
roryc89 Oct 8, 2024
bda8b52
put handlers in their own modules
roryc89 Oct 9, 2024
84f6468
remove Config var from HandlerM
roryc89 Oct 9, 2024
343428f
adds cancel running requests
roryc89 Oct 9, 2024
82e296e
adds cancellation and error handling
roryc89 Oct 9, 2024
2ae4d0c
use vfs for rebuilding and diagnostics
roryc89 Oct 9, 2024
6ade82c
remove will save sync
roryc89 Oct 9, 2024
fa1537a
remove comma
roryc89 Oct 9, 2024
f31bcf6
easier to read logs
roryc89 Oct 10, 2024
76747e9
prettier logging
roryc89 Oct 10, 2024
b3a5d01
move from glob to instr, remove value selection of ast decls, add Nam…
roryc89 Oct 13, 2024
bc1dab5
fix go to definition for values bugs
roryc89 Oct 13, 2024
d72bae3
fix decl at line
roryc89 Oct 13, 2024
e4cea7f
type definition via ast working
roryc89 Oct 13, 2024
f3d7018
adds type var lookups
roryc89 Oct 13, 2024
77419c8
adds import defintions
roryc89 Oct 13, 2024
3c9f963
adds type for imports without docs
roryc89 Oct 13, 2024
846f147
fix getting last decl
roryc89 Oct 14, 2024
8033aaf
adds hover for local bindings
roryc89 Oct 14, 2024
ee5cae6
adds hover to types using ast
roryc89 Oct 14, 2024
857fc44
clean up
roryc89 Oct 14, 2024
bf5d16b
remove unused queries
roryc89 Oct 14, 2024
5b39f4d
stop storing declaration blobs
roryc89 Oct 14, 2024
3429485
remove end env from cache
roryc89 Oct 14, 2024
4b3de18
adds clear cache commands
roryc89 Oct 14, 2024
8cd5544
remove spaces from commands
roryc89 Oct 14, 2024
bc25b19
removes unnecessary indexing
roryc89 Oct 14, 2024
efa7be9
auto complete working better without manual triggering
roryc89 Oct 14, 2024
eddff6b
adds index custom handler
roryc89 Oct 14, 2024
d821f4f
adds index full
roryc89 Oct 14, 2024
d14e52f
clean up
roryc89 Oct 14, 2024
3b977bc
use purs-lsp-client config section in tests
roryc89 Oct 15, 2024
54e2639
remove env config and use lsp config
roryc89 Oct 15, 2024
2625cd6
remove unused lsp command opts
roryc89 Oct 15, 2024
91b2884
use purescript-lsp config section
roryc89 Oct 15, 2024
d36e71f
remove logs
roryc89 Oct 15, 2024
ae624c2
adds db path log
roryc89 Oct 15, 2024
341f673
canonicalize DB path
roryc89 Oct 15, 2024
e4cd06a
better methods logging
roryc89 Oct 15, 2024
7a967c4
show expression on hover
roryc89 Oct 15, 2024
703a2e5
only update available srcs when needed
roryc89 Oct 16, 2024
aff1581
index ast modules from externs
roryc89 Oct 16, 2024
ae05715
move loglevel to own module and log perf on indexing
roryc89 Oct 16, 2024
f3f0fb8
adds running method debug
roryc89 Oct 16, 2024
69bdc98
make ast declarations unique
roryc89 Oct 16, 2024
8872890
adds hover and go to definition for type class instances
roryc89 Oct 16, 2024
f427864
adds hover and goto def for class members
roryc89 Oct 17, 2024
f54e648
adds monad base control to HandlerM
roryc89 Oct 17, 2024
fe86256
read externs concurrently
roryc89 Oct 17, 2024
b678342
use lifted async for lsp handlers
roryc89 Oct 17, 2024
adabb52
use record syntax for unHandlerM
roryc89 Oct 17, 2024
d415019
adds outputPath to default config
roryc89 Oct 17, 2024
6aeb89c
remove unused arg from codegen
roryc89 Oct 17, 2024
a23e99f
rebuild module even when typechecking fails
roryc89 Oct 17, 2024
249a5a7
use parser to get qualifier name
roryc89 Oct 17, 2024
6f8fac5
rebuild without cache if imports fail
roryc89 Oct 18, 2024
5693acd
rebuild without cache if imports fail
roryc89 Oct 18, 2024
d502cd5
adds constructors to indexing
roryc89 Oct 21, 2024
41e06b2
ctr imports working
roryc89 Oct 21, 2024
8ed7ed3
dont loose import on equal
roryc89 Oct 21, 2024
b0647a6
adds operator search
roryc89 Oct 21, 2024
ef36c07
adds printed types for operators when indexing
roryc89 Oct 21, 2024
72144e3
adds completion kinds
roryc89 Oct 21, 2024
5e77425
names name type not null
roryc89 Oct 21, 2024
e3baba7
insert externs concurrently
roryc89 Oct 21, 2024
52499f5
remove progress indicator as not working
roryc89 Oct 21, 2024
dde90b7
removes module and position from error messages
roryc89 Oct 22, 2024
59f93f1
adds apply all changes quickfix
roryc89 Oct 22, 2024
bb9c5d1
adds purs-tidy formatter
roryc89 Oct 22, 2024
5ff7162
adds import sorting to formatting
roryc89 Oct 22, 2024
c222463
display data and ctr types better
roryc89 Oct 23, 2024
ea57f21
remove logs
roryc89 Oct 23, 2024
d52bd4d
display name types in autocomplete
roryc89 Oct 23, 2024
b8da8a8
check for more possible errors due to cache
roryc89 Oct 23, 2024
5f83c13
dont show value inline for completion
roryc89 Oct 23, 2024
6ca3705
adds everything at types
roryc89 Oct 23, 2024
5b44ffa
hover working for expressions
roryc89 Oct 24, 2024
7512126
adds type value hovering
roryc89 Oct 25, 2024
2d5cba5
adds hover for direct where decls
roryc89 Oct 25, 2024
882b14c
adds inferExprType
roryc89 Oct 26, 2024
c210d86
hover via typed holes working
roryc89 Oct 28, 2024
9c84b89
on hover expr show inference, source type and docs
roryc89 Oct 28, 2024
9b8a65c
remove logs
roryc89 Oct 29, 2024
db4e877
adds binder on hover
roryc89 Oct 29, 2024
68deae6
use lazy state
roryc89 Oct 29, 2024
b3a5086
remove logs
roryc89 Oct 29, 2024
e130e01
adds option to not infer
roryc89 Oct 29, 2024
613a726
bold docs
roryc89 Oct 29, 2024
a8adee5
type kinds on hover fixed
roryc89 Oct 29, 2024
faea44a
fix type syn signatures
roryc89 Oct 30, 2024
be4b701
type class signatures showing
roryc89 Oct 30, 2024
2231c46
get smallest expr
roryc89 Oct 30, 2024
c973284
fixes type alias hovering
roryc89 Oct 30, 2024
a2432af
remove logs
roryc89 Oct 30, 2024
d30b8f9
clean up
roryc89 Oct 30, 2024
9aa5abe
Merge branch 'master' of https://github.com/purescript/purescript int…
roryc89 Oct 31, 2024
0d2d49d
go back to type hole inference
roryc89 Oct 31, 2024
9c07400
adds check state to cache
roryc89 Oct 31, 2024
355c0f9
adds IdeArtifacts
roryc89 Nov 1, 2024
ae6065c
dont track generated expressions
roryc89 Nov 1, 2024
0275285
countUnkownsAndVars
roryc89 Nov 1, 2024
f5596da
use inferBinder instead of inferBinder'
roryc89 Nov 1, 2024
62c2557
revert addIdeExpr
roryc89 Nov 1, 2024
3a7a19d
adds applied types for constructors on hover
roryc89 Nov 2, 2024
8e89356
adds applied types to functions with contrained types
roryc89 Nov 2, 2024
2a5aa80
show substituted types on exprs
roryc89 Nov 4, 2024
202f589
hover showing substituted types
roryc89 Nov 4, 2024
6bc7383
on purs projects hover is running fast but without type substituion
roryc89 Nov 4, 2024
6a93d35
on purs projects hover is running fast but with limited type substitu…
roryc89 Nov 4, 2024
4c19995
decent hover without inferring all expressions
roryc89 Nov 5, 2024
560c68a
remove unneeded ide adding
roryc89 Nov 5, 2024
6682610
adds handling for type synonyms
roryc89 Nov 5, 2024
a7ad826
adds hover on imports
roryc89 Nov 5, 2024
d79bb17
goto def working with artifacts
roryc89 Nov 5, 2024
f2f80d3
remove logs
roryc89 Nov 6, 2024
802325f
use set for artifacts
roryc89 Nov 6, 2024
832e21a
add log for getting diags
roryc89 Nov 6, 2024
cc92ed0
increase cache size
roryc89 Nov 6, 2024
102a9b3
adds functions to cache envs
roryc89 Nov 6, 2024
4a83529
set cache size in mb
roryc89 Nov 6, 2024
05bb2ae
adds export caching
roryc89 Nov 7, 2024
44bd44f
adds in memory caching for environments
roryc89 Nov 7, 2024
b97a48b
fixes ide binders and classnames
roryc89 Nov 7, 2024
13a9209
stop prim hover
roryc89 Nov 7, 2024
c1af4d9
remove hover debug and clean up
roryc89 Nov 7, 2024
8b93fe1
fixes get at position on multi lines
roryc89 Nov 7, 2024
c02599c
fix binder type
roryc89 Nov 7, 2024
e2715bd
adds full rebuild caching
roryc89 Nov 10, 2024
2e373e1
remove test logs
roryc89 Nov 11, 2024
2c29c0c
remove export env from state
roryc89 Nov 12, 2024
2ff0537
adds option to show error module and filepath
roryc89 Nov 12, 2024
dc0e981
better name for diagnostics options
roryc89 Nov 12, 2024
674829e
use force instead of NFData
roryc89 Nov 12, 2024
4d672f0
adds debug-cache-size-evaluated
roryc89 Nov 12, 2024
d2dc3b7
adds refences handler placeholder
roryc89 Nov 15, 2024
48f96dc
adds debug logs for definition
roryc89 Nov 15, 2024
d56fe72
adds format in place
roryc89 Nov 25, 2024
f624114
remove unused import
roryc89 Nov 25, 2024
29b54d2
use longer of ranges
roryc89 Nov 25, 2024
db07957
fix format in place
roryc89 Nov 25, 2024
a26dfe0
adds partial artifacts
roryc89 Nov 28, 2024
e08c605
adds env tables and sql functions
roryc89 Nov 29, 2024
d6afa0b
adds env indexing
roryc89 Dec 1, 2024
7083814
starts rebuildModuleWithIndexDb
roryc89 Dec 2, 2024
2a6a449
adds selectEnvFromImports using env
roryc89 Dec 2, 2024
2e15089
fixes operator selecting
roryc89 Dec 2, 2024
62519c2
type classes importing associated types
roryc89 Dec 2, 2024
af7f8fd
operators importing
roryc89 Dec 3, 2024
c1e3619
clean up
roryc89 Dec 3, 2024
e956f3a
adds op alias importing
roryc89 Dec 3, 2024
d842ca5
adds dict constructor importing
roryc89 Dec 4, 2024
b7c2adc
try getting class dicts but failing as before typechecking
roryc89 Dec 4, 2024
15f4240
adds imports insert
roryc89 Dec 4, 2024
815283b
use exports for hidden imports
roryc89 Dec 5, 2024
3be413a
fixes merging of intances in env
roryc89 Dec 5, 2024
be1eefc
adds env name constraints
roryc89 Dec 5, 2024
832d3d2
value fixities importing with definition module names
roryc89 Dec 10, 2024
63d05f7
type fixities importing with definition module names
roryc89 Dec 10, 2024
e0d6c7a
working but without type synonyms
roryc89 Dec 16, 2024
299383a
adds type synonyms
roryc89 Dec 16, 2024
1e7c284
adds GetEnv
roryc89 Dec 19, 2024
b9624a7
remove checkExhaustiveExpr env
roryc89 Dec 19, 2024
b25fbca
uses GetEnv in Coercible
roryc89 Dec 20, 2024
91bb2e0
use db for type synonyms
roryc89 Dec 20, 2024
52c6111
simple purs building
roryc89 Dec 20, 2024
ef80b10
adds db env to corefn desugaring
roryc89 Dec 27, 2024
98bcacc
dont store ide imports
roryc89 Dec 27, 2024
96daaf9
remove comments
roryc89 Dec 27, 2024
e6810b1
allow ' in decoded idents
roryc89 Dec 27, 2024
4fe0b4e
moves selection of type class instances to entailment
roryc89 Dec 27, 2024
e7e59a6
only fetch dicts when needed
roryc89 Dec 30, 2024
dae4bdd
force eval
roryc89 Dec 30, 2024
dc22b3a
delete class instances when deleting env
roryc89 Dec 30, 2024
7662cb7
store more env in memory
roryc89 Dec 30, 2024
28b261c
fix selectDoesClassInstanceExist
roryc89 Jan 1, 2025
aae15d7
stop indexing that was leaking memory
roryc89 Jan 2, 2025
f828eab
complex project building without errors
roryc89 Jan 2, 2025
336a1eb
adds modules to db
roryc89 Jan 3, 2025
f533a00
start makeDb
roryc89 Jan 3, 2025
3d7033c
adds db build plan
roryc89 Jan 7, 2025
7775451
remove double delete
roryc89 Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
hovering works
roryc89 committed Sep 27, 2024
commit 376197f38cc3271984d06d757af2916d85573740
8 changes: 4 additions & 4 deletions app/Command/Lsp.hs
Original file line number Diff line number Diff line change
@@ -28,21 +28,21 @@ command = Opts.helper <*> subcommands
"server"
( Opts.info
(fmap server serverOptions <**> Opts.helper)
(Opts.progDesc "Start a server process")
(Opts.progDesc "Start a server LSP process")
)
]

server :: ServerOptions -> IO ()
server opts'@(ServerOptions dir globs _globsFromFile _globsExcluded outputPath logLevel) = do
when
(logLevel == LogDebug || logLevel == LogAll)
(putText "Parsed Options:" *> print opts')
(hPutStrLn stderr ("Parsed Options:" :: Text) *> hPutStrLn stderr (show opts' :: Text))
maybe (pure ()) setCurrentDirectory dir
let conf =
LspConfig
{ confOutputPath = outputPath,
confGlobs = globs,
confLogLevel = logLevel
confGlobs = globs
-- confLogLevel = logLevel
}
env <- mkEnv conf
startServer env
2 changes: 2 additions & 0 deletions purescript.cabal
Original file line number Diff line number Diff line change
@@ -342,7 +342,9 @@ library
Language.PureScript.Lsp
Language.PureScript.Lsp.DB
Language.PureScript.Lsp.Cache
Language.PureScript.Lsp.Cache.IO
Language.PureScript.Lsp.Cache.Query
Language.PureScript.Lsp.Print
Language.PureScript.Lsp.Rebuild
Language.PureScript.Lsp.State
Language.PureScript.Lsp.Types
103 changes: 64 additions & 39 deletions src/Language/PureScript/Lsp/Cache.hs
Original file line number Diff line number Diff line change
@@ -8,17 +8,20 @@ import Data.Map qualified as Map
import Data.Set qualified as Set
import Data.Text qualified as T
import Database.SQLite.Simple
import Language.PureScript qualified as P
import Language.PureScript.AST qualified as P
import Language.PureScript.AST.Declarations (declName, declRefName, declSourceAnn)
import Language.PureScript.Externs (ExternsFile (efModuleName), externsFileName)
import Language.PureScript.AST.SourcePos (SourceSpan (spanName))
import Language.PureScript.Externs (ExternsFile (efModuleName, efSourceSpan))
import Language.PureScript.Externs qualified as P
import Language.PureScript.Ide.Error (IdeError (GeneralError))
import Language.PureScript.Ide.Externs (readExternFile)
import Language.PureScript.Ide.Types (ModuleMap)
import Language.PureScript.Lsp.DB qualified as DB
import Language.PureScript.Lsp.Print (printEfDeclName, printName)
import Language.PureScript.Lsp.Types (LspConfig (..), LspEnvironment (lspConfig))
import Language.PureScript.Lsp.Util (efDeclCategory, efDeclName, efDeclSourceSpan, printDeclarationType, printName)
import Language.PureScript.Lsp.Util (efDeclCategory, efDeclSourceSpan)
import Language.PureScript.Names qualified as P
import Protolude
import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents)
import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents, makeAbsolute)
import System.FilePath (normalise, (</>))
import "monad-logger" Control.Monad.Logger (MonadLogger)

@@ -34,20 +37,32 @@ dropTables = do
initDb :: (MonadReader LspEnvironment m, MonadIO m) => m ()
initDb = do
DB.execute_ "CREATE TABLE IF NOT EXISTS modules (module_name TEXT PRIMARY KEY, path TEXT, UNIQUE(module_name), UNIQUE(path))"
DB.execute_ "CREATE TABLE IF NOT EXISTS declarations (module_name TEXT, name TEXT, type_printed TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, comments TEXT, exported BOOLEAN, value BLOB, PRIMARY KEY (module_name, name))"
DB.execute_ "CREATE TABLE IF NOT EXISTS externs (path TEXT PRIMARY KEY, ef_version TEXT, value BLOB, module_name TEXT, UNIQUE(path), UNIQUE(module_name))"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_imports (module_name TEXT, import_name TEXT, imported_module TEXT, import_type TEXT, imported_as TEXT, value BLOB)"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_exports (module_name TEXT, export_name TEXT, value BLOB, name TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER)"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_declarations (module_name TEXT, name TEXT, value BLOB, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, category TEXT)"
DB.execute_ "CREATE TABLE IF NOT EXISTS declarations (module_name TEXT, name BLOB, printed_name TEXT, type_printed TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, comments TEXT, exported BOOLEAN, value BLOB, shown TEXT, PRIMARY KEY (module_name, name))"
DB.execute_ "CREATE TABLE IF NOT EXISTS externs (path TEXT PRIMARY KEY, ef_version TEXT, value BLOB, module_name TEXT, shown TEXT, UNIQUE(path), UNIQUE(module_name))"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_imports (module_name TEXT, imported_module TEXT, import_type TEXT, imported_as TEXT, value BLOB)"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_exports (module_name TEXT, export_name TEXT, value BLOB, name BLOB, printed_name TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER)"
DB.execute_ "CREATE TABLE IF NOT EXISTS ef_declarations (module_name TEXT, name TEXT, value BLOB, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, category TEXT, shown TEXT)"

selectAllExternsMap :: (MonadIO m, MonadReader LspEnvironment m) => m (ModuleMap ExternsFile)
selectAllExternsMap :: (MonadIO m, MonadReader LspEnvironment m) => m (Map P.ModuleName ExternsFile)
selectAllExternsMap = do
Map.fromList . fmap (\ef -> (efModuleName ef, ef)) <$> selectAllExterns

selectAllExterns :: (MonadIO m, MonadReader LspEnvironment m) => m [ExternsFile]
selectAllExterns = do
DB.query_ (Query "SELECT value FROM externs") <&> fmap (deserialise . fromOnly)

selectExternFromFilePath :: (MonadIO m, MonadReader LspEnvironment m) => FilePath -> m (Maybe ExternsFile)
selectExternFromFilePath path = do
absPath <- liftIO $ makeAbsolute path
res <- DB.queryNamed (Query "SELECT value FROM externs WHERE path = :path") [":path" := absPath]
pure $ deserialise . fromOnly <$> listToMaybe res

selectExternModuleNameFromFilePath :: (MonadIO m, MonadReader LspEnvironment m) => FilePath -> m (Maybe P.ModuleName)
selectExternModuleNameFromFilePath path = do
absPath <- liftIO $ makeAbsolute path
res <- DB.queryNamed (Query "SELECT module_name FROM externs WHERE path = :path") [":path" := absPath]
pure $ P.ModuleName . fromOnly <$> listToMaybe res

insertAllExterns ::
( MonadIO m,
MonadReader LspEnvironment m,
@@ -59,9 +74,9 @@ insertAllExterns = do
oDir <- asks (confOutputPath . lspConfig)
externPaths <- findAvailableExterns
forM_ externPaths $ \name -> do
extern <- readExternFile (oDir </> toS (P.runModuleName name) </> P.externsFileName)

insertExtern oDir extern
let externPath = oDir </> toS (P.runModuleName name) </> P.externsFileName
extern <- readExternFile externPath
insertExtern extern

-- | Finds all the externs inside the output folder and returns the
-- corresponding module names
@@ -87,17 +102,19 @@ findAvailableExterns = do

insertExtern ::
(MonadIO m, MonadReader LspEnvironment m) =>
FilePath ->
ExternsFile ->
m ()
insertExtern outDir extern = do
insertExtern extern = do
path <- liftIO $ makeAbsolute externPath
DB.executeNamed
(Query "INSERT OR REPLACE INTO externs (path, ef_version, value, module_name) VALUES (:path, :ef_version, :value, :module_name)")
[ ":path" := externsPath,
(Query "INSERT OR REPLACE INTO externs (path, ef_version, value, module_name, shown) VALUES (:path, :ef_version, :value, :module_name, :shown)")
[ ":path" := path,
":ef_version" := P.efVersion extern,
":value" := serialise extern,
":module_name" := P.runModuleName name
":module_name" := P.runModuleName name,
":shown" := (show extern :: Text)
]

DB.executeNamed
(Query "DELETE FROM ef_imports WHERE module_name = :module_name")
[":module_name" := P.runModuleName name]
@@ -111,8 +128,8 @@ insertExtern outDir extern = do
[":module_name" := P.runModuleName name]
forM_ (P.efDeclarations extern) $ insertEfDeclaration name
where
externsPath = outDir </> T.unpack (P.runModuleName name) <> externsFileName
name = efModuleName extern
externPath = spanName (efSourceSpan extern)

insertEfImport :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> P.ExternsImport -> m ()
insertEfImport moduleName' ei = do
@@ -128,10 +145,11 @@ insertEfImport moduleName' ei = do
insertEfDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> P.ExternsDeclaration -> m ()
insertEfDeclaration moduleName' decl = do
DB.executeNamed
(Query "INSERT OR REPLACE INTO ef_declarations (module_name, value, name, start_col, start_line, end_col, end_line, category) VALUES (:module_name, :value, :name, :start_col, :start_line, :end_col, :end_line, :category)")
(Query "INSERT OR REPLACE INTO ef_declarations (module_name, value, shown, name, start_col, start_line, end_col, end_line, category) VALUES (:module_name, :value, :shown, :name, :start_col, :start_line, :end_col, :end_line, :category)")
[ ":module_name" := P.runModuleName moduleName',
":name" := efDeclName decl,
":name" := printEfDeclName decl,
":value" := serialise decl,
":shown" := (show decl :: Text),
":start_col" := (P.sourcePosColumn . P.spanStart) span,
":start_line" := (P.sourcePosLine . P.spanStart) span,
":end_col" := (P.sourcePosColumn . P.spanEnd) span,
@@ -144,10 +162,11 @@ insertEfDeclaration moduleName' decl = do
insertEfExport :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> P.DeclarationRef -> m ()
insertEfExport moduleName' dr = do
DB.executeNamed
(Query "INSERT OR REPLACE INTO ef_exports (module_name, value, name, start_col, start_line, end_col, end_line) VALUES (:module_name, :value, :name, :start_col, :start_line, :end_col, :end_line)")
(Query "INSERT OR REPLACE INTO ef_exports (module_name, value, name, printed_name, start_col, start_line, end_col, end_line) VALUES (:module_name, :value, :name, :printed_name, :start_col, :start_line, :end_col, :end_line)")
[ ":module_name" := P.runModuleName moduleName',
":value" := serialise dr,
":name" := printName (declRefName dr),
":name" := serialise (declRefName dr),
":printed_name" := printName (declRefName dr),
":start_col" := (P.sourcePosColumn . P.spanStart) span,
":start_line" := (P.sourcePosLine . P.spanStart) span,
":end_col" := (P.sourcePosColumn . P.spanEnd) span,
@@ -166,25 +185,31 @@ insertModule srcPath m = do
]

let exported = Set.fromList $ P.exportedDeclarations m
DB.executeNamed "DELETE FROM declarations WHERE module_name = :module_name" [":module_name" := P.runModuleName moduleName']
traverse_ (insertDeclaration moduleName' exported) (P.getModuleDeclarations m)

insertDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Set P.Declaration -> P.Declaration -> m ()
insertDeclaration moduleName' exportedDecls decl = do
DB.executeNamed
(Query "INSERT OR REPLACE INTO declarations (module_name, name, type_printed, start_col, start_line, end_col, end_line, comments, exported, value) VALUES (:module_name, :name, :type_printed, :start_col, :start_line, :end_col, :end_line, :comments, :exported, :value)")
[ ":module_name" := P.runModuleName moduleName',
":name" := maybe (show decl) printName (declName decl),
":type_printed" := typeName,
":start_col" := (P.sourcePosColumn . P.spanStart) declLocation,
":start_line" := (P.sourcePosLine . P.spanStart) declLocation,
":end_col" := (P.sourcePosColumn . P.spanEnd) declLocation,
":end_line" := (P.sourcePosLine . P.spanEnd) declLocation,
":comments" := encode comments,
":exported" := exported,
":value" := serialise decl
]
for_ (declName decl) $ \name -> do
DB.executeNamed
( Query
"INSERT OR REPLACE INTO declarations \
\(module_name, name, printed_name, start_col, start_line, end_col, end_line, comments, exported, value, shown) \
\VALUES \
\(:module_name, :name, :printed_name, :start_col, :start_line, :end_col, :end_line, :comments, :exported, :value, :shown)"
)
[ ":module_name" := P.runModuleName moduleName',
":name" := serialise name,
":printed_name" := printName name,
":start_col" := (P.sourcePosColumn . P.spanStart) declLocation,
":start_line" := (P.sourcePosLine . P.spanStart) declLocation,
":end_col" := (P.sourcePosColumn . P.spanEnd) declLocation,
":end_line" := (P.sourcePosLine . P.spanEnd) declLocation,
":comments" := encode comments,
":exported" := exported,
":value" := serialise decl,
":shown" := (show decl :: Text)
]
where
typeName = printDeclarationType decl

exported = Set.member decl exportedDecls
(declLocation, comments) = declSourceAnn decl
23 changes: 23 additions & 0 deletions src/Language/PureScript/Lsp/Cache/IO.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Language.PureScript.Lsp.Cache.IO where

import Protolude
import Database.SQLite.Simple qualified as SQL


dropTables :: SQL.Connection -> IO ()
dropTables conn = do
SQL.execute_ conn "DROP TABLE IF EXISTS modules"
SQL.execute_ conn "DROP TABLE IF EXISTS declarations"
SQL.execute_ conn "DROP TABLE IF EXISTS externs"
SQL.execute_ conn "DROP TABLE IF EXISTS ef_imports"
SQL.execute_ conn "DROP TABLE IF EXISTS ef_exports"
SQL.execute_ conn "DROP TABLE IF EXISTS ef_declarations"

initDb :: SQL.Connection -> IO ()
initDb conn = do
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS modules (module_name TEXT PRIMARY KEY, path TEXT, UNIQUE(module_name), UNIQUE(path))"
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS declarations (module_name TEXT, name BLOB, printed_name TEXT, type_printed TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, comments TEXT, exported BOOLEAN, value BLOB, shown TEXT, PRIMARY KEY (module_name, name))"
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS externs (path TEXT PRIMARY KEY, ef_version TEXT, value BLOB, module_name TEXT, shown TEXT, UNIQUE(path), UNIQUE(module_name))"
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS ef_imports (module_name TEXT, imported_module TEXT, import_type TEXT, imported_as TEXT, value BLOB)"
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS ef_exports (module_name TEXT, export_name TEXT, value BLOB, name BLOB, printed_name TEXT, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER)"
SQL.execute_ conn "CREATE TABLE IF NOT EXISTS ef_declarations (module_name TEXT, name TEXT, value BLOB, start_col INTEGER, start_line INTEGER, end_col INTEGER, end_line INTEGER, category TEXT, shown TEXT)"
57 changes: 42 additions & 15 deletions src/Language/PureScript/Lsp/Cache/Query.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wno-unused-matches #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}

module Language.PureScript.Lsp.Cache.Query where

@@ -12,7 +14,10 @@ import Data.Set qualified as Set
import Data.Text qualified as T
import Database.SQLite.Simple
import Language.LSP.Protocol.Types (Position)
import Language.PureScript qualified as P
import Language.PureScript.AST qualified as P
import Language.PureScript.Comments qualified as P
import Language.PureScript.Externs qualified as P
import Language.PureScript.Names qualified as P
import Language.PureScript.AST.Declarations (declSourceAnn)
import Language.PureScript.AST.Traversals (accumTypes)
import Language.PureScript.Externs (ExternsFile (efModuleName), externsFileName)
@@ -21,25 +26,24 @@ import Language.PureScript.Ide.Externs (readExternFile)
import Language.PureScript.Ide.Types (ModuleMap)
import Language.PureScript.Lsp.DB qualified as DB
import Language.PureScript.Lsp.Types (LspConfig (..), LspEnvironment (lspConfig))
import Language.PureScript.Lsp.Util (printName)
import Language.PureScript.Pretty.Types (prettyPrintType)
import Protolude
import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents)
import System.FilePath (normalise, (</>))
import Control.Monad.Trans.Writer (execWriterT)
import Language.PureScript.Lsp.Print (printName)

-- getDeclarationAt :: (MonadIO m, MonadReader LspEnvironment m) => Position -> m (Maybe P.Declaration)
-- getDeclarationAt pos = do
-- getEfDeclarationAt :: (MonadIO m, MonadReader LspEnvironment m) => Position -> m (Maybe P.Declaration)
-- getEfDeclarationAt pos = do
-- decls <-
-- DB.queryNamed
-- "SELECT * FROM declarations WHERE startLine <= :line AND endLine >= :line AND startColumn <= :column AND endColumn >= :column"
-- [":line" := line
-- , ":column" := column
-- ]
-- pure $ listToMaybe decls

-- getImportedModules


getEfImports :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> m [P.ExternsImport]
getEfImports moduleName' = do
imports <-
@@ -54,24 +58,29 @@ importMightContainIdent ident import' = case P.eiImportType import' of
P.Explicit refs -> any ((==) ident . printName . P.declRefName) refs
P.Hiding refs -> not $ any ((==) ident . printName . P.declRefName) refs

getDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe P.ExternsDeclaration)
getDeclaration moduleName' name = do
getEfDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe (P.ModuleName, P.ExternsDeclaration))
getEfDeclaration moduleName' name = do
inModule <- getEfDeclarationOnlyInModule moduleName' name
case inModule of
Just decl -> pure $ Just decl
Nothing -> getImportedDeclaration moduleName' name
Just decl -> pure $ Just (moduleName', decl)
Nothing -> getEFImportedDeclaration moduleName' name


getImportedDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe P.ExternsDeclaration)
getImportedDeclaration moduleName' name = do
getEFImportedDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe (P.ModuleName, P.ExternsDeclaration))
getEFImportedDeclaration moduleName' name = do
imports <- filter (importMightContainIdent name) <$> getEfImports moduleName'
foldM go Nothing imports
where
go :: (MonadIO m, MonadReader LspEnvironment m) => Maybe P.ExternsDeclaration -> P.ExternsImport -> m (Maybe P.ExternsDeclaration)
go ::
(MonadIO m, MonadReader LspEnvironment m) =>
Maybe (P.ModuleName, P.ExternsDeclaration) ->
P.ExternsImport ->
m (Maybe (P.ModuleName, P.ExternsDeclaration))
go acc import' = do
case acc of
Just _ -> pure acc
Nothing -> getEfDeclarationOnlyInModule (P.eiModule import') name
Nothing -> fmap (toTup $ P.eiModule import') <$> getEfDeclarationOnlyInModule (P.eiModule import') name

toTup a b = (a, b)

getEfDeclarationOnlyInModule :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe P.ExternsDeclaration)
getEfDeclarationOnlyInModule moduleName' name = do
@@ -82,3 +91,21 @@ getEfDeclarationOnlyInModule moduleName' name = do
":name" := name
]
pure $ deserialise . fromOnly <$> listToMaybe decls

getDeclaration :: (MonadIO m, MonadReader LspEnvironment m) => P.ModuleName -> Text -> m (Maybe P.Declaration)
getDeclaration moduleName' name = do
decls <-
DB.queryNamed
"SELECT value FROM declarations WHERE module_name = :module_name AND name = :name"
[ ":module_name" := P.runModuleName moduleName',
":name" := name
]
pure $ deserialise . fromOnly <$> listToMaybe decls


getDeclarationDocumentation :: (MonadIO m, MonadReader LspEnvironment m) => P.Module -> P.Declaration -> m [P.Comment]
getDeclarationDocumentation module' decl =
execWriterT $ do
P.everywhereOnValuesM handleDecl pure pure ^. _1 $ decl
where
handleDecl = pure
Loading
Oops, something went wrong.