Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Goto dependency definition #3704

Closed
wants to merge 50 commits into from

Conversation

nlander
Copy link
Contributor

@nlander nlander commented Jul 11, 2023

For users using cabal HEAD, enables indexing of dependency HIE files so that the source can be written out on calls to gotoDefinition.

@nlander nlander marked this pull request as draft July 11, 2023 10:53
@michaelpj
Copy link
Collaborator

Tests?

liftIO $ atomically $
unGetTQueue indexQueue $ \withHieDb -> withHieDb $ \db -> do
HieDb.addSrcFile db hieFile writeOutPath False
putMVar completionToken ()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be outside the withHieDb retry block

ms -> foldr1 (</>) ms
breakOnDot :: FilePath -> [FilePath]
breakOnDot = words . map replaceDotWithSpace
replaceDotWithSpace :: Char -> Char
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Language.Haskell.Syntax.Module.Name.moduleNameSlashes

HAR
(Compat.hie_module hieFile)
(Compat.hie_asts hieFile)
mempty
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can fill in the RefMap using Compat.generateReferencesMap

(libraryDir : _) -> libraryDir
hieDir :: FilePath
hieDir = pkgLibDir </> "extra-compilation-artifacts"
modIfaces <- mapMaybeM loadModIface modules
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to load .hi files here?

mkModule (unitInfoId package) moduleName
-- When module is re-exported from another package,
-- the origin module is represented by value in Just
makeModule (_, Just otherPackageMod) = otherPackageMod
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modules from other packages won't have a .hie file in the extra-compilation directory of the package under consideration, so we can just skip them from the list.

let hiePath :: NormalizedFilePath
hiePath = toNormalizedFilePath' $
hieDir </> toFilePath (moduleName $ mi_module modIface) ++ ".hie"
hieCheck <- checkHieFile recorder se "newHscEnvEqWithImportPaths" hiePath
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to be less granular with the HieAlreadyIndexed check - each package can contain hundreds/thousands of modules, and we don't want to check all these modules on every startup.

It's also wasteful because once we successfully index a whole unit/package we can assume that it doesn't change. So maybe we need to only check if a package has been indexed rather than checking for each file in the package.

This might require another table in hiedb to keep track of the packages we have indexed.

)
tmr <- fst <$> (
handleMaybeM "Unable to TypeCheck"
case Shake.getSourceFileOrigin nfp of
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have pluginFileType in PluginDescriptor which specifies which filetypes plugins want to handle. We should extend this concept to extend to specifying whether plugins want to handle FromDependency files.


getSourceFileOrigin :: NormalizedFilePath -> SourceFileOrigin
getSourceFileOrigin f =
case isInfixOf ".hls/dependencies" (show f) of
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isInfixOf and show are the wrong functions to use here.

You probably want to inspect the path using functions from System.FilePath and use fromNormalizedFilePath to convert NormalizedFilePath to FilePath.

deleteMissingDependencySources :: IO ()
deleteMissingDependencySources = do
completionToken <- newEmptyMVar
atomically $ unGetTQueue (indexQueue $ hiedbWriter se) $
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want unGetTQueue here.

@nlander nlander force-pushed the goto-dependency-definition branch from 3c686d9 to 68edc00 Compare July 14, 2023 00:30

getSourceFileOrigin :: NormalizedFilePath -> SourceFileOrigin
getSourceFileOrigin f =
case [".hls", "dependencies"] `isInfixOf` (splitDirectories file) of
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wz1000 What do you think of this? It still uses isInfixOf but not show. I don't see any predicate in System.FilePath that is like isInfixOf but for directories being contained in a FilePath.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems alright to me

@nlander nlander force-pushed the goto-dependency-definition branch from 0c7a635 to 9a4b009 Compare July 21, 2023 12:35

let dflags = hsc_dflags hscEnv
indexDependencyHieFiles
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to do this asynchronously.

pure $ projectDir </> ".hls"
deleteMissingDependencySources :: IO ()
deleteMissingDependencySources = do
completionToken <- newEmptyMVar
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to wait for this to complete, we can just queue it up

lookupPackage db unit
case moduleRows of
[] -> traverse_ (indexModuleHieFile hieDir) modules
_ -> return ()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments explaining that we have already indexed the package

@@ -112,10 +120,88 @@ newHscEnvEqWithImportPaths envImportPaths hscEnv deps = do
(evaluate . force . Just $ listVisibleModuleNames hscEnv)

return HscEnvEq{..}
where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we probably want to move this code to another module.

-- for any reason.
-- See the function `lookupMod` in Development.IDE.Core.Actions
-- for where dependency files get created and indexed in hiedb.
fileExists <- liftIO $ doesFileExist src
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to do this, as long as we check for .hls on startup.

@joyfulmantis
Copy link
Collaborator

Closed as per request by @nlander on Matrix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants