diff --git a/src/Hint/Context.hs b/src/Hint/Context.hs index 566812a..9524463 100644 --- a/src/Hint/Context.hs +++ b/src/Hint/Context.hs @@ -2,7 +2,7 @@ module Hint.Context ( isModuleInterpreted, loadModules, getLoadedModules, setTopLevelModules, setImports, setImportsQ, - reset, + reset, reload, PhantomModule(..), cleanPhantomModules, @@ -197,14 +197,18 @@ isPhantomModule mn = do (as,zs) <- getPhantomModules loadModules :: MonadInterpreter m => [String] -> m () loadModules fs = do -- first, unload everything, and do some clean-up reset - doLoad fs `catchIE` (\e -> reset >> throwM e) - -doLoad :: MonadInterpreter m => [String] -> m () -doLoad fs = mayFail $ do - targets <- mapM (\f->runGhc2 GHC.guessTarget f Nothing) fs - -- - runGhc1 GHC.setTargets targets - res <- runGhc1 GHC.load GHC.LoadAllTargets + targets <- mapM (\f->runGhc2 GHC.guessTarget f Nothing) fs + runGhc1 GHC.setTargets targets + reload + +-- | Reload any loaded modules that have changed, similar to a @:reload@ in GHCi. +-- Note that you may need to restore your set of top level modules afterwards. +reload :: MonadInterpreter m => m () +reload = doLoad GHC.LoadAllTargets `catchIE` (\e -> reset >> throwM e) + +doLoad :: MonadInterpreter m => GHC.LoadHowMuch -> m () +doLoad howmuch = mayFail $ do + res <- runGhc1 GHC.load howmuch -- loading the targets removes the support module reinstallSupportModule return $ guard (isSucceeded res) >> Just () diff --git a/src/Language/Haskell/Interpreter.hs b/src/Language/Haskell/Interpreter.hs index 30c19ed..fd00829 100644 --- a/src/Language/Haskell/Interpreter.hs +++ b/src/Language/Haskell/Interpreter.hs @@ -24,7 +24,7 @@ module Language.Haskell.Interpreter( ModuleName, isModuleInterpreted, loadModules, getLoadedModules, setTopLevelModules, setImports, setImportsQ, - reset, + reset, reload, -- ** Module querying ModuleElem(..), Id, name, children, getModuleExports, diff --git a/unit-tests/run-unit-tests.hs b/unit-tests/run-unit-tests.hs index cf8c3e7..e64f47b 100644 --- a/unit-tests/run-unit-tests.hs +++ b/unit-tests/run-unit-tests.hs @@ -20,8 +20,8 @@ import qualified Test.HUnit as HUnit import Language.Haskell.Interpreter -test_reload_modified :: TestCase -test_reload_modified = TestCase "reload_modified" [mod_file] $ do +test_load_modified :: TestCase +test_load_modified = TestCase "load_modified" [mod_file] $ do liftIO $ writeFile mod_file mod_v1 f_v1 <- get_f -- @@ -30,7 +30,7 @@ test_reload_modified = TestCase "reload_modified" [mod_file] $ do -- liftIO $ (f_v1 5, f_v2 5) @?= (5, 6) -- - where mod_name = "TEST_ReloadModified" + where mod_name = "TEST_LoadModified" mod_file = mod_name ++ ".hs" -- mod_v1 = unlines ["module " ++ mod_name, @@ -46,6 +46,42 @@ test_reload_modified = TestCase "reload_modified" [mod_file] $ do setTopLevelModules [mod_name] interpret "f" (as :: Int -> Int) +test_reload_modified :: TestCase +test_reload_modified = TestCase "reload_modified" [mod_file_a, mod_file_b] $ do + liftIO $ writeFile mod_file_a mod_a_v1 + loadModules [mod_file_a] + setTopLevelModules [mod_name_a] + f_v1 <- interpret "fin" (as :: String -> String) + let a = (f_v1 "foo") + -- + liftIO $ writeFile mod_file_a mod_a_v2 + liftIO $ writeFile mod_file_b mod_b + set [searchPath := ["."]] + reload + setTopLevelModules [mod_name_a] + f_v2 <- interpret "fun" (as :: String -> String) + let b = (f_v2 "foo") + -- + liftIO $ (a, b) @?= ("foooof", "ooffoo") + -- + where mod_name_a = "TEST_ReloadModified" + mod_file_a = mod_name_a ++ ".hs" + -- + mod_name_b = "TEST_ReloadModifiedB" + mod_file_b = mod_name_b ++ ".hs" + -- + mod_a_v1 = unlines ["module " ++ mod_name_a ++ " where", + "fin :: String -> String", + "fin s = s ++ reverse s"] + mod_a_v2 = unlines ["module " ++ mod_name_a ++ " where", + "import " ++ mod_name_b ++ " (gi)", + "fun :: String -> String", + "fun = gi"] + mod_b = unlines ["module " ++ mod_name_b ++ " where", + "gi :: String -> String", + "gi s = reverse s ++ s"] + + test_lang_exts :: TestCase test_lang_exts = TestCase "lang_exts" [mod_file] $ do liftIO $ writeFile mod_file "data T where T :: T" @@ -202,6 +238,7 @@ test_only_one_instance = TestCase "only_one_instance" [] $ liftIO $ do tests :: [TestCase] tests = [test_reload_modified + ,test_load_modified ,test_lang_exts ,test_work_in_main ,test_comments_in_expr