mirror of
https://github.com/haskell/haskell-ide-engine.git
synced 2024-09-11 11:05:30 +03:00
Merge remote-tracking branch 'upstream/master' into wip/friday-fixes
This commit is contained in:
commit
a0296aef4c
@ -29,4 +29,12 @@ jobs:
|
||||
- bash: |
|
||||
source .azure/linux.bashrc
|
||||
stack install.hs help
|
||||
displayName: Run help of `instal.hs`
|
||||
displayName: Run help of `install.hs`
|
||||
- bash: |
|
||||
source .azure/linux.bashrc
|
||||
stack install.hs stack-install-cabal
|
||||
displayName: Run stack-install-cabal target of `install.hs`
|
||||
- bash: |
|
||||
source .azure/linux.bashrc
|
||||
stack install.hs build-latest
|
||||
displayName: Run build-latest target of `install.hs`
|
||||
|
@ -23,8 +23,6 @@ jobs:
|
||||
YAML_FILE: stack-8.4.3.yaml
|
||||
stack-8.4.2:
|
||||
YAML_FILE: stack-8.4.2.yaml
|
||||
stack-8.2.2:
|
||||
YAML_FILE: stack-8.2.2.yaml
|
||||
variables:
|
||||
STACK_ROOT: /home/vsts/.stack
|
||||
steps:
|
||||
|
@ -29,4 +29,12 @@ jobs:
|
||||
- bash: |
|
||||
source .azure/macos.bashrc
|
||||
stack install.hs help
|
||||
displayName: Run help of `instal.hs`
|
||||
displayName: Run help of `install.hs`
|
||||
- bash: |
|
||||
source .azure/macos.bashrc
|
||||
stack install.hs stack-install-cabal
|
||||
displayName: Run stack-install-cabal target of `install.hs`
|
||||
- bash: |
|
||||
source .azure/macos.bashrc
|
||||
stack install.hs build-latest
|
||||
displayName: Run build-latest target of `install.hs`
|
||||
|
@ -19,10 +19,8 @@ jobs:
|
||||
YAML_FILE: stack-8.4.3.yaml
|
||||
stack-8.4.2:
|
||||
YAML_FILE: stack-8.4.2.yaml
|
||||
stack-8.2.2:
|
||||
YAML_FILE: stack-8.2.2.yaml
|
||||
variables:
|
||||
STACK_ROOT: /Users/vsts/.stack
|
||||
STACK_ROOT: $(Build.SourcesDirectory)/.stack
|
||||
steps:
|
||||
- task: CacheBeta@0
|
||||
inputs:
|
||||
|
@ -27,4 +27,12 @@ jobs:
|
||||
- bash: |
|
||||
source .azure/windows.bashrc
|
||||
stack install.hs help
|
||||
displayName: Run help of `instal.hs`
|
||||
displayName: Run help of `install.hs`
|
||||
- bash: |
|
||||
source .azure/windows.bashrc
|
||||
stack install.hs stack-install-cabal
|
||||
displayName: Run stack-install-cabal target of `install.hs`
|
||||
- bash: |
|
||||
source .azure/windows.bashrc
|
||||
stack install.hs build-latest
|
||||
displayName: Run build-latest target of `install.hs`
|
||||
|
@ -21,8 +21,6 @@ jobs:
|
||||
YAML_FILE: stack-8.4.3.yaml
|
||||
stack-8.4.2:
|
||||
YAML_FILE: stack-8.4.2.yaml
|
||||
stack-8.2.2:
|
||||
YAML_FILE: stack-8.2.2.yaml
|
||||
variables:
|
||||
STACK_ROOT: "C:\\sr"
|
||||
|
||||
|
@ -101,21 +101,6 @@ defaults: &defaults
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
ghc-8.0.2:
|
||||
environment:
|
||||
- STACK_FILE: "stack-8.0.2.yaml"
|
||||
<<: *defaults
|
||||
|
||||
ghc-8.2.1:
|
||||
environment:
|
||||
- STACK_FILE: "stack-8.2.1.yaml"
|
||||
<<: *defaults
|
||||
|
||||
ghc-8.2.2:
|
||||
environment:
|
||||
- STACK_FILE: "stack-8.2.2.yaml"
|
||||
<<: *defaults
|
||||
|
||||
ghc-8.4.2:
|
||||
environment:
|
||||
- STACK_FILE: "stack-8.4.2.yaml"
|
||||
@ -199,7 +184,6 @@ workflows:
|
||||
version: 2
|
||||
multiple-ghcs:
|
||||
jobs:
|
||||
- ghc-8.2.2
|
||||
- ghc-8.4.2
|
||||
- ghc-8.4.3
|
||||
- ghc-8.4.4
|
||||
|
17
README.md
17
README.md
@ -178,7 +178,7 @@ sudo dnf install libicu-devel ncurses-devel
|
||||
|
||||
In order to avoid problems with long paths on Windows you can do the following:
|
||||
|
||||
1. Edit the group policy: set "Enable Win32 long paths" to "Enabled" (Works
|
||||
1. In the `Local Group Policy Editor`: `Local Computer Policy -> Computer Configuration -> Administrative Templates -> System -> Filesystem` set `Enable Win32 long paths` to `Enabled` (Works
|
||||
only for Windows 10).
|
||||
|
||||
2. Clone the `haskell-ide-engine` to the root of your logical drive (e.g. to
|
||||
@ -216,7 +216,7 @@ cabal v2-run ./install.hs --project-file install/shake.project <target>
|
||||
|
||||
Running the script with cabal on windows requires a cabal version greater or equal to `3.0.0.0`.
|
||||
|
||||
Unfortunately, it is still required to have `stack` installed so that the install-script can locate the `local-bin` directory (on Linux `~/.local/bin`) and copy the `hie` binaries to `hie-x.y.z`, which is required for the `hie-wrapper` to function as expected.
|
||||
Unfortunately, it is still required to have `stack` installed so that the install-script can locate the `local-bin` directory (on Linux `~/.local/bin`) and copy the `hie` binaries to `hie-x.y.z`, which is required for the `hie-wrapper` to function as expected. There are plans to remove this requirement and let users build hie only with one build tool or another.
|
||||
|
||||
For brevity, only the `stack`-based commands are presented in the following sections.
|
||||
|
||||
@ -246,13 +246,12 @@ stack ./install.hs hie-8.4.4
|
||||
stack ./install.hs build-data
|
||||
```
|
||||
|
||||
The Haskell IDE Engine can also be built with `cabal new-build` instead of `stack build`.
|
||||
The Haskell IDE Engine can also be built with `cabal v2-build` instead of `stack build`.
|
||||
This has the advantage that you can decide how the GHC versions have been installed.
|
||||
However, this approach does currently not work for windows due to a missing feature upstream.
|
||||
To see what GHC versions are available, the command `stack install.hs cabal-ghcs` can be used.
|
||||
It will list all GHC versions that are on the path and their respective installation directory.
|
||||
If you think, this list is incomplete, you can try to modify the PATH variable, such that the executables can be found.
|
||||
Note, that the targets `cabal-build`, `cabal-build-data` and `cabal-build-all` depend on the found GHC versions.
|
||||
Note, that the targets `cabal-build` and `cabal-build-data` depend on the found GHC versions.
|
||||
They install Haskell IDE Engine only for the found GHC versions.
|
||||
|
||||
An example output is:
|
||||
@ -274,12 +273,6 @@ stack install.hs cabal-hie-8.4.4
|
||||
stack install.hs cabal-build-data
|
||||
```
|
||||
|
||||
To install HIE for all GHC versions that are present on your system, use:
|
||||
|
||||
```bash
|
||||
stack ./install.hs cabal-build-all
|
||||
```
|
||||
|
||||
In general, targets that use `cabal` instead of `stack` are prefixed with `cabal-*` and are identical to their counterpart, except they do not install a GHC if it is missing but fail.
|
||||
|
||||
##### Multiple versions of HIE (optional)
|
||||
@ -503,7 +496,7 @@ Then issue `:CocConfig` and add the following to your Coc config file.
|
||||
"initializationOptions": {
|
||||
"languageServerHaskell": {
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -7,7 +7,6 @@ environment:
|
||||
- GHCVER: 8.4.4
|
||||
- GHCVER: 8.4.3
|
||||
- GHCVER: 8.4.2
|
||||
- GHCVER: 8.2.2
|
||||
install:
|
||||
- cmd: >-
|
||||
git submodule update --init --recursive
|
||||
|
@ -13,7 +13,6 @@ The design of the build system has the following main goals:
|
||||
- `stack`
|
||||
- `git`
|
||||
* is completely functional right after a simple `git clone` and after every `git pull`
|
||||
* one-stop-shop for building and naming all executables required for using `hie` in IDEs.
|
||||
* prevents certain build failures by either identifying a failed precondition (such as wrong `stack` version) or by performing the necessary steps so users can't forget them (such as invoking `git` to update submodules)
|
||||
|
||||
|
||||
@ -28,8 +27,9 @@ See the project's `README` for detailed information about installing `hie`.
|
||||
The build script `install.hs` defines several targets using the `shake` build system. The targets are roughly:
|
||||
|
||||
* `hie-*`: builds and installs the `hie` binaries. Also renames the binaries to contain the correct version-number.
|
||||
* `build`: builds and installs `hie` binaries for all supported `ghc` versions.
|
||||
* `build-latest`: builds and installs `hie` for the latest available and supported `ghc` version.
|
||||
* `build-data`: builds the hoogle-db required by `hie`
|
||||
* `build`: builds and installs `hie` for the latest supported `ghc` version (like `build-latest`) and the hoogle-db (like `build-data`)
|
||||
* `cabal-*`: execute the same task as the original target, but with `cabal` instead of `stack`
|
||||
|
||||
Each `stack-*.yaml` contains references to packages in the submodules. Calling `stack` with one of those causes the build to fail if the submodules have not been initialized already. The file `shake.yaml` solves this issue invoking the `git` binary itself to update the submodules. Moreover, it specifies the correct version of `shake` and is used for installing all run-time dependencies such as `cabal` and `hoogle` if necessary.
|
||||
@ -38,7 +38,7 @@ Each `stack-*.yaml` contains references to packages in the submodules. Calling `
|
||||
|
||||
`hie` depends on a correct environment in order to function properly:
|
||||
|
||||
* `cabal-install`: If no `cabal` executable can be found or has an outdated version, `cabal-install` is installed via `stack`.
|
||||
* `cabal-install`: This dependency is required by `hie` to handle correctly projects that are not `stack` based (without `stack.yaml`). You can install an appropiate version using `stack` with the `stack-install-cabal` target.
|
||||
* The `hoogle` database: `hoogle generate` needs to be called with the most-recent `hoogle` version.
|
||||
|
||||
### Steps to build `hie`
|
||||
@ -47,16 +47,15 @@ Installing `hie` is a multi-step process:
|
||||
|
||||
1. `git submodule sync && git submodule update --init`
|
||||
2. `hoogle generate` (`hoogle>=5.0.17` to be safe)
|
||||
3. ensure that `cabal-install` is installed in the correct version
|
||||
4. `stack --stack-yaml=stack-<X>.yaml install` or `cabal new-install -w ghc-<X>`
|
||||
5. rename `hie` binary to `hie-<X>` in `$HOME/.local/bin`, where `<X>` is the GHC version used
|
||||
6. repeat step 4 and 5 for all desired GHC versions
|
||||
3. `stack --stack-yaml=stack-<X>.yaml install` or `cabal v2-install -w ghc-<X>`
|
||||
4. rename `hie` binary to `hie-<X>` in `$HOME/.local/bin`, where `<X>` is the GHC version used
|
||||
5. repeat step 3 and 4 for all desired GHC versions
|
||||
|
||||
This ensures that a complete install is always possible after each `git pull` or a `git clone`.
|
||||
|
||||
#### Building `hie` with profiling support
|
||||
|
||||
To build `hie` with profiling enabled `cabal new-install` needs to be used instead of `stack`.
|
||||
To build `hie` with profiling enabled `cabal v2-install` needs to be used instead of `stack`.
|
||||
|
||||
Configure `cabal` to enable profiling by setting `profiling: True` in `cabal.project.local` for all packages. If that file does not already exist, create it as follows:
|
||||
|
||||
@ -71,7 +70,7 @@ Then `hie` can be compiled for a specific GHC version:
|
||||
|
||||
```bash
|
||||
export GHCP=<path-to-ghc-binary>
|
||||
cabal new-install exe:hie -w $GHCP \
|
||||
cabal v2-install exe:hie -w $GHCP \
|
||||
--write-ghc-environment-files=never --symlink-bindir=$HOME/.local/bin \
|
||||
--overwrite-policy=always --reinstall
|
||||
```
|
||||
@ -90,19 +89,17 @@ The final step is to configure the `hie` client to use a custom `hie-wrapper` sc
|
||||
The `install.hs` script performs some checks to ensure that a correct installation is possible and provide meaningful error messages for known issues.
|
||||
|
||||
* `stack` needs to be up-to-date. Version `1.9.3` is required
|
||||
* `cabal` needs to be up-to-date. Version `2.4.1.0` is required to *use* haskell-ide-engine until the pull request #1126 is merged. Unfortunately cabal version `3.0.0.0` is needed to *install* hie in windows systems but that inconsistence will be fixed by the mentioned pull request.
|
||||
* `ghc-8.6.3` is broken on windows. Trying to install `hie-8.6.3` on windows is not possible.
|
||||
* `cabal new-build` does not work on windows at the moment. All `cabal-*` targets exit with an error message about that.
|
||||
* When the build fails, an error message, that suggests to remove `.stack-work` directory, is displayed.
|
||||
|
||||
### Tradeoffs
|
||||
|
||||
#### `stack` is a build dependency
|
||||
|
||||
Currently, it is not possible to build all `hie-*` executables automatically without `stack`, since the `install.hs` script is executed by `stack`.
|
||||
Currently, `stack` is needed even if you run the script with `cabal` to get the path where install the binaries but there are plans to remove that dependency (see #1380).
|
||||
|
||||
We are open to suggestions of other build systems that honor the requirements above, but are executable without `stack`.
|
||||
|
||||
#### `install.hs` installs a GHC before running
|
||||
#### run `install.hs` with `stack` installs a GHC before running
|
||||
|
||||
Before the code in `install.hs` can be executed, `stack` installs a `GHC`, depending on the `resolver` field in `shake.yaml`. This is necessary if `install.hs` should be completely functional right after a fresh `git clone` without further configuration.
|
||||
|
||||
|
@ -69,8 +69,8 @@ library
|
||||
, gitrev >= 1.1
|
||||
, haddock-api
|
||||
, haddock-library
|
||||
, haskell-lsp == 0.17.*
|
||||
, haskell-lsp-types == 0.17.*
|
||||
, haskell-lsp == 0.18.*
|
||||
, haskell-lsp-types == 0.18.*
|
||||
, haskell-src-exts
|
||||
, hie-plugin-api
|
||||
, hoogle >= 5.0.13
|
||||
@ -98,10 +98,7 @@ library
|
||||
, hie-bios
|
||||
, bytestring-trie
|
||||
, unliftio
|
||||
if impl(ghc < 8.4)
|
||||
build-depends: hlint >= 2.0.11 && < 2.1.18
|
||||
else
|
||||
build-depends: hlint >= 2.2.2
|
||||
, hlint >= 2.2.2
|
||||
|
||||
ghc-options: -Wall -Wredundant-constraints
|
||||
if flag(pedantic)
|
||||
@ -203,11 +200,12 @@ test-suite unit-test
|
||||
, free
|
||||
, ghc
|
||||
, haskell-ide-engine
|
||||
, haskell-lsp-types == 0.17.*
|
||||
, haskell-lsp-types == 0.18.*
|
||||
, hie-test-utils
|
||||
, hie-plugin-api
|
||||
, hoogle > 5.0.11
|
||||
, hspec
|
||||
, process
|
||||
, quickcheck-instances
|
||||
, text
|
||||
, unordered-containers
|
||||
@ -291,8 +289,8 @@ test-suite func-test
|
||||
, filepath
|
||||
, lsp-test >= 0.8.0.0
|
||||
, haskell-ide-engine
|
||||
, haskell-lsp-types == 0.17.*
|
||||
, haskell-lsp == 0.17.*
|
||||
, haskell-lsp-types == 0.18.*
|
||||
, haskell-lsp == 0.18.*
|
||||
, hie-test-utils
|
||||
, hie-plugin-api
|
||||
, hspec
|
||||
|
@ -37,18 +37,12 @@ isExtensionOf ext = isSuffixOf ('.':ext) . takeExtensions
|
||||
#endif
|
||||
|
||||
|
||||
#if MIN_VERSION_ghc(8, 4, 0)
|
||||
type GhcTc = GHC.GhcTc
|
||||
#else
|
||||
type GhcTc = GHC.Id
|
||||
#endif
|
||||
|
||||
pattern HsOverLitType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsOverLitType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsOverLit _ (GHC.overLitType -> t)
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsOverLit (GHC.overLitType -> t)
|
||||
#else
|
||||
GHC.HsOverLit (GHC.overLitType -> t)
|
||||
#endif
|
||||
@ -57,8 +51,6 @@ pattern HsLitType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsLitType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsLit _ (TcHsSyn.hsLitType -> t)
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsLit (TcHsSyn.hsLitType -> t)
|
||||
#else
|
||||
GHC.HsLit (TcHsSyn.hsLitType -> t)
|
||||
#endif
|
||||
@ -67,8 +59,6 @@ pattern HsLamType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsLamType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsLam _ ((\(GHC.MG { GHC.mg_ext = groupTy }) -> matchGroupType groupTy) -> t)
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsLam (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#else
|
||||
GHC.HsLam (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#endif
|
||||
@ -77,8 +67,6 @@ pattern HsLamCaseType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsLamCaseType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsLamCase _ ((\(GHC.MG { GHC.mg_ext = groupTy }) -> matchGroupType groupTy) -> t)
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsLamCase (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#else
|
||||
GHC.HsLamCase (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#endif
|
||||
@ -87,8 +75,6 @@ pattern HsCaseType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsCaseType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsCase _ _ ((\(GHC.MG { GHC.mg_ext = groupTy }) -> matchGroupType groupTy) -> t)
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsCase _ (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#else
|
||||
GHC.HsCase _ (\GHC.MG { GHC.mg_res_ty = res, GHC.mg_arg_tys = args } -> Type.mkFunTys args res -> t)
|
||||
#endif
|
||||
@ -97,8 +83,6 @@ pattern ExplicitListType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern ExplicitListType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.ExplicitList (TysWiredIn.mkListTy -> t) _ _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.ExplicitList (TysWiredIn.mkListTy -> t) _ _
|
||||
#else
|
||||
GHC.ExplicitList (TysWiredIn.mkListTy -> t) _ _
|
||||
#endif
|
||||
@ -107,8 +91,6 @@ pattern ExplicitSumType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern ExplicitSumType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.ExplicitSum (TysWiredIn.mkSumTy -> t) _ _ _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.ExplicitSum _ _ _ (TysWiredIn.mkSumTy -> t)
|
||||
#else
|
||||
GHC.ExplicitSum _ _ _ (TysWiredIn.mkSumTy -> t)
|
||||
#endif
|
||||
@ -118,8 +100,6 @@ pattern HsMultiIfType :: Type.Type -> GHC.HsExpr GhcTc
|
||||
pattern HsMultiIfType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.HsMultiIf t _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.HsMultiIf t _
|
||||
#else
|
||||
GHC.HsMultiIf t _
|
||||
#endif
|
||||
@ -128,8 +108,6 @@ pattern FunBindType :: Type.Type -> GHC.HsBindLR GhcTc GhcTc
|
||||
pattern FunBindType t <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.FunBind _ (GHC.L _ (Var.varType -> t)) _ _ _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.FunBind (GHC.L _ (Var.varType -> t)) _ _ _ _
|
||||
#else
|
||||
GHC.FunBind (GHC.L _ (Var.varType -> t)) _ _ _ _
|
||||
#endif
|
||||
@ -138,8 +116,6 @@ pattern FunBindGen :: Type.Type -> GHC.MatchGroup GhcTc (GHC.LHsExpr GhcTc) -> G
|
||||
pattern FunBindGen t fmatches <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.FunBind _ (GHC.L _ (Var.varType -> t)) fmatches _ _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.FunBind (GHC.L _ (Var.varType -> t)) fmatches _ _ _
|
||||
#else
|
||||
GHC.FunBind (GHC.L _ (Var.varType -> t)) fmatches _ _ _
|
||||
#endif
|
||||
@ -148,10 +124,8 @@ pattern AbsBinds :: GHC.LHsBinds GhcTc -> GHC.HsBindLR GhcTc GhcTc
|
||||
pattern AbsBinds bs <-
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
GHC.AbsBinds _ _ _ _ _ bs _
|
||||
#elif MIN_VERSION_ghc(8, 4, 0)
|
||||
GHC.AbsBinds _ _ _ _ bs _
|
||||
#else
|
||||
GHC.AbsBinds _ _ _ _ bs
|
||||
GHC.AbsBinds _ _ _ _ bs _
|
||||
#endif
|
||||
|
||||
#if MIN_VERSION_ghc(8, 6, 0)
|
||||
|
@ -52,7 +52,7 @@ library
|
||||
, hie-bios
|
||||
, ghc-project-types >= 5.9.0.0
|
||||
, cabal-helper
|
||||
, haskell-lsp == 0.17.*
|
||||
, haskell-lsp == 0.18.*
|
||||
, hslogger
|
||||
, unliftio
|
||||
, monad-control
|
||||
|
@ -14,6 +14,7 @@ build-depends:
|
||||
-- * `stack install.hs <target>`
|
||||
|
||||
-- TODO: set `shake.project` in cabal-config above, when supported
|
||||
-- (see https://github.com/haskell/cabal/issues/6353)
|
||||
|
||||
import HieInstall (defaultMain)
|
||||
|
||||
|
@ -31,20 +31,29 @@ cabalBuildData = do
|
||||
execCabal_ ["v2-build", "hoogle"]
|
||||
execCabal_ ["v2-exec", "hoogle", "generate"]
|
||||
|
||||
cabalBuildHie :: VersionNumber -> Action ()
|
||||
cabalBuildHie versionNumber = do
|
||||
ghcPath <- getGhcPathOf versionNumber >>= \case
|
||||
getGhcPathOfOrThrowError :: VersionNumber -> Action GhcPath
|
||||
getGhcPathOfOrThrowError versionNumber =
|
||||
getGhcPathOf versionNumber >>= \case
|
||||
Nothing -> do
|
||||
printInStars $ ghcVersionNotFoundFailMsg versionNumber
|
||||
error (ghcVersionNotFoundFailMsg versionNumber)
|
||||
Just p -> return p
|
||||
|
||||
cabalBuildHie :: VersionNumber -> Action ()
|
||||
cabalBuildHie versionNumber = do
|
||||
ghcPath <- getGhcPathOfOrThrowError versionNumber
|
||||
execCabal_
|
||||
["v2-build", "-w", ghcPath, "--write-ghc-environment-files=never", "--max-backjumps=5000", "--disable-tests"]
|
||||
[ "v2-build"
|
||||
, "-w", ghcPath
|
||||
, "--write-ghc-environment-files=never"
|
||||
, "--max-backjumps=5000"
|
||||
, "--disable-tests"]
|
||||
|
||||
cabalInstallHie :: VersionNumber -> Action ()
|
||||
cabalInstallHie versionNumber = do
|
||||
localBin <- getLocalBin
|
||||
cabalVersion <- getCabalVersion
|
||||
ghcPath <- getGhcPathOfOrThrowError versionNumber
|
||||
|
||||
let isCabal3 = checkVersion [3,0,0,0] cabalVersion
|
||||
installDirOpt | isCabal3 = "--installdir"
|
||||
@ -53,8 +62,9 @@ cabalInstallHie versionNumber = do
|
||||
| otherwise = []
|
||||
execCabal_ $
|
||||
[ "v2-install"
|
||||
, "-w", ghcPath
|
||||
, "--write-ghc-environment-files=never"
|
||||
, installDirOpt ++ "=" ++ localBin
|
||||
, installDirOpt, localBin
|
||||
, "exe:hie"
|
||||
, "--overwrite-policy=always"
|
||||
]
|
||||
|
@ -8,7 +8,10 @@ import Development.Shake.FilePath
|
||||
import System.Info ( os
|
||||
, arch
|
||||
)
|
||||
import Data.Maybe ( isJust )
|
||||
import Data.Maybe ( isJust
|
||||
, isNothing
|
||||
, mapMaybe
|
||||
)
|
||||
import System.Directory ( findExecutable
|
||||
, findExecutables
|
||||
, listDirectory
|
||||
@ -17,13 +20,13 @@ import Data.Function ( (&)
|
||||
, on
|
||||
)
|
||||
import Data.List ( sort
|
||||
, sortBy
|
||||
, isInfixOf
|
||||
, nubBy
|
||||
)
|
||||
import Data.Ord ( comparing )
|
||||
import Control.Monad.Extra ( mapMaybeM )
|
||||
import Data.Maybe ( isNothing
|
||||
, mapMaybe
|
||||
)
|
||||
|
||||
import qualified Data.Text as T
|
||||
|
||||
import Version
|
||||
@ -45,15 +48,18 @@ findInstalledGhcs = do
|
||||
hieVersions <- getHieVersions :: IO [VersionNumber]
|
||||
knownGhcs <- mapMaybeM
|
||||
(\version -> getGhcPathOf version >>= \case
|
||||
Nothing -> return Nothing
|
||||
Just p -> return $ Just (version, p)
|
||||
Nothing -> return Nothing
|
||||
Just p -> return $ Just (version, p)
|
||||
)
|
||||
(reverse hieVersions)
|
||||
availableGhcs <- getGhcPaths
|
||||
-- filter out not supported ghc versions
|
||||
availableGhcs <- filter ((`elem` hieVersions) . fst) <$> getGhcPaths
|
||||
return
|
||||
-- sort by version to make it coherent with getHieVersions
|
||||
$ sortBy (comparing fst)
|
||||
-- nub by version. knownGhcs takes precedence.
|
||||
$ nubBy ((==) `on` fst)
|
||||
-- filter out stack provided GHCs
|
||||
-- filter out stack provided GHCs (assuming that stack programs path is the default one in linux)
|
||||
$ filter (not . isInfixOf ".stack" . snd) (knownGhcs ++ availableGhcs)
|
||||
|
||||
-- | Get the path to a GHC that has the version specified by `VersionNumber`
|
||||
@ -63,7 +69,7 @@ findInstalledGhcs = do
|
||||
-- command fits to the desired version.
|
||||
getGhcPathOf :: MonadIO m => VersionNumber -> m (Maybe GhcPath)
|
||||
getGhcPathOf ghcVersion =
|
||||
liftIO $ findExecutable ("ghc-" ++ ghcVersion) >>= \case
|
||||
liftIO $ findExecutable ("ghc-" ++ ghcVersion <.> exe) >>= \case
|
||||
Nothing -> lookup ghcVersion <$> getGhcPaths
|
||||
path -> return path
|
||||
|
||||
@ -87,7 +93,6 @@ ghcVersionNotFoundFailMsg versionNumber =
|
||||
-- | Defines all different hie versions that are buildable.
|
||||
--
|
||||
-- The current directory is scanned for `stack-*.yaml` files.
|
||||
-- On windows, `8.6.3` is excluded as this version of ghc does not work there
|
||||
getHieVersions :: MonadIO m => m [VersionNumber]
|
||||
getHieVersions = do
|
||||
let stackYamlPrefix = T.pack "stack-"
|
||||
|
@ -12,13 +12,23 @@ import Version
|
||||
import BuildSystem
|
||||
import Cabal
|
||||
|
||||
stackCommand :: TargetDescription -> String
|
||||
stackCommand target = "stack install.hs " ++ fst target
|
||||
|
||||
cabalCommand :: TargetDescription -> String
|
||||
cabalCommand target = "cabal v2-run install.hs --project-file install/shake.project " ++ fst target
|
||||
|
||||
buildCommand :: TargetDescription -> String
|
||||
buildCommand | isRunFromCabal = cabalCommand
|
||||
| otherwise = stackCommand
|
||||
|
||||
printUsage :: Action ()
|
||||
printUsage = do
|
||||
printLine ""
|
||||
printLine "Usage:"
|
||||
printLineIndented "stack install.hs <target>"
|
||||
printLineIndented (stackCommand templateTarget)
|
||||
printLineIndented "or"
|
||||
printLineIndented "cabal new-run install.hs --project-file install/shake.project <target>"
|
||||
printLineIndented (cabalCommand templateTarget)
|
||||
|
||||
-- | short help message is printed by default
|
||||
shortHelpMessage :: Action ()
|
||||
@ -35,7 +45,7 @@ shortHelpMessage = do
|
||||
[ ("help", "Show help message including all targets")
|
||||
, emptyTarget
|
||||
, buildTarget
|
||||
, buildAllTarget
|
||||
, buildLatestTarget
|
||||
, hieTarget $ last hieVersions
|
||||
, buildDataTarget
|
||||
, cabalGhcsTarget
|
||||
@ -76,12 +86,12 @@ helpMessage versions@BuildableVersions {..} = do
|
||||
-- All targets with their respective help message.
|
||||
generalTargets = [helpTarget]
|
||||
|
||||
defaultTargets = [buildTarget, buildAllTarget, buildDataTarget]
|
||||
defaultTargets = [buildTarget, buildLatestTarget, buildDataTarget]
|
||||
++ map hieTarget (getDefaultBuildSystemVersions versions)
|
||||
|
||||
stackTargets =
|
||||
[ stackTarget buildTarget
|
||||
, stackTarget buildAllTarget
|
||||
, stackTarget buildLatestTarget
|
||||
, stackTarget buildDataTarget
|
||||
]
|
||||
++ (if isRunFromStack then [stackTarget installCabalTarget] else [])
|
||||
@ -90,7 +100,7 @@ helpMessage versions@BuildableVersions {..} = do
|
||||
cabalTargets =
|
||||
[ cabalGhcsTarget
|
||||
, cabalTarget buildTarget
|
||||
, cabalTarget buildAllTarget
|
||||
, cabalTarget buildLatestTarget
|
||||
, cabalTarget buildDataTarget
|
||||
]
|
||||
++ map (cabalTarget . hieTarget) cabalVersions
|
||||
@ -99,6 +109,9 @@ helpMessage versions@BuildableVersions {..} = do
|
||||
emptyTarget :: (String, String)
|
||||
emptyTarget = ("", "")
|
||||
|
||||
templateTarget :: (String, String)
|
||||
templateTarget = ("<target>", "")
|
||||
|
||||
targetWithBuildSystem :: String -> TargetDescription -> TargetDescription
|
||||
targetWithBuildSystem system (target, description) =
|
||||
(system ++ "-" ++ target, description ++ "; with " ++ system)
|
||||
@ -114,17 +127,16 @@ hieTarget version =
|
||||
("hie-" ++ version, "Builds hie for GHC version " ++ version)
|
||||
|
||||
buildTarget :: TargetDescription
|
||||
buildTarget = ("build", "Builds hie with all installed GHCs")
|
||||
buildTarget = ("build", "Build hie with the latest available GHC and the data files")
|
||||
|
||||
buildLatestTarget :: TargetDescription
|
||||
buildLatestTarget = ("build-latest", "Build hie with the latest available GHC")
|
||||
|
||||
buildDataTarget :: TargetDescription
|
||||
buildDataTarget =
|
||||
("build-data", "Get the required data-files for `hie` (Hoogle DB)")
|
||||
|
||||
buildAllTarget :: TargetDescription
|
||||
buildAllTarget =
|
||||
("build-all", "Builds hie for all installed GHC versions and the data files")
|
||||
|
||||
-- speical targets
|
||||
-- special targets
|
||||
|
||||
macosIcuTarget :: TargetDescription
|
||||
macosIcuTarget = ("icu-macos-fix", "Fixes icu related problems in MacOS")
|
||||
@ -135,13 +147,15 @@ helpTarget = ("help", "Show help message including all targets")
|
||||
cabalGhcsTarget :: TargetDescription
|
||||
cabalGhcsTarget =
|
||||
( "cabal-ghcs"
|
||||
, "Show all GHC versions that can be installed via `cabal-build` and `cabal-build-all`."
|
||||
, "Show all GHC versions that can be installed via `cabal-build`."
|
||||
)
|
||||
|
||||
installCabalTarget :: TargetDescription
|
||||
installCabalTarget =
|
||||
( "install-cabal"
|
||||
, "Install the cabal executable. It will install the required minimum version for hie (currently " ++ versionToString requiredCabalVersion ++ ") if it isn't already present in $PATH"
|
||||
, "Install the cabal executable. It will install the required minimum version for hie (currently "
|
||||
++ versionToString requiredCabalVersion
|
||||
++ ") if it isn't already present in $PATH"
|
||||
)
|
||||
|
||||
-- | Creates a message of the form "a, b, c and d", where a,b,c,d are GHC versions.
|
||||
|
@ -57,6 +57,8 @@ defaultMain = do
|
||||
, cabalVersions = ghcVersions
|
||||
}
|
||||
|
||||
let latestVersion = last hieVersions
|
||||
|
||||
putStrLn $ "run from: " ++ buildSystem
|
||||
|
||||
shakeArgs shakeOptions { shakeFiles = "_build" } $ do
|
||||
@ -82,7 +84,7 @@ defaultMain = do
|
||||
|
||||
-- default-targets
|
||||
phony "build" $ need [buildSystem ++ "-build"]
|
||||
phony "build-all" $ need [buildSystem ++ "-build-all"]
|
||||
phony "build-latest" $ need [buildSystem ++ "-build-latest"]
|
||||
phony "build-data" $ need [buildSystem ++ "-build-data"]
|
||||
forM_
|
||||
(getDefaultBuildSystemVersions versions)
|
||||
@ -92,8 +94,9 @@ defaultMain = do
|
||||
|
||||
-- stack specific targets
|
||||
when isRunFromStack (phony "stack-install-cabal" (need ["cabal"]))
|
||||
phony "stack-build" (need (reverse $ map ("stack-hie-" ++) hieVersions))
|
||||
phony "stack-build-all" (need ["build-data", "build"])
|
||||
phony "stack-build-latest" (need ["stack-hie-" ++ last hieVersions])
|
||||
phony "stack-build" (need ["build-data", "stack-build-latest"])
|
||||
|
||||
phony "stack-build-data" $ do
|
||||
need ["submodules"]
|
||||
need ["check-stack"]
|
||||
@ -108,8 +111,8 @@ defaultMain = do
|
||||
)
|
||||
|
||||
-- cabal specific targets
|
||||
phony "cabal-build" (need (map ("cabal-hie-" ++) ghcVersions))
|
||||
phony "cabal-build-all" (need ["cabal-build-data", "cabal-build"])
|
||||
phony "cabal-build-latest" (need ["cabal-hie-" ++ last ghcVersions])
|
||||
phony "cabal-build" (need ["build-data", "cabal-build-latest"])
|
||||
phony "cabal-build-data" $ do
|
||||
need ["submodules"]
|
||||
need ["cabal"]
|
||||
|
@ -18,7 +18,7 @@ printLineIndented = printLine . (" " ++)
|
||||
|
||||
embedInStars :: String -> String
|
||||
embedInStars str =
|
||||
let starsLine = "\n" <> replicate 30 '*' <> "\n"
|
||||
let starsLine = "\n" <> replicate 80 '*' <> "\n"
|
||||
in starsLine <> str <> starsLine
|
||||
|
||||
printInStars :: MonadIO m => String -> m ()
|
||||
|
@ -3,11 +3,13 @@ module Stack where
|
||||
import Development.Shake
|
||||
import Development.Shake.Command
|
||||
import Development.Shake.FilePath
|
||||
import Control.Exception
|
||||
import Control.Monad
|
||||
import Data.List
|
||||
import System.Directory ( copyFile )
|
||||
import System.FilePath ( searchPathSeparator, (</>) )
|
||||
import System.FilePath ( splitSearchPath, searchPathSeparator, (</>) )
|
||||
import System.Environment ( lookupEnv, setEnv, getEnvironment )
|
||||
import System.IO.Error ( isDoesNotExistError )
|
||||
import BuildSystem
|
||||
import Version
|
||||
import Print
|
||||
@ -102,6 +104,7 @@ stackBuildFailMsg =
|
||||
-- |Run actions without the stack cached binaries
|
||||
withoutStackCachedBinaries :: Action a -> Action a
|
||||
withoutStackCachedBinaries action = do
|
||||
|
||||
mbPath <- liftIO (lookupEnv "PATH")
|
||||
|
||||
case (mbPath, isRunFromStack) of
|
||||
@ -121,13 +124,7 @@ withoutStackCachedBinaries action = do
|
||||
otherwise -> action
|
||||
|
||||
where removePathsContaining strs path =
|
||||
joinPaths (filter (not . containsAny) (splitPaths path))
|
||||
joinPaths (filter (not . containsAny) (splitSearchPath path))
|
||||
where containsAny p = any (`isInfixOf` p) strs
|
||||
|
||||
joinPaths = intercalate [searchPathSeparator]
|
||||
|
||||
splitPaths s =
|
||||
case dropWhile (== searchPathSeparator) s of
|
||||
"" -> []
|
||||
s' -> w : words s''
|
||||
where (w, s'') = break (== searchPathSeparator) s'
|
||||
joinPaths = intercalate [searchPathSeparator]
|
@ -42,6 +42,8 @@ import Packages (listVisibleModuleNames)
|
||||
import Language.Haskell.Refact.API ( showGhc )
|
||||
|
||||
import qualified Language.Haskell.LSP.Types as J
|
||||
import qualified Language.Haskell.LSP.Types.Capabilities
|
||||
as J
|
||||
import qualified Language.Haskell.LSP.Types.Lens
|
||||
as J
|
||||
import qualified Haskell.Ide.Engine.Support.Fuzzy
|
||||
@ -92,8 +94,8 @@ instance FromJSON CompItemResolveData where
|
||||
instance ToJSON CompItemResolveData where
|
||||
toJSON = genericToJSON $ customOptions 0
|
||||
|
||||
resolveCompletion :: J.CompletionItem -> IdeM J.CompletionItem
|
||||
resolveCompletion origCompl =
|
||||
resolveCompletion :: WithSnippets -> J.CompletionItem -> IdeM J.CompletionItem
|
||||
resolveCompletion withSnippets origCompl =
|
||||
case fromJSON <$> origCompl ^. J.xdata of
|
||||
Just (J.Success compdata) -> do
|
||||
mdocs <- Hoogle.infoCmd' $ hoogleQuery compdata
|
||||
@ -113,10 +115,11 @@ resolveCompletion origCompl =
|
||||
insertText = label <> " " <> getArgText typ
|
||||
det = Just . stripForall $ T.pack (showGhc typ) <> "\n"
|
||||
pure (det,Just insertText)
|
||||
return $ origCompl & J.documentation .~ docs
|
||||
let compl = origCompl & J.documentation .~ docs
|
||||
& J.insertText .~ insert
|
||||
& J.insertTextFormat ?~ J.Snippet
|
||||
& J.detail .~ (detail <> origCompl ^. J.detail)
|
||||
toggleSnippets <$> getClientCapabilities <*> pure withSnippets <*> pure compl
|
||||
Just (J.Error err) -> do
|
||||
debugm $ "resolveCompletion: Decoding data failed because of: " ++ err
|
||||
pure origCompl
|
||||
@ -293,26 +296,28 @@ instance ModuleCache CachedCompletions where
|
||||
|
||||
newtype WithSnippets = WithSnippets Bool
|
||||
|
||||
toggleSnippets :: J.ClientCapabilities -> WithSnippets -> J.CompletionItem -> J.CompletionItem
|
||||
toggleSnippets clientCaps (WithSnippets with) x
|
||||
| with && supported = x
|
||||
| otherwise = x { J._insertTextFormat = Just J.PlainText
|
||||
, J._insertText = Nothing
|
||||
}
|
||||
where supported = fromMaybe False (clientCaps ^? J.textDocument
|
||||
. _Just
|
||||
. J.completion
|
||||
. _Just
|
||||
. J.completionItem
|
||||
. _Just
|
||||
. J.snippetSupport
|
||||
. _Just)
|
||||
|
||||
-- | Returns the cached completions for the given module and position.
|
||||
getCompletions :: Uri -> VFS.PosPrefixInfo -> WithSnippets -> IdeM (IdeResult [J.CompletionItem])
|
||||
getCompletions uri prefixInfo (WithSnippets withSnippets) =
|
||||
getCompletions uri prefixInfo withSnippets =
|
||||
pluginGetFile "getCompletions: " uri $ \file -> do
|
||||
let snippetLens = (^? J.textDocument
|
||||
. _Just
|
||||
. J.completion
|
||||
. _Just
|
||||
. J.completionItem
|
||||
. _Just
|
||||
. J.snippetSupport
|
||||
. _Just)
|
||||
supportsSnippets <- fromMaybe False . snippetLens <$> getClientCapabilities
|
||||
let toggleSnippets x
|
||||
| withSnippets && supportsSnippets = x
|
||||
| otherwise = x { J._insertTextFormat = Just J.PlainText
|
||||
, J._insertText = Nothing
|
||||
}
|
||||
caps <- getClientCapabilities
|
||||
|
||||
VFS.PosPrefixInfo { VFS.fullLine, VFS.prefixModule, VFS.prefixText } = prefixInfo
|
||||
let VFS.PosPrefixInfo { VFS.fullLine, VFS.prefixModule, VFS.prefixText } = prefixInfo
|
||||
debugm $ "got prefix" ++ show (prefixModule, prefixText)
|
||||
let enteredQual = if T.null prefixModule then "" else prefixModule <> "."
|
||||
fullPrefix = enteredQual <> prefixText
|
||||
@ -378,7 +383,7 @@ getCompletions uri prefixInfo (WithSnippets withSnippets) =
|
||||
]
|
||||
|
||||
filtListWithSnippet f list suffix =
|
||||
[ toggleSnippets (f label (snippet <> suffix))
|
||||
[ toggleSnippets caps withSnippets (f label (snippet <> suffix))
|
||||
| (snippet, label) <- list
|
||||
, Fuzzy.test fullPrefix label
|
||||
]
|
||||
@ -403,7 +408,8 @@ getCompletions uri prefixInfo (WithSnippets withSnippets) =
|
||||
| "{-# " `T.isPrefixOf` fullLine
|
||||
= filtPragmaCompls (pragmaSuffix fullLine)
|
||||
| otherwise
|
||||
= filtModNameCompls ++ map (toggleSnippets . mkCompl . stripAutoGenerated) filtCompls
|
||||
= filtModNameCompls ++ map (toggleSnippets caps withSnippets
|
||||
. mkCompl . stripAutoGenerated) filtCompls
|
||||
in
|
||||
return $ IdeResultOk result
|
||||
where
|
||||
|
@ -1,9 +1,6 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
module Haskell.Ide.Engine.Options where
|
||||
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Semigroup hiding (option)
|
||||
#endif
|
||||
import Options.Applicative.Simple
|
||||
|
||||
data GlobalOpts = GlobalOpts
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
@ -26,11 +25,7 @@ import Haskell.Ide.Engine.PluginUtils
|
||||
import Language.Haskell.Exts.SrcLoc
|
||||
import Language.Haskell.Exts.Parser
|
||||
import Language.Haskell.Exts.Extension
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
import Language.Haskell.HLint4 as Hlint
|
||||
#else
|
||||
import Language.Haskell.HLint3 as Hlint
|
||||
#endif
|
||||
import qualified Language.Haskell.LSP.Types as LSP
|
||||
import qualified Language.Haskell.LSP.Types.Lens as LSP
|
||||
import Refact.Apply
|
||||
|
@ -11,9 +11,6 @@ import Data.Aeson
|
||||
import Data.Foldable
|
||||
import qualified Data.Map as Map
|
||||
import Data.Maybe
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Semigroup
|
||||
#endif
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Versions as V
|
||||
import Development.GitRev (gitCommitCount)
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
@ -9,9 +8,6 @@ import Control.Lens
|
||||
import Control.Monad.IO.Class
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as H
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as S
|
||||
import qualified Data.Text as T
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
@ -14,9 +13,6 @@ import qualified Data.Aeson.Types as J
|
||||
import Data.Algorithm.Diff
|
||||
import Data.Algorithm.DiffOutput
|
||||
import Data.Foldable
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Exception
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
@ -9,9 +8,6 @@ module Haskell.Ide.Engine.Plugin.Haddock where
|
||||
import Control.Monad.State
|
||||
import Data.Foldable
|
||||
import qualified Data.Map as Map
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import qualified Data.Text as T
|
||||
import Data.IORef
|
||||
import Data.Function
|
||||
@ -196,9 +192,7 @@ renderMarkDown =
|
||||
["```\n"])
|
||||
, markupHeader = \h ->
|
||||
T.replicate (headerLevel h) "#" <> " " <> headerTitle h <> "\n"
|
||||
#if __GLASGOW_HASKELL__ >= 804
|
||||
, markupTable = mempty
|
||||
#endif
|
||||
}
|
||||
where surround c x = c <> T.replace c "" x <> c
|
||||
removeInner x = T.replace "```" "" $ T.replace "```haskell" "" x
|
||||
|
@ -1,6 +1,5 @@
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module Haskell.Ide.Engine.Plugin.Hoogle where
|
||||
|
||||
@ -11,9 +10,6 @@ import Control.Applicative (liftA2)
|
||||
import Data.Aeson
|
||||
import Data.Bifunctor
|
||||
import Data.Maybe
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import qualified Data.Text as T
|
||||
import Data.List
|
||||
import Haskell.Ide.Engine.MonadTypes
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
@ -10,9 +9,6 @@ import Control.Monad
|
||||
import Control.Monad.IO.Class
|
||||
import Control.Monad.Trans.Class
|
||||
import Control.Exception (bracket)
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import Data.Aeson
|
||||
import qualified Data.ByteString.Lazy as BS
|
||||
import qualified Data.Map as Map
|
||||
@ -170,10 +166,19 @@ runLiquidHaskell fp = do
|
||||
cp = (shell cmd) { cwd = Just dir }
|
||||
-- logm $ "runLiquidHaskell:cmd=[" ++ cmd ++ "]"
|
||||
mpp <- lookupEnv "GHC_PACKAGE_PATH"
|
||||
mge <- lookupEnv "GHC_ENVIRONMENT"
|
||||
-- logm $ "runLiquidHaskell:mpp=[" ++ show mpp ++ "]"
|
||||
-- env <- getEnvironment
|
||||
-- logm $ "runLiquidHaskell:env=[" ++ show env ++ "]"
|
||||
(ec,o,e) <- bracket
|
||||
(unsetEnv "GHC_PACKAGE_PATH")
|
||||
(\_ -> mapM_ (setEnv "GHC_PACKAGE_PATH") mpp)
|
||||
(do
|
||||
unsetEnv "GHC_ENVIRONMENT"
|
||||
unsetEnv "GHC_PACKAGE_PATH"
|
||||
)
|
||||
(\_ -> do
|
||||
mapM_ (setEnv "GHC_PACKAGE_PATH") mpp
|
||||
mapM_ (setEnv "GHC_ENVIRONMENT" ) mge
|
||||
)
|
||||
(\_ -> readCreateProcessWithExitCode cp "")
|
||||
-- logm $ "runLiquidHaskell:v=" ++ show (ec,o,e)
|
||||
return $ Just (ec,[o,e])
|
||||
|
@ -1,4 +1,3 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
@ -21,9 +20,6 @@ import Control.Monad.IO.Class
|
||||
import qualified Data.Aeson as J
|
||||
import qualified Data.ByteString.Builder as B
|
||||
import qualified Data.ByteString.Lazy.Char8 as B
|
||||
#if __GLASGOW_HASKELL__ < 804
|
||||
import Data.Monoid
|
||||
#endif
|
||||
import qualified Data.Text as T
|
||||
import GHC.Generics
|
||||
import Haskell.Ide.Engine.PluginsIdeMonads
|
||||
|
@ -634,12 +634,13 @@ reactor inp diagIn = do
|
||||
|
||||
ReqCompletionItemResolve req -> do
|
||||
liftIO $ U.logs $ "reactor:got CompletionItemResolveRequest:" ++ show req
|
||||
snippets <- Completions.WithSnippets <$> configVal completionSnippetsOn
|
||||
let origCompl = req ^. J.params
|
||||
callback res = do
|
||||
let rspMsg = Core.makeResponseMessage req $ res
|
||||
reactorSend $ RspCompletionItemResolve rspMsg
|
||||
hreq = IReq tn "completion" (req ^. J.id) callback $ runIdeResultT $ do
|
||||
lift $ lift $ Completions.resolveCompletion origCompl
|
||||
lift $ lift $ Completions.resolveCompletion snippets origCompl
|
||||
makeRequest hreq
|
||||
|
||||
-- -------------------------------
|
||||
@ -950,18 +951,22 @@ syncOptions = J.TextDocumentSyncOptions
|
||||
, J._save = Just $ J.SaveOptions $ Just False
|
||||
}
|
||||
|
||||
-- | Create 'Language.Haskell.LSP.Core.Options'.
|
||||
-- There may need to be more options configured, depending on what handlers
|
||||
-- are registered.
|
||||
-- Consult the haskell-lsp haddocks to see all possible options.
|
||||
hieOptions :: [T.Text] -> Core.Options
|
||||
hieOptions commandIds =
|
||||
def { Core.textDocumentSync = Just syncOptions
|
||||
, Core.completionProvider = Just (J.CompletionOptions (Just True) (Just ["."]))
|
||||
, Core.typeDefinitionProvider = Just (J.GotoOptionsStatic True)
|
||||
-- The characters that trigger completion automatically.
|
||||
, Core.completionTriggerCharacters = Just ['.']
|
||||
-- As of 2018-05-24, vscode needs the commands to be registered
|
||||
-- otherwise they will not be available as codeActions (will be
|
||||
-- silently ignored, despite UI showing to the contrary).
|
||||
--
|
||||
-- Hopefully the end May 2018 vscode release will stabilise
|
||||
-- this, it is a major rework of the machinery anyway.
|
||||
, Core.executeCommandProvider = Just (J.ExecuteCommandOptions (J.List commandIds))
|
||||
, Core.executeCommandCommands = Just commandIds
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
resolver: lts-11.18 # lts-11.x is the last one for GHC 8.2.2
|
||||
packages:
|
||||
- .
|
||||
- hie-plugin-api
|
||||
|
||||
extra-deps:
|
||||
- ./hie-bios
|
||||
- ./submodules/HaRe
|
||||
- ./submodules/cabal-helper
|
||||
- ./submodules/ghc-mod
|
||||
- ./submodules/ghc-mod/core
|
||||
- ./submodules/ghc-mod/ghc-project-types
|
||||
|
||||
- brittany-0.12.0.0
|
||||
- butcher-1.3.1.1
|
||||
- bytestring-trie-0.2.5.0
|
||||
- cabal-plan-0.5.0.0
|
||||
- conduit-parse-0.2.1.0
|
||||
- constrained-dynamic-0.1.0.0
|
||||
- czipwith-1.0.1.0
|
||||
- floskell-0.10.0
|
||||
- ghc-exactprint-0.5.8.2
|
||||
- haddock-api-2.18.1
|
||||
- haddock-library-1.4.4
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-src-exts-1.21.0
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.1.17 # last hlint supporting GHC 8.2
|
||||
- hoogle-5.0.17.9
|
||||
- hsimport-0.8.8
|
||||
- lsp-test-0.8.0.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- pretty-show-1.8.2
|
||||
- rope-utf16-splay-0.3.1.0
|
||||
- sorted-list-0.2.1.0
|
||||
- syz-0.2.0.0
|
||||
# To make build work in windows 7
|
||||
- unix-time-0.4.7
|
||||
- ghc-boot-8.2.2
|
||||
## introduced by hie-bios
|
||||
#- hie-bios-0.2.1
|
||||
- extra-1.6.18
|
||||
- unix-compat-0.5.2
|
||||
- yaml-0.11.1.2
|
||||
- unordered-containers-0.2.10.0
|
||||
- directory-1.3.0.2
|
||||
- file-embed-0.0.11
|
||||
- filepath-1.4.1.2
|
||||
- libyaml-0.1.1.0
|
||||
- transformers-0.5.6.2
|
||||
- process-1.6.1.0
|
||||
- binary-0.8.5.1
|
||||
- unix-2.7.2.2
|
||||
# - Win32-2.6.2.
|
||||
- time-1.8.0.2
|
||||
|
||||
|
||||
flags:
|
||||
haskell-ide-engine:
|
||||
pedantic: true
|
||||
hie-plugin-api:
|
||||
pedantic: true
|
||||
|
||||
nix:
|
||||
packages: [ icu libcxx zlib ]
|
||||
|
||||
concurrent-tests: false
|
@ -19,14 +19,14 @@ extra-deps:
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.20.0
|
||||
- haddock-library-1.6.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- pretty-show-1.8.2
|
||||
- rope-utf16-splay-0.3.1.0
|
||||
|
@ -19,14 +19,14 @@ extra-deps:
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.20.0
|
||||
- haddock-library-1.6.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- pretty-show-1.8.2
|
||||
- rope-utf16-splay-0.3.1.0
|
||||
|
@ -18,14 +18,14 @@ extra-deps:
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.20.0
|
||||
- haddock-library-1.6.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- optparse-simple-0.1.0
|
||||
- pretty-show-1.9.5
|
||||
|
@ -22,14 +22,14 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.21.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- monad-memo-0.4.1
|
||||
- monoid-subclasses-0.4.6.1
|
||||
|
@ -18,14 +18,14 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.21.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- monad-memo-0.4.1
|
||||
- multistate-0.8.0.1
|
||||
|
@ -17,14 +17,14 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.21.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- haskell-src-exts-util-0.2.5
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2
|
||||
- monad-memo-0.4.1
|
||||
- multistate-0.8.0.1
|
||||
|
@ -17,13 +17,13 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.22.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- haskell-src-exts-1.21.1
|
||||
- hlint-2.2.3
|
||||
- hoogle-5.0.17.11
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2@rev:1
|
||||
- monad-memo-0.4.1
|
||||
- multistate-0.8.0.1
|
||||
|
@ -18,12 +18,12 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.22.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- hlint-2.2.3
|
||||
- hsimport-0.11.0
|
||||
- hoogle-5.0.17.11
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2@rev:1
|
||||
- syz-0.2.0.0
|
||||
- temporary-1.2.1.1
|
||||
|
@ -19,11 +19,11 @@ extra-deps:
|
||||
- floskell-0.10.1
|
||||
- ghc-lib-parser-8.8.1
|
||||
- haddock-api-2.22.0
|
||||
- haskell-lsp-0.17.0.0
|
||||
- haskell-lsp-types-0.17.0.0
|
||||
- haskell-lsp-0.18.0.0
|
||||
- haskell-lsp-types-0.18.0.0
|
||||
- hlint-2.2.3
|
||||
- hsimport-0.11.0
|
||||
- lsp-test-0.8.0.0
|
||||
- lsp-test-0.8.2.0
|
||||
- monad-dijkstra-0.1.1.2@rev:1
|
||||
- syz-0.2.0.0
|
||||
- temporary-1.2.1.1
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 03de7522995a3b192c3a2b010539d02e753e3d3d
|
||||
Subproject commit 26d1048d30ac5d995af46b35c9988172ecfb1f3e
|
@ -74,12 +74,13 @@ startServer :: IO (Scheduler IO, TChan LogVal, ThreadId)
|
||||
startServer = do
|
||||
scheduler <- newScheduler plugins testOptions
|
||||
logChan <- newTChanIO
|
||||
dispatcher <- forkIO $
|
||||
dispatcher <- forkIO $ do
|
||||
flushStackEnvironment
|
||||
runScheduler
|
||||
scheduler
|
||||
(\lid errCode e -> logToChan logChan ("received an error", Left (lid, errCode, e)))
|
||||
(\g x -> g x)
|
||||
def
|
||||
scheduler
|
||||
(\lid errCode e -> logToChan logChan ("received an error", Left (lid, errCode, e)))
|
||||
(\g x -> g x)
|
||||
def
|
||||
|
||||
return (scheduler, logChan, dispatcher)
|
||||
|
||||
|
@ -120,7 +120,7 @@ spec = describe "completions" $ do
|
||||
item ^. label `shouldBe` "OPTIONS_GHC"
|
||||
item ^. kind `shouldBe` Just CiKeyword
|
||||
item ^. insertTextFormat `shouldBe` Just Snippet
|
||||
item ^. insertText `shouldBe` Just ("OPTIONS_GHC -${1:option} #-}")
|
||||
item ^. insertText `shouldBe` Just "OPTIONS_GHC -${1:option} #-}"
|
||||
|
||||
-- -----------------------------------
|
||||
|
||||
@ -358,4 +358,12 @@ spec = describe "completions" $ do
|
||||
item ^. kind `shouldBe` Just CiFunction
|
||||
item ^. insertTextFormat `shouldBe` Just PlainText
|
||||
item ^. insertText `shouldBe` Nothing
|
||||
|
||||
resolvedRes <- request CompletionItemResolve item
|
||||
let Just (resolved :: CompletionItem) = resolvedRes ^. result
|
||||
liftIO $ do
|
||||
resolved ^. label `shouldBe` "foldl"
|
||||
resolved ^. kind `shouldBe` Just CiFunction
|
||||
resolved ^. insertTextFormat `shouldBe` Just PlainText
|
||||
resolved ^. insertText `shouldBe` Nothing
|
||||
noSnippetsCaps = (textDocument . _Just . completion . _Just . completionItem . _Just . snippetSupport ?~ False) fullCaps
|
||||
|
@ -1,5 +1,4 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE CPP #-}
|
||||
|
||||
module FunctionalCodeActionsSpec where
|
||||
|
||||
@ -213,34 +212,34 @@ spec = describe "code actions" $ do
|
||||
]
|
||||
]
|
||||
describe "add package suggestions" $ do
|
||||
-- Only execute this test with ghc 8.4.4, below seems to be broken in the package.
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
it "adds to .cabal files" $ runSession hieCommand fullCaps "test/testdata/addPackageTest/cabal-exe" $ do
|
||||
doc <- openDoc "AddPackage.hs" "haskell"
|
||||
it "adds to .cabal files" $ do
|
||||
flushStackEnvironment
|
||||
runSession hieCommand fullCaps "test/testdata/addPackageTest/cabal-exe" $ do
|
||||
doc <- openDoc "AddPackage.hs" "haskell"
|
||||
|
||||
-- ignore the first empty hlint diagnostic publish
|
||||
[_,diag:_] <- count 2 waitForDiagnostics
|
||||
-- ignore the first empty hlint diagnostic publish
|
||||
[_,diag:_] <- count 2 waitForDiagnostics
|
||||
|
||||
let prefixes = [ "Could not load module `Data.Text'" -- Windows && GHC >= 8.6
|
||||
, "Could not find module `Data.Text'" -- Windows
|
||||
, "Could not load module ‘Data.Text’" -- GHC >= 8.6
|
||||
, "Could not find module ‘Data.Text’"
|
||||
]
|
||||
in liftIO $ diag ^. L.message `shouldSatisfy` \m -> any (`T.isPrefixOf` m) prefixes
|
||||
let prefixes = [ "Could not load module `Data.Text'" -- Windows && GHC >= 8.6
|
||||
, "Could not find module `Data.Text'" -- Windows
|
||||
, "Could not load module ‘Data.Text’" -- GHC >= 8.6
|
||||
, "Could not find module ‘Data.Text’"
|
||||
]
|
||||
in liftIO $ diag ^. L.message `shouldSatisfy` \m -> any (`T.isPrefixOf` m) prefixes
|
||||
|
||||
acts <- getAllCodeActions doc
|
||||
let (CACodeAction action:_) = acts
|
||||
acts <- getAllCodeActions doc
|
||||
let (CACodeAction action:_) = acts
|
||||
|
||||
liftIO $ do
|
||||
action ^. L.title `shouldBe` "Add text as a dependency"
|
||||
action ^. L.kind `shouldBe` Just CodeActionQuickFix
|
||||
action ^. L.command . _Just . L.command `shouldSatisfy` T.isSuffixOf "package:add"
|
||||
liftIO $ do
|
||||
action ^. L.title `shouldBe` "Add text as a dependency"
|
||||
action ^. L.kind `shouldBe` Just CodeActionQuickFix
|
||||
action ^. L.command . _Just . L.command `shouldSatisfy` T.isSuffixOf "package:add"
|
||||
|
||||
executeCodeAction action
|
||||
executeCodeAction action
|
||||
|
||||
contents <- getDocumentEdit . TextDocumentIdentifier =<< getDocUri "add-package-test.cabal"
|
||||
liftIO $ T.lines contents `shouldSatisfy` \x -> any (\l -> "text -any" `T.isSuffixOf` (x !! l)) [15, 16]
|
||||
|
||||
contents <- getDocumentEdit . TextDocumentIdentifier =<< getDocUri "add-package-test.cabal"
|
||||
liftIO $ T.lines contents `shouldSatisfy` \x -> any (\l -> "text -any" `T.isSuffixOf` (x !! l)) [15, 16]
|
||||
#endif
|
||||
it "adds to hpack package.yaml files" $
|
||||
runSession hieCommand fullCaps "test/testdata/addPackageTest/hpack-exe" $ do
|
||||
doc <- openDoc "app/Asdf.hs" "haskell"
|
||||
|
@ -101,11 +101,16 @@ spec = describe "liquid haskell diagnostics" $ do
|
||||
-- liftIO $ show diags3 `shouldBe` ""
|
||||
liftIO $ do
|
||||
length diags3 `shouldBe` 1
|
||||
d ^. range `shouldBe` Range (Position 8 0) (Position 8 7)
|
||||
d ^. range `shouldBe` Range (Position 8 0) (Position 8 11)
|
||||
d ^. severity `shouldBe` Just DsError
|
||||
d ^. code `shouldBe` Nothing
|
||||
d ^. source `shouldBe` Just "liquid"
|
||||
d ^. message `shouldSatisfy` (T.isPrefixOf "Error: Liquid Type Mismatch\n Inferred type\n VV : {v : Int | v == (7 : int)}\n \n not a subtype of Required type\n VV : {VV : Int | VV mod 2 == 0}\n")
|
||||
d ^. message `shouldSatisfy` T.isPrefixOf ("Error: Liquid Type Mismatch\n" <>
|
||||
" Inferred type\n" <>
|
||||
" VV : {v : GHC.Types.Int | v == 7}\n" <>
|
||||
" \n" <>
|
||||
" not a subtype of Required type\n" <>
|
||||
" VV : {VV : GHC.Types.Int | VV mod 2 == 0}\n ")
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
|
@ -35,10 +35,10 @@ newPluginSpec = do
|
||||
delayedCallback = \r -> threadDelay 10000 >> defCallback r
|
||||
|
||||
let req0 = GReq 0 "0" Nothing Nothing (Just $ IdInt 0) (\_ -> return () :: IO ()) "none" $ return $ IdeResultOk $ T.pack "text0"
|
||||
req1 = GReq 1 "1" Nothing Nothing (Just $ IdInt 1) defCallback $ return $ IdeResultOk "none" $ T.pack "text1"
|
||||
req2 = GReq 2 "2" Nothing Nothing (Just $ IdInt 2) delayedCallback $ return "none" $ IdeResultOk $ T.pack "text2"
|
||||
req3 = GReq 3 "3" Nothing (Just (filePathToUri "test", 2)) Nothing defCallback $ return $ IdeResultOk "none" $ T.pack "text3"
|
||||
req4 = GReq 4 "4" Nothing Nothing (Just $ IdInt 3) defCallback $ return $ IdeResultOk "none" $ T.pack "text4"
|
||||
req1 = GReq 1 "1" Nothing Nothing (Just $ IdInt 1) defCallback "none" $ return $ IdeResultOk $ T.pack "text1"
|
||||
req2 = GReq 2 "2" Nothing Nothing (Just $ IdInt 2) delayedCallback "none" $ return $ IdeResultOk $ T.pack "text2"
|
||||
req3 = GReq 3 "3" Nothing (Just (filePathToUri "test", 2)) Nothing defCallback "none" $ return $ IdeResultOk $ T.pack "text3"
|
||||
req4 = GReq 4 "4" Nothing Nothing (Just $ IdInt 3) defCallback "none" $ return $ IdeResultOk $ T.pack "text4"
|
||||
|
||||
let makeReq = sendRequest scheduler
|
||||
|
||||
|
@ -100,7 +100,6 @@ applyRefactSpec = do
|
||||
PublishDiagnosticsParams
|
||||
{ _uri = filePath
|
||||
, _diagnostics = List
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
[Diagnostic {_range = Range { _start = Position {_line = 12, _character = 23}
|
||||
, _end = Position {_line = 12, _character = 100000}}
|
||||
, _severity = Just DsInfo
|
||||
@ -108,23 +107,6 @@ applyRefactSpec = do
|
||||
, _source = Just "hlint"
|
||||
, _message = T.pack filePathNoUri <> ":13:24: error:\n Operator applied to too few arguments: +\n data instance Sing (z :: (a :~: b)) where\n> SRefl :: Sing Refl +\n\n"
|
||||
, _relatedInformation = Nothing }]}
|
||||
#elif (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,2,2,0)))
|
||||
[Diagnostic {_range = Range { _start = Position {_line = 13, _character = 0}
|
||||
, _end = Position {_line = 13, _character = 100000}}
|
||||
, _severity = Just DsInfo
|
||||
, _code = Just (StringValue "parser")
|
||||
, _source = Just "hlint"
|
||||
, _message = "Parse error: virtual }\n data instance Sing (z :: (a :~: b)) where\n SRefl :: Sing Refl +\n> \n\n"
|
||||
, _relatedInformation = Nothing }]}
|
||||
#else
|
||||
[Diagnostic {_range = Range { _start = Position {_line = 11, _character = 28}
|
||||
, _end = Position {_line = 11, _character = 100000}}
|
||||
, _severity = Just DsInfo
|
||||
, _code = Just "parser"
|
||||
, _source = Just "hlint"
|
||||
, _message = "Parse error: :~:\n import Data.Type.Equality ((:~:) (..), (:~~:) (..))\n \n> data instance Sing (z :: (a :~: b)) where\n SRefl :: Sing Refl +\n\n"
|
||||
, _relatedInformation = Nothing }]}
|
||||
#endif
|
||||
testCommand testPlugins act "applyrefact" "lint" arg res
|
||||
|
||||
-- ---------------------------------
|
||||
|
@ -482,11 +482,6 @@ ghcmodSpec =
|
||||
, (Range (toPos (33, 15)) (toPos (33, 19)), "Int -> Test -> ShowS")
|
||||
, (Range (toPos (33, 15)) (toPos (33, 19)), "Test -> String")
|
||||
, (Range (toPos (33, 15)) (toPos (33, 19)), "[Test] -> ShowS")
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
#else
|
||||
, (Range (toPos (33, 15)) (toPos (33, 19)), "Int -> Test -> ShowS")
|
||||
, (Range (toPos (33, 15)) (toPos (33, 19)), "[Test] -> ShowS")
|
||||
#endif
|
||||
]
|
||||
testCommand testPlugins act "generic" "type" arg res
|
||||
|
||||
@ -501,11 +496,6 @@ ghcmodSpec =
|
||||
[ (Range (toPos (33, 21)) (toPos (33, 23)), "(Test -> Test -> Bool) -> (Test -> Test -> Bool) -> Eq Test")
|
||||
, (Range (toPos (33, 21)) (toPos (33, 23)), "Test -> Test -> Bool")
|
||||
, (Range (toPos (33, 21)) (toPos (33, 23)), "Test -> Test -> Bool")
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
#else
|
||||
, (Range (toPos (33, 21)) (toPos (33, 23)), "Test -> Test -> Bool")
|
||||
, (Range (toPos (33, 21)) (toPos (33, 23)), "Test -> Test -> Bool")
|
||||
#endif
|
||||
]
|
||||
testCommand testPlugins act "generic" "type" arg res
|
||||
|
||||
|
@ -3,16 +3,19 @@
|
||||
module LiquidSpec where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.List
|
||||
import qualified Data.ByteString.Lazy as BS
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Monoid ((<>))
|
||||
import Data.Maybe (isJust)
|
||||
import Haskell.Ide.Engine.MonadTypes
|
||||
import Haskell.Ide.Engine.Plugin.Liquid
|
||||
import System.Directory
|
||||
import System.Exit
|
||||
import System.FilePath
|
||||
import System.Process
|
||||
import Test.Hspec
|
||||
-- import Control.Monad.IO.Class
|
||||
|
||||
main :: IO ()
|
||||
main = hspec spec
|
||||
@ -24,22 +27,27 @@ spec = do
|
||||
|
||||
-- ---------------------------------
|
||||
|
||||
it "finds liquid haskell exe in $PATH" $ findExecutable "liquid" >>= (`shouldSatisfy` isJust)
|
||||
it "the liquid haskell exe in $PATH has the supported version" $ do
|
||||
mexe <- findExecutable "liquid"
|
||||
case mexe of
|
||||
Nothing -> expectationFailure "liquid haskell exe is NOT in $PATH"
|
||||
Just exe -> do
|
||||
version <- readProcess exe ["--numeric-version"] ""
|
||||
version `shouldSatisfy` isPrefixOf "0.8.6.2"
|
||||
|
||||
-- ---------------------------------
|
||||
|
||||
-- AZ: this test has been moved to func-tests, stack > 2.1 sets
|
||||
-- its own package environment, we can't run it from here.
|
||||
|
||||
-- -- This produces some products in /test/testdata/liquid/.liquid/ that is used in subsequent test
|
||||
-- it "runs the liquid haskell exe" $ do
|
||||
-- let
|
||||
-- fp = cwd </> "test/testdata/liquid/Evens.hs"
|
||||
-- -- fp = "/home/alanz/tmp/haskell-proc-play/Evens.hs"
|
||||
-- -- uri = filePathToUri fp
|
||||
-- Just (ef, (msg:_)) <- runLiquidHaskell fp
|
||||
-- msg `shouldSatisfy` isPrefixOf "RESULT\n[{\"start\":{\"line\":9,\"column\":1},\"stop\":{\"line\":9,\"column\":8},\"message\":\"Error: Liquid Type Mismatch\\n Inferred type\\n VV : {v : Int | v == (7 : int)}\\n \\n not a subtype of Required type\\n VV : {VV : Int | VV mod 2 == 0}\\n"
|
||||
-- ef `shouldBe` ExitFailure 1
|
||||
-- This produces some products in /test/testdata/liquid/.liquid/
|
||||
-- that are used in subsequent test
|
||||
it "runs the liquid haskell exe" $ do
|
||||
let
|
||||
fp = cwd </> "test/testdata/liquid/Evens.hs"
|
||||
Just (ef, (msg:_)) <- runLiquidHaskell fp
|
||||
-- liftIO $ putStrLn $ "msg=" ++ msg
|
||||
-- liftIO $ putStrLn $ "msg=" ++ unlines (drop 3 (lines msg))
|
||||
let msg' = unlines (drop 3 (lines msg))
|
||||
msg' `shouldSatisfy` isInfixOf "RESULT\n[{\"start\":{\"line\""
|
||||
ef `shouldBe` ExitFailure 1
|
||||
|
||||
-- ---------------------------------
|
||||
it "gets annot file paths" $ do
|
||||
@ -60,12 +68,15 @@ spec = do
|
||||
let Just v = decode jf :: Maybe LiquidJson
|
||||
let [LE { start, stop, message }] = errors v
|
||||
start `shouldBe` LP 9 1
|
||||
stop `shouldBe` LP 9 8
|
||||
stop `shouldBe` LP 9 12
|
||||
message `shouldSatisfy` T.isPrefixOf
|
||||
("Error: Liquid Type Mismatch\n Inferred type\n" <>
|
||||
" VV : {v : Int | v == (7 : int)}\n \n" <>
|
||||
("Error: Liquid Type Mismatch\n" <>
|
||||
" Inferred type\n" <>
|
||||
" VV : {v : GHC.Types.Int | v == 7}\n" <>
|
||||
" \n" <>
|
||||
" not a subtype of Required type\n" <>
|
||||
" VV : {VV : Int | VV mod 2 == 0}\n")
|
||||
" VV : {VV : GHC.Types.Int | VV mod 2 == 0}\n" <>
|
||||
" ")
|
||||
|
||||
-- ---------------------------------
|
||||
|
||||
@ -100,8 +111,8 @@ spec = do
|
||||
take 2 ts
|
||||
`shouldBe`
|
||||
[LE (LP 1 1) (LP 1 1) "GHC.Types.Module"
|
||||
,LE (LP 6 1) (LP 6 10) "[{v : GHC.Types.Int | v mod 2 == 0}]"]
|
||||
length ts `shouldBe` 38
|
||||
,LE (LP 6 1) (LP 6 10) "[{VV : GHC.Types.Int | VV mod 2 == 0}]"]
|
||||
length ts `shouldBe` 53
|
||||
|
||||
-- ---------------------------------
|
||||
|
||||
@ -112,8 +123,8 @@ spec = do
|
||||
take 2 ts
|
||||
`shouldBe`
|
||||
[LE (LP 1 1) (LP 1 1) "GHC.Types.Module"
|
||||
,LE (LP 6 1) (LP 6 10) "[{v : GHC.Types.Int | v mod 2 == 0}]"]
|
||||
length ts `shouldBe` 38
|
||||
,LE (LP 6 1) (LP 6 10) "[{VV : GHC.Types.Int | VV mod 2 == 0}]"]
|
||||
length ts `shouldBe` 53
|
||||
|
||||
-- ---------------------------------
|
||||
|
||||
|
@ -64,7 +64,6 @@ packageSpec = do
|
||||
args = AddParams fp (fp </> "AddPackage.hs") "text"
|
||||
act = addCmd' args
|
||||
textEdits =
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
List
|
||||
[ TextEdit (Range (Position 0 0) (Position 7 27)) $ T.concat
|
||||
[ "cabal-version: >=1.10\n"
|
||||
@ -85,25 +84,6 @@ packageSpec = do
|
||||
, " text -any"
|
||||
]
|
||||
]
|
||||
#else
|
||||
List -- TODO: this seems to indicate that the command does nothing
|
||||
[ TextEdit (Range (Position 0 0) (Position 7 27)) $ T.concat
|
||||
[ "name: add-package-test\n"
|
||||
, "version: 0.1.0.0\n"
|
||||
, "cabal-version: >=1.10\n"
|
||||
, "build-type: Simple\n"
|
||||
, "license: BSD3\n"
|
||||
, "maintainer: luke_lau@icloud.com\n"
|
||||
, "author: Luke Lau\n"
|
||||
, "extra-source-files:\n"
|
||||
, " ChangeLog.md"
|
||||
]
|
||||
, TextEdit (Range (Position 9 0) (Position 13 34)) $ T.concat
|
||||
[ "executable AddPackage\n"
|
||||
, " main-is: AddPackage.hs\n"
|
||||
]
|
||||
]
|
||||
#endif
|
||||
res = IdeResultOk
|
||||
$ WorkspaceEdit (Just $ H.singleton uri textEdits) Nothing
|
||||
testCommand testPlugins act "package" "add" args res
|
||||
@ -117,7 +97,6 @@ packageSpec = do
|
||||
args = AddParams fp (fp </> "AddPackage.hs") "text"
|
||||
act = addCmd' args
|
||||
textEdits =
|
||||
#if (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,0,0)))
|
||||
List
|
||||
[ TextEdit (Range (Position 0 0) (Position 7 27)) $ T.concat
|
||||
[ "cabal-version: >=1.10\n"
|
||||
@ -139,29 +118,6 @@ packageSpec = do
|
||||
, " text -any"
|
||||
]
|
||||
]
|
||||
#else
|
||||
List
|
||||
[ TextEdit (Range (Position 0 0) (Position 7 27)) $ T.concat
|
||||
[ "name: add-package-test\n"
|
||||
, "version: 0.1.0.0\n"
|
||||
, "cabal-version: >=1.10\n"
|
||||
, "build-type: Simple\n"
|
||||
, "license: BSD3\n"
|
||||
, "maintainer: luke_lau@icloud.com\n"
|
||||
, "author: Luke Lau\n"
|
||||
, "extra-source-files:\n"
|
||||
, " ChangeLog.md"
|
||||
]
|
||||
, TextEdit (Range (Position 10 0) (Position 13 34)) $ T.concat
|
||||
[ " exposed-modules:\n"
|
||||
, " AddPackage\n"
|
||||
, " build-depends:\n"
|
||||
, " base >=4.7 && <5,\n"
|
||||
, " text -any\n"
|
||||
, " default-language: Haskell2010\n"
|
||||
]
|
||||
]
|
||||
#endif
|
||||
res = IdeResultOk
|
||||
$ WorkspaceEdit (Just $ H.singleton uri textEdits) Nothing
|
||||
testCommand testPlugins act "package" "add" args res
|
||||
|
@ -15,6 +15,7 @@ module TestUtils
|
||||
, hieCommandExamplePlugin
|
||||
, getHspecFormattedConfig
|
||||
, testOptions
|
||||
, flushStackEnvironment
|
||||
) where
|
||||
|
||||
import Control.Concurrent.STM
|
||||
@ -52,6 +53,7 @@ testOptions = HIE.defaultOptions { cradleOptsVerbosity = Verbose }
|
||||
testCommand :: (ToJSON a, Typeable b, ToJSON b, Show b, Eq b)
|
||||
=> IdePlugins -> IdeGhcM (IdeResult b) -> PluginId -> CommandName -> a -> IdeResult b -> IO ()
|
||||
testCommand testPlugins act plugin cmd arg res = do
|
||||
flushStackEnvironment
|
||||
(newApiRes, oldApiRes) <- runIGM testPlugins $ do
|
||||
new <- act
|
||||
old <- makeRequest plugin cmd arg
|
||||
@ -150,12 +152,6 @@ stackYaml =
|
||||
"stack-8.4.3.yaml"
|
||||
#elif (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,4,2,0)))
|
||||
"stack-8.4.2.yaml"
|
||||
#elif (defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,2,2,0)))
|
||||
"stack-8.2.2.yaml"
|
||||
#elif __GLASGOW_HASKELL__ >= 802
|
||||
"stack-8.2.1.yaml"
|
||||
#else
|
||||
"stack-8.0.2.yaml"
|
||||
#endif
|
||||
|
||||
logFilePath :: String
|
||||
@ -297,3 +293,14 @@ xmlFormatter = silent {
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
flushStackEnvironment :: IO ()
|
||||
flushStackEnvironment = do
|
||||
-- We need to clear these environment variables to prevent
|
||||
-- collisions with stack usages
|
||||
-- See https://github.com/commercialhaskell/stack/issues/4875
|
||||
unsetEnv "GHC_PACKAGE_PATH"
|
||||
unsetEnv "GHC_ENVIRONMENT"
|
||||
unsetEnv "HASKELL_PACKAGE_SANDBOX"
|
||||
unsetEnv "HASKELL_PACKAGE_SANDBOXES"
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user