diff options
author | Julian Priestley <jupriest@devvm610.lla2.facebook.com> | 2018-01-31 21:35:00 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-01-31 23:28:06 -0500 |
commit | 0bff9e677f0569bc8a7207c20cddddfd67e2448f (patch) | |
tree | 77bec47e70244bd3d39906ce8d0611b5ae8babc4 /ghc | |
parent | 0171e09e4d073d8466953ebbf01292e55829fb20 (diff) | |
download | haskell-0bff9e677f0569bc8a7207c20cddddfd67e2448f.tar.gz |
Don't add targets that can't be found in GHCi
When using the :add command in haxlsh/ghci, a module/file that can't
be found is still added to the list of targets, resulting in an error
message for the bad module/file for every subsequent usage of the
command. The add command should verify that the module/file can be
found before adding it to the list of targets.
Also add a ":show targets" command to show the currently added list of
commands, and an ":unadd" command to remove a target.
Test Plan:
Add a new GHCi testcase that checks that :add doesn't remember either
files or modules that could not be found, and that both the new :show
and :unadd commands work as expected.
Reviewers: simonmar, bgamari
Reviewed By: simonmar
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14676
Differential Revision: https://phabricator.haskell.org/D4321
Diffstat (limited to 'ghc')
-rw-r--r-- | ghc/GHCi/UI.hs | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs index 01c8505562..b83ceeb7d9 100644 --- a/ghc/GHCi/UI.hs +++ b/ghc/GHCi/UI.hs @@ -43,6 +43,7 @@ import GHCi.RemoteTypes import GHCi.BreakArray import DynFlags import ErrUtils hiding (traceCmd) +import Finder import GhcMonad ( modifySession ) import qualified GHC import GHC ( LoadHowMuch(..), Target(..), TargetId(..), InteractiveImport(..), @@ -208,6 +209,7 @@ ghciCommands = map mkCmd [ ("stepmodule",keepGoing stepModuleCmd, completeIdentifier), ("type", keepGoing' typeOfExpr, completeExpression), ("trace", keepGoing traceCmd, completeExpression), + ("unadd", keepGoingPaths unAddModule, completeFilename), ("undef", keepGoing undefineMacro, completeMacro), ("unset", keepGoing unsetOptions, completeSetOptions), ("where", keepGoing whereCmd, noCompletion) @@ -305,6 +307,7 @@ defFullHelpText = " :type <expr> show the type of <expr>\n" ++ " :type +d <expr> show the type of <expr>, defaulting type variables\n" ++ " :type +v <expr> show the type of <expr>, with its specified tyvars\n" ++ + " :unadd <module> ... remove module(s) from the current target set\n" ++ " :undef <cmd> undefine user-defined command :<cmd>\n" ++ " :!<command> run the shell command <command>\n" ++ "\n" ++ @@ -371,6 +374,7 @@ defFullHelpText = " :show packages show the currently active package flags\n" ++ " :show paths show the currently active search paths\n" ++ " :show language show the currently active language flags\n" ++ + " :show targets show the current set of targets\n" ++ " :show <setting> show value of <setting>, which is one of\n" ++ " [args, prog, editor, stop]\n" ++ " :showi language show language flags for interactive evaluation\n" ++ @@ -1657,9 +1661,39 @@ addModule files = do lift revertCAFs -- always revert CAFs on load/add. files' <- mapM expandPath files targets <- mapM (\m -> GHC.guessTarget m Nothing) files' + targets' <- filterM checkTarget targets -- remove old targets with the same id; e.g. for :add *M + mapM_ GHC.removeTarget [ tid | Target tid _ _ <- targets' ] + mapM_ GHC.addTarget targets' + _ <- doLoadAndCollectInfo False LoadAllTargets + return () + where + checkTarget :: Target -> InputT GHCi Bool + checkTarget (Target (TargetModule m) _ _) = checkTargetModule m + checkTarget (Target (TargetFile f _) _ _) = liftIO $ checkTargetFile f + + checkTargetModule :: ModuleName -> InputT GHCi Bool + checkTargetModule m = do + hsc_env <- GHC.getSession + result <- liftIO $ + Finder.findImportedModule hsc_env m (Just (fsLit "this")) + case result of + Found _ _ -> return True + _ -> (liftIO $ putStrLn $ + "Module " ++ moduleNameString m ++ " not found") >> return False + + checkTargetFile :: String -> IO Bool + checkTargetFile f = do + exists <- (doesFileExist f) :: IO Bool + unless exists $ putStrLn $ "File " ++ f ++ " not found" + return exists + +-- | @:unadd@ command +unAddModule :: [FilePath] -> InputT GHCi () +unAddModule files = do + files' <- mapM expandPath files + targets <- mapM (\m -> GHC.guessTarget m Nothing) files' mapM_ GHC.removeTarget [ tid | Target tid _ _ <- targets ] - mapM_ GHC.addTarget targets _ <- doLoadAndCollectInfo False LoadAllTargets return () @@ -2779,6 +2813,7 @@ showCmd str = do , action "language" $ showLanguages , hidden "languages" $ showLanguages -- backwards compat , hidden "lang" $ showLanguages -- useful abbreviation + , action "targets" $ showTargets ] case words str of @@ -2941,6 +2976,14 @@ showLanguages' show_all dflags = Nothing -> Just Haskell2010 other -> other +showTargets :: GHCi () +showTargets = mapM_ showTarget =<< GHC.getTargets + where + showTarget :: Target -> GHCi () + showTarget (Target (TargetFile f _) _ _) = liftIO (putStrLn f) + showTarget (Target (TargetModule m) _ _) = + liftIO (putStrLn $ moduleNameString m) + -- ----------------------------------------------------------------------------- -- Completion |