descript-lang-0.2.0.0: src/Descript/BasicInj/Process/Refactor/RenameModuleElem.hs
{-# 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