-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Clean up module imports, split and merge modules -- -- Clean up module imports, split and merge modules. @package module-management @version 0.13 module Language.Haskell.Modules.Util.Temp -- | Adapted from withTempDirectory to work in MonadCatchIO -- instances. withTempDirectory :: MonadCatchIO m => FilePath -> String -> (FilePath -> m a) -> m a module Language.Haskell.Modules.Util.DryIO class MonadIO m => MonadDryRun m dry :: MonadDryRun m => m Bool putDry :: MonadDryRun m => Bool -> m () dryIO :: MonadDryRun m => IO () -> m () dryIO' :: MonadDryRun m => IO a -> IO a -> m a tildeBackup :: FilePath -> Maybe FilePath noBackup :: FilePath -> Maybe FilePath readFileMaybe :: FilePath -> IO (Maybe String) -- | Replace the file at path with the given text, moving the original to -- the location returned by passing path to backup. If backup is the -- identity function you're going to have a bad time. replaceFile :: MonadDryRun m => (FilePath -> Maybe FilePath) -> FilePath -> String -> m () replaceFileIfDifferent :: MonadDryRun m => FilePath -> String -> m Bool removeFileIfPresent :: MonadDryRun m => FilePath -> m () createDirectoryIfMissing :: MonadDryRun m => Bool -> String -> m () writeFile :: MonadDryRun m => FilePath -> String -> m () module Language.Haskell.Modules.Util.SrcLoc class HasSpanInfo a spanInfo :: HasSpanInfo a => a -> SrcSpanInfo srcSpan :: HasSpanInfo x => x -> SrcSpan srcLoc :: HasSpanInfo x => x -> SrcLoc endLoc :: HasSpanInfo x => x -> SrcLoc textEndLoc :: FilePath -> String -> SrcLoc -- | Update a SrcLoc to move it from l past the string argument. increaseSrcLoc :: String -> SrcLoc -> SrcLoc textSpan :: FilePath -> String -> SrcSpanInfo -- | Given a beginning and end location, and a string which starts at the -- beginning location, return a (beforeend,afterend) pair. srcPairText :: SrcLoc -> SrcLoc -> String -> (String, String) -- | Build a tree of SrcSpanInfo makeTree :: (HasSpanInfo a, Show a, Eq a, Ord a) => Set a -> Tree a instance HasSpanInfo SrcSpanInfo instance HasSpanInfo Decl instance HasSpanInfo ImportDecl instance HasSpanInfo ExportSpec instance HasSpanInfo ExportSpecList instance HasSpanInfo WarningText instance HasSpanInfo ModulePragma instance HasSpanInfo ModuleName instance HasSpanInfo ModuleHead instance HasSpanInfo a => HasSpanInfo (Tree a) instance HasSpanInfo SrcSpan module Language.Haskell.Modules.Util.Symbols -- | Do a fold over the names that are declared in a declaration (not every -- name that appears, just the ones that the declaration is causing to -- exist - what's the word for that? Reify!) class FoldDeclared a foldDeclared :: FoldDeclared a => (Maybe Name -> r -> r) -> r -> a -> r -- | Fold over the declared members - e.g. the method names of a class -- declaration, the constructors of a data declaration. class FoldMembers a foldMembers :: FoldMembers a => (Maybe Name -> r -> r) -> r -> a -> r symbols :: FoldDeclared a => a -> Set (Maybe Name) exports :: (FoldDeclared a, FoldMembers a) => a -> [ExportSpec] imports :: (FoldDeclared a, FoldMembers a) => a -> [ImportSpec] tests :: Test instance FoldDeclared (GadtDecl l) instance FoldDeclared (FieldDecl l) instance FoldDeclared (ConDecl l) instance FoldDeclared (QualConDecl l) instance FoldMembers (Decl a) instance FoldDeclared (ExportSpec l) instance FoldDeclared (ImportSpec l) instance FoldDeclared (Name l) instance FoldDeclared (RPat a) instance FoldDeclared (PatField a) instance FoldDeclared (Pat a) instance FoldDeclared (QName a) instance FoldDeclared (Match a) instance FoldDeclared (InstHead a) instance FoldDeclared (ClassDecl a) instance FoldDeclared (DeclHead a) instance FoldDeclared (Decl a) module Language.Haskell.Modules.Util.Test repoModules :: [String] logicModules :: [String] diff :: FilePath -> FilePath -> IO (ExitCode, String, String) -- | Like diff, but ignores extra files in b. diff' :: FilePath -> FilePath -> IO (ExitCode, String, String) rsync :: FilePath -> FilePath -> IO () -- | Convenience function for building the moduVerse, searches for modules -- in a directory hierarchy. FIXME: This should be in MonadClean and use -- the value of sourceDirs to remove prefixes from the module paths. And -- then it should look at the module text to see what the module name -- really is. findHsModules :: [FilePath] -> IO [String] -- | Find the paths of all the files below the directory top. findHsFiles :: [FilePath] -> IO [FilePath] -- | IO operations predicated on the verbosity value managed by the methods -- of MonadVerbosity. Noisily increases this value and quietly decreases -- it, and the q* operations only happen when the value is greater than -- zero. module Language.Haskell.Modules.Util.QIO class MonadIO m => MonadVerbosity m getVerbosity :: MonadVerbosity m => m Int putVerbosity :: MonadVerbosity m => Int -> m () modifyVerbosity :: MonadVerbosity m => (Int -> Int) -> m () quietly :: MonadVerbosity m => m a -> m a noisily :: MonadVerbosity m => m a -> m a qIO :: MonadVerbosity m => m () -> m () qPutStr :: MonadVerbosity m => String -> m () qPutStrLn :: MonadVerbosity m => String -> m () qLnPutStr :: MonadVerbosity m => String -> m () module Language.Haskell.Modules.SourceDirs class MonadCatchIO m => SourceDirs m putDirs :: SourceDirs m => [FilePath] -> m () getDirs :: SourceDirs m => m [FilePath] modifyDirs :: SourceDirs m => ([FilePath] -> [FilePath]) -> m () -- | A FilePath that can be assumed to be unique. newtype PathKey PathKey :: FilePath -> PathKey unPathKey :: PathKey -> FilePath pathKey :: SourceDirs m => FilePath -> m PathKey pathKeyMaybe :: SourceDirs m => FilePath -> m (Maybe PathKey) -- | Search the path directory list, preferring an already existing file, -- but if there is none construct one using the first element of the -- directory list. modulePath :: SourceDirs m => String -> ModuleName -> m FilePath -- | Construct the base of a module path. modulePathBase :: String -> ModuleName -> FilePath instance Eq PathKey instance Ord PathKey instance Show PathKey module Language.Haskell.Modules.ModuVerse data ModuleInfo ModuleInfo :: Module SrcSpanInfo -> String -> [Comment] -> PathKey -> ModuleInfo module_ :: ModuleInfo -> Module SrcSpanInfo text_ :: ModuleInfo -> String comments_ :: ModuleInfo -> [Comment] key_ :: ModuleInfo -> PathKey moduleName :: ModuleInfo -> ModuleName data ModuVerseState moduVerseInit :: ModuVerseState class (MonadIO m, MonadCatchIO m, Functor m) => ModuVerse m getModuVerse :: ModuVerse m => m ModuVerseState modifyModuVerse :: ModuVerse m => (ModuVerseState -> ModuVerseState) -> m () getNames :: ModuVerse m => m (Set ModuleName) getInfo :: ModuVerse m => ModuleName -> m (Maybe ModuleInfo) putModule :: (ModuVerse m, MonadVerbosity m) => String -> m () putModuleAnew :: (ModuVerse m, MonadVerbosity m) => String -> m () findModule :: (ModuVerse m, MonadVerbosity m) => String -> m (Maybe ModuleInfo) delName :: ModuVerse m => ModuleName -> m () getExtensions :: ModuVerse m => m [Extension] modifyExtensions :: ModuVerse m => ([Extension] -> [Extension]) -> m () parseModule :: (ModuVerse m, MonadVerbosity m) => PathKey -> m ModuleInfo parseModuleMaybe :: (ModuVerse m, MonadVerbosity m) => Maybe PathKey -> m (Maybe ModuleInfo) -- | Force a possibly cached module to be reloaded. loadModule :: (ModuVerse m, MonadVerbosity m) => PathKey -> m ModuleInfo unloadModule :: (ModuVerse m, MonadVerbosity m) => PathKey -> m () instance Ord Comment instance Eq ModuleInfo instance Ord ModuleInfo instance Show ModuleInfo instance Eq ModuVerseState instance Ord ModuVerseState instance Show ModuVerseState instance ModuVerse m => SourceDirs m -- | foldModule is a utility function used to implement the clean, -- split, and merge operations. module Language.Haskell.Modules.Fold -- | Given the result of parseModuleWithComments and the original module -- text, this does a fold over the parsed module contents, calling the -- seven argument functions in order. Each function is passed the AST -- value, the text of the space and comments leading up to the element, -- and the text for the element. Note that not everything passed to the -- pre argument of the functions will be comments and space - for -- example, the module keyword will be passed in the pre argument -- to the ModuleName function. foldModule :: Show r => (String -> r -> r) -> (ModulePragma -> String -> String -> String -> r -> r) -> (ModuleName -> String -> String -> String -> r -> r) -> (WarningText -> String -> String -> String -> r -> r) -> (String -> r -> r) -> (ExportSpec -> String -> String -> String -> r -> r) -> (String -> r -> r) -> (ImportDecl -> String -> String -> String -> r -> r) -> (Decl -> String -> String -> String -> r -> r) -> (String -> r -> r) -> ModuleInfo -> r -> r -- | Do just the header portion of foldModule. foldHeader :: Show r => (String -> r -> r) -> (ModulePragma -> String -> String -> String -> r -> r) -> (ModuleName -> String -> String -> String -> r -> r) -> (WarningText -> String -> String -> String -> r -> r) -> ModuleInfo -> r -> r -- | Do just the exports portion of foldModule. foldExports :: Show r => (String -> r -> r) -> (ExportSpec -> String -> String -> String -> r -> r) -> (String -> r -> r) -> ModuleInfo -> r -> r -- | Do just the imports portion of foldModule. foldImports :: Show r => (ImportDecl -> String -> String -> String -> r -> r) -> ModuleInfo -> r -> r -- | Do just the declarations portion of foldModule. foldDecls :: Show r => (Decl -> String -> String -> String -> r -> r) -> (String -> r -> r) -> ModuleInfo -> r -> r -- | This can be passed to foldModule to include the original text in the -- result echo :: Monoid m => t -> m -> m -> m -> Seq m -> Seq m -- | Similar to echo, but used for the two argument separator -- functions echo2 :: Monoid m => m -> Seq m -> Seq m -- | This can be passed to foldModule to omit the original text from the -- result. ignore :: t -> m -> m -> m -> r -> r -- | Similar to ignore, but used for the two argument separator -- functions ignore2 :: m -> r -> r instance Show St instance Spans (WarningText SrcSpanInfo) instance Spans (ModuleName SrcSpanInfo) instance Spans (Decl SrcSpanInfo) instance Spans (ImportDecl SrcSpanInfo) instance Spans (ModulePragma SrcSpanInfo) instance Spans (ExportSpec SrcSpanInfo) instance Spans (ExportSpecList SrcSpanInfo) instance Spans (ModuleHead SrcSpanInfo) instance Spans (Module SrcSpanInfo) -- | Functions to control the state variables of MonadClean. module Language.Haskell.Modules.Params -- | If this flag is set, imports that become empty are removed. Sometimes -- this will lead to errors, specifically when an instance in the removed -- import that was required is no longer be available. (Note that this -- reflects a limitation of the -ddump-minimal-imports option of -- GHC.) If this happens this flag should be set. Note that an import -- that is already empty when cleanImports runs will never be -- removed, on the assumption that it was placed there only to import -- instances. Default is True. modifyRemoveEmptyImports :: MonadClean m => (Bool -> Bool) -> m () -- | Modify the list of extra flags passed to GHC. Default is []. modifyHsFlags :: MonadClean m => ([String] -> [String]) -> m () -- | Controls whether file updates will actually be performed. Default is -- False. (I recommend running in a directory controlled by a version -- control system so you don't have to worry about this.) modifyDryRun :: MonadClean m => (Bool -> Bool) -> m () -- | If TestMode is turned on no import cleaning will occur after a split -- or cat. Default is False. modifyTestMode :: MonadClean m => (Bool -> Bool) -> m () module Language.Haskell.Modules.Imports -- | Clean up the imports of a source file. cleanImports :: MonadClean m => [FilePath] -> m [ModuleResult] cleanResults :: MonadClean m => [ModuleResult] -> m [ModuleResult] module Language.Haskell.Modules.Merge -- | Merge the declarations from several modules into a single new one, -- updating the imports of the modules in the moduVerse to reflect the -- change. It *is* permissable to use one of the input modules as the -- output module. Note that circular imports can be created by this -- operation. mergeModules :: MonadClean m => [ModuleName] -> ModuleName -> m [ModuleResult] module Language.Haskell.Modules.Split -- | Split each of a module's declarations into a new module. Update the -- imports of all the modules in the moduVerse to reflect the split. For -- example, if you have a module like -- --
--   module Start (a, b, (.+.)) where
--   import
--   a = 1 + a
--   b = 2
--   c = 3
--   c' = 4
--   (.+.) = b + c
--   
-- -- After running splitModuleDecls Start.hs the -- Start module will be gone. The a and b -- symbols will be in new modules named Start.A and -- Start.B. Because they were not exported by Start, -- the c and c' symbols will both be in a new module -- named Start.Internal.C. And the .+. symbol will be -- in a module named Start.OtherSymbols. Note that this module -- needs to import new Start.A and Start.Internal.C -- modules. -- -- If we had imported and then re-exported a symbol in Start it would go -- into a module named Start.ReExported. Any instance -- declarations would go into Start.Instances. splitModule :: MonadClean m => (Maybe Name -> ModuleName) -> FilePath -> m [ModuleResult] -- | Do splitModuleBy with the default symbol to module mapping (was -- splitModule) splitModuleDecls :: MonadClean m => FilePath -> m [ModuleResult] -- | This can be used to build function parameter of splitModule, it -- determines which module should a symbol be moved to. defaultSymbolToModule :: ModuleInfo -> Maybe Name -> ModuleName instance Eq DeclClass instance Ord DeclClass instance Show DeclClass instance Default ImportDecl module Language.Haskell.Modules.Common -- | Combine sortBy and groupBy groupBy' :: Ord a => (a -> a -> Ordering) -> [a] -> [[a]] withCurrentDirectory :: MonadCatchIO m => FilePath -> m a -> m a -- | This package provides functions to clean import lists, to split up -- modules, and to merge modules. The important entry points are: -- -- There are several features worth noting. The Params type in -- the state of MonadClean has a removeEmptyImports -- field, which is True by default. This determines whether imports that -- turn into empty lists are preserved or not - if your program needs -- instances from a such an import, you will either want to set this flag -- to False or (better) add an empty import list to the import. -- -- These are the important entry points: -- -- -- -- Examples: -- -- -- --
--   findHsFiles ["Language", "Tests.hs", "Tests"] >>= runCleanT . cleanImports
--   
-- -- -- --
--   :m +Language.Haskell.Exts.Syntax
--       findHsModules ["Language", "Tests.hs", "Tests"] >>= \ modules -> runCleanT $
--         mapM putModule modules >>
--         splitModuleDecls "Language/Haskell/Modules/Common.hs" >>
--         mergeModules [ModuleName "Language.Haskell.Modules.Common.WithCurrentDirectory",
--                       ModuleName "Language.Haskell.Modules.Common.Internal.ToEq"]
--                      (ModuleName "Language.Haskell.Modules.Common")
--   
-- -- -- --
--   findHsModules ["Language", "Tests.hs", "Tests"] >>= \ modules -> runCleanT $
--         mapM putModule modules >>
--         splitModule (\ n -> if elem n [Just (Ident "ModuleResult"), Just (Ident "doResult")]
--                             then ModuleName "Tmp"
--                             else ModuleName "Language.Haskell.Modules.Internal")
--                     (ModuleName "Language/Haskell/Modules/Internal.hs") >>
--         mergeModules [ModuleName "Language.Haskell.Modules.Common", ModuleName "Tmp"]
--                      (ModuleName "Language.Haskell.Modules.Common")
--   
module Language.Haskell.Modules -- | Clean up the imports of a source file. cleanImports :: MonadClean m => [FilePath] -> m [ModuleResult] -- | Split each of a module's declarations into a new module. Update the -- imports of all the modules in the moduVerse to reflect the split. For -- example, if you have a module like -- --
--   module Start (a, b, (.+.)) where
--   import
--   a = 1 + a
--   b = 2
--   c = 3
--   c' = 4
--   (.+.) = b + c
--   
-- -- After running splitModuleDecls Start.hs the -- Start module will be gone. The a and b -- symbols will be in new modules named Start.A and -- Start.B. Because they were not exported by Start, -- the c and c' symbols will both be in a new module -- named Start.Internal.C. And the .+. symbol will be -- in a module named Start.OtherSymbols. Note that this module -- needs to import new Start.A and Start.Internal.C -- modules. -- -- If we had imported and then re-exported a symbol in Start it would go -- into a module named Start.ReExported. Any instance -- declarations would go into Start.Instances. splitModule :: MonadClean m => (Maybe Name -> ModuleName) -> FilePath -> m [ModuleResult] -- | Do splitModuleBy with the default symbol to module mapping (was -- splitModule) splitModuleDecls :: MonadClean m => FilePath -> m [ModuleResult] -- | This can be used to build function parameter of splitModule, it -- determines which module should a symbol be moved to. defaultSymbolToModule :: ModuleInfo -> Maybe Name -> ModuleName -- | Merge the declarations from several modules into a single new one, -- updating the imports of the modules in the moduVerse to reflect the -- change. It *is* permissable to use one of the input modules as the -- output module. Note that circular imports can be created by this -- operation. mergeModules :: MonadClean m => [ModuleName] -> ModuleName -> m [ModuleResult] class (MonadIO m, MonadCatchIO m, Functor m) => MonadClean m -- | An instance of MonadClean. type CleanT m = StateT Params m -- | Create the environment required to do import cleaning and module -- splitting/merging. This environment, StateT Params m a, is an instance -- of MonadClean. runCleanT :: MonadCatchIO m => CleanT m a -> m a putModule :: (ModuVerse m, MonadVerbosity m) => String -> m () findModule :: (ModuVerse m, MonadVerbosity m) => String -> m (Maybe ModuleInfo) -- | Controls whether file updates will actually be performed. Default is -- False. (I recommend running in a directory controlled by a version -- control system so you don't have to worry about this.) modifyDryRun :: MonadClean m => (Bool -> Bool) -> m () -- | Modify the list of extra flags passed to GHC. Default is []. modifyHsFlags :: MonadClean m => ([String] -> [String]) -> m () -- | If this flag is set, imports that become empty are removed. Sometimes -- this will lead to errors, specifically when an instance in the removed -- import that was required is no longer be available. (Note that this -- reflects a limitation of the -ddump-minimal-imports option of -- GHC.) If this happens this flag should be set. Note that an import -- that is already empty when cleanImports runs will never be -- removed, on the assumption that it was placed there only to import -- instances. Default is True. modifyRemoveEmptyImports :: MonadClean m => (Bool -> Bool) -> m () modifyExtensions :: ModuVerse m => ([Extension] -> [Extension]) -> m () -- | If TestMode is turned on no import cleaning will occur after a split -- or cat. Default is False. modifyTestMode :: MonadClean m => (Bool -> Bool) -> m () modifyDirs :: SourceDirs m => ([FilePath] -> [FilePath]) -> m () putDirs :: SourceDirs m => [FilePath] -> m () noisily :: MonadVerbosity m => m a -> m a quietly :: MonadVerbosity m => m a -> m a -- | Construct the base of a module path. modulePathBase :: String -> ModuleName -> FilePath -- | Convenience function for building the moduVerse, searches for modules -- in a directory hierarchy. FIXME: This should be in MonadClean and use -- the value of sourceDirs to remove prefixes from the module paths. And -- then it should look at the module text to see what the module name -- really is. findHsModules :: [FilePath] -> IO [String] -- | Find the paths of all the files below the directory top. findHsFiles :: [FilePath] -> IO [FilePath] withCurrentDirectory :: MonadCatchIO m => FilePath -> m a -> m a