packages feed

ghc-imported-from 0.2.0.3 → 0.2.0.4

raw patch · 4 files changed

+79/−51 lines, 4 filesdep +parsecPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: parsec

API changes (from Hackage documentation)

- Language.Haskell.GhcImportedFrom: findHaddockModule :: QualifiedName -> [HaskellModule] -> GhcPkgOptions -> (Name, [GlobalRdrElt]) -> IO [(Maybe String, Maybe String, Maybe String, Maybe String)]
+ Language.Haskell.GhcImportedFrom: findHaddockModule :: QualifiedName -> [HaskellModule] -> [String] -> GhcPkgOptions -> (Name, [GlobalRdrElt]) -> IO [(Maybe String, Maybe String, Maybe String, Maybe String)]
- Language.Haskell.GhcImportedFrom: getSummary :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([String], [GHCOption], ModSummary)
+ Language.Haskell.GhcImportedFrom: getSummary :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([GHCOption], ModSummary)
- Language.Haskell.GhcImportedFrom: getTextualImports :: GhcMonad m => GhcOptions -> FilePath -> String -> m [Located (ImportDecl RdrName)]
+ Language.Haskell.GhcImportedFrom: getTextualImports :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([GHCOption], [Located (ImportDecl RdrName)])
- Language.Haskell.GhcImportedFrom: ghcPkgFindModule :: GhcPkgOptions -> String -> IO (Maybe String)
+ Language.Haskell.GhcImportedFrom: ghcPkgFindModule :: [String] -> GhcPkgOptions -> String -> IO (Maybe String)
- Language.Haskell.GhcImportedFrom: ghcPkgHaddockUrl :: GhcPkgOptions -> String -> IO (Maybe String)
+ Language.Haskell.GhcImportedFrom: ghcPkgHaddockUrl :: [String] -> GhcPkgOptions -> String -> IO (Maybe String)
- Language.Haskell.GhcImportedFrom: modifyDFlags :: [String] -> DynFlags -> IO ([String], [GHCOption], DynFlags)
+ Language.Haskell.GhcImportedFrom: modifyDFlags :: [String] -> DynFlags -> IO ([GHCOption], DynFlags)
- Language.Haskell.GhcImportedFrom: setDynamicFlags :: GhcMonad m => GhcOptions -> DynFlags -> m ([String], [GHCOption], DynFlags)
+ Language.Haskell.GhcImportedFrom: setDynamicFlags :: GhcMonad m => GhcOptions -> DynFlags -> m ([GHCOption], DynFlags)

Files

