Skip to content

Commit

Permalink
revert root change
Browse files Browse the repository at this point in the history
  • Loading branch information
soulomoon committed May 19, 2024
1 parent bb45003 commit bc9cb69
Show file tree
Hide file tree
Showing 17 changed files with 90 additions and 107 deletions.
3 changes: 1 addition & 2 deletions exe/Wrapper.hs
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,7 @@ newtype ErrorLSPM c a = ErrorLSPM { unErrorLSPM :: (LspM c) a }
-- to shut down the LSP.
launchErrorLSP :: Recorder (WithPriority (Doc ())) -> T.Text -> IO ()
launchErrorLSP recorder errorMsg = do
cwd <- getCurrentDirectory
let defaultArguments = Main.defaultArguments (cmapWithPrio pretty recorder) cwd (IdePlugins [])
let defaultArguments = Main.defaultArguments (cmapWithPrio pretty recorder) (IdePlugins [])

inH <- Main.argsHandleIn defaultArguments

Expand Down
6 changes: 3 additions & 3 deletions ghcide/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ main = withTelemetryRecorder $ \telemetryRecorder -> do

let arguments =
if argsTesting
then IDEMain.testing (cmapWithPrio LogIDEMain recorder) argsCwd hlsPlugins
else IDEMain.defaultArguments (cmapWithPrio LogIDEMain recorder) argsCwd hlsPlugins
then IDEMain.testing (cmapWithPrio LogIDEMain recorder) hlsPlugins
else IDEMain.defaultArguments (cmapWithPrio LogIDEMain recorder) hlsPlugins

IDEMain.defaultMain (cmapWithPrio LogIDEMain recorder) arguments
{ IDEMain.argsProjectRoot = argsCwd
{ IDEMain.argsProjectRoot = Just argsCwd
, IDEMain.argCommand = argsCommand
, IDEMain.argsHlsPlugins = IDEMain.argsHlsPlugins arguments <> pluginDescToIdePlugins [lspRecorderPlugin]

Expand Down
51 changes: 26 additions & 25 deletions ghcide/session-loader/Development/IDE/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ import Development.IDE.Types.Shake (WithHieDb, toNoFileKey)
import HieDb.Create
import HieDb.Types
import HieDb.Utils
import Ide.PluginUtils (toAbsolute)
import qualified System.Random as Random
import System.Random (RandomGen)

Expand Down Expand Up @@ -439,8 +438,7 @@ loadSession :: Recorder (WithPriority Log) -> FilePath -> IO (Action IdeGhcSessi
loadSession recorder = loadSessionWithOptions recorder def

loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -> FilePath -> IO (Action IdeGhcSession)
loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
let toAbsolutePath = toAbsolute rootDir
loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
cradle_files <- newIORef []
-- Mapping from hie.yaml file to HscEnv, one per hie.yaml file
hscEnvs <- newVar Map.empty :: IO (Var HieMap)
Expand All @@ -461,7 +459,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
-- Sometimes we get C:, sometimes we get c:, and sometimes we get a relative path
-- try and normalise that
-- e.g. see https://github.com/haskell/ghcide/issues/126
let res' = toAbsolutePath <$> res
res' <- traverse makeAbsolute res
return $ normalise <$> res'

dummyAs <- async $ return (error "Uninitialised")
Expand Down Expand Up @@ -523,7 +521,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
packageSetup (hieYaml, cfp, opts, libDir) = do
-- Parse DynFlags for the newly discovered component
hscEnv <- emptyHscEnv ideNc libDir
newTargetDfs <- evalGhcEnv hscEnv $ setOptions cfp opts (hsc_dflags hscEnv) rootDir
newTargetDfs <- evalGhcEnv hscEnv $ setOptions cfp opts (hsc_dflags hscEnv)
let deps = componentDependencies opts ++ maybeToList hieYaml
dep_info <- getDependencyInfo deps
-- Now lookup to see whether we are combining with an existing HscEnv
Expand Down Expand Up @@ -590,7 +588,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
-- HscEnv but set the active component accordingly
hscEnv <- emptyHscEnv ideNc _libDir
let new_cache = newComponentCache recorder optExtensions hieYaml _cfp hscEnv
all_target_details <- new_cache old_deps new_deps rootDir
all_target_details <- new_cache old_deps new_deps

this_dep_info <- getDependencyInfo $ maybeToList hieYaml
let (all_targets, this_flags_map, this_options)
Expand Down Expand Up @@ -634,20 +632,25 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do

let consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq, [FilePath])
consultCradle hieYaml cfp = do
let lfpLog = makeRelative rootDir cfp
lfpLog <- flip makeRelative cfp <$> getCurrentDirectory
logWith recorder Info $ LogCradlePath lfpLog

when (isNothing hieYaml) $
logWith recorder Warning $ LogCradleNotFound lfpLog
cradle <- loadCradle recorder hieYaml rootDir

cradle <- loadCradle recorder hieYaml dir
-- TODO: Why are we repeating the same command we have on line 646?
lfp <- flip makeRelative cfp <$> getCurrentDirectory

when optTesting $ mRunLspT lspEnv $
sendNotification (SMethod_CustomMethod (Proxy @"ghcide/cradle/loaded")) (toJSON cfp)

-- Display a user friendly progress message here: They probably don't know what a cradle is
let progMsg = "Setting up " <> T.pack (takeBaseName (cradleRootDir cradle))
<> " (for " <> T.pack lfpLog <> ")"
<> " (for " <> T.pack lfp <> ")"
eopts <- mRunLspTCallback lspEnv (\act -> withIndefiniteProgress progMsg Nothing NotCancellable (const act)) $
withTrace "Load cradle" $ \addTag -> do
addTag "file" lfpLog
addTag "file" lfp
old_files <- readIORef cradle_files
res <- cradleToOptsAndLibDir recorder (sessionLoading clientConfig) cradle cfp old_files
addTag "result" (show res)
Expand Down Expand Up @@ -710,7 +713,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
modifyVar_ hscEnvs (const (return Map.empty))

v <- Map.findWithDefault HM.empty hieYaml <$> readVar fileToFlags
let cfp = toAbsolutePath file
cfp <- makeAbsolute file
case HM.lookup (toNormalizedFilePath' cfp) v of
Just (opts, old_di) -> do
deps_ok <- checkDependencyInfo old_di
Expand All @@ -732,7 +735,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
-- before attempting to do so.
let getOptions :: FilePath -> IO (IdeResult HscEnvEq, [FilePath])
getOptions file = do
let ncfp = toNormalizedFilePath' (toAbsolutePath file)
ncfp <- toNormalizedFilePath' <$> makeAbsolute file
cachedHieYamlLocation <- HM.lookup ncfp <$> readVar filesMap
hieYaml <- cradleLoc file
sessionOpts (join cachedHieYamlLocation <|> hieYaml, file) `Safe.catch` \e ->
Expand All @@ -744,7 +747,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir = do
void $ wait as
asyncRes <- async $ getOptions file
return (asyncRes, wait asyncRes)
pure $ (fmap . fmap) toAbsolutePath opts
pure opts

-- | Run the specific cradle on a specific FilePath via hie-bios.
-- This then builds dependencies or whatever based on the cradle, gets the
Expand Down Expand Up @@ -811,20 +814,19 @@ fromTargetId :: [FilePath] -- ^ import paths
-> TargetId
-> IdeResult HscEnvEq
-> DependencyInfo
-> FilePath
-> IO [TargetDetails]
-- For a target module we consider all the import paths
fromTargetId is exts (GHC.TargetModule modName) env dep dir = do
fromTargetId is exts (GHC.TargetModule modName) env dep = do
let fps = [i </> moduleNameSlashes modName -<.> ext <> boot
| ext <- exts
, i <- is
, boot <- ["", "-boot"]
]
let locs = fmap (toNormalizedFilePath' . toAbsolute dir) fps
locs <- mapM (fmap toNormalizedFilePath' . makeAbsolute) fps
return [TargetDetails (TargetModule modName) env dep locs]
-- For a 'TargetFile' we consider all the possible module names
fromTargetId _ _ (GHC.TargetFile f _) env deps dir = do
let nf = toNormalizedFilePath' $ toAbsolute dir f
fromTargetId _ _ (GHC.TargetFile f _) env deps = do
nf <- toNormalizedFilePath' <$> makeAbsolute f
let other
| "-boot" `isSuffixOf` f = toNormalizedFilePath' (L.dropEnd 5 $ fromNormalizedFilePath nf)
| otherwise = toNormalizedFilePath' (fromNormalizedFilePath nf ++ "-boot")
Expand Down Expand Up @@ -913,9 +915,8 @@ newComponentCache
-> HscEnv -- ^ An empty HscEnv
-> [ComponentInfo] -- ^ New components to be loaded
-> [ComponentInfo] -- ^ old, already existing components
-> FilePath -- ^ root dir
-> IO [ [TargetDetails] ]
newComponentCache recorder exts cradlePath _cfp hsc_env old_cis new_cis dir = do
newComponentCache recorder exts cradlePath _cfp hsc_env old_cis new_cis = do
let cis = Map.unionWith unionCIs (mkMap new_cis) (mkMap old_cis)
-- When we have multiple components with the same uid,
-- prefer the new one over the old.
Expand Down Expand Up @@ -960,7 +961,7 @@ newComponentCache recorder exts cradlePath _cfp hsc_env old_cis new_cis dir = do

forM (Map.elems cis) $ \ci -> do
let df = componentDynFlags ci
let createHscEnvEq = maybe newHscEnvEqPreserveImportPaths (newHscEnvEq dir) cradlePath
let createHscEnvEq = maybe newHscEnvEqPreserveImportPaths newHscEnvEq cradlePath
thisEnv <- do
#if MIN_VERSION_ghc(9,3,0)
-- In GHC 9.4 we have multi component support, and we have initialised all the units
Expand All @@ -985,7 +986,7 @@ newComponentCache recorder exts cradlePath _cfp hsc_env old_cis new_cis dir = do
logWith recorder Debug $ LogNewComponentCache (targetEnv, targetDepends)
evaluate $ liftRnf rwhnf $ componentTargets ci

let mk t = fromTargetId (importPaths df) exts (targetId t) targetEnv targetDepends dir
let mk t = fromTargetId (importPaths df) exts (targetId t) targetEnv targetDepends
ctargets <- concatMapM mk (componentTargets ci)

return (L.nubOrdOn targetTarget ctargets)
Expand Down Expand Up @@ -1170,8 +1171,8 @@ addUnit unit_str = liftEwM $ do
putCmdLineState (unit_str : units)

-- | Throws if package flags are unsatisfiable
setOptions :: GhcMonad m => NormalizedFilePath -> ComponentOptions -> DynFlags -> FilePath -> m (NonEmpty (DynFlags, [GHC.Target]))
setOptions cfp (ComponentOptions theOpts compRoot _) dflags dir = do
setOptions :: GhcMonad m => NormalizedFilePath -> ComponentOptions -> DynFlags -> m (NonEmpty (DynFlags, [GHC.Target]))
setOptions cfp (ComponentOptions theOpts compRoot _) dflags = do
((theOpts',_errs,_warns),units) <- processCmdLineP unit_flags [] (map noLoc theOpts)
case NE.nonEmpty units of
Just us -> initMulti us
Expand All @@ -1194,7 +1195,7 @@ setOptions cfp (ComponentOptions theOpts compRoot _) dflags dir = do
--
-- If we don't end up with a target for the current file in the end, then
-- we will report it as an error for that file
let abs_fp = toAbsolute dir (fromNormalizedFilePath cfp)
abs_fp <- liftIO $ makeAbsolute (fromNormalizedFilePath cfp)
let special_target = Compat.mkSimpleTarget df abs_fp
pure $ (df, special_target : targets) :| []
where
Expand Down
2 changes: 1 addition & 1 deletion ghcide/src/Development/IDE.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Development.IDE.Core.Shake as X (FastResult (..),
defineNoDiagnostics,
getClientConfig,
getPluginConfigAction,
ideLogger, rootDir,
ideLogger,
runIdeAction,
shakeExtras, use,
useNoFile,
Expand Down
9 changes: 5 additions & 4 deletions ghcide/src/Development/IDE/Core/Rules.hs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ import Language.LSP.Server (LspT)
import qualified Language.LSP.Server as LSP
import Language.LSP.VFS
import Prelude hiding (mod)
import System.Directory (doesFileExist)
import System.Directory (doesFileExist,
makeAbsolute)
import System.Info.Extra (isWindows)


Expand Down Expand Up @@ -718,13 +719,13 @@ loadGhcSession recorder ghcSessionDepsConfig = do

defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GhcSession file -> do
IdeGhcSession{loadSessionFun} <- useNoFile_ GhcSessionIO
-- loading is always returning a absolute path now
(val,deps) <- liftIO $ loadSessionFun $ fromNormalizedFilePath file

-- add the deps to the Shake graph
let addDependency fp = do
-- VSCode uses absolute paths in its filewatch notifications
let nfp = toNormalizedFilePath' fp
afp <- liftIO $ makeAbsolute fp
let nfp = toNormalizedFilePath' afp
itExists <- getFileExists nfp
when itExists $ void $ do
use_ GetModificationTime nfp
Expand Down Expand Up @@ -852,7 +853,7 @@ getModIfaceFromDiskAndIndexRule recorder =
hie_loc = Compat.ml_hie_file $ ms_location ms
fileHash <- liftIO $ Util.getFileHash hie_loc
mrow <- liftIO $ withHieDb (\hieDb -> HieDb.lookupHieFileFromSource hieDb (fromNormalizedFilePath f))
let hie_loc' = HieDb.hieModuleHieFile <$> mrow
hie_loc' <- liftIO $ traverse (makeAbsolute . HieDb.hieModuleHieFile) mrow
case mrow of
Just row
| fileHash == HieDb.modInfoHash (HieDb.hieModInfo row)
Expand Down
8 changes: 3 additions & 5 deletions ghcide/src/Development/IDE/Core/Service.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@ initialise :: Recorder (WithPriority Log)
-> WithHieDb
-> IndexQueue
-> Monitoring
-> FilePath
-> IO IdeState
initialise recorder defaultConfig plugins mainRule lspEnv debouncer options withHieDb hiedbChan metrics rootDir = do
initialise recorder defaultConfig plugins mainRule lspEnv debouncer options withHieDb hiedbChan metrics = do
shakeProfiling <- do
let fromConf = optShakeProfiling options
fromEnv <- lookupEnv "GHCIDE_BUILD_PROFILING"
Expand All @@ -87,12 +86,11 @@ initialise recorder defaultConfig plugins mainRule lspEnv debouncer options with
hiedbChan
(optShakeOptions options)
metrics
(do
$ do
addIdeGlobal $ GlobalIdeOptions options
ofInterestRules (cmapWithPrio LogOfInterest recorder)
fileExistsRules (cmapWithPrio LogFileExists recorder) lspEnv
mainRule)
rootDir
mainRule

-- | Shutdown the Compiler Service.
shutdown :: IdeState -> IO ()
Expand Down
6 changes: 2 additions & 4 deletions ghcide/src/Development/IDE/Core/Shake.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
-- always stored as real Haskell values, whereas Shake serialises all 'A' values
-- between runs. To deserialise a Shake value, we just consult Values.
module Development.IDE.Core.Shake(
IdeState, shakeSessionInit, shakeExtras, shakeDb, rootDir,
IdeState, shakeSessionInit, shakeExtras, shakeDb,
ShakeExtras(..), getShakeExtras, getShakeExtrasRules,
KnownTargets, Target(..), toKnownFiles,
IdeRule, IdeResult,
Expand Down Expand Up @@ -535,7 +535,6 @@ data IdeState = IdeState
,shakeExtras :: ShakeExtras
,shakeDatabaseProfile :: ShakeDatabase -> IO (Maybe FilePath)
,stopMonitoring :: IO ()
,rootDir :: FilePath
}


Expand Down Expand Up @@ -624,12 +623,11 @@ shakeOpen :: Recorder (WithPriority Log)
-> ShakeOptions
-> Monitoring
-> Rules ()
-> FilePath
-> IO IdeState
shakeOpen recorder lspEnv defaultConfig idePlugins debouncer
shakeProfileDir (IdeReportProgress reportProgress)
ideTesting@(IdeTesting testing)
withHieDb indexQueue opts monitoring rules rootDir = mdo
withHieDb indexQueue opts monitoring rules = mdo

#if MIN_VERSION_ghc(9,3,0)
ideNc <- initNameCache 'r' knownKeyNames
Expand Down
21 changes: 8 additions & 13 deletions ghcide/src/Development/IDE/LSP/LanguageServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,14 @@ runLanguageServer recorder options inH outH defaultConfig parseConfig onConfigCh
setupLSP ::
forall config err.
Recorder (WithPriority Log)
-> FilePath -- ^ root directory
-> (FilePath -> IO FilePath) -- ^ Map root paths to the location of the hiedb for the project
-> LSP.Handlers (ServerM config)
-> (LSP.LanguageContextEnv config -> FilePath -> WithHieDb -> IndexQueue -> IO IdeState)
-> (LSP.LanguageContextEnv config -> Maybe FilePath -> WithHieDb -> IndexQueue -> IO IdeState)
-> MVar ()
-> IO (LSP.LanguageContextEnv config -> TRequestMessage Method_Initialize -> IO (Either err (LSP.LanguageContextEnv config, IdeState)),
LSP.Handlers (ServerM config),
(LanguageContextEnv config, IdeState) -> ServerM config <~> IO)
setupLSP recorder defaultRoot getHieDbLoc userHandlers getIdeState clientMsgVar = do
setupLSP recorder getHieDbLoc userHandlers getIdeState clientMsgVar = do
-- Send everything over a channel, since you need to wait until after initialise before
-- LspFuncs is available
clientMsgChan :: Chan ReactorMessage <- newChan
Expand Down Expand Up @@ -177,7 +176,7 @@ setupLSP recorder defaultRoot getHieDbLoc userHandlers getIdeState clientMsgVar
-- Cancel requests are special since they need to be handled
-- out of order to be useful. Existing handlers are run afterwards.

let doInitialize = handleInit recorder defaultRoot getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan
let doInitialize = handleInit recorder getHieDbLoc getIdeState reactorLifetime exit clearReqId waitForCancel clientMsgChan

let interpretHandler (env, st) = LSP.Iso (LSP.runLspT env . flip (runReaderT . unServerM) (clientMsgChan,st)) liftIO

Expand All @@ -186,23 +185,19 @@ setupLSP recorder defaultRoot getHieDbLoc userHandlers getIdeState clientMsgVar

handleInit
:: Recorder (WithPriority Log)
-> FilePath
-> (FilePath -> IO FilePath)
-> (LSP.LanguageContextEnv config -> FilePath -> WithHieDb -> IndexQueue -> IO IdeState)
-> (LSP.LanguageContextEnv config -> Maybe FilePath -> WithHieDb -> IndexQueue -> IO IdeState)
-> MVar ()
-> IO ()
-> (SomeLspId -> IO ())
-> (SomeLspId -> IO ())
-> Chan ReactorMessage
-> LSP.LanguageContextEnv config -> TRequestMessage Method_Initialize -> IO (Either err (LSP.LanguageContextEnv config, IdeState))
handleInit recorder defaultRoot getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan env (TRequestMessage _ _ m params) = otTracedHandler "Initialize" (show m) $ \sp -> do
handleInit recorder getHieDbLoc getIdeState lifetime exitClientMsg clearReqId waitForCancel clientMsgChan env (TRequestMessage _ _ m params) = otTracedHandler "Initialize" (show m) $ \sp -> do
traceWithSpan sp params
let rootMaybe = LSP.resRootPath env
-- only shift if lsp root is different from the rootDir
root <- case rootMaybe of
Just lspRoot | lspRoot /= defaultRoot -> setCurrentDirectory lspRoot >> return lspRoot
_ -> pure defaultRoot
dbLoc <- getHieDbLoc root
let root = LSP.resRootPath env
dir <- maybe getCurrentDirectory return root
dbLoc <- getHieDbLoc dir
let initConfig = parseConfiguration params
logWith recorder Info $ LogRegisteringIdeConfig initConfig
dbMVar <- newEmptyMVar
Expand Down
Loading

0 comments on commit bc9cb69

Please sign in to comment.