module Darcs.Patch.Rebase.Name
( RebaseName(..)
, commuteNamePrim, commutePrimName
, commuteNameNamed, commuteNamedName
, canonizeNamePair
) where
import Prelude ()
import Darcs.Prelude
import Darcs.Patch.CommuteFn ( CommuteFn )
import Darcs.Patch.Effect ( Effect(..) )
import Darcs.Patch.Info ( PatchInfo, isInverted, showPatchInfo, readPatchInfo )
import Darcs.Patch.Inspect ( PatchInspect(..) )
import Darcs.Patch.Named ( Named(..) )
import Darcs.Patch.Apply ( Apply(..) )
import Darcs.Patch.Commute ( Commute(..) )
import Darcs.Patch.Invert ( Invert(..) )
import Darcs.Patch.Read ( ReadPatch(..) )
import Darcs.Patch.Show ( ShowPatch(..) )
import Darcs.Patch.Permutations ( inverseCommuter )
import Darcs.Patch.Prim ( PrimPatchBase(..) )
import Darcs.Patch.ReadMonads ( lexString )
import Darcs.Patch.Show ( ShowPatchBasic(..) )
import Darcs.Patch.Witnesses.Eq ( Eq2(..) )
import Darcs.Patch.Witnesses.Ordered ( (:>)(..), FL(..) )
import Darcs.Patch.Witnesses.Sealed ( Sealed(..) )
import Darcs.Patch.Witnesses.Show
( Show1(..), Show2(..)
, ShowDict(ShowDictClass)
)
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP )
import Darcs.Util.Printer ( empty, blueText, ($$) )
import Control.Applicative ( (<|>) )
import qualified Data.ByteString.Char8 as BC ( pack )
data RebaseName (p :: * -> * -> *) wX wY where
AddName :: PatchInfo -> RebaseName p wX wY
DelName :: PatchInfo -> RebaseName p wX wY
Rename :: PatchInfo -> PatchInfo -> RebaseName p wX wY
deriving Show
instance Show1 (RebaseName p wX) where
showDict1 = ShowDictClass
instance Show2 (RebaseName p) where
showDict2 = ShowDictClass
instance ShowPatchBasic (RebaseName p) where
showPatch f (AddName n) = blueText "addname" $$ showPatchInfo f n
showPatch f (DelName n) = blueText "delname" $$ showPatchInfo f n
showPatch f (Rename old new) = blueText "rename" $$ showPatchInfo f old $$ showPatchInfo f new
instance ShowPatch (RebaseName p) where
summary _ = empty
summaryFL _ = empty
instance ReadPatch (RebaseName p) where
readPatch' = readAddName <|> readDelName <|> readRename
where
readAddName = do lexString (BC.pack "addname")
n <- readPatchInfo
return (Sealed (AddName n))
readDelName = do lexString (BC.pack "delname")
n <- readPatchInfo
return (Sealed (DelName n))
readRename = do lexString (BC.pack "rename")
old <- readPatchInfo
new <- readPatchInfo
return (Sealed (Rename old new))
instance Commute (RebaseName p) where
commute (AddName n1 :> AddName n2)
| n1 == n2 = impossible
| otherwise = Just (AddName n2 :> AddName n1)
commute (DelName n1 :> DelName n2)
| n1 == n2 = impossible
| otherwise = Just (DelName n2 :> DelName n1)
commute (AddName n1 :> DelName n2)
| n1 /= n2 = Just (DelName n2 :> AddName n1)
| otherwise = Nothing
commute (DelName n1 :> AddName n2)
| n1 /= n2 = Just (AddName n2 :> DelName n1)
| otherwise = Nothing
commute (Rename old new :> AddName n)
| n == old = Nothing
| n == new = impossible
| otherwise = Just (AddName n :> Rename old new)
commute (AddName n :> Rename old new)
| n == old = Nothing
| n == new = impossible
| otherwise = Just (Rename old new :> AddName n)
commute (Rename old new :> DelName n)
| n == old = impossible
| n == new = Nothing
| otherwise = Just (DelName n :> Rename old new)
commute (DelName n :> Rename old new)
| n == old = impossible
| n == new = Nothing
| otherwise = Just (Rename old new :> DelName n)
commute (Rename old1 new1 :> Rename old2 new2)
| old1 == old2 = impossible
| new1 == new2 = impossible
| old1 == new2 = Nothing
| new1 == old2 = Nothing
| otherwise = Just (Rename old2 new2 :> Rename old1 new1)
instance Invert (RebaseName p) where
invert (AddName n) = DelName n
invert (DelName n) = AddName n
invert (Rename old new) = Rename new old
instance PatchInspect (RebaseName p) where
listTouchedFiles _ = []
hunkMatches _ _ = False
instance Apply (RebaseName p) where
type ApplyState (RebaseName p) = ApplyState p
apply _ = return ()
instance PrimPatchBase p => PrimPatchBase (RebaseName p) where
type PrimOf (RebaseName p) = PrimOf p
instance Effect (RebaseName p) where
effect _ = unsafeCoerceP NilFL
instance Eq2 (RebaseName p) where
AddName n1 `unsafeCompare` AddName n2 = n1 == n2
AddName _ `unsafeCompare` _ = False
_ `unsafeCompare` AddName _ = False
DelName n1 `unsafeCompare` DelName n2 = n1 == n2
DelName _ `unsafeCompare` _ = False
_ `unsafeCompare` DelName _ = False
Rename old1 new1 `unsafeCompare` Rename old2 new2 = old1 == old2 && new1 == new2
commuteNamePrim :: (RebaseName p :> PrimOf p) wX wY -> (PrimOf p :> RebaseName p) wX wY
commuteNamePrim (n :> f) = unsafeCoerceP f :> unsafeCoerceP n
commutePrimName :: (PrimOf p :> RebaseName p) wX wY -> (RebaseName p :> PrimOf p) wX wY
commutePrimName (f :> n) = unsafeCoerceP n :> unsafeCoerceP f
commuteNameNamed :: Invert p => CommuteFn (RebaseName p) (Named p)
commuteNameNamed pair@(_ :> NamedP pn _ _)
| isInverted pn = inverseCommuter commuteNamedName pair
commuteNameNamed (AddName an :> p@(NamedP pn deps _))
| an == pn = impossible
| an `elem` deps = Nothing
| otherwise = Just (unsafeCoerceP p :> AddName an)
commuteNameNamed (DelName dn :> p@(NamedP pn deps _))
| dn == pn = impossible
| dn `elem` deps = impossible
| otherwise = Just (unsafeCoerceP p :> DelName dn)
commuteNameNamed (Rename old new :> NamedP pn deps body)
| old == pn = impossible
| new == pn = impossible
| old `elem` deps = impossible
| otherwise =
let newdeps = map (\dep -> if new == dep then old else dep) deps
in Just (NamedP pn newdeps (unsafeCoerceP body) :> Rename old new)
commuteNamedName :: Invert p => CommuteFn (Named p) (RebaseName p)
commuteNamedName pair@(NamedP pn _ _ :> _)
| isInverted pn = inverseCommuter commuteNameNamed pair
commuteNamedName (p@(NamedP pn deps _) :> AddName an)
| an == pn = impossible
| an `elem` deps = impossible
| otherwise = Just (AddName an :> unsafeCoerceP p)
commuteNamedName (p@(NamedP pn deps _) :> DelName dn)
| dn == pn = Nothing
| dn `elem` deps = Nothing
| otherwise = Just (DelName dn :> unsafeCoerceP p)
commuteNamedName (NamedP pn deps body :> Rename old new)
| old == pn = Nothing
| new == pn = impossible
| new `elem` deps = impossible
| otherwise =
let newdeps = map (\dep -> if old == dep then new else dep) deps
in Just (Rename old new :> NamedP pn newdeps (unsafeCoerceP body))
canonizeNamePair :: (RebaseName p :> RebaseName p) wX wY -> FL (RebaseName p) wX wY
canonizeNamePair (AddName n :> Rename old new) | n == old = AddName new :>: NilFL
canonizeNamePair (Rename old new :> DelName n) | n == new = DelName old :>: NilFL
canonizeNamePair (Rename old1 new1 :> Rename old2 new2) | new1 == old2 = Rename old1 new2 :>: NilFL
canonizeNamePair (n1 :> n2) = n1 :>: n2 :>: NilFL