3
3
4
4
module Ide.Plugin.SemanticTokens.Tokenize (computeRangeHsSemanticTokenTypeList ) where
5
5
6
- import Control.Lens (Identity (Identity , runIdentity ))
6
+ import Control.Lens (Identity (runIdentity ))
7
7
import Control.Monad (foldM , guard )
8
8
import Control.Monad.State.Strict (MonadState (get ),
9
9
MonadTrans (lift ),
10
- evalStateT , gets , mapStateT ,
11
- modify' , put )
10
+ evalStateT , modify , put )
12
11
import Control.Monad.Trans.State.Strict (StateT , runStateT )
13
12
import Data.Char (isAlphaNum )
14
13
import Data.DList (DList )
@@ -32,25 +31,13 @@ import Prelude hiding (length, span)
32
31
33
32
type Tokenizer m a = StateT PTokenState m a
34
33
type HsSemanticLookup = Identifier -> Maybe HsSemanticTokenType
35
- type CachedHsSemanticLookup m = Identifier -> Tokenizer m (Maybe HsSemanticTokenType )
36
-
37
- cacheLookup :: (Monad m ) => HsSemanticLookup -> CachedHsSemanticLookup m
38
- cacheLookup _ (Left _) = return $ Just TModule
39
- cacheLookup lk idt@ (Right n) = do
40
- ne <- gets semanticLookupCache
41
- case lookupNameEnv ne n of
42
- Nothing -> do
43
- let hsSemanticTy = lk idt
44
- modify' (\ x -> x{ semanticLookupCache= extendNameEnv ne n hsSemanticTy })
45
- return hsSemanticTy
46
- Just x -> return x
34
+
47
35
48
36
data PTokenState = PTokenState
49
37
{
50
- rope :: ! Rope -- the remains of rope we are working on
51
- , cursor :: ! Char. Position -- the cursor position of the current rope to the start of the original file in code point position
52
- , columnsInUtf16 :: ! UInt -- the column of the start of the current rope in utf16
53
- , semanticLookupCache :: ! (NameEnv (Maybe HsSemanticTokenType )) -- the cache for semantic lookup result of the current file
38
+ rope :: ! Rope -- the remains of rope we are working on
39
+ , cursor :: ! Char. Position -- the cursor position of the current rope to the start of the original file in code point position
40
+ , columnsInUtf16 :: ! UInt -- the column of the start of the current rope in utf16
54
41
}
55
42
56
43
data SplitResult
@@ -62,14 +49,14 @@ getSplitTokenText :: SplitResult -> Text
62
49
getSplitTokenText (NoSplit (t, _)) = t
63
50
getSplitTokenText (Split (t, _, _)) = t
64
51
52
+
65
53
mkPTokenState :: VirtualFile -> PTokenState
66
54
mkPTokenState vf =
67
55
PTokenState
68
56
{
69
57
rope = vf. _file_text,
70
58
cursor = Char. Position 0 0 ,
71
- columnsInUtf16 = 0 ,
72
- semanticLookupCache = emptyNameEnv
59
+ columnsInUtf16 = 0
73
60
}
74
61
75
62
-- lift a Tokenizer Maybe a to Tokenizer m a,
@@ -85,15 +72,15 @@ foldMapM f ta = foldM (\b a -> mappend b <$> f a) mempty ta
85
72
86
73
computeRangeHsSemanticTokenTypeList :: HsSemanticLookup -> VirtualFile -> HieAST a -> RangeHsSemanticTokenTypes
87
74
computeRangeHsSemanticTokenTypeList lookupHsTokenType vf ast =
88
- RangeHsSemanticTokenTypes $ DL. toList $ runIdentity $ evalStateT (foldAst (cacheLookup lookupHsTokenType) ast) (mkPTokenState vf)
75
+ RangeHsSemanticTokenTypes $ DL. toList $ runIdentity $ evalStateT (foldAst lookupHsTokenType ast) (mkPTokenState vf)
89
76
-- | foldAst
90
77
-- visit every leaf node in the ast in depth first order
91
- foldAst :: (Monad m ) => CachedHsSemanticLookup Identity -> HieAST t -> Tokenizer m (DList (Range , HsSemanticTokenType ))
78
+ foldAst :: (Monad m ) => HsSemanticLookup -> HieAST t -> Tokenizer m (DList (Range , HsSemanticTokenType ))
92
79
foldAst lookupHsTokenType ast = if null (nodeChildren ast)
93
- then visitLeafIds lookupHsTokenType ast
80
+ then liftMaybeM ( visitLeafIds lookupHsTokenType ast)
94
81
else foldMapM (foldAst lookupHsTokenType) $ nodeChildren ast
95
82
96
- visitLeafIds :: ( Monad m ) => CachedHsSemanticLookup Identity -> HieAST t -> Tokenizer m (DList (Range , HsSemanticTokenType ))
83
+ visitLeafIds :: HsSemanticLookup -> HieAST t -> Tokenizer Maybe (DList (Range , HsSemanticTokenType ))
97
84
visitLeafIds lookupHsTokenType leaf = liftMaybeM $ do
98
85
let span = nodeSpan leaf
99
86
(ran, token) <- focusTokenAt leaf
@@ -103,23 +90,21 @@ visitLeafIds lookupHsTokenType leaf = liftMaybeM $ do
103
90
-- only handle the leaf node with single column token
104
91
guard $ srcSpanStartLine span == srcSpanEndLine span
105
92
splitResult <- lift $ splitRangeByText token ran
106
- mapStateT hoistIdMaybe
107
- $ foldMapM (combineNodeIds lookupHsTokenType ran splitResult)
108
- $ Map. filterWithKey (\ k _ -> k == SourceInfo ) $ getSourcedNodeInfo $ sourcedNodeInfo leaf
93
+ foldMapM (combineNodeIds lookupHsTokenType ran splitResult) $ Map. filterWithKey (\ k _ -> k == SourceInfo ) $ getSourcedNodeInfo $ sourcedNodeInfo leaf
109
94
where
110
- hoistIdMaybe :: Identity (a , s ) -> Maybe (a , s )
111
- hoistIdMaybe (Identity x) = Just x
112
- combineNodeIds :: CachedHsSemanticLookup Identity -> Range -> SplitResult -> NodeInfo a -> Tokenizer Identity (DList (Range , HsSemanticTokenType ))
113
- combineNodeIds lookupHsTokenType ran ranSplit (NodeInfo _ _ bd) = do
114
- maybeTokenType <- foldMapM (maybe (return Nothing ) lookupHsTokenType . getIdentifier ranSplit) (M. keys bd)
95
+ combineNodeIds :: (Monad m ) => HsSemanticLookup -> Range -> SplitResult -> NodeInfo a -> Tokenizer m (DList (Range , HsSemanticTokenType ))
96
+ combineNodeIds lookupHsTokenType ran ranSplit (NodeInfo _ _ bd) =
115
97
case (maybeTokenType, ranSplit) of
116
98
(Nothing , _) -> return mempty
117
99
(Just TModule , _) -> return $ DL. singleton (ran, TModule )
118
100
(Just tokenType, NoSplit (_, tokenRan)) -> return $ DL. singleton (tokenRan, tokenType)
119
101
(Just tokenType, Split (_, ranPrefix, tokenRan)) -> return $ DL. fromList [(ranPrefix, TModule ),(tokenRan, tokenType)]
120
- getIdentifier ranSplit idt = do
102
+ where maybeTokenType = foldMap (getIdentifier lookupHsTokenType ranSplit) (M. keys bd)
103
+
104
+ getIdentifier :: HsSemanticLookup -> SplitResult -> Identifier -> Maybe HsSemanticTokenType
105
+ getIdentifier lookupHsTokenType ranSplit idt = do
121
106
case idt of
122
- Left _moduleName -> Just idt
107
+ Left _moduleName -> Just TModule
123
108
Right name -> do
124
109
occStr <- T. pack <$> case (occNameString . nameOccName) name of
125
110
-- the generated selector name with {-# LANGUAGE DuplicateRecordFields #-}
@@ -129,7 +114,7 @@ visitLeafIds lookupHsTokenType leaf = liftMaybeM $ do
129
114
c : ' :' : _ | isAlphaNum c -> Nothing
130
115
ns -> Just ns
131
116
guard $ getSplitTokenText ranSplit == occStr
132
- return idt
117
+ lookupHsTokenType idt
133
118
134
119
135
120
focusTokenAt ::
@@ -153,7 +138,7 @@ focusTokenAt leaf = do
153
138
let nce = newColumn ncs token
154
139
-- compute the new range for utf16, tuning the columns is enough
155
140
let ran = codePointRangeToRangeWith ncs nce $ realSrcSpanToCodePointRange span
156
- modify' $ \ s -> s {columnsInUtf16 = nce, rope = remains, cursor = tokenEndPos}
141
+ modify $ \ s -> s {columnsInUtf16 = nce, rope = remains, cursor = tokenEndPos}
157
142
return (ran, token)
158
143
where
159
144
srcSpanCharPositions :: RealSrcSpan -> (Char. Position , Char. Position )
0 commit comments