{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ApplicativeDo #-} module Descript.BasicInj.Process.Refactor.RenameModuleElem ( renameModuleElem , renameModuleElem' ) where import Descript.BasicInj.Process.Refactor.GenRenameSymbol import qualified Descript.BasicInj.Traverse.Term as T import Descript.BasicInj.Traverse import Descript.BasicInj.Data import Descript.Misc import Data.Functor.Identity import Core.Data.List import qualified Data.List.NonEmpty as NonEmpty import Control.Monad.Trans.Writer.Strict data RenameModuleElem = RenameModuleElem [Symbol ()] (GenRenameSymbol Symbol) instance Traversal RenameModuleElem where type Eff RenameModuleElem = ResultT RefactorError (WriterT [RefactorWarning] Identity) type TAnn RenameModuleElem = SrcAnn tonTerm T.ModulePath (RenameModuleElem prevs rsym) x@(ModulePath ann es) = case splitPrefixBy (=@=) prevs $ NonEmpty.toList es of Nothing -> pure x Just (_, []) -> pure x Just (fes, (targ : res)) -> do targ' <- renameSymbol rsym targ pure $ ModulePath ann $ NonEmpty.fromList $ fes ++ targ' : res tonTerm _ _ x = pure x -- | Replaces every occurrence of the first import element immediately -- after the previous elements with the second. renameModuleElem :: [String] -> String -> String -> RefactorFunc Source renameModuleElem prevs old new = renameModuleElem' T.Source (map (Symbol ()) prevs) (Symbol () old) (Symbol () new) -- | Replaces every occurrence of the first import element immediately -- after the previous elements with the second. renameModuleElem' :: TTerm t -> [Symbol ()] -> Symbol () -> Symbol () -> RefactorFunc t renameModuleElem' term prevs old new = travTerm term $ RenameModuleElem prevs $ GenRenameSymbol old new