on master help sign in
Move the ofInterest kicking around in the IDE (#1669)
e2e158aNeil Mitchell
BUILD.bazel+1
@@ -35,6 +35,7 @@ depends = [
35 "transformers",
35 "transformers",
36 "uniplate",
36 "uniplate",
37 "unordered-containers",
37 "unordered-containers",
38+ "utf8-string",
38 "uri-encode",
39 "uri-encode",
39]
40]
40
41
haskell-ide-core.cabal+1
@@ -55,6 +55,7 @@ library
55 transformers,
55 transformers,
56 uniplate,
56 uniplate,
57 unordered-containers,
57 unordered-containers,
58+ utf8-string,
58 uri-encode
59 uri-encode
59
60
60 cpp-options: -DGHC_STABLE
61 cpp-options: -DGHC_STABLE
src/Development/IDE/State/RuleTypes.hs+8−6
@@ -19,6 +19,8 @@ import Development.IDE.Functions.FindImports (Import(..))
19import Development.IDE.Functions.DependencyInformation
19import Development.IDE.Functions.DependencyInformation
20import Data.Hashable
20import Data.Hashable
21import Data.Typeable
21import Data.Typeable
22+import Development.IDE.Types.Diagnostics
23+import Data.Set(Set)
22import Development.Shake hiding (Env, newCache)
24import Development.Shake hiding (Env, newCache)
23import GHC.Generics (Generic)
25import GHC.Generics (Generic)
24
26
@@ -33,9 +35,6 @@ import Development.IDE.Types.SpanInfo
33-- Foo+ means Foo for the dependencies
35-- Foo+ means Foo for the dependencies
34-- Foo* means Foo for me and Foo+
36-- Foo* means Foo for me and Foo+
35
37
36−-- | Kick off things
37−type instance RuleResult OfInterest = ()
38−
39-- | The parse tree for the file using GetFileContents
38-- | The parse tree for the file using GetFileContents
40type instance RuleResult GetParsedModule = ParsedModule
39type instance RuleResult GetParsedModule = ParsedModule
41
40
@@ -73,10 +72,13 @@ type instance RuleResult ReportImportCycles = ()
73type instance RuleResult GetHieFile = HieFile
72type instance RuleResult GetHieFile = HieFile
74
73
75
74
76−data OfInterest = OfInterest
75+type instance RuleResult GetFilesOfInterest = Set NormalizedFilePath
76+
77+
78+data GetFilesOfInterest = GetFilesOfInterest
77 deriving (Eq, Show, Typeable, Generic)
79 deriving (Eq, Show, Typeable, Generic)
78−instance Hashable OfInterest
80+instance Hashable GetFilesOfInterest
79−instance NFData OfInterest
81+instance NFData GetFilesOfInterest
80
82
81data GetParsedModule = GetParsedModule
83data GetParsedModule = GetParsedModule
82 deriving (Eq, Show, Typeable, Generic)
84 deriving (Eq, Show, Typeable, Generic)
src/Development/IDE/State/Rules.hs+12
@@ -31,6 +31,9 @@ import Development.IDE.Functions.DependencyInformation
31import Development.IDE.Functions.FindImports
31import Development.IDE.Functions.FindImports
32import Development.IDE.State.FileStore
32import Development.IDE.State.FileStore
33import Development.IDE.Types.Diagnostics as Base
33import Development.IDE.Types.Diagnostics as Base
34+import qualified Data.ByteString.UTF8 as BS
35+import Control.Exception
36+import Control.Concurrent.Extra
34import Data.Bifunctor
37import Data.Bifunctor
35import Data.Either.Extra
38import Data.Either.Extra
36import Data.Maybe
39import Data.Maybe
@@ -72,6 +75,14 @@ defineNoFile f = define $ \k file -> do
72------------------------------------------------------------
75------------------------------------------------------------
73-- Exposed API
76-- Exposed API
74
77
78+getFilesOfInterestRule :: Rules ()
79+getFilesOfInterestRule = do
80+ defineEarlyCutoff $ \GetFilesOfInterest _file -> assert (null $ fromNormalizedFilePath _file) $ do
81+ alwaysRerun
82+ Env{..} <- getServiceEnv
83+ filesOfInterest <- liftIO $ readVar envOfInterestVar
84+ pure (Just $ BS.fromString $ show filesOfInterest, ([], Just filesOfInterest))
85+
75
86
76-- | Get GHC Core for the supplied file.
87-- | Get GHC Core for the supplied file.
77getGhcCore :: NormalizedFilePath -> Action (Maybe [CoreModule])
88getGhcCore :: NormalizedFilePath -> Action (Maybe [CoreModule])
@@ -318,6 +329,7 @@ mainRule = do
318 generateCoreRule
329 generateCoreRule
319 loadGhcSession
330 loadGhcSession
320 getHieFileRule
331 getHieFileRule
332+ getFilesOfInterestRule
321
333
322------------------------------------------------------------
334------------------------------------------------------------
323
335
test/Demo.hs+13−4
@@ -11,6 +11,7 @@ import Development.IDE.State.Service
11import Development.IDE.State.Rules
11import Development.IDE.State.Rules
12import Development.IDE.State.Shake
12import Development.IDE.State.Shake
13import Development.IDE.State.RuleTypes
13import Development.IDE.State.RuleTypes
14+import Data.String
14import Development.IDE.Types.Diagnostics
15import Development.IDE.Types.Diagnostics
15import Development.IDE.Types.Options
16import Development.IDE.Types.Options
16import Development.IDE.Logger
17import Development.IDE.Logger
@@ -39,6 +40,9 @@ getLibdir = fromMaybe GHC.Paths.libdir <$> lookupEnv "NIX_GHC_LIBDIR"
39
40
40main :: IO ()
41main :: IO ()
41main = do
42main = do
43+ -- WARNING: If you write to stdout before runLanguageServer
44+ -- then the language server will not work
45+ hPutStrLn stderr "Starting haskell-ide-core Demo"
42 (ghcOptions, map toNormalizedFilePath -> files, isIde) <- getCmdLine
46 (ghcOptions, map toNormalizedFilePath -> files, isIde) <- getCmdLine
43
47
44 -- lock to avoid overlapping output on stdout
48 -- lock to avoid overlapping output on stdout
@@ -56,21 +60,26 @@ main = do
56 }
60 }
57
61
58 if isIde then do
62 if isIde then do
59− putStrLn "Starting IDE server"
63+ hPutStrLn stderr "Starting running the IDE server"
60 runLanguageServer logger $ \event vfs -> do
64 runLanguageServer logger $ \event vfs -> do
61− putStrLn "Server started"
65+ hPutStrLn stderr "Server started"
62− initialise mainRule event logger options vfs
66+ initialise (mainRule >> action kick) event logger options vfs
63 else do
67 else do
64 vfs <- makeVFSHandle
68 vfs <- makeVFSHandle
65 ide <- initialise mainRule (showEvent lock) logger options vfs
69 ide <- initialise mainRule (showEvent lock) logger options vfs
66 setFilesOfInterest ide $ Set.fromList files
70 setFilesOfInterest ide $ Set.fromList files
67− _ <- runAction ide $ uses_ TypeCheck files
71+ runAction ide kick
68 -- shake now writes an async message that it is completed with timing info,
72 -- shake now writes an async message that it is completed with timing info,
69 -- so we sleep briefly to wait for it to have been written
73 -- so we sleep briefly to wait for it to have been written
70 sleep 0.01
74 sleep 0.01
71 putStrLn "Done"
75 putStrLn "Done"
72
76
73
77
78+kick :: Action ()
79+kick = do
80+ files <- use_ GetFilesOfInterest $ fromString ""
81+ void $ uses TypeCheck $ Set.toList files
82+
74-- | Print an LSP event.
83-- | Print an LSP event.
75showEvent :: Lock -> FromServerMessage -> IO ()
84showEvent :: Lock -> FromServerMessage -> IO ()
76showEvent _ (EventFileDiagnostics _ []) = return ()
85showEvent _ (EventFileDiagnostics _ []) = return ()