Skip to content

Commit 185a63b

Browse files
committed
Add transitive dependency test
1 parent 3f9cf44 commit 185a63b

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ getDefinition file pos = runMaybeT $ do
193193
ide@ShakeExtras{ withHieDb, hiedbWriter } <- ask
194194
opts <- liftIO $ getIdeOptionsIO ide
195195
(HAR _ hf _ _ _, mapping) <- useWithStaleFastMT GetHieAst file
196-
(ImportMap imports, _) <- useWithStaleFastMT GetImportMap file
196+
(ImportMap imports, _) <- case getSourceFileOrigin file of
197+
FromProject -> useWithStaleFastMT GetImportMap file
198+
FromDependency -> pure (ImportMap mempty, PositionMapping idDelta)
197199
!pos' <- MaybeT (pure $ fromCurrentPosition mapping pos)
198200
locations <- AtPoint.gotoDefinition withHieDb (lookupMod hiedbWriter) opts imports hf pos'
199201
MaybeT $ Just <$> toCurrentLocations mapping file locations

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,9 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
12631263
-- GetModificationTime is safe for any file, and
12641264
-- can be called in dependency files by estimateFileVersionUnsafely.
12651265
| Just Refl <- eqT @k @GetModificationTime = True
1266+
-- AddWatchedFile can be called by GetModificationTime
1267+
-- and is also safe for any file.
1268+
| Just Refl <- eqT @k @AddWatchedFile = True
12661269
| otherwise = False
12671270

12681271
traceA :: A v -> String

ghcide/test/exe/Dependency.hs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Control.Monad.IO.Class (liftIO)
99
import qualified Data.Aeson as A
1010
import Data.Bool (bool)
1111
import Data.List (isSuffixOf)
12+
import Data.Maybe (fromMaybe)
1213
import Data.Proxy (Proxy (..))
1314
import Language.LSP.Protocol.Message (TCustomMessage (NotMess),
1415
TNotificationMessage (..))
@@ -31,6 +32,7 @@ tests :: TestTree
3132
tests =
3233
testGroup "gotoDefinition for dependencies"
3334
[ dependencyTest
35+
, transitiveDependencyTest
3436
]
3537

3638
fileDoneIndexing :: [String] -> Session FilePath
@@ -71,3 +73,49 @@ dependencyTest = testSessionWithExtraFiles "dependency" "gotoDefinition in async
7173
liftIO $
7274
assertFailure $ "Wrong location for AsyncCancelled: "
7375
++ show wrongLocation
76+
77+
-- Tests that we can go to the definition of a dependency, and then
78+
-- from the dependency file we can use gotoDefinition to see a
79+
-- tranisive dependency.
80+
transitiveDependencyTest :: TestTree
81+
transitiveDependencyTest = testSessionWithExtraFiles "dependency" "goto transitive dependency async -> hashable" $
82+
\dir -> do
83+
localDoc <- openDoc (dir </> "Dependency" <.> "hs") "haskell"
84+
_asyncHieFile <- fileDoneIndexing ["Control", "Concurrent", "Async.hie"]
85+
_hashableHieFile <- fileDoneIndexing ["Data", "Hashable", "Class.hie"]
86+
asyncDefs <- getDefinitions localDoc (Position 5 20)
87+
asyncHsFile <- case asyncDefs of
88+
InL (Definition (InR [Location uri _actualRange])) ->
89+
liftIO $ do
90+
let fp :: FilePath
91+
fp = fromMaybe "" $ uriToFilePath uri
92+
locationDirectories :: [String]
93+
locationDirectories = splitDirectories fp
94+
assertBool "AsyncCancelled found in a module that is not Control.Concurrent Async"
95+
$ ["Control", "Concurrent", "Async.hs"]
96+
`isSuffixOf` locationDirectories
97+
pure fp
98+
wrongLocation ->
99+
liftIO $
100+
assertFailure $ "Wrong location for AsyncCancelled: "
101+
++ show wrongLocation
102+
asyncDoc <- openDoc asyncHsFile "haskell"
103+
hashableDefs <- getDefinitions asyncDoc (Position 246 11)
104+
-- The location of the definition of Hashable in
105+
-- Data.Hashable.Class
106+
let expRange = Range (Position 198 14) (Position 198 22)
107+
case hashableDefs of
108+
InL (Definition (InR [Location uri actualRange])) ->
109+
liftIO $ do
110+
let locationDirectories :: [String]
111+
locationDirectories =
112+
maybe [] splitDirectories $
113+
uriToFilePath uri
114+
assertBool "Hashable found in a module that is not Data.Hashable.Class"
115+
$ ["Data", "Hashable", "Class.hs"]
116+
`isSuffixOf` locationDirectories
117+
actualRange @?= expRange
118+
wrongLocation ->
119+
liftIO $
120+
assertFailure $ "Wrong location for Hashable: "
121+
++ show wrongLocation

0 commit comments

Comments
 (0)