13
13
{-# LANGUAGE ScopedTypeVariables #-}
14
14
{-# LANGUAGE TupleSections #-}
15
15
{-# LANGUAGE TypeFamilies #-}
16
+ {-# LANGUAGE UnicodeSyntax #-}
16
17
17
18
-- |
18
19
-- This module provides the core functionality of the plugin.
@@ -22,6 +23,8 @@ import Control.Lens ((^.))
22
23
import Control.Monad.Except (ExceptT , liftEither ,
23
24
withExceptT )
24
25
import Control.Monad.IO.Class (MonadIO , liftIO )
26
+ import Control.Monad.Trans (lift )
27
+ import Control.Monad.Trans.Except (runExceptT )
25
28
import Data.Either (fromRight )
26
29
import qualified Data.Map as Map
27
30
import Data.Maybe (listToMaybe , mapMaybe )
@@ -30,21 +33,25 @@ import Development.IDE (Action,
30
33
GetDocMap (GetDocMap ),
31
34
GetHieAst (GetHieAst ),
32
35
HieAstResult (HAR , hieAst , hieModule , refMap ),
33
- IdeState , Priority (.. ),
34
- Recorder , Rules ,
35
- WithPriority ,
36
+ IdeResult , IdeState ,
37
+ Pretty (pretty ),
38
+ Priority (.. ), Recorder ,
39
+ Rules , WithPriority ,
36
40
cmapWithPrio , define ,
37
41
hieKind , ideLogger ,
38
42
logPriority , use_ )
39
43
import Development.IDE.Core.PluginUtils (runActionE ,
40
44
useWithStaleE )
41
45
import Development.IDE.Core.PositionMapping (idDelta , toCurrentRange )
42
- import Development.IDE.Core.Rules (Log ( LogShake ) )
46
+ import Development.IDE.Core.Rules (toIdeResult )
43
47
import Development.IDE.Core.RuleTypes (DocAndKindMap (.. ))
44
- import Development.IDE.Core.Shake (addPersistentRule )
45
- import Development.IDE.GHC.Compat
48
+ import Development.IDE.Core.Shake (addPersistentRule ,
49
+ useWithStale_ )
50
+ import Development.IDE.GHC.Compat hiding (Warning )
51
+ import Ide.Logger (logWith )
46
52
import Ide.Plugin.Error (PluginError (PluginInternalError ),
47
- getNormalizedFilePathE )
53
+ getNormalizedFilePathE ,
54
+ handleMaybe )
48
55
import Ide.Plugin.SemanticTokens.Mappings
49
56
import Ide.Plugin.SemanticTokens.Query
50
57
import Ide.Plugin.SemanticTokens.Types
@@ -56,16 +63,16 @@ import Language.LSP.Protocol.Types (NormalizedFilePath,
56
63
type (|? ) (InL ))
57
64
import Prelude hiding (span )
58
65
59
- logWith :: (MonadIO m ) => IdeState -> Priority -> String -> m ()
60
- logWith st prior = liftIO . logPriority (ideLogger st) prior . T. pack
66
+ logActionWith :: (MonadIO m ) => IdeState -> Priority -> String -> m ()
67
+ logActionWith st prior = liftIO . logPriority (ideLogger st) prior . T. pack
61
68
62
69
-----------------------
63
70
---- the api
64
71
-----------------------
65
72
66
73
computeSemanticTokens :: IdeState -> NormalizedFilePath -> ExceptT PluginError Action SemanticTokens
67
74
computeSemanticTokens state nfp = do
68
- let dbg = logWith state Debug
75
+ let dbg = logActionWith state Debug
69
76
dbg $ " Computing semantic tokens for: " <> show nfp
70
77
(RangeHsSemanticTokenTypes {tokens}, mapping) <- useWithStaleE GetSemanticTokens nfp
71
78
let rangeTokens = mapMaybe (\ (span , name) -> (,name) <$> toCurrentRange mapping span ) tokens
@@ -77,6 +84,7 @@ semanticTokensFull state _ param = do
77
84
items <- runActionE " SemanticTokens.semanticTokensFull" state $ computeSemanticTokens state nfp
78
85
return $ InL items
79
86
87
+
80
88
-- | Defines the 'getSemanticTokensRule' function, compute semantic tokens for a Haskell source file.
81
89
--
82
90
-- This Rule collects information from various sources, including:
@@ -87,13 +95,12 @@ semanticTokensFull state _ param = do
87
95
-- Visible names from 'tmrRenamed'
88
96
--
89
97
-- It then combines this information to compute the semantic tokens for the file.
90
- getSemanticTokensRule :: Recorder (WithPriority Log ) -> Rules ()
98
+ getSemanticTokensRule :: Recorder (WithPriority SemanticLog ) -> Rules ()
91
99
getSemanticTokensRule recorder =
92
- define (cmapWithPrio LogShake recorder) $ \ GetSemanticTokens nfp -> do
93
- -- (hscEnv -> hsc) <- use_ GhcSessionDeps nfp
94
- (HAR {.. }) <- use_ GetHieAst nfp
95
- (DKMap {getKindMap}) <- use_ GetDocMap nfp
96
- Just (_, ast) <- return $ listToMaybe $ Map. toList $ getAsts hieAst
100
+ define (cmapWithPrio LogShake recorder) $ \ GetSemanticTokens nfp -> handleError recorder $ do
101
+ (HAR {.. }) <- lift $ use_ GetHieAst nfp
102
+ (DKMap {getKindMap}, _) <- lift $ useWithStale_ GetDocMap nfp
103
+ (_, ast) <- handleMaybe LogNoAST $ listToMaybe $ Map. toList $ getAsts hieAst
97
104
-- get current location from the old ones
98
105
let spanNamesMap = hieAstSpanNames ast
99
106
let names = nameSetElemsStable $ unionNameSets $ Map. elems spanNamesMap
@@ -104,7 +111,7 @@ getSemanticTokensRule recorder =
104
111
-- let importedNameSemanticMap = computeImportedNameSemanticMap $ nameSetElemsStable nameSet
105
112
let sMap = plusNameEnv_C (<>) importedNameSemanticMap localSemanticMap
106
113
let rangeTokenType = extractSemanticTokensFromNames sMap spanNamesMap
107
- return ( [] , Just $ RangeHsSemanticTokenTypes rangeTokenType)
114
+ return $ RangeHsSemanticTokenTypes rangeTokenType
108
115
where
109
116
-- ignore one already in discovered in local
110
117
getTypeExclude :: NameEnv a
@@ -121,3 +128,14 @@ getSemanticTokensRule recorder =
121
128
-- | Persistent rule to ensure that semantic tokens doesn't block on startup
122
129
persistentGetSemanticTokensRule :: Rules ()
123
130
persistentGetSemanticTokensRule = addPersistentRule GetSemanticTokens $ \ _ -> pure $ Just (RangeHsSemanticTokenTypes mempty , idDelta, Nothing )
131
+
132
+ -- taken from /haskell-language-server/plugins/hls-code-range-plugin/src/Ide/Plugin/CodeRange/Rules.hs
133
+ -- | Handle error in 'Action'. Returns an 'IdeResult' with no value and no diagnostics on error. (but writes log)
134
+ handleError :: Recorder (WithPriority msg ) -> ExceptT msg Action a -> Action (IdeResult a )
135
+ handleError recorder action' = do
136
+ valueEither <- runExceptT action'
137
+ case valueEither of
138
+ Left msg -> do
139
+ logWith recorder Warning msg
140
+ pure $ toIdeResult (Left [] )
141
+ Right value -> pure $ toIdeResult (Right value)
0 commit comments