3
3
{-# LANGUAGE PatternSynonyms #-}
4
4
{-# LANGUAGE RecordWildCards #-}
5
5
6
- module Ide.Plugin.Eval.Rules (GetEvalComments (.. ), rules ) where
6
+ module Ide.Plugin.Eval.Rules (GetEvalComments (.. ), rules , queueForEvaluation ) where
7
7
8
+ import Control.Monad.IO.Class (MonadIO (liftIO ))
9
+ import Data.HashSet (HashSet )
10
+ import qualified Data.HashSet as Set
11
+ import Data.IORef
8
12
import qualified Data.Map.Strict as Map
9
13
import Data.String (fromString )
10
14
import Development.IDE (GetModSummaryWithoutTimestamps (GetModSummaryWithoutTimestamps ),
11
15
GetParsedModuleWithComments (GetParsedModuleWithComments ),
12
- IsFileOfInterest (IsFileOfInterest ),
13
- IsFileOfInterestResult (NotFOI ),
16
+ IdeState ,
14
17
NeedsCompilation (NeedsCompilation ),
18
+ NormalizedFilePath ,
15
19
RuleBody (RuleNoDiagnostics ),
16
20
Rules , defineEarlyCutoff ,
17
21
encodeLinkableType ,
18
22
fromNormalizedFilePath ,
19
23
msrModSummary ,
20
24
realSrcSpanToRange ,
21
- useWithStale_ , use_ )
25
+ useWithStale_ )
22
26
import Development.IDE.Core.PositionMapping (toCurrentRange )
23
27
import Development.IDE.Core.Rules (computeLinkableType ,
24
28
needsCompilationRule )
29
+ import Development.IDE.Core.Shake (IsIdeGlobal ,
30
+ RuleBody (RuleWithCustomNewnessCheck ),
31
+ addIdeGlobal ,
32
+ getIdeGlobalAction ,
33
+ getIdeGlobalState )
25
34
import Development.IDE.GHC.Compat
26
35
import qualified Development.IDE.GHC.Compat as SrcLoc
27
36
import qualified Development.IDE.GHC.Compat.Util as FastString
@@ -33,6 +42,15 @@ rules :: Rules ()
33
42
rules = do
34
43
evalParsedModuleRule
35
44
redefinedNeedsCompilation
45
+ addIdeGlobal . EvaluatingVar =<< liftIO(newIORef mempty )
46
+
47
+ newtype EvaluatingVar = EvaluatingVar (IORef (HashSet NormalizedFilePath ))
48
+ instance IsIdeGlobal EvaluatingVar
49
+
50
+ queueForEvaluation :: IdeState -> NormalizedFilePath -> IO ()
51
+ queueForEvaluation ide nfp = do
52
+ EvaluatingVar var <- getIdeGlobalState ide
53
+ modifyIORef var (Set. insert nfp)
36
54
37
55
#if MIN_VERSION_ghc(9,0,0)
38
56
pattern RealSrcSpanAlready :: SrcLoc. RealSrcSpan -> SrcLoc. RealSrcSpan
@@ -75,18 +93,24 @@ evalParsedModuleRule = defineEarlyCutoff $ RuleNoDiagnostics $ \GetEvalComments
75
93
return (Just fingerPrint, Just comments)
76
94
77
95
-- Redefine the NeedsCompilation rule to set the linkable type to Just _
78
- -- whenever the module has Eval comments and is of interest.
96
+ -- whenever the module is being evaluated
79
97
-- This will ensure that the modules are loaded with linkables
80
98
-- and the interactive session won't try to compile them on the fly,
81
99
-- leading to much better performance of the evaluate code lens
82
100
redefinedNeedsCompilation :: Rules ()
83
- redefinedNeedsCompilation = defineEarlyCutoff $ RuleNoDiagnostics $ \ NeedsCompilation f -> do
84
- (comments, _) <- useWithStale_ GetEvalComments f
85
- isFOI <- use_ IsFileOfInterest f
86
- if nullComments comments || isFOI == NotFOI then needsCompilationRule f else do
101
+ redefinedNeedsCompilation = defineEarlyCutoff $ RuleWithCustomNewnessCheck (<=) $ \ NeedsCompilation f -> do
102
+ EvaluatingVar var <- getIdeGlobalAction
103
+
104
+ isEvaluating <- liftIO $ (f `elem` ) <$> readIORef var
105
+
106
+ if not isEvaluating then needsCompilationRule f else do
87
107
ms <- msrModSummary . fst <$> useWithStale_ GetModSummaryWithoutTimestamps f
88
108
let ms' = ms{ms_hspp_opts = df'}
89
109
df' = xopt_set (ms_hspp_opts ms) LangExt. TemplateHaskell
90
110
linkableType = computeLinkableType ms' [] []
91
111
fp = encodeLinkableType linkableType
112
+
113
+ -- remove the module from the Evaluating state
114
+ liftIO $ modifyIORef var (Set. delete f)
115
+
92
116
pure (Just fp, Just linkableType)
0 commit comments