" <statement> evaluate/run <statement>\n" ++
" : repeat last command\n" ++
" :{\\n ..lines.. \\n:}\\n multiline command\n" ++
- " :add <filename> ... add module(s) to the current target set\n" ++
+ " :add [*]<module> ... add module(s) to the current target set\n" ++
" :browse[!] [[*]<mod>] display the names defined by module <mod>\n" ++
" (!: more details; *: all top-level names)\n" ++
" :cd <dir> change directory to <dir>\n" ++
" :help, :? display this list of commands\n" ++
" :info [<name> ...] display information about the given names\n" ++
" :kind <type> show the kind of <type>\n" ++
- " :load <filename> ... load module(s) and their dependents\n" ++
+ " :load [*]<module> ... load module(s) and their dependents\n" ++
" :main [<arguments> ...] run the main function with the given arguments\n" ++
" :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
" :quit exit GHCi\n" ++
files <- mapM expandPath files
targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
session <- getSession
- io (mapM_ (GHC.addTarget session) targets)
+ -- remove old targets with the same id; e.g. for :add *M
+ io $ mapM_ (GHC.removeTarget session) [ tid | Target tid _ _ <- targets ]
+ io $ mapM_ (GHC.addTarget session) targets
prev_context <- io $ GHC.getContext session
- ok <- io (GHC.load session LoadAllTargets)
+ ok <- io $ GHC.load session LoadAllTargets
afterLoad ok session False prev_context
changeDirectory :: String -> GHCi ()
Just file -> return file
Nothing -> ghcError (CmdLineError "No files to edit.")
- where fromTarget (GHC.Target (GHC.TargetFile f _) _) = Just f
+ where fromTarget (GHC.Target (GHC.TargetFile f _) _ _) = Just f
fromTarget _ = Nothing -- when would we get a module target?
defineMacro :: Bool{-overwrite-} -> String -> GHCi ()
[] -> Nothing
(m:_) -> Just m
- summary `matches` Target (TargetModule m) _
+ summary `matches` Target (TargetModule m) _ _
= GHC.ms_mod_name summary == m
- summary `matches` Target (TargetFile f _) _
+ summary `matches` Target (TargetFile f _) _ _
| Just f' <- GHC.ml_hs_file (GHC.ms_location summary) = f == f'
_ `matches` _
= False
wantInterpretedModule str = do
session <- getSession
modl <- lookupModule str
+ dflags <- getDynFlags
+ when (GHC.modulePackageId modl /= thisPackage dflags) $
+ ghcError (CmdLineError ("module '" ++ str ++ "' is from another package;\nthis command requires an interpreted module"))
is_interpreted <- io (GHC.moduleIsInterpreted session modl)
when (not is_interpreted) $
- ghcError (CmdLineError ("module '" ++ str ++ "' is not interpreted"))
+ ghcError (CmdLineError ("module '" ++ str ++ "' is not interpreted; try \':add *" ++ str ++ "' first"))
return modl
wantNameFromInterpretedModule :: (Name -> SDoc -> GHCi ()) -> String
removeTarget s target_id
= modifySession s (\h -> h{ hsc_targets = filter (hsc_targets h) })
where
- filter targets = [ t | t@(Target id _) <- targets, id /= target_id ]
+ filter targets = [ t | t@(Target id _ _) <- targets, id /= target_id ]
-- Attempts to guess what Target a string refers to. This function implements
-- the --make/GHCi command-line syntax for filenames:
-- - otherwise interpret the string as a module name
--
guessTarget :: String -> Maybe Phase -> IO Target
-guessTarget file (Just phase)
- = return (Target (TargetFile file (Just phase)) Nothing)
-guessTarget file Nothing
+guessTarget str (Just phase)
+ = return (Target (TargetFile str (Just phase)) True Nothing)
+guessTarget str Nothing
| isHaskellSrcFilename file
- = return (Target (TargetFile file Nothing) Nothing)
- | looksLikeModuleName file
- = return (Target (TargetModule (mkModuleName file)) Nothing)
+ = return (target (TargetFile file Nothing))
| otherwise
= do exists <- doesFileExist hs_file
if exists
- then return (Target (TargetFile hs_file Nothing) Nothing)
+ then return (target (TargetFile hs_file Nothing))
else do
exists <- doesFileExist lhs_file
if exists
- then return (Target (TargetFile lhs_file Nothing) Nothing)
+ then return (target (TargetFile lhs_file Nothing))
else do
+ if looksLikeModuleName file
+ then return (target (TargetModule (mkModuleName file)))
+ else do
throwGhcException
(ProgramError (showSDoc $
text "target" <+> quotes (text file) <+>
text "is not a module name or a source file"))
where
+ (file,obj_allowed)
+ | '*':rest <- str = (rest, False)
+ | otherwise = (str, True)
+
hs_file = file <.> "hs"
lhs_file = file <.> "lhs"
+ target tid = Target tid obj_allowed Nothing
+
-- -----------------------------------------------------------------------------
-- Extending the program scope
old_summary_map = mkNodeMap old_summaries
getRootSummary :: Target -> IO ModSummary
- getRootSummary (Target (TargetFile file mb_phase) maybe_buf)
+ getRootSummary (Target (TargetFile file mb_phase) obj_allowed maybe_buf)
= do exists <- doesFileExist file
if exists
- then summariseFile hsc_env old_summaries file mb_phase maybe_buf
+ then summariseFile hsc_env old_summaries file mb_phase
+ obj_allowed maybe_buf
else throwErrMsg $ mkPlainErrMsg noSrcSpan $
text "can't find file:" <+> text file
- getRootSummary (Target (TargetModule modl) maybe_buf)
+ getRootSummary (Target (TargetModule modl) obj_allowed maybe_buf)
= do maybe_summary <- summariseModule hsc_env old_summary_map False
- (L rootLoc modl) maybe_buf excl_mods
+ (L rootLoc modl) obj_allowed
+ maybe_buf excl_mods
case maybe_summary of
Nothing -> packageModErr modl
Just s -> return s
loop ss done
else
do { multiRootsErr summs; return [] }
- | otherwise = do { mb_s <- summariseModule hsc_env old_summary_map
- is_boot wanted_mod Nothing excl_mods
- ; case mb_s of
- Nothing -> loop ss done
- Just s -> loop (msDeps s ++ ss)
- (addToFM done key [s]) }
+ | otherwise
+ = do mb_s <- summariseModule hsc_env old_summary_map
+ is_boot wanted_mod True
+ Nothing excl_mods
+ case mb_s of
+ Nothing -> loop ss done
+ Just s -> loop (msDeps s ++ ss) (addToFM done key [s])
where
key = (unLoc wanted_mod, if is_boot then HsBootFile else HsSrcFile)
-> [ModSummary] -- old summaries
-> FilePath -- source file name
-> Maybe Phase -- start phase
+ -> Bool -- object code allowed?
-> Maybe (StringBuffer,ClockTime)
-> IO ModSummary
-summariseFile hsc_env old_summaries file mb_phase maybe_buf
+summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
-- we can use a cached summary if one is available and the
-- source file hasn't changed, But we have to look up the summary
-- by source file, rather than module name as we do in summarise.
if ms_hs_date old_summary == src_timestamp
then do -- update the object-file timestamp
obj_timestamp <-
- if isObjectTarget (hscTarget (hsc_dflags hsc_env)) -- bug #1205
+ if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+ || obj_allowed -- bug #1205
then getObjTimestamp location False
else return Nothing
return old_summary{ ms_obj_date = obj_timestamp }
-- when the user asks to load a source file by name, we only
-- use an object file if -fobject-code is on. See #1205.
obj_timestamp <-
- if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+ if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+ || obj_allowed -- bug #1205
then modificationTimeIfExists (ml_obj_file location)
else return Nothing
-> NodeMap ModSummary -- Map of old summaries
-> IsBootInterface -- True <=> a {-# SOURCE #-} import
-> Located ModuleName -- Imported module to be summarised
+ -> Bool -- object code allowed?
-> Maybe (StringBuffer, ClockTime)
-> [ModuleName] -- Modules to exclude
-> IO (Maybe ModSummary) -- Its new summary
-summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf excl_mods
+summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
+ obj_allowed maybe_buf excl_mods
| wanted_mod `elem` excl_mods
= return Nothing
check_timestamp old_summary location src_fn src_timestamp
| ms_hs_date old_summary == src_timestamp = do
-- update the object-file timestamp
- obj_timestamp <- getObjTimestamp location is_boot
+ obj_timestamp <-
+ if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+ || obj_allowed -- bug #1205
+ then getObjTimestamp location is_boot
+ else return Nothing
return (Just old_summary{ ms_obj_date = obj_timestamp })
| otherwise =
-- source changed: re-summarise.
$$ text "Expected:" <+> quotes (ppr wanted_mod)
-- Find the object timestamp, and return the summary
- obj_timestamp <- getObjTimestamp location is_boot
+
+ obj_timestamp <-
+ if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+ || obj_allowed -- bug #1205
+ then getObjTimestamp location is_boot
+ else return Nothing
return (Just ( ModSummary { ms_mod = mod,
ms_hsc_src = hsc_src,
-- module. If so, use this instead of the file contents (this
-- is for use in an IDE where the file hasn't been saved by
-- the user yet).
-data Target = Target TargetId (Maybe (StringBuffer,ClockTime))
+data Target = Target
+ TargetId -- module or filename
+ Bool -- object code allowed?
+ (Maybe (StringBuffer,ClockTime)) -- in-memory text buffer?
data TargetId
= TargetModule ModuleName
deriving Eq
pprTarget :: Target -> SDoc
-pprTarget (Target id _) = pprTargetId id
+pprTarget (Target id obj _) =
+ (if obj then char '*' else empty) <> pprTargetId id
instance Outputable Target where
ppr = pprTarget
confusion, because non-exported top-level definitions of a module
are only available for use in expressions at the prompt when the
module is interpreted (see <xref linkend="ghci-scope" />). For
- this reason, if you ask GHCi to load a filename rather than a
- module name (e.g. <literal>:load Main.hs</literal> rather than
- <literal>:load Main</literal>) then any existing object file will
- be ignored and the module will be interpreted rather than
- compiled. Using <literal>-fobject-code</literal> disables this
- behaviour (see <xref linkend="ghci-obj" />).</para>
+ this reason, you might sometimes want to force GHCi to load a
+ module using the interpreter. This can be done by prefixing
+ a <literal>*</literal> to the module name or filename when
+ using <literal>:load</literal>, for example</para>
+
+<screen>
+Prelude> :load *A
+Compiling A ( A.hs, interpreted )
+*A>
+</screen>
+
+<para>When the <literal>*</literal> is used, GHCi ignores any
+ pre-compiled object code and interprets the module. If you have
+ already loaded a number of modules as object code and decide that
+ you wanted to interpret one of them, instead of re-loading the whole
+ set you can use <literal>:add *M</literal> to specify that you want
+ <literal>M</literal> to be interpreted (note that this might cause
+ other modules to be interpreted too, because compiled modules cannot
+ depend on interpreted ones).</para>
+
+<para>To always compile everything to object code and never use the
+ interpreter, use the <literal>-fobject-code</literal> option (see
+ <xref linkend="ghci-obj" />).</para>
<para>HINT: since GHCi will only use a compiled object file if it
can be sure that the compiled version is up-to-date, a good technique
<para>NOTE: for technical reasons, GHCi can only support the
<literal>*</literal>-form for modules that are interpreted.
Compiled modules and package modules can only contribute their
- exports to the current scope. This is why GHCi will always
- interpret, not compile, a module if you specify its filename
- rather than its module name to <literal>:load</literal>.</para>
+ exports to the current scope. To ensure that GHCi loads the
+ interpreted version of a module, add the <literal>*</literal>
+ when loading the module, e.g. <literal>:load *M</literal>.</para>
<para>The scope is manipulated using the
<literal>:module</literal> command. For example, if the current
<screen>
*Main> :set -fbreak-on-exception
*Main> :trace qsort ("abc" ++ undefined)
-"Stopped at <exception thrown>
+“Stopped at <exception thrown>
_exception :: e
[<exception thrown>] *Main> :hist
-1 : qsort.hs:3:24-38
<varlistentry>
<term>
- <literal>:add</literal> <replaceable>module</replaceable> ...
+ <literal>:add</literal> <optional><literal>*</literal></optional><replaceable>module</replaceable> ...
<indexterm><primary><literal>:add</literal></primary></indexterm>
</term>
<listitem>
<para>Add <replaceable>module</replaceable>(s) to the
current <firstterm>target set</firstterm>, and perform a
- reload.</para>
+ reload. Normally pre-compiled code for the module will be
+ loaded if available, or otherwise the module will be
+ compiled to byte-code. Using the <literal>*</literal>
+ prefix forces the module to be loaded as byte-code.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <literal>:load</literal> <replaceable>module</replaceable> ...
+ <literal>:load</literal> <optional><literal>*</literal></optional><replaceable>module</replaceable> ...
<indexterm><primary><literal>:load</literal></primary></indexterm>
</term>
<listitem>
to unload all the currently loaded modules and
bindings.</para>
+ <para>Normally pre-compiled code for a module will be loaded
+ if available, or otherwise the module will be compiled to
+ byte-code. Using the <literal>*</literal> prefix forces a
+ module to be loaded as byte-code.</para>
+
<para>After a <literal>:load</literal> command, the current
context is set to:</para>