Skip to content

Commit

Permalink
Backport HIE files to GHC 8.6 (haskell/ghcide#689)
Browse files Browse the repository at this point in the history
* Backport HIE files support to 8.6

* Use hie files as source of truth for name source spans.

Since we started reusing `.hi` files, this exposes a bug where definitions
aren't available since a bad source span from the `.hi` file gets put into
the NameCache. We rectify by ensuring the span in the NameCache always matches
the one from the `.hie` file.

This has surfaced because an interaction between the commit which uses `.hi`
instead of retypechecking and the change to use the shared global NameCache
to read `.hie` files.
  • Loading branch information
wz1000 authored Jul 16, 2020
1 parent 95c595d commit 4654733
Show file tree
Hide file tree
Showing 7 changed files with 3,349 additions and 29 deletions.
8 changes: 8 additions & 0 deletions ghcide/ghcide.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ library
Development.IDE.Plugin.CodeAction.RuleTypes
Development.IDE.Plugin.Completions.Logic
Development.IDE.Plugin.Completions.Types
if (impl(ghc > 8.5) && impl(ghc < 8.7)) && !flag(ghc-lib)
hs-source-dirs: src-ghc86
other-modules:
Development.IDE.GHC.HieAst
Development.IDE.GHC.HieBin
Development.IDE.GHC.HieTypes
Development.IDE.GHC.HieDebug
Development.IDE.GHC.HieUtils
if (impl(ghc > 8.7) && impl(ghc < 8.10)) || flag(ghc-lib)
hs-source-dirs: src-ghc88
other-modules:
Expand Down
68 changes: 39 additions & 29 deletions ghcide/src/Development/IDE/GHC/Compat.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,16 @@ module Development.IDE.GHC.Compat(
upNameCache,

module GHC,
#if MIN_GHC_API_VERSION(8,6,0)

#if MIN_GHC_API_VERSION(8,8,0)
module HieTypes,
module HieUtils,
#else
module Development.IDE.GHC.HieTypes,
module Development.IDE.GHC.HieUtils,
#endif

#endif
) where

Expand Down Expand Up @@ -94,35 +101,38 @@ import Avail
import ErrUtils (ErrorMessages)
import FastString (FastString)

#if MIN_GHC_API_VERSION(8,8,0)
#if MIN_GHC_API_VERSION(8,6,0)
import Development.IDE.GHC.HieAst (mkHieFile)
import Development.IDE.GHC.HieBin

#if MIN_GHC_API_VERSION(8,8,0)
import HieUtils
import HieTypes
#else
import Development.IDE.GHC.HieUtils
import Development.IDE.GHC.HieTypes
import System.FilePath ((-<.>))
#endif

supportsHieFiles :: Bool
supportsHieFiles = True

hieExportNames :: HieFile -> [(SrcSpan, Name)]
hieExportNames = nameListFromAvails . hie_exports
#endif

#else
#if !MIN_GHC_API_VERSION(8,8,0)

import IfaceEnv
#if MIN_GHC_API_VERSION(8,6,0)
import BinIface
import GhcPlugins (srcErrorMessages)
#else
import System.IO.Error
#endif

import IfaceEnv
import Binary
import Control.Exception (catch)
import Data.ByteString (ByteString)
import GhcPlugins (Hsc, srcErrorMessages)
import TcRnTypes
import MkIface
#endif

import Control.Exception (catch)
import System.IO
import Foreign.ForeignPtr
import MkIface


hPutStringBuffer :: Handle -> StringBuffer -> IO ()
Expand All @@ -132,6 +142,20 @@ hPutStringBuffer hdl (StringBuffer buf len cur)

#endif

#if MIN_GHC_API_VERSION(8,6,0)
supportsHieFiles :: Bool
supportsHieFiles = True

hieExportNames :: HieFile -> [(SrcSpan, Name)]
hieExportNames = nameListFromAvails . hie_exports

#if !MIN_GHC_API_VERSION(8,8,0)
ml_hie_file :: GHC.ModLocation -> FilePath
ml_hie_file ml = ml_hi_file ml -<.> ".hie"
#endif

#endif

upNameCache :: IORef NameCache -> (NameCache -> (NameCache, c)) -> IO c
#if !MIN_GHC_API_VERSION(8,8,0)
upNameCache ref upd_fn
Expand Down Expand Up @@ -271,7 +295,7 @@ nameListFromAvails :: [AvailInfo] -> [(SrcSpan, Name)]
nameListFromAvails as =
map (\n -> (nameSrcSpan n, n)) (concatMap availNames as)

#if !MIN_GHC_API_VERSION(8,8,0)
#if !MIN_GHC_API_VERSION(8,6,0)
-- Reimplementations of functions for HIE files for GHC 8.6

mkHieFile :: ModSummary -> TcGblEnv -> RenamedSource -> ByteString -> Hsc HieFile
Expand Down Expand Up @@ -303,21 +327,7 @@ writeHieFile :: FilePath -> HieFile -> IO ()
readHieFile :: NameCacheUpdater -> FilePath -> IO HieFileResult
supportsHieFiles :: Bool

#if MIN_GHC_API_VERSION(8,6,0)

writeHieFile fp hie = do
bh <- openBinMem (1024 * 1024)
putWithUserData (const $ return ()) bh hie
writeBinMem bh fp

readHieFile nc fp = do
bh <- readBinMem fp
hie_file <- getWithUserData nc bh
return (HieFileResult hie_file)

supportsHieFiles = True

#else
#if MIN_GHC_API_VERSION(8,4,0)

supportsHieFiles = False

Expand Down
Loading

0 comments on commit 4654733

Please sign in to comment.