In this commit we add support for loading multiple components into one
ghcide session.
The current behaviour is that each component is loaded lazily into the
session. When a file from an unrecognised component is loaded, the
cradle is consulted again to get a new set of options for the new
component. This will cause all the currently loaded files to be
reloaded into a new HscEnv which is shared by all the currently known
components. The result of this is that functions such as go-to
definition work between components if they have been loaded into the
same session but you have to open at least one file from each component
before it will work.
Only minimal changes are needed to the internals to ghcide to make the
file searching logic look in include directories for all currently
loaded components. The main changes are in exe/Main.hs which has been
heavily rewritten to avoid shake indirections. A global map is created
which maps a filepath to the HscEnv which should be used to compile it.
When a new component is created this map is completely refreshed so each
path maps to a new
Which paths belong to a componenent is determined by the targets listed
by the cradle. Therefore it is important that each cradle also lists all
the targets for the cradle. There are some other choices here as well
which are less accurate such as mapping via include directories which
is the aproach that I implemented in haskell-ide-engine.
The commit has been tested so far with cabal and hadrian.
Also deleted the .ghci file which was causing errors during testing and
seemed broken anyway.
Co-authored-by: Alan Zimmerman <alan.zimm@gmail.com>
Co-authored-by: fendor <power.walross@gmail.com>
* Update to hie-bios 0.5.0
* Fix test-cases due to changes in the direct cradle
* Update test/exe/Main.hs comment
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
Follow up from #557. We definitely want the progress state to be fully evaluated, so demand that with evaluating functions like evaluate and $!, rather than relying on the compiler to get it right. My guess is the `$!` is unnecessary now we have `evaluate`, but it's also not harmful, so belt and braces approach.
* Refactor rawDependencyInformation
There are two reasons why this patch is good:
1. We remove the special case of the initial module from the dependency
search. It is now treated uniformly like the rest of the modules.
2. rawDependencyInformation can now take a list of files and create
dependency information for all of them. This isn't currently used but on
my fork we have a rule which gets the dependency information for the
whole project in order to create a module graph.
It seemed simplest to upstream this part first, which is already a
strict improvement to make the overal patch easier to review.
* Make indentation not depend on identifier length
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* Rats: Fix space leak in withProgress
Eta-expanding the function means GHC no longer allocates a function
closure every time `withProgress` is called (which is a lot).
See: https://www.joachim-breitner.de/blog/763-Faster_Winter_5__Eta-Expanding_ReaderT
* Rats: Share computation of position mapping
Ensure that PositionMappings are shared between versions
There was a quadratic space leak as the tails of the position maps were
not shared with each other. Now the space usage is linear which is
produces more acceptable levels of residency after 3000 modifications.
* Rats: Eta-expand modification function
See: https://www.joachim-breitner.de/blog/763-Faster_Winter_5__Eta-Expanding_ReaderT
* Add a comment warning about eta-reducing
* Distinguish between a Delta and a Mapping in PositionMapping
A Delta is a change between two versions
A Mapping is a change from the current version to a specific older
version.
Fix hlint
Fix hlint
* Track dependencies when using qAddDependentFile
Closes#492
* Add test for qAddDependentFile
* Update test/exe/Main.hs
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* Update test/exe/Main.hs
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* [#518] Build ghcide with GHC 8.10.1
Resolves#518
* Move CPP logic to the Compat module
* Revert changes to mkHieFile
* Add local fork of HieAst for 8.10.1
The fix for mkHieFile didn't make it into 8.10.1, so the override is still needed
* Ignore hlint in src-ghc810/HieAst.hs
* Whitelist CPP for Development.IDE.GHC.Orphans
* [#518] Build ghcide with GHC 8.10.1
Resolves#518
* Move CPP logic to the Compat module
* Revert changes to mkHieFile
* Add local fork of HieAst for 8.10.1
The fix for mkHieFile didn't make it into 8.10.1, so the override is still needed
* Ignore hlint in src-ghc810/HieAst.hs
* Whitelist CPP for Development.IDE.GHC.Orphans
* Plugin tests known broken in 8.10.1 (#556)
* Bump up ghc-check version
Co-authored-by: Pepe Iborra <pepeiborra@gmail.com>
Co-authored-by: pepe iborra <pepeiborra@gmail.com>
* Add a custom prefix to command IDs
A client can run more than one instance of ghcide. Some clients have a global
command registry, and all commands must be unique in that registry.
So to make the command ids unique, prefix them with the ghcide server process
id, as is done in haskell-ide-engine.
* Use same command naming scheme as in haskell-language-server
To ease interoperability
* Use makeLspCommandId for prefixing commands
This puts all the prefixing logic in one place.
* Add hlint exception for CPP in Development.IDE.Compat
* Bring in Win32 dependency for windows build
* Create rule to get ModSummary without parsing entire source file
* Load file source from disk if not available in memory
* Fix build after cherry pick
* Couple of fixes
- extract getModSummaryFromImports and fix diagnostics
- replace GetParsedModule by GetModSummary where possible
There is only one usage of GetParsedModule left, and that is in GetSpanInfos
for documentation. This the wrong approach, docs should be loaded from
interface files and not from sources. TODO
* Fix watched file tests
Progress notifications are not being sent anymore
* Compat with GHC 8.6
* Avoid parsing source files for completions and documentation
Instead, embed haddocks in interface files
* Allow CPP in module
* Force things after parsing in order to release buffers
* avoid holding on to stringbuffer unnecessarily
* Skip unnecessary file contents read
* Drop HscEnv requirement
* Add comments on forcing things
* Add comments on GHC_LIB restriction
* Parse files of interest twice to capture Haddock errors
If Opt_Haddock is not enabled we parse twice to capture Haddock parse errors
* Parallelize two-pass parsing
* Update src/Development/IDE/Core/Compile.hs
Co-authored-by: Marcelo Lazaroni <lazaronijunior@gmail.com>
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* Expose codeAction and codeLens providers for haskell-language-server
Also tweak the code action reply type to generate well-formed JSON
* Expose moduleOutline for symbolProvider in hls too
* Revert to using [CAResult] rather than List CAResult
* Rules for loading interface files
* Typechecking with interface files
* Add a note in the README about the optimal project setup
* Improve support for hs-boot files
The branch was failing to load GHC because the module graph was missing
edges between a .hs file and its .hs-boot file. This means the .hs-boot
file was getting added into the HPT after the .hs file which led to
confusing errors about variables being out of scope.
The fix is to maintain a map from hs-boot to hs files and then add an
edge for this case when calling `transitiveDependencies`.
Also tidy up some code in setupEnv which I assume was attempting to fix
this but in an incorrect manner.
Add the -boot suffix when looking for hi-boot files.
For some reason, the `hi` path is not set to the right thing for
`hs-boot` files. I don't know why not perhaps it is ok to use an
existing `.hi` file in place of an `hs-boot` file. More investigation
needed. My experience is that GHC is quite bad a recompilation avoidance
for hs-boot files anyway.
For example: https://gitlab.haskell.org/ghc/ghc/issues/17434
Add the -boot suffix when writing interface files
* Generate .hi and .hie files during type checking
* Refactor GetModIface to not retain TypeChecked module in memory
This improves memory performance on a cold cache.
* Trailing whitespace
* Turn debug log messages into diagnostics
* Implement "hie" files for ghc-8.6.5
This means that the .hi files patch can also be used with 8.6.5
* Add tests for hover/definition on imported symbols
* hlints
* Generate .hie files when missing
* Fix subtle bug in setDefaultHieDir
* Simplify optimal project setup in README
* Move interface loading diagnostics behind --test flag
Reusing the --test flag for this seems harmless, I cannot justify introducing a
new flag
* Avoid expensive interface file generation for files of interest
* avoid redundant arguments (thanks Moritz K)
* qualify a DAML only comment
* Skip module source when generating hie file
thanks Moritz Kiefer for noting that we don't care for the generated .hie files
to embed module sources
* runGhcEnv <-> evalGhcEnv
* Apply suggestions from code review
Thanks Moritz Kiefer
Co-Authored-By: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* Add suggested Show instance
Co-Authored-By: Matthew Pickering <matthewtpickering@gmail.com>
* Use Control.Exception.Safe
This is to avoid accidentally capturing asynchronous exceptions
* Rename atomicFileUpdate
* Fix a flaky test
We have to be careful with module naming in tests to avoid interference of .hi
files across tests
* Undo formatting of D.IDE.GHC.Util
* follow changes in master
Co-authored-by: Matthew Pickering <matthewtpickering@gmail.com>
Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
* Use custom version of h-l-t
* Use normalized path functions from h-l-t
* Restore empty path corner case
* Create a wrapper over NFP to override IsString
* Use maybe instead fromMaybe
* Use patched version of lsp-types in all yaml files
* Remove unused import
* Rename specific NormalizeFilePath to NormalizeFilePath'
* Remove specific newtype and IsString instance
* Use released haskell-lsp-0.21
* Adapt to type changes of haskell-lsp-0.21
* Add tags field to CompletionItem
* Fix test case about empty file path
* Correct stack.yaml used in azure ci cache
* Build ghcide including tests in windows azure ci
* Qualify haskell-lsp modules to avoid name clashes
The completion context determines whether we show completions for
types or completions for values. This is done by looking at the parsed
module.
This PR fixes two things:
1. While we only use the parsed module for getting the context
previously we got the parsed module out of the typechecked
module. This means that if you have a module that parses but
doesn’t typecheck, we will use the parsed module at the point where
it last typechecked which is out of date and produces incorrect (or
just no) contexts.
2. When we could not find a context, we defaulted to assuming we are
in a value context. Especially in combination with 1 but also just
in general, this is rather annoying. If we aren’t sure we should
show the user everything we have and not filter out some
completions. Filtering out completions interacts particularly badly
with VSCode’s default behavior of accepting the first completion
when you press return.
It causes problems for our conversion to DAML-LF atm and isn’t
necessary (since we don’t have template Haskell) so let’s make it
configurable. I originally thought we could just copy paste all of
compileModule to DAML but it turns out that this pull in too much
stuff that I don’t want to see diverge from `ghcide` so I abandoned
that idea.
This is necessary for DAML where we have additional
keywords (e.g. `with`) and other keywords don’t
exist (e.g. `foreign`).
I considered using just a modify function `[T.Text] -> [T.Text]`
but decided against it in the end. The list is small enough and I
think it’s much easier to understand with an explicit enumeration (and
you can just show the field in the options which is often convenient
for debugging).
* Add azure job for windows and ghc-8.6
* Trigger build in branches starting with azure
* Add other valid stack.yaml to windows using matrix
* Using azure task Cache@2 instead CacheBeta@0
* Ignore tests in windows for now
* Install happy standalone to avoid spurious build error
* Add comment about installing happy
* Use matrix names more consistent with existing ones
* Enable build using ghc-8.8.2 for windows
* Ignore .vscode dir
* Use templates and matrix in linux job
* Working on Plugin support for hls
Fix PluginCommand reply type for executeCommand needs
* Remove PluginCommand
It will move to haskell-language-server instead
* Make azure CI hlint happy
By removing explicit OverloadedStrings pragma, in favour of the one already
enabled in the cabal file.
* Remove unneeded 'do'
* Fix more nits from review
* Fix isWorkspaceFile for relative paths
This fixes a performance regression on GetFileExists
* Avoid interrupting hie-bios when it's doing its thing
I noticed that the GHC hie-bios direct cradle, which uses Hadrian, a Shake build
system, was failing to start due to the following problem:
1. ghcide starts evaluating the LoadCradle node
2. The evaluation gets cancelled
3. Immediately after, ghcide starts evaluating LoadCradle again
4. Hadrian fails, since there is still another Hadrian process alive taking its
Shake lock
* Improve watched files test suite