This repository was archived by the owner on Oct 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 206
/
Copy pathRunTest.hs
128 lines (113 loc) · 4.69 KB
/
RunTest.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE OverloadedStrings #-}
module RunTest
( findAllSourceFiles
, compileTarget
, runServer
, prettyPrintDiags
)
where
import GhcMonad
import qualified GHC
import Control.Monad
import qualified Control.Concurrent.STM as STM
import Data.List ( isPrefixOf )
import qualified Data.Text as T
import qualified Data.Map as Map
import Data.Default
import System.Directory ( doesDirectoryExist
, listDirectory
, canonicalizePath
, doesFileExist
)
import System.FilePath
import Language.Haskell.LSP.Core
import Language.Haskell.LSP.Types
import Haskell.Ide.Engine.PluginsIdeMonads
hiding ( withIndefiniteProgress
, withProgress
)
import Haskell.Ide.Engine.GhcModuleCache
import qualified Haskell.Ide.Engine.ModuleCache
as MC
import qualified Haskell.Ide.Engine.Ghc as Ghc
findAllSourceFiles :: FilePath -> IO [FilePath]
findAllSourceFiles fp = do
absFp <- canonicalizePath fp
isDir <- doesDirectoryExist absFp
if isDir
then findFilesRecursively
isHaskellSource
(\path -> any (\p -> p path) [isHidden, isSpecialDir])
absFp
else filterM doesFileExist [absFp]
where
isHaskellSource = (== ".hs") . takeExtension
isHidden = ("." `isPrefixOf`) . takeFileName
isSpecialDir = (== "dist-newstyle") . takeFileName
findFilesRecursively
:: (FilePath -> Bool) -> (FilePath -> Bool) -> FilePath -> IO [FilePath]
findFilesRecursively p exclude dir = do
dirContents' <- listDirectory dir
let dirContents = map (dir </>) dirContents'
files <- forM dirContents $ \fp -> do
isDirectory <- doesDirectoryExist fp
if isDirectory
then if not $ exclude fp
then findFilesRecursively p exclude fp
else return []
else if p fp then return [fp] else return []
return $ concat files
-- ---------------------------------------------------------------------
compileTarget
:: GHC.DynFlags
-> FilePath
-> IdeGhcM (IdeResult (Ghc.Diagnostics, Ghc.AdditionalErrs))
compileTarget dynFlags fp = do
let pubDiags _ _ _ = return ()
let defAction = return (mempty, mempty)
let action = Ghc.setTypecheckedModule (filePathToUri fp)
actionResult <- MC.runActionWithContext pubDiags
dynFlags
(Just fp)
defAction
action
return $ join actionResult
-- ---------------------------------------------------------------------
runServer
:: Maybe FilePath
-> IdePlugins
-> [FilePath]
-> IO [(FilePath, IdeResult (Ghc.Diagnostics, Ghc.AdditionalErrs))]
runServer mlibdir ideplugins targets = do
let initialState = IdeState emptyModuleCache Map.empty Map.empty Nothing
stateVar <- STM.newTVarIO initialState
runIdeGhcM mlibdir ideplugins dummyLspFuncs stateVar $ do
dynFlags <- getSessionDynFlags
mapM (\fp -> (fp, ) <$> compileTarget dynFlags fp) targets
-- ---------------------------------------------------------------------
prettyPrintDiags
:: FilePath -> IdeResult (Ghc.Diagnostics, Ghc.AdditionalErrs) -> T.Text
prettyPrintDiags fp diags = T.pack fp <> ": " <> case diags of
Left IdeError { ideMessage } -> "FAILED\n\t" <> ideMessage
Right (_diags, errs) ->
if null errs then "OK" else T.unlines (map (T.append "\t") errs)
-- ---------------------------------------------------------------------
dummyLspFuncs :: Default a => LspFuncs a
dummyLspFuncs = LspFuncs
{ clientCapabilities = def
, config = return (Just def)
, sendFunc = const (return ())
, getVirtualFileFunc = const (return Nothing)
, persistVirtualFileFunc = \uri ->
return (uriToFilePath (fromNormalizedUri uri))
, reverseFileMapFunc = return id
, publishDiagnosticsFunc = mempty
, flushDiagnosticsBySourceFunc = mempty
, getNextReqId = pure (IdInt 0)
, rootPath = Nothing
, getWorkspaceFolders = return Nothing
, withProgress = \_ _ f -> f (const (return ()))
, withIndefiniteProgress = \_ _ f -> f
}