Skip to content

Commit b862c6d

Browse files
committed
cache semantic lookup
1 parent f844a29 commit b862c6d

File tree

1 file changed

+28
-13
lines changed
  • plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens

1 file changed

+28
-13
lines changed

plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens/Tokenize.hs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import Control.Lens (Identity (runIdentity))
77
import Control.Monad (foldM, guard)
88
import Control.Monad.State.Strict (MonadState (get),
99
MonadTrans (lift),
10-
evalStateT, modify, put)
10+
evalStateT, gets, modify',
11+
put)
1112
import Control.Monad.Trans.State.Strict (StateT, runStateT)
1213
import Data.Char (isAlphaNum)
1314
import Data.DList (DList)
@@ -31,13 +32,27 @@ import Prelude hiding (length, span)
3132

3233
type Tokenizer m a = StateT PTokenState m a
3334
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
47+
3448

3549

3650
data PTokenState = PTokenState
3751
{
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
52+
rope :: !Rope -- the remains of rope we are working on
53+
, cursor :: !Char.Position -- the cursor position of the current rope to the start of the original file in code point position
54+
, columnsInUtf16 :: !UInt -- the column of the start of the current rope in utf16
55+
, semanticLookupCache :: !(NameEnv (Maybe HsSemanticTokenType)) -- the cache for semantic lookup result of the current file
4156
}
4257

4358
data SplitResult
@@ -56,7 +71,8 @@ mkPTokenState vf =
5671
{
5772
rope = vf._file_text,
5873
cursor = Char.Position 0 0,
59-
columnsInUtf16 = 0
74+
columnsInUtf16 = 0,
75+
semanticLookupCache = emptyNameEnv
6076
}
6177

6278
-- lift a Tokenizer Maybe a to Tokenizer m a,
@@ -77,10 +93,10 @@ computeRangeHsSemanticTokenTypeList lookupHsTokenType vf ast =
7793
-- visit every leaf node in the ast in depth first order
7894
foldAst :: (Monad m) => HsSemanticLookup -> HieAST t -> Tokenizer m (DList (Range, HsSemanticTokenType))
7995
foldAst lookupHsTokenType ast = if null (nodeChildren ast)
80-
then liftMaybeM (visitLeafIds lookupHsTokenType ast)
96+
then visitLeafIds lookupHsTokenType ast
8197
else foldMapM (foldAst lookupHsTokenType) $ nodeChildren ast
8298

83-
visitLeafIds :: HsSemanticLookup -> HieAST t -> Tokenizer Maybe (DList (Range, HsSemanticTokenType))
99+
visitLeafIds :: (Monad m) => HsSemanticLookup -> HieAST t -> Tokenizer m (DList (Range, HsSemanticTokenType))
84100
visitLeafIds lookupHsTokenType leaf = liftMaybeM $ do
85101
let span = nodeSpan leaf
86102
(ran, token) <- focusTokenAt leaf
@@ -93,16 +109,15 @@ visitLeafIds lookupHsTokenType leaf = liftMaybeM $ do
93109
foldMapM (combineNodeIds lookupHsTokenType ran splitResult) $ Map.filterWithKey (\k _ -> k == SourceInfo) $ getSourcedNodeInfo $ sourcedNodeInfo leaf
94110
where
95111
combineNodeIds :: (Monad m) => HsSemanticLookup -> Range -> SplitResult -> NodeInfo a -> Tokenizer m (DList (Range, HsSemanticTokenType))
96-
combineNodeIds lookupHsTokenType ran ranSplit (NodeInfo _ _ bd) =
112+
combineNodeIds lookupHsTokenType ran ranSplit (NodeInfo _ _ bd) = do
113+
maybeTokenType <- foldMapM (cacheLookup $ lookupIdentifier lookupHsTokenType ranSplit) (M.keys bd)
97114
case (maybeTokenType, ranSplit) of
98115
(Nothing, _) -> return mempty
99116
(Just TModule, _) -> return $ DL.singleton (ran, TModule)
100117
(Just tokenType, NoSplit (_, tokenRan)) -> return $ DL.singleton (tokenRan, tokenType)
101118
(Just tokenType, Split (_, ranPrefix, tokenRan)) -> return $ DL.fromList [(ranPrefix, TModule),(tokenRan, tokenType)]
102-
where maybeTokenType = foldMap (getIdentifier lookupHsTokenType ranSplit) (M.keys bd)
103-
104-
getIdentifier :: HsSemanticLookup -> SplitResult -> Identifier -> Maybe HsSemanticTokenType
105-
getIdentifier lookupHsTokenType ranSplit idt = do
119+
lookupIdentifier :: HsSemanticLookup -> SplitResult -> HsSemanticLookup
120+
lookupIdentifier lookupHsTokenType ranSplit idt = do
106121
case idt of
107122
Left _moduleName -> Just TModule
108123
Right name -> do
@@ -138,7 +153,7 @@ focusTokenAt leaf = do
138153
let nce = newColumn ncs token
139154
-- compute the new range for utf16, tuning the columns is enough
140155
let ran = codePointRangeToRangeWith ncs nce $ realSrcSpanToCodePointRange span
141-
modify $ \s -> s {columnsInUtf16 = nce, rope = remains, cursor = tokenEndPos}
156+
modify' $ \s -> s {columnsInUtf16 = nce, rope = remains, cursor = tokenEndPos}
142157
return (ran, token)
143158
where
144159
srcSpanCharPositions :: RealSrcSpan -> (Char.Position, Char.Position)

0 commit comments

Comments
 (0)