{-# LANGUAGE FlexibleInstances, TemplateHaskell #-} -- | Representation of modules, their collections, refactoring changes and exceptions. module Language.Haskell.Tools.Refactor.Representation where import Control.Exception import Control.Reference import Data.List import Data.List.Split import Data.Typeable import System.FilePath import Bag (bagToList) import ErrUtils as GHC import Outputable import Language.Haskell.Tools.AST as AST -- | A type for the input and result of refactoring a module type UnnamedModule = Ann AST.UModule IdDom SrcTemplateStage -- | The name of the module and the AST type ModuleDom = (SourceFileKey, UnnamedModule) -- | Module name and marker to separate .hs-boot module definitions. Specifies a source file in a working directory. data SourceFileKey = SourceFileKey { _sfkFileName :: FilePath , _sfkModuleName :: String } deriving (Eq, Ord, Show) -- | Change in the project, modification or removal of a module. data RefactorChange = ContentChanged { fromContentChanged :: ModuleDom } | ModuleRemoved { removedModuleName :: String } | ModuleCreated { createdModuleName :: String , createdModuleContent :: UnnamedModule , sameLocation :: SourceFileKey } instance Show RefactorChange where show (ContentChanged (n, _)) = "ContentChanged (" ++ show n ++ ")" show (ModuleRemoved n) = "ModuleRemoved " ++ n show (ModuleCreated n _ other) = "ModuleCreated " ++ n ++ " (" ++ show other ++ ")" -- | Exceptions that can occur while loading modules or during internal operations (not during performing the refactor). data RefactorException = IllegalExtensions [String] | SourceCodeProblem ErrorMessages | UnknownException String deriving (Show, Typeable) instance Show ErrorMessages where show = show . bagToList instance Exception RefactorException where displayException (SourceCodeProblem prob) = "Source code problem: " ++ showSDocUnsafe (vcat (pprErrMsgBagWithLoc prob)) displayException (IllegalExtensions exts) = "The following extensions are not allowed: " ++ (concat $ intersperse ", " exts) ++ "." displayException (UnknownException ex) = "An unexpected problem appeared: " ++ ex ++ "." -- | Transforms module name to a .hs file name relative to the source root directory. moduleSourceFile :: String -> FilePath moduleSourceFile m = (foldl1 () (splitOn "." m)) <.> "hs" -- | Transforms a source root relative file name into module name. sourceFileModule :: FilePath -> String sourceFileModule fp = intercalate "." $ splitDirectories $ dropExtension fp makeReferences ''SourceFileKey