content: module Policeman.Hie
      ( createHieFiles
      , readHieFiles
      ) where
  
  import HieBin (HieFileResult (hie_file_result), readHieFile)
  import HieTypes (HieFile)
  import NameCache (NameCache, initNameCache)
  import Shellmet ()
  import System.Directory (doesFileExist, getCurrentDirectory, setCurrentDirectory)
  import System.Directory.Recursive (getDirRecursive)
  import System.FilePath ((</>))
  import UniqSupply (mkSplitUniqSupply)
  
  
  {- | Generates HIE files for the project in the given folder and
  returns their parsed content. The generated files are going to be
  created in the @.hie/@ folder inside the given directory.
  -}
  createHieFiles :: FilePath -> IO [HieFile]
  createHieFiles projectDir = do
      curDir <- getCurrentDirectory
      setCurrentDirectory projectDir
  
      -- make sure cabal isn't confused by any other "cabal.project"
      -- file in a parent directory
      -- See discussion: https://github.com/kowainik/policeman/issues/52
      writeFile "cabal.project" "packages: ."
  
      "cabal" ["clean"]
      "cabal"
          [ "v2-build"
          , "--ghc-options=-fwrite-ide-info"
          , "--ghc-options=-hiedir=.hie"
          , "--verbose=0"
          ]
      readHieFiles <* setCurrentDirectory curDir
  
  {- | Returns content of all @.hie@ files recursively in the current
  directory from the @.hie/@ folder.
  -}
  readHieFiles :: IO [HieFile]
  readHieFiles = do
      hieDir <- (</> ".hie") <$> getCurrentDirectory
      nameCache <- createNameCache
      hieContent <- getDirRecursive hieDir
      hieFiles <- filterM doesFileExist hieContent
      forM hieFiles $ \hiePath -> do
          (hieFileResult, _newCache) <- readHieFile nameCache hiePath
          pure $ hie_file_result hieFileResult
  
  createNameCache :: IO NameCache
  createNameCache = do
      uniqSupply <- mkSplitUniqSupply 'z'
      pure $ initNameCache uniqSupply []
  