Language/Haskell/GhcImportedFrom.hs view
@@ -97,6 +97,9 @@  import Control.Exception (SomeException) +import qualified Text.Parsec as TP+import Data.Functor.Identity+ #if __GLASGOW_HASKELL__ >= 708 import DynFlags ( unsafeGlobalDynFlags ) tdflags = unsafeGlobalDynFlags@@ -109,6 +112,8 @@  getGhcOptionsViaCabalRepl :: IO (Maybe [String]) getGhcOptionsViaCabalRepl = do+    putStrLn $ "getGhcOptionsViaCabalRepl..."+     (Just _, Just hout, Just _, _) <- createProcess (proc "cabal" ["repl", "--with-ghc=fake-ghc-for-ghc-imported-from"]){ std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe }      ineof <- hIsEOF hout@@ -126,12 +131,35 @@     case length result' of 1 -> return $ Just $ filterOpts $ words $ head result'                            _ -> return Nothing -    where filterOpts :: [String] -> [String]-          filterOpts xs = filter (\x -> x /= "--interactive" && x /= "-fbuilding-cabal-package") $ dropModuleNames xs+filterOpts :: [String] -> [String]+filterOpts xs = filter (\x -> x /= "--interactive" && x /= "-fbuilding-cabal-package" && x /= "-Wall") $ dropModuleNames xs -          dropModuleNames :: [String] -> [String]-          dropModuleNames xs = reverse $ dropWhile (not . ("-" `isPrefixOf`)) (reverse xs)+dropModuleNames :: [String] -> [String]+dropModuleNames = filter parseHelper +parseHaskellModuleName :: TP.ParsecT String u Data.Functor.Identity.Identity String+parseHaskellModuleName = do+    c <- TP.upper+    cs <- TP.many (TP.choice [TP.lower, TP.upper])+    return (c:cs)++parseDottedHaskellModuleName :: TP.ParsecT String u Data.Functor.Identity.Identity String+parseDottedHaskellModuleName = do+    TP.char '.'+    cs <- parseHaskellModuleName+    return cs++parseFullHaskellModuleName :: TP.ParsecT String u Data.Functor.Identity.Identity String+parseFullHaskellModuleName = do+    h <- parseHaskellModuleName+    rest <- many parseDottedHaskellModuleName++    return $ intercalate "." (h:rest)++parseHelper :: String -> Bool+parseHelper s = case (TP.parse (parseFullHaskellModuleName <* TP.eof) "" s) of Right _ -> False+                                                                               Left _  -> True+ getGhcOptionsViaCabalReplOrEmpty :: IO [String] getGhcOptionsViaCabalReplOrEmpty =  liftM (fromMaybe []) getGhcOptionsViaCabalRepl @@ -159,7 +187,7 @@                     } deriving (Show, Eq)  -- | Add user-supplied GHC options to those discovered via cabl repl.-modifyDFlags :: [String] -> DynFlags -> IO ([String], [GHCOption], DynFlags)+modifyDFlags :: [String] -> DynFlags -> IO ([GHCOption], DynFlags) modifyDFlags ghcOpts0 dflags0 =     -- defaultErrorHandler defaultFatalMessager defaultFlushOut $         runGhc (Just libdir) $ do@@ -171,7 +199,7 @@                                   , ghcLink = LinkInMemory                                   } -            return ([], [], dflags2)+            return (ghcOpts0 ++ ghcOpts1, dflags2)  -- | Set GHC options and run 'initPackages' in 'GhcMonad'. --@@ -181,14 +209,14 @@ -- >    runGhc (Just libdir) $ do -- >        getSessionDynFlags >>= setDynamicFlags (GhcOptions myGhcOptionList) -- >        -- do stuff-setDynamicFlags :: GhcMonad m => GhcOptions -> DynFlags -> m ([String], [GHCOption], DynFlags)+setDynamicFlags :: GhcMonad m => GhcOptions -> DynFlags -> m ([GHCOption], DynFlags) setDynamicFlags (GhcOptions extraGHCOpts) dflags0 = do-    (ghcOpts1, ghcOpts2, dflags1) <- GhcMonad.liftIO $ modifyDFlags extraGHCOpts dflags0+    (allGhcOpts, dflags1) <- GhcMonad.liftIO $ modifyDFlags extraGHCOpts dflags0      void $ setSessionDynFlags dflags1     _ <- GhcMonad.liftIO $ Packages.initPackages dflags1 -    return (ghcOpts1, ghcOpts2, dflags1)+    return (allGhcOpts, dflags1)  -- |Read the textual imports in a file. --@@ -202,27 +230,27 @@ -- -- See also 'toHaskellModule' and 'getSummary'. -getTextualImports :: GhcMonad m => GhcOptions -> FilePath -> String -> m [SrcLoc.Located (ImportDecl RdrName)]+getTextualImports :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([GHCOption], [SrcLoc.Located (ImportDecl RdrName)]) getTextualImports ghcopts targetFile targetModuleName = do     GhcMonad.liftIO $ putStrLn $ "getTextualImports: " ++ show (targetFile, targetModuleName)-    (ghcOpts1, ghcOpts2, modSum) <- getSummary ghcopts targetFile targetModuleName+    (allGhcOpts, modSum) <- getSummary ghcopts targetFile targetModuleName -    GhcMonad.liftIO $ putStrLn $ "getTextualImports: ghcOpts1: " ++ show ghcOpts1-    GhcMonad.liftIO $ putStrLn $ "getTextualImports: ghcOpts2: " ++ show ghcOpts2+    GhcMonad.liftIO $ putStrLn $ "getTextualImports: allGhcOpts: " ++ show allGhcOpts -    return $ ms_textual_imps modSum+    return (allGhcOpts, ms_textual_imps modSum)  -- | Get the module summary for a particular file/module. The first and second components of the -- return value are @ghcOpts1@ and @ghcOpts2@; see 'setDynamicFlags'.-getSummary :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([String], [GHCOption], ModSummary)+getSummary :: GhcMonad m => GhcOptions -> FilePath -> String -> m ([GHCOption], ModSummary) getSummary ghcopts targetFile targetModuleName = do             GhcMonad.liftIO $ putStrLn $ "getSummary, setting dynamic flags..."-            (ghcOpts1, ghcOpts2, _) <- getSessionDynFlags >>= setDynamicFlags ghcopts+            (allGhcOpts, _) <- getSessionDynFlags >>= setDynamicFlags ghcopts              -- Load the target file (e.g. "Muddle.hs").             GhcMonad.liftIO $ putStrLn $ "getSummary, loading the target file..."             target <- guessTarget targetFile Nothing             setTargets [target]+             _ <- load LoadAllTargets              -- Set the context by loading the module, e.g. "Muddle" which is in "Muddle.hs".@@ -242,7 +270,7 @@             -- let graph_names = map (GHC.moduleNameString . GHC.ms_mod_name) graph             -- GhcMonad.liftIO $ print $ "graph_names: " ++ show graph_names -            return (ghcOpts1, ghcOpts2, modSum)+            return (allGhcOpts, modSum)  -- |Convenience function for converting an 'GHC.ImportDecl' to a 'HaskellModule'. --@@ -484,11 +512,9 @@  -- | Call @ghc-pkg find-module@ to determine that package that provides a module, e.g. @Prelude@ is defined -- in @base-4.6.0.1@.-ghcPkgFindModule :: GhcPkgOptions -> String -> IO (Maybe String)-ghcPkgFindModule (GhcPkgOptions extraGHCPkgOpts) m = do-    gopts <- getGhcOptionsViaCabalReplOrEmpty--    let opts = ["find-module", m, "--simple-output"] ++ ["--global", "--user"] ++ optsForGhcPkg gopts ++ extraGHCPkgOpts+ghcPkgFindModule :: [String] -> GhcPkgOptions -> String -> IO (Maybe String)+ghcPkgFindModule allGhcOptions (GhcPkgOptions extraGHCPkgOpts) m = do+    let opts = ["find-module", m, "--simple-output"] ++ ["--global", "--user"] ++ optsForGhcPkg allGhcOptions ++ extraGHCPkgOpts     putStrLn $ "ghc-pkg " ++ show opts      (_, Just hout, Just herr, _) <- createProcess (proc "ghc-pkg" opts){ std_in  = CreatePipe@@ -505,11 +531,9 @@     return $ join $ Safe.lastMay <$> words <$> (Safe.lastMay . lines) output  -- | Call @ghc-pkg field@ to get the @haddock-html@ field for a package.-ghcPkgHaddockUrl :: GhcPkgOptions -> String -> IO (Maybe String)-ghcPkgHaddockUrl (GhcPkgOptions extraGHCPkgOpts) p = do-    gopts <- getGhcOptionsViaCabalReplOrEmpty--    let opts = ["field", p, "haddock-html"] ++ ["--global", "--user"] ++ optsForGhcPkg gopts ++ extraGHCPkgOpts+ghcPkgHaddockUrl :: [String] -> GhcPkgOptions -> String -> IO (Maybe String)+ghcPkgHaddockUrl allGhcOptions (GhcPkgOptions extraGHCPkgOpts) p = do+    let opts = ["field", p, "haddock-html"] ++ ["--global", "--user"] ++ optsForGhcPkg allGhcOptions ++ extraGHCPkgOpts     putStrLn $ "ghc-pkg "++ show opts      (_, Just hout, _, _) <- createProcess (proc "ghc-pkg" opts){ std_in = CreatePipe@@ -615,8 +639,8 @@  -- | Find the haddock module. Returns a 4-tuple consisting of: module that the symbol is imported -- from, haddock url, module, and module's HTML filename.-findHaddockModule :: QualifiedName -> [HaskellModule] -> GhcPkgOptions -> (Name, [GlobalRdrElt]) -> IO [(Maybe String, Maybe String, Maybe String, Maybe String)]-findHaddockModule symbol'' smatches ghcpkgOpts (name, lookUp) = do+findHaddockModule :: QualifiedName -> [HaskellModule] -> [String] -> GhcPkgOptions -> (Name, [GlobalRdrElt]) -> IO [(Maybe String, Maybe String, Maybe String, Maybe String)]+findHaddockModule symbol'' smatches allGhcOpts ghcpkgOpts (name, lookUp) = do  -- FIXME this is messy - the code below has a dodgy fromJust...  if isJust (moduleOfQualifiedName symbol'')   then do@@ -642,14 +666,14 @@      forM importedFrom $ \impfrom -> do         let impfrom' = Just impfrom-        foundModule <- maybe (return Nothing) (ghcPkgFindModule ghcpkgOpts) impfrom'+        foundModule <- maybe (return Nothing) (ghcPkgFindModule allGhcOpts ghcpkgOpts) impfrom'         putStrLn $ "ghcPkgFindModule result: " ++ show foundModule          let base = moduleNameToHtmlFile <$> impfrom'          putStrLn $ "base: : " ++ show base -        haddock <- maybe (return Nothing) (ghcPkgHaddockUrl ghcpkgOpts) foundModule+        haddock <- maybe (return Nothing) (ghcPkgHaddockUrl allGhcOpts ghcpkgOpts) foundModule          putStrLn $ "haddock: " ++ show haddock         putStrLn $ "foundModule1: " ++ show foundModule@@ -712,12 +736,12 @@                                                     else return []     return $ concat blah -actualFinalCase ghcOpts0 ghcpkgOptions targetFile targetModule symbol haskellModuleNames' = do+actualFinalCase allGhcOpts ghcpkgOptions targetFile targetModule symbol haskellModuleNames' = do     -- This is getting ridiculous...     GhcMonad.liftIO $ putStrLn "last bits 1..."-    zzz <- finalCase ghcOpts0 targetFile targetModule symbol haskellModuleNames'+    zzz <- finalCase allGhcOpts targetFile targetModule symbol haskellModuleNames'     GhcMonad.liftIO $ putStrLn "last bits 2..."-    yyy <- forM zzz $ \r -> do p <- GhcMonad.liftIO $ ghcPkgFindModule ghcpkgOptions r+    yyy <- forM zzz $ \r -> do p <- GhcMonad.liftIO $ ghcPkgFindModule allGhcOpts ghcpkgOptions r                                GhcMonad.liftIO $ print $ "forM_ last bits: " ++ show p                                case p of Nothing  -> return []                                          (Just _) -> return [(r, fromJust p)]@@ -726,7 +750,7 @@      GhcMonad.liftIO $ putStrLn "last bits 3..."     -- FIXME why don't we have the full ghc options right now? More than just the user-supplied ones?-    yyy'' <- forM yyy' $ \(mname, pname) -> do haddock <- GhcMonad.liftIO $ ghcPkgHaddockUrl (GhcPkgOptions ghcOpts0) pname+    yyy'' <- forM yyy' $ \(mname, pname) -> do haddock <- GhcMonad.liftIO $ ghcPkgHaddockUrl allGhcOpts (GhcPkgOptions allGhcOpts) pname                                                if isJust haddock                                                      then do GhcMonad.liftIO $ putStrLn $ "last bits 3 inner loop: " ++ show haddock                                                              url <- GhcMonad.liftIO $ matchToUrl (Just mname, haddock, Just mname, Just $ moduleNameToHtmlFile mname)@@ -770,7 +794,7 @@      -- Put a runGhc up here, then change the types further down???     runGhc (Just libdir) $ do-        textualImports <- getTextualImports (GhcOptions ghcOpts0) targetFile targetModule+        (allGhcOpts, textualImports) <- getTextualImports (GhcOptions ghcOpts0) targetFile targetModule          let haskellModules0 = map toHaskellModule textualImports             haskellModuleNames0 = map modName haskellModules0@@ -815,7 +839,6 @@         GhcMonad.liftIO $ putStrLn $ "maybeExtraModule': " ++ show maybeExtraModule'         GhcMonad.liftIO $ putStrLn $ "haskellModuleNames': " ++ show haskellModuleNames' -         let smatches = specificallyMatches symbol (map toHaskellModule textualImports)         GhcMonad.liftIO $ putStrLn $ "smatches: " ++ show smatches @@ -830,7 +853,7 @@         -- Then this does a runGhc as well.         final1 <- lookupSymbol (GhcOptions ghcOpts0) targetFile targetModule symbol'' haskellModuleNames' -        final1' <- GhcMonad.liftIO $ concatMapM (findHaddockModule symbol'' smatches ghcpkgOptions) final1+        final1' <- GhcMonad.liftIO $ concatMapM (findHaddockModule symbol'' smatches allGhcOpts ghcpkgOptions) final1         GhcMonad.liftIO $ putStrLn $ "final1': " ++ show final1'          -- Remove any modules that have this name hidden.
README.md view
@@ -69,13 +69,10 @@  Run the tests using cabal: -    cabal test --show-details=streaming--As of 2014-05-18 just running ```cabal test``` seems to run the-tests and then hang (waiting on a PID). This seems to be the problem:-https://github.com/haskell/cabal/issues/1810+    cabal test -Running with ```--show-details=streaming``` seems to work ok.+If the tests hang, check that your version of Cabal/cabal-install has this+fix: https://github.com/haskell/cabal/issues/1810  ### ghcimportedfrom-vim @@ -89,7 +86,7 @@  Or watch the screencast (be sure to set 720p HD and then fullscreen): -[http://www.youtube.com/watch?v=VVc8uupYJGs](http://www.youtube.com/watch?v=VVc8uupYJGs)+[https://www.youtube.com/watch?v=7yO_VGCWMu8](https://www.youtube.com/watch?v=7yO_VGCWMu8)  ## Notes 
changelog.md view
@@ -1,4 +1,9 @@-2014-05-16 v0.2.0.3+2014-05-22 v0.2.0.4++* Speedup: factor out calls to getGhcOptionsViaCabalRepl.+* Bug fix: filter out haskell module names from the cabal options list.++2014-05-19 v0.2.0.3  * Fixed test cases. * Added alternative heuristic for lookup.
ghc-imported-from.cabal view
@@ -1,5 +1,5 @@ name:                ghc-imported-from-version:             0.2.0.3+version:             0.2.0.4 synopsis:            Find the Haddock documentation for a symbol. description:         Given a Haskell module and symbol, determine the URL to the Haddock documentation                      for that symbol.@@ -19,7 +19,7 @@                      test/data/*.hs  library-    GHC-Options:         -Wall -O2+    GHC-Options:         -Wall     exposed-modules: Language.Haskell.GhcImportedFrom     other-modules:   Language.Haskell.GhcImportedFrom.UtilsFromGhcMod                      Language.Haskell.GhcImportedFrom.Types@@ -38,6 +38,7 @@                  , containers                  , mtl                  , transformers+                 , parsec     if impl(ghc < 7.7)       Build-Depends:  Cabal >= 1.10 && < 1.17     else@@ -47,7 +48,7 @@  executable fake-ghc-for-ghc-imported-from   main-is:          fake-ghc-for-ghc-imported-from.hs-  GHC-Options:      -Wall -O2+  GHC-Options:      -Wall   hs-source-dirs:   src   build-depends: base >=4.6 && <4.8                , process@@ -55,7 +56,7 @@  executable ghc-imported-from   main-is:             Main.hs-  GHC-Options:         -Wall -O2+  GHC-Options:         -Wall   other-modules:        Paths_ghc_imported_from   other-extensions:    CPP, Rank2Types   build-depends: base >=4.6 && <4.8@@ -72,6 +73,7 @@                , containers                , mtl                , transformers+               , parsec                , hspec    if impl(ghc < 7.7)@@ -84,7 +86,7 @@  Test-Suite spec   Default-Language:     Haskell2010-  GHC-Options:          -Wall -O2+  GHC-Options:          -Wall   Main-Is:              Spec.hs   Hs-Source-Dirs:       test, .   Type:                 exitcode-stdio-1.0@@ -103,6 +105,7 @@                       , containers                       , mtl                       , transformers+                      , parsec                       , hspec   if impl(ghc < 7.7)       Build-Depends:  Cabal >= 1.10 && < 1.17