Skip to content

Commit 5122481

Browse files
committed
fix position mapping for persistent
1 parent f92678c commit 5122481

File tree

6 files changed

+54
-34
lines changed

6 files changed

+54
-34
lines changed

cabal.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ packages:
1212
./plugins/hls-hlint-plugin
1313
./plugins/hls-retrie-plugin
1414
./plugins/hls-splice-plugin
15+
/home/zubin/hiedb/
1516

1617
tests: true
1718

ghcide/src/Development/IDE/Core/PositionMapping.hs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ module Development.IDE.Core.PositionMapping
1010
, toCurrentPosition
1111
, PositionDelta(..)
1212
, addDelta
13+
, idDelta
1314
, mkDelta
1415
, toCurrentRange
1516
, fromCurrentRange
1617
, applyChange
1718
, zeroMapping
18-
, mappingFromDiff
19+
, deltaFromDiff
1920
-- toCurrent and fromCurrent are mainly exposed for testing
2021
, toCurrent
2122
, fromCurrent
@@ -28,6 +29,8 @@ import Data.List
2829
import Data.Algorithm.Diff
2930
import Data.Maybe
3031
import Data.Bifunctor
32+
import Control.DeepSeq
33+
import Debug.Trace
3134

3235
-- | Either an exact position, or the range of text that was substituted
3336
data PositionResult a
@@ -68,6 +71,12 @@ data PositionDelta = PositionDelta
6871
, fromDelta :: !(Position -> PositionResult Position)
6972
}
7073

74+
instance Show PositionDelta where
75+
show PositionDelta{} = "PositionDelta{..}"
76+
77+
instance NFData PositionDelta where
78+
rnf (PositionDelta a b) = a `seq` b `seq` ()
79+
7180
fromCurrentPosition :: PositionMapping -> Position -> Maybe Position
7281
fromCurrentPosition (PositionMapping pm) = positionResultToMaybe . fromDelta pm
7382

@@ -163,8 +172,8 @@ fromCurrent (Range start@(Position startLine startColumn) end@(Position endLine
163172
| otherwise = column
164173
newLine = line - lineDiff
165174

166-
mappingFromDiff :: T.Text -> T.Text -> PositionMapping
167-
mappingFromDiff (T.lines -> old) (T.lines -> new) = PositionMapping (PositionDelta (lookupPos lnew old2new) (lookupPos lold new2old))
175+
deltaFromDiff :: T.Text -> T.Text -> PositionDelta
176+
deltaFromDiff (T.lines -> old) (T.lines -> new) = PositionDelta (lookupPos lnew old2new) (lookupPos lold new2old)
168177
where
169178
diff = getDiff old new
170179

@@ -174,7 +183,7 @@ mappingFromDiff (T.lines -> old) (T.lines -> new) = PositionMapping (PositionDel
174183
lold = length old
175184

176185
lookupPos :: Int -> [(Int,Maybe Int)] -> Position -> PositionResult Position
177-
lookupPos maxNew xs (Position line col) = go (-1) xs
186+
lookupPos maxNew xs (Position line col) = (\x -> traceShow ("lookupPos",line,x) x) $ go (-1) xs
178187
where
179188
go prev [] = PositionRange (Position (prev+1) 0) (Position maxNew 0)
180189
go prev ((l,b):xs)

ghcide/src/Development/IDE/Core/Rules.hs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ import Module
102102
import qualified Data.Rope.UTF16 as Rope
103103
import GHC.IO.Encoding
104104
import Data.ByteString.Encoding as T
105+
import Debug.Trace
106+
import Outputable (showSDocUnsafe)
107+
import HieDebug
105108

106109
import qualified HieDb
107110

@@ -149,10 +152,12 @@ getAtPoint file pos = runMaybeT $ do
149152
ide <- ask
150153
opts <- liftIO $ getIdeOptionsIO ide
151154

152-
(hf, mapping) <- useE GetHieAst file
155+
(hf@HAR{hieAst = asts}, mapping) <- useE GetHieAst file
153156
dkMap <- lift $ maybe (DKMap mempty mempty) fst <$> (runMaybeT $ useE GetDocMap file)
154157

155158
!pos' <- MaybeT (return $ fromCurrentPosition mapping pos)
159+
traceShowM ("Got pos",pos',"in original file")
160+
-- traceM (showSDocUnsafe $ ppHies asts)
156161
MaybeT $ pure $ fmap (first (toCurrentRange mapping =<<)) $ AtPoint.atPoint opts hf dkMap pos'
157162

158163
toCurrentLocations :: PositionMapping -> [Location] -> [Location]
@@ -518,15 +523,15 @@ persistentHieFileRule :: Rules ()
518523
persistentHieFileRule = addPersistentRule GetHieAst $ \file -> runMaybeT $ do
519524
res <- readHieFileForSrcFromDisk file
520525
vfs <- asks vfs
521-
currentSource <- liftIO $ do
526+
(currentSource,ver) <- liftIO $ do
522527
mvf <- getVirtualFile vfs $ filePathToUri' file
523528
case mvf of
524-
Nothing -> T.readFile $ fromNormalizedFilePath file
525-
Just vf -> pure $ Rope.toText $ _text vf
529+
Nothing -> (,Nothing) <$> T.readFile (fromNormalizedFilePath file)
530+
Just vf -> pure $ (Rope.toText $ _text vf, Just $ _lsp_version vf)
526531
encoding <- liftIO $ getLocaleEncoding
527532
let refmap = generateReferencesMap . getAsts . hie_asts $ res
528-
mapping = mappingFromDiff (T.decode encoding $ hie_hs_src res) currentSource
529-
pure $ (HAR (hie_module res) (hie_asts res) refmap (HieFromDisk res),mapping)
533+
del = deltaFromDiff (T.decode encoding $ hie_hs_src res) currentSource
534+
pure $ (HAR (hie_module res) (hie_asts res) refmap (HieFromDisk res),del,ver)
530535

531536
getHieAstRuleDefinition :: NormalizedFilePath -> HscEnv -> TcModuleResult -> Action (IdeResult HieAstResult)
532537
getHieAstRuleDefinition f hsc tmr = do
@@ -554,7 +559,7 @@ getImportMapRule = define $ \GetImportMap f -> do
554559

555560
-- | Ensure that go to definition doesn't block on startup
556561
persistentImportMapRule :: Rules ()
557-
persistentImportMapRule = addPersistentRule GetImportMap $ \_ -> pure $ Just (ImportMap mempty, zeroMapping)
562+
persistentImportMapRule = addPersistentRule GetImportMap $ \_ -> pure $ Just (ImportMap mempty, idDelta, Nothing)
558563

559564
getBindingsRule :: Rules ()
560565
getBindingsRule =
@@ -588,7 +593,7 @@ getDocMapRule =
588593

589594
-- | Persistent rule to ensure that hover doesn't block on startup
590595
persistentDocMapRule :: Rules ()
591-
persistentDocMapRule = addPersistentRule GetDocMap $ \_ -> pure $ Just (DKMap mempty mempty, zeroMapping)
596+
persistentDocMapRule = addPersistentRule GetDocMap $ \_ -> pure $ Just (DKMap mempty mempty, idDelta, Nothing)
592597

593598
readHieFileForSrcFromDisk :: NormalizedFilePath -> MaybeT IdeAction HieFile
594599
readHieFileForSrcFromDisk file = do

ghcide/src/Development/IDE/Core/Service.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Development.IDE.Core.Service(
2121
import Data.Maybe
2222
import Development.IDE.Types.Options (IdeOptions(..))
2323
import Development.IDE.Core.Debouncer
24-
import Development.IDE.Core.FileStore (VFSHandle, fileStoreRules)
24+
import Development.IDE.Core.FileStore (fileStoreRules)
2525
import Development.IDE.Core.FileExists (fileExistsRules)
2626
import Development.IDE.Core.OfInterest
2727
import Development.IDE.Types.Logger as Logger

ghcide/src/Development/IDE/Core/Shake.hs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ import OpenTelemetry.Eventlog
135135
import GHC.Fingerprint
136136

137137
import HieDb.Types
138+
import Debug.Trace
138139

139140
-- | We need to serialize writes to the database, so we send any function that
140141
-- needs to write to the database over the channel, where it will be picked up by
@@ -207,7 +208,7 @@ data ProgressEvent
207208
= KickStarted
208209
| KickCompleted
209210

210-
type GetStalePersistent = NormalizedFilePath -> IdeAction (Maybe (Dynamic,PositionMapping))
211+
type GetStalePersistent = NormalizedFilePath -> IdeAction (Maybe (Dynamic,PositionDelta,TextDocumentVersion))
211212

212213
getShakeExtras :: Action ShakeExtras
213214
getShakeExtras = do
@@ -223,11 +224,11 @@ getShakeExtrasRules = do
223224
-- This is called when we don't already have a result, or computing the rule failed.
224225
-- The result of this function will always be marked as 'stale', and a 'proper' rebuild of the rule will
225226
-- be queued if the rule hasn't run before.
226-
addPersistentRule :: IdeRule k v => k -> (NormalizedFilePath -> IdeAction (Maybe (v,PositionMapping))) -> Rules ()
227+
addPersistentRule :: IdeRule k v => k -> (NormalizedFilePath -> IdeAction (Maybe (v,PositionDelta,TextDocumentVersion))) -> Rules ()
227228
addPersistentRule k getVal = do
228229
ShakeExtras{persistentKeys} <- getShakeExtrasRules
229230
liftIO $ modifyVar_ persistentKeys $ \hm -> do
230-
pure $ HMap.insert (Key k) (fmap (fmap (first toDyn)) . getVal) hm
231+
pure $ HMap.insert (Key k) (fmap (fmap (first3 toDyn)) . getVal) hm
231232
return ()
232233

233234
class Typeable a => IsIdeGlobal a where
@@ -291,34 +292,36 @@ getIdeOptionsIO ide = do
291292
-- for the version of that value.
292293
lastValueIO :: IdeRule k v => ShakeExtras -> k -> NormalizedFilePath -> IO (Maybe (v, PositionMapping))
293294
lastValueIO s@ShakeExtras{positionMapping,persistentKeys,state} k file = do
295+
hm <- readVar state
296+
allMappings <- readVar positionMapping
297+
294298
let readPersistent = do
295299
pmap <- readVar persistentKeys
296300
mv <- runMaybeT $ do
297301
liftIO $ Logger.logDebug (logger s) $ T.pack $ "LOOKUP UP PERSISTENT FOR" ++ show k
298302
f <- MaybeT $ pure $ HMap.lookup (Key k) pmap
299-
(dv,mapping) <- MaybeT $ runIdeAction "lastValueIO" s $ f file
300-
MaybeT $ pure $ (,mapping) <$> fromDynamic dv
301-
modifyVar state $ \hm -> case mv of
302-
Nothing -> pure (HMap.insertWith upd (file,Key k) (Failed True) hm,Nothing)
303-
Just (v,mapping) -> pure (HMap.insertWith upd (file,Key k) (Stale Nothing (toDyn v)) hm, Just (v,mapping))
303+
(dv,del,ver) <- MaybeT $ runIdeAction "lastValueIO" s $ f file
304+
MaybeT $ pure $ (,del,ver) <$> fromDynamic dv
305+
modifyVar state $ \hm -> pure $ case mv of
306+
Nothing -> (HMap.insertWith upd (file,Key k) (Failed True) hm,Nothing)
307+
Just (v,del,ver) -> (HMap.insertWith upd (file,Key k) (Stale (Just del) ver (toDyn v)) hm
308+
,Just (v,addDelta del $ mappingForVersion allMappings file ver))
304309

305310
-- Update preserving 'monotonicity'
306311
-- Don't want to overwrite a newer value with an older one
307312
upd _new@(Failed False) old = old
308313
upd new@(Failed True) (Failed False) = new
309314
upd _new@(Failed True) old = old
310-
upd new@(Stale _ _) Failed{} = new
311-
upd new@(Stale v _) old@(Stale v' _) = if v >= v' then new else old
312-
upd new@(Stale v _) old@(Succeeded v' _) = if v >= v' then new else old
315+
upd new@(Stale _ _ _) Failed{} = new
316+
upd new@(Stale _ v _) old@(Stale _ v' _) = if v >= v' then new else old
317+
upd new@(Stale _ v _) old@(Succeeded v' _) = if v >= v' then new else old
313318
upd new _old = new
314319

315-
hm <- readVar state
316-
allMappings <- readVar positionMapping
317320
case HMap.lookup (file,Key k) hm of
318321
Nothing -> readPersistent
319322
Just v -> case v of
320323
Succeeded ver (fromDynamic -> Just v) -> pure (Just (v, mappingForVersion allMappings file ver))
321-
Stale ver (fromDynamic -> Just v) -> pure (Just (v, mappingForVersion allMappings file ver))
324+
Stale del ver (fromDynamic -> Just v) -> pure (Just (v, maybe id addDelta del $ mappingForVersion allMappings file ver))
322325
Failed p | not p -> readPersistent
323326
_ -> pure Nothing
324327

@@ -332,7 +335,7 @@ lastValue key file = do
332335
valueVersion :: Value v -> Maybe TextDocumentVersion
333336
valueVersion = \case
334337
Succeeded ver _ -> Just ver
335-
Stale ver _ -> Just ver
338+
Stale _ ver _ -> Just ver
336339
Failed _ -> Nothing
337340

338341
mappingForVersion
@@ -435,7 +438,7 @@ knownTargets = do
435438
seqValue :: Value v -> b -> b
436439
seqValue v b = case v of
437440
Succeeded ver v -> rnf ver `seq` v `seq` b
438-
Stale ver v -> rnf ver `seq` v `seq` b
441+
Stale d ver v -> rnf d `seq` rnf ver `seq` v `seq` b
439442
Failed _ -> b
440443

441444
-- | Open a 'IdeState', should be shut using 'shakeShut'.
@@ -936,8 +939,8 @@ defineEarlyCutoff op = addBuiltinRule noLint noIdentity $ \(Q (key, file)) (old
936939
pure $ case staleV of
937940
Nothing -> (toShakeValue ShakeResult bs, Failed False)
938941
Just v -> case v of
939-
Succeeded ver v -> (toShakeValue ShakeStale bs, Stale ver v)
940-
Stale ver v -> (toShakeValue ShakeStale bs, Stale ver v)
942+
Succeeded ver v -> (toShakeValue ShakeStale bs, Stale Nothing ver v)
943+
Stale d ver v -> (toShakeValue ShakeStale bs, Stale d ver v)
941944
Failed b -> (toShakeValue ShakeResult bs, Failed b)
942945
Just v -> pure (maybe ShakeNoCutoff ShakeResult bs, Succeeded (vfsVersion =<< modTime) v)
943946
liftIO $ setValues state key file res
@@ -1180,7 +1183,8 @@ filterVersionMap =
11801183
HMap.intersectionWith $ \versionsToKeep versionMap -> Map.restrictKeys versionMap versionsToKeep
11811184

11821185
updatePositionMapping :: IdeState -> VersionedTextDocumentIdentifier -> List TextDocumentContentChangeEvent -> IO ()
1183-
updatePositionMapping IdeState{shakeExtras = ShakeExtras{positionMapping}} VersionedTextDocumentIdentifier{..} (List changes) = do
1186+
updatePositionMapping IdeState{shakeExtras = ShakeExtras{positionMapping}} v@VersionedTextDocumentIdentifier{..} (List changes) = do
1187+
traceShowM ("UpdatePositionMapping",v,changes)
11841188
modifyVar_ positionMapping $ \allMappings -> do
11851189
let uri = toNormalizedUri _uri
11861190
let mappingForUri = HMap.lookupDefault Map.empty uri allMappings

ghcide/src/Development/IDE/Types/Shake.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import Data.HashMap.Strict
88
import Data.Typeable
99
import GHC.Generics
1010
import Language.Haskell.LSP.Types
11+
import Development.IDE.Core.PositionMapping
1112

1213
data Value v
1314
= Succeeded TextDocumentVersion v
14-
| Stale TextDocumentVersion v
15+
| Stale (Maybe PositionDelta) TextDocumentVersion v
1516
| Failed Bool
1617
deriving (Functor, Generic, Show)
1718

@@ -21,7 +22,7 @@ instance NFData v => NFData (Value v)
2122
-- up2date results not for stale values.
2223
currentValue :: Value v -> Maybe v
2324
currentValue (Succeeded _ v) = Just v
24-
currentValue (Stale _ _) = Nothing
25+
currentValue (Stale _ _ _) = Nothing
2526
currentValue Failed{} = Nothing
2627

2728
-- | The state of the all values.

0 commit comments

Comments
 (0)