-- Copyright (C) 2003-2004 David Roundy
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING.  If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-- Boston, MA 02110-1301, USA.

{- | Definitions used in this module:

[Explicit dependencies]: The set of patches that a (named) patch depends on
  "by name", i.e. irrespective of (non-)commutation (non commuting patches are
  implicit dependencies). The most important example are tags, but non-tag
  patches can also have explicit dependencies by recording them with
  --ask-deps.

[Covered]: A patch @p@ is covered by a tag @t@ if @t@ explicitly depends on
  @p@ or a tag covered by @t@ explicitly depends on @p@. In other words, the
  transitive closure of the relation "is depended on", restricted to
  situations where the right hand side is a tag. Note that it does /not/ take
  explicit dependencies of non-tag patches into account at all.

[Clean]: A tag @t@ in a repository is clean if all patches prior to the tag are
  covered by @t@. Tags normally start out as clean tags (the exception is
  if --ask-deps is used). It typically becomes unclean when it is merged into
  another repo (here the exceptions are if --reorder-patches is used, or if
  the target repo is actually a subset of the source repo).
-}

module Darcs.Patch.Depends
    ( getUncovered
    , areUnrelatedRepos
    , findCommonAndUncommon
    , mergeThem
    , findCommonWithThem
    , countUsThem
    , removeFromPatchSet
    , slightlyOptimizePatchset
    , splitOnTag
    , patchSetUnion
    , patchSetIntersection
    , findUncommon
    , cleanLatestTag
    , contextPatches
    ) where

import Darcs.Prelude

import Data.List ( delete, intersect, (\\) )
import Data.Maybe ( fromMaybe )

import Darcs.Patch.Named ( getdeps )
import Darcs.Patch.Commute ( Commute )
import Darcs.Patch.Ident ( fastRemoveSubsequenceRL, merge2FL )
import Darcs.Patch.Info ( PatchInfo, isTag, displayPatchInfo )
import Darcs.Patch.Merge ( Merge )
import Darcs.Patch.Permutations ( partitionFL, partitionRL )
import Darcs.Patch.PatchInfoAnd( PatchInfoAnd, hopefully, hopefullyM, info )
import Darcs.Patch.Set
    ( PatchSet(..)
    , Tagged(..)
    , SealedPatchSet
    , patchSet2RL
    , appendPSFL
    , patchSetSplit
    , Origin
    )
import Darcs.Patch.Progress ( progressRL )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP, unsafeCoercePStart )
import Darcs.Patch.Witnesses.Eq ( Eq2 )
import Darcs.Patch.Witnesses.Ordered
    ( (:\/:)(..), (:/\:)(..), (:>)(..), Fork(..),
    (+<<+), mapFL, RL(..), FL(..), isShorterThanRL, breakRL,
    (+<+), reverseFL, reverseRL, mapRL )
import Darcs.Patch.Witnesses.Sealed
    ( Sealed(..), seal )

import Darcs.Util.Printer ( renderString, vcat )

{-|
Find clean tags that are common to both argument 'PatchSet's and return a
'Fork' with the common clean tags and whatever remains of the 'PatchSet's.
The two "uncommon" sequences may still have patches in common, even clean
tags, since we look only at the "known clean" tags of the second argument,
i.e. those that are the head of a 'Tagged' section.

This is a pretty efficient function, because it makes use of the
already-broken-up nature of 'PatchSet's.

Note that the first argument should be the repository that is more cheaply
accessed (i.e. local), as 'taggedIntersection' does its best to reduce the
number of inventories that are accessed from its second argument.
-}
taggedIntersection :: forall rt p wX wY . Commute p
                   => PatchSet rt p Origin wX -> PatchSet rt p Origin wY ->
                      Fork (RL (Tagged rt p))
                           (RL (PatchInfoAnd rt p))
                           (RL (PatchInfoAnd rt p)) Origin wX wY
taggedIntersection :: PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps1) PatchSet rt p Origin wY
s2 = RL (Tagged rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wX
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps1 (PatchSet rt p Origin wY -> RL (PatchInfoAnd rt p) Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wY
s2)
taggedIntersection PatchSet rt p Origin wX
s1 (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wY
ps2) = RL (Tagged rt p) Origin Origin
-> RL (PatchInfoAnd rt p) Origin wX
-> RL (PatchInfoAnd rt p) Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (PatchSet rt p Origin wX -> RL (PatchInfoAnd rt p) Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wX
s1) RL (PatchInfoAnd rt p) wX wY
RL (PatchInfoAnd rt p) Origin wY
ps2
taggedIntersection PatchSet rt p Origin wX
s1 (PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
t2 Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wY
ps2)
    -- If t2 is the head of any of the Tagged sections of s1,
    -- unwrap everything in s1 after t2 and be done with it.
    | Just (PatchSet RL (Tagged rt p) Origin wX
ts1 RL (PatchInfoAnd rt p) wX wX
ps1) <- PatchInfo
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag (PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t2) PatchSet rt p Origin wX
s1 =
        RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin wX
ts1 RL (PatchInfoAnd rt p) wX wX
ps1 (RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
taggedIntersection PatchSet rt p Origin wX
s1 s2 :: PatchSet rt p Origin wY
s2@(PatchSet (RL (Tagged rt p) Origin wY
ts2 :<: Tagged PatchInfoAnd rt p wY wX
t2 Maybe String
_ RL (PatchInfoAnd rt p) wY wY
t2ps) RL (PatchInfoAnd rt p) wX wY
ps2) =
    -- Same case as before but now we know that t2 is not the head of any
    -- Tagged section of s1. If t2 has already been fully retrieved, then
    -- we know that the next Tagged section of s2 is available without
    -- opening another remote inventory; in this case we recurse i.e.
    -- we unwrap t2 and its patches and continue with the next Tagged of s2.
    -- Otherwise we try to make t2 clean in s1 by looking at s1's trailing
    -- patch list, too.
    -- Question by bf: Wouldn't it be better to call splitOnTag /before/ we
    -- test if t2 has already been opened? If it succeeds, then we'd get
    -- more common Tagged sections and still don't have to open a remote
    -- inventory.
    case PatchInfoAnd rt p wY wX -> Maybe (Named p wY wX)
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> Maybe (p wA wB)
hopefullyM PatchInfoAnd rt p wY wX
t2 of
        Just Named p wY wX
_ ->
            PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
s1 (RL (Tagged rt p) Origin wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts2 (RL (PatchInfoAnd rt p) wY wY
t2ps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t2 RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps2))
        Maybe (Named p wY wX)
Nothing ->
            case PatchInfo
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag (PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t2) PatchSet rt p Origin wX
s1 of
                Just (PatchSet RL (Tagged rt p) Origin wX
com RL (PatchInfoAnd rt p) wX wX
us) ->
                      RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin wX
com RL (PatchInfoAnd rt p) wX wX
us (RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
                Maybe (PatchSet rt p Origin wX)
Nothing -> RL (Tagged rt p) Origin Origin
-> RL (PatchInfoAnd rt p) Origin wX
-> RL (PatchInfoAnd rt p) Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (PatchSet rt p Origin wX -> RL (PatchInfoAnd rt p) Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wX
s1) (PatchSet rt p Origin wY -> RL (PatchInfoAnd rt p) Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wY
s2)

-- |'maybeSplitSetOnTag' takes a tag's 'PatchInfo', @t0@, and a 'PatchSet' and
-- attempts to find @t0@ in one of the 'Tagged's in the PatchSet. If the tag is
-- found, the 'PatchSet' is split up, on that tag, such that all later patches
-- are in the "since last tag" patch list. If the tag is not found, 'Nothing'
-- is returned.
-- This is a simpler version of 'splitOnTag' that only looks at the heads
-- of 'Tagged' sections and does not commute any patches.
maybeSplitSetOnTag :: PatchInfo -> PatchSet rt p wStart wX
                   -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag :: PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag PatchInfo
t0 origSet :: PatchSet rt p wStart wX
origSet@(PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
pst) RL (PatchInfoAnd rt p) wX wX
ps)
    | PatchInfo
t0 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t = PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall a. a -> Maybe a
Just PatchSet rt p wStart wX
origSet
    | Bool
otherwise = do
        PatchSet RL (Tagged rt p) Origin wX
ts' RL (PatchInfoAnd rt p) wX wX
ps' <- PatchInfo
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag PatchInfo
t0 (RL (Tagged rt p) Origin wY
-> RL (PatchInfoAnd rt p) wY wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
pst RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t))
        PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a. a -> Maybe a
Just (PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX))
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts' (RL (PatchInfoAnd rt p) wX wX
ps' RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps)
maybeSplitSetOnTag PatchInfo
_ PatchSet rt p wStart wX
_ = Maybe (PatchSet rt p wStart wX)
forall a. Maybe a
Nothing

-- | Take a tag's 'PatchInfo', and a 'PatchSet', and attempt to find the tag in
-- the 'PatchSet'. If found, return a new 'PatchSet', in which the tag is now
-- clean (and the last of the 'Tagged' list), while all patches that are not
-- covered by the tag are in the trailing list of patches.
-- If the tag is not in the 'PatchSet', we return 'Nothing'.
splitOnTag :: Commute p => PatchInfo -> PatchSet rt p wStart wX
           -> Maybe (PatchSet rt p wStart wX)
-- If the tag we are looking for is the first Tagged tag of the patchset, just
-- separate out the patchset's patches.
splitOnTag :: PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t s :: PatchSet rt p wStart wX
s@(PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
hp Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wX
_) | PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t = PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall a. a -> Maybe a
Just PatchSet rt p wStart wX
s
-- If the tag is the most recent patch in the set, we check if the patch is the
-- only non-depended-on patch in the set (i.e. it is a clean tag); creating a
-- new Tagged out of the patches and tag, and adding it to the patchset, if
-- this is the case. Otherwise, we try to make the tag clean.
splitOnTag PatchInfo
t patchset :: PatchSet rt p wStart wX
patchset@(PatchSet RL (Tagged rt p) Origin wX
ts hps :: RL (PatchInfoAnd rt p) wX wX
hps@(RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wX
hp)) | PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t =
    if PatchSet rt p wStart wX -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
        -- If t is the only patch not covered by any tag...
        then PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a. a -> Maybe a
Just (PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX))
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts RL (Tagged rt p) Origin wX
-> Tagged rt p wX wX -> RL (Tagged rt p) Origin wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wX
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wX
hp Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
        else case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> RL (PatchInfoAnd rt p) wX wX
-> (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wX wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL ((PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (PatchInfo
t PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: Named p wY wX -> [PatchInfo]
forall (p :: * -> * -> *) wX wY.
HasDeps p =>
p wX wY -> [PatchInfo]
getdeps (PatchInfoAnd rt p wY wX -> Named p wY wX
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> p wA wB
hopefully PatchInfoAnd rt p wY wX
hp))) (PatchInfo -> Bool)
-> (PatchInfoAndG rt (Named p) wU wV -> PatchInfo)
-> PatchInfoAndG rt (Named p) wU wV
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) RL (PatchInfoAnd rt p) wX wX
hps of
            -- Partition hps by those that are the tag and its explicit deps.
            tagAndDeps :: RL (PatchInfoAnd rt p) wX wZ
tagAndDeps@(RL (PatchInfoAnd rt p) wX wY
ds' :<: PatchInfoAnd rt p wY wZ
hp') :> RL (PatchInfoAnd rt p) wZ wX
nonDeps ->
                -- If @ds@ doesn't contain the tag of the first Tagged, that
                -- tag will also be returned by the call to getUncovered - so
                -- we need to unwrap the next Tagged in order to expose it to
                -- being partitioned out in the recursive call to splitOnTag.
                if PatchSet rt p Origin wZ -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps) [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
                    then let tagged :: Tagged rt p wX wZ
tagged = PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wZ
hp' Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ds' in
                         PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (m :: * -> *) a. Monad m => a -> m a
return (PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX))
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wZ
-> RL (PatchInfoAnd rt p) wZ wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts RL (Tagged rt p) Origin wX
-> Tagged rt p wX wZ -> RL (Tagged rt p) Origin wZ
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: Tagged rt p wX wZ
tagged) RL (PatchInfoAnd rt p) wZ wX
nonDeps
                    else do
                        PatchSet rt p Origin wZ
unfolded <- PatchSet rt p Origin wZ -> Maybe (PatchSet rt p Origin wZ)
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged (PatchSet rt p Origin wZ -> Maybe (PatchSet rt p Origin wZ))
-> PatchSet rt p Origin wZ -> Maybe (PatchSet rt p Origin wZ)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps
                        PatchSet RL (Tagged rt p) Origin wX
xx RL (PatchInfoAnd rt p) wX wZ
yy <- PatchInfo
-> PatchSet rt p Origin wZ -> Maybe (PatchSet rt p Origin wZ)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t PatchSet rt p Origin wZ
unfolded
                        PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (m :: * -> *) a. Monad m => a -> m a
return (PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX))
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
xx (RL (PatchInfoAnd rt p) wX wZ
yy RL (PatchInfoAnd rt p) wX wZ
-> RL (PatchInfoAnd rt p) wZ wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wZ wX
nonDeps)
            (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wX wX
_ -> String -> Maybe (PatchSet rt p wStart wX)
forall a. HasCallStack => String -> a
error String
"impossible case"
-- We drop the leading patch, to try and find a non-Tagged tag.
splitOnTag PatchInfo
t (PatchSet RL (Tagged rt p) Origin wX
ts (RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wX
p)) = do
    PatchSet RL (Tagged rt p) Origin wX
ns RL (PatchInfoAnd rt p) wX wY
xs <- PatchInfo
-> PatchSet rt p Origin wY -> Maybe (PatchSet rt p Origin wY)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps)
    PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (m :: * -> *) a. Monad m => a -> m a
return (PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX))
-> PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ns (RL (PatchInfoAnd rt p) wX wY
xs RL (PatchInfoAnd rt p) wX wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
p)
-- If there are no patches left, we "unfold" the next Tagged, and try again.
splitOnTag PatchInfo
t0 patchset :: PatchSet rt p wStart wX
patchset@(PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
_ Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_s) RL (PatchInfoAnd rt p) wX wX
NilRL) =
    PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged PatchSet rt p wStart wX
patchset Maybe (PatchSet rt p wStart wX)
-> (PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX))
-> Maybe (PatchSet rt p wStart wX)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t0
-- If we've checked all the patches, but haven't found the tag, return Nothing.
splitOnTag PatchInfo
_ (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
NilRL) = Maybe (PatchSet rt p wStart wX)
forall a. Maybe a
Nothing

-- | Reorder a 'PatchSet' such that the latest tag becomes clean.
cleanLatestTag :: Commute p
               => PatchSet rt p wStart wX
               -> PatchSet rt p wStart wX
cleanLatestTag :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
cleanLatestTag inp :: PatchSet rt p wStart wX
inp@(PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wX
ps) =
  case (forall wA wB. PatchInfoAnd rt p wA wB -> Bool)
-> RL (PatchInfoAnd rt p) wX wX
-> (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wX wX
forall (p :: * -> * -> *) wX wY.
(forall wA wB. p wA wB -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
breakRL (PatchInfo -> Bool
isTag (PatchInfo -> Bool)
-> (PatchInfoAndG rt (Named p) wA wB -> PatchInfo)
-> PatchInfoAndG rt (Named p) wA wB
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wA wB -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) RL (PatchInfoAnd rt p) wX wX
ps of
    RL (PatchInfoAnd rt p) wX wZ
NilRL :> RL (PatchInfoAnd rt p) wZ wX
_ -> PatchSet rt p wStart wX
inp -- no tag among the ps -> we are done
    (left :: RL (PatchInfoAnd rt p) wX wZ
left@(RL (PatchInfoAnd rt p) wX wY
_ :<: PatchInfoAnd rt p wY wZ
t) :> RL (PatchInfoAnd rt p) wZ wX
right) ->
      case PatchInfo
-> PatchSet rt p Origin wZ -> Maybe (PatchSet rt p Origin wZ)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag (PatchInfoAnd rt p wY wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wZ
t) (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
left) of
        Just (PatchSet RL (Tagged rt p) Origin wX
ts' RL (PatchInfoAnd rt p) wX wZ
ps') -> RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts' (RL (PatchInfoAnd rt p) wX wZ
ps' RL (PatchInfoAnd rt p) wX wZ
-> RL (PatchInfoAnd rt p) wZ wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wZ wX
right)
        Maybe (PatchSet rt p Origin wZ)
_ -> String -> PatchSet rt p wStart wX
forall a. HasCallStack => String -> a
error String
"impossible case" -- because t is in left

-- |'unwrapOneTagged' unfolds a single Tagged object in a PatchSet, adding the
-- tag and patches to the PatchSet's patch list.
unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged (PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
tps) RL (PatchInfoAnd rt p) wX wY
ps) =
    PatchSet rt p Origin wY -> Maybe (PatchSet rt p Origin wY)
forall a. a -> Maybe a
Just (PatchSet rt p Origin wY -> Maybe (PatchSet rt p Origin wY))
-> PatchSet rt p Origin wY -> Maybe (PatchSet rt p Origin wY)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
tps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps)
unwrapOneTagged PatchSet rt p wX wY
_ = Maybe (PatchSet rt p wX wY)
forall a. Maybe a
Nothing

-- | Return the 'PatchInfo' for all the patches in a 'PatchSet'
-- that are not depended on by any tag (in the given 'PatchSet').
--
-- This is exactly the set of patches that a new tag recorded on top
-- of the 'PatchSet' would explicitly depend on.
getUncovered :: PatchSet rt p wStart wX -> [PatchInfo]
getUncovered :: PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset = case PatchSet rt p wStart wX
patchset of
    (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps) -> [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ((forall wW wZ.
 PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo]))
-> RL (PatchInfoAnd rt p) wX wX -> [(PatchInfo, Maybe [PatchInfo])]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ.
PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo])
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps RL (PatchInfoAnd rt p) wX wX
ps)
    (PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wX
ps) ->
        [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ((forall wW wZ.
 PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo]))
-> RL (PatchInfoAnd rt p) wY wX -> [(PatchInfo, Maybe [PatchInfo])]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ.
PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo])
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps (RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps))
  where
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [] = []
    findUncovered ((PatchInfo
pi, Maybe [PatchInfo]
Nothing) : [(PatchInfo, Maybe [PatchInfo])]
rest) = PatchInfo
pi PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [(PatchInfo, Maybe [PatchInfo])]
rest
    findUncovered ((PatchInfo
pi, Just [PatchInfo]
deps) : [(PatchInfo, Maybe [PatchInfo])]
rest) =
        PatchInfo
pi PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ([PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
deps [(PatchInfo, Maybe [PatchInfo])]
rest)

    -- |dropDepsIn traverses the list of patches, dropping any patches that
    -- occur in the dependency list; when a patch is dropped, its dependencies
    -- are added to the dependency list used for later patches.
    dropDepsIn :: [PatchInfo] -> [(PatchInfo, Maybe [PatchInfo])]
               -> [(PatchInfo, Maybe [PatchInfo])]
    dropDepsIn :: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [] [(PatchInfo, Maybe [PatchInfo])]
pps = [(PatchInfo, Maybe [PatchInfo])]
pps
    dropDepsIn [PatchInfo]
_  []  = []
    dropDepsIn [PatchInfo]
ds ((PatchInfo, Maybe [PatchInfo])
hp : [(PatchInfo, Maybe [PatchInfo])]
pps)
        | (PatchInfo, Maybe [PatchInfo]) -> PatchInfo
forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
ds =
            let extraDeps :: [PatchInfo]
extraDeps = [PatchInfo] -> Maybe [PatchInfo] -> [PatchInfo]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [PatchInfo] -> [PatchInfo])
-> Maybe [PatchInfo] -> [PatchInfo]
forall a b. (a -> b) -> a -> b
$ (PatchInfo, Maybe [PatchInfo]) -> Maybe [PatchInfo]
forall a b. (a, b) -> b
snd (PatchInfo, Maybe [PatchInfo])
hp in
            [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn ([PatchInfo]
extraDeps [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. [a] -> [a] -> [a]
++ PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => a -> [a] -> [a]
delete ((PatchInfo, Maybe [PatchInfo]) -> PatchInfo
forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp) [PatchInfo]
ds) [(PatchInfo, Maybe [PatchInfo])]
pps
        | Bool
otherwise = (PatchInfo, Maybe [PatchInfo])
hp (PatchInfo, Maybe [PatchInfo])
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
forall a. a -> [a] -> [a]
: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
ds [(PatchInfo, Maybe [PatchInfo])]
pps

    -- |infoAndExplicitDeps returns the patch info and (for tags only) the list
    -- of explicit dependencies of a patch.
    infoAndExplicitDeps :: PatchInfoAnd rt p wX wY
                        -> (PatchInfo, Maybe [PatchInfo])
    infoAndExplicitDeps :: PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps PatchInfoAnd rt p wX wY
p
        | PatchInfo -> Bool
isTag (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p) = (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, Named p wX wY -> [PatchInfo]
forall (p :: * -> * -> *) wX wY.
HasDeps p =>
p wX wY -> [PatchInfo]
getdeps (Named p wX wY -> [PatchInfo])
-> Maybe (Named p wX wY) -> Maybe [PatchInfo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` PatchInfoAnd rt p wX wY -> Maybe (Named p wX wY)
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> Maybe (p wA wB)
hopefullyM PatchInfoAnd rt p wX wY
p)
        | Bool
otherwise = (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, Maybe [PatchInfo]
forall a. Maybe a
Nothing)

-- | Create a new 'Tagged' section for the most recent clean tag found in the
-- tail of un-'Tagged' patches without re-ordering patches. Note that earlier
-- tags may remain un-'Tagged' even if they are actually clean.
slightlyOptimizePatchset :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset (PatchSet RL (Tagged rt p) Origin wX
ts0 RL (PatchInfoAnd rt p) wX wX
ps0) =
    PatchSet rt p Origin wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
go (PatchSet rt p Origin wX -> PatchSet rt p Origin wX)
-> PatchSet rt p Origin wX -> PatchSet rt p Origin wX
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts0 (String
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY. String -> RL a wX wY -> RL a wX wY
progressRL String
"Optimizing inventory" RL (PatchInfoAnd rt p) wX wX
ps0)
  where
    go :: PatchSet rt p wStart wY -> PatchSet rt p wStart wY
    go :: PatchSet rt p wStart wY -> PatchSet rt p wStart wY
go (PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
NilRL) = RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
    go s :: PatchSet rt p wStart wY
s@(PatchSet RL (Tagged rt p) Origin wX
ts (RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wY
hp))
        | PatchInfo -> Bool
isTag (PatchInfoAnd rt p wY wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp)
        , [PatchInfoAnd rt p wY wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp] [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== PatchSet rt p wStart wY -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wY
s =
            RL (Tagged rt p) Origin wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts RL (Tagged rt p) Origin wX
-> Tagged rt p wX wY -> RL (Tagged rt p) Origin wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wY
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wY
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wY
hp Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
        | Bool
otherwise = PatchSet rt p Origin wY
-> FL (PatchInfoAnd rt p) wY wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
PatchSet rt p wStart wX
-> FL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
appendPSFL (PatchSet rt p Origin wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
go (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps)) (PatchInfoAnd rt p wY wY
hp PatchInfoAnd rt p wY wY
-> FL (PatchInfoAnd rt p) wY wY -> FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)

removeFromPatchSet :: (Commute p, Eq2 p) => FL (PatchInfoAnd rt p) wX wY
                   -> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet :: FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps) | (PatchInfo -> Bool) -> [PatchInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
ps) ((forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> FL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info FL (PatchInfoAnd rt p) wX wY
bad) = do
    RL (PatchInfoAnd rt p) wX wX
ps' <- RL (PatchInfoAnd rt p) wX wY
-> RL (PatchInfoAnd rt p) wX wY
-> Maybe (RL (PatchInfoAnd rt p) wX wX)
forall (p :: * -> * -> *) wY wZ wX.
(Commute p, Ident p) =>
RL p wY wZ -> RL p wX wZ -> Maybe (RL p wX wY)
fastRemoveSubsequenceRL (FL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wX wY
bad) RL (PatchInfoAnd rt p) wX wY
ps
    PatchSet rt p Origin wX -> Maybe (PatchSet rt p Origin wX)
forall (m :: * -> *) a. Monad m => a -> m a
return (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wX
ps')
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
_ (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wY
_) = Maybe (PatchSet rt p wStart wX)
forall a. Maybe a
Nothing
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
tps) RL (PatchInfoAnd rt p) wX wY
ps) =
    FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p Origin wY -> Maybe (PatchSet rt p Origin wX)
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wStart.
(Commute p, Eq2 p) =>
FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (RL (Tagged rt p) Origin wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p Origin wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
tps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps))

findCommonAndUncommon :: forall rt p wX wY . Commute p
                      => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
                      -> Fork (PatchSet rt p)
                              (FL (PatchInfoAnd rt p))
                              (FL (PatchInfoAnd rt p)) Origin wX wY
findCommonAndUncommon :: PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
findCommonAndUncommon PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them = case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
    Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
        case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (RL (PatchInfoAnd rt p) wU wY
-> PatchInfoAndG rt (Named p) wU wV -> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wY (rt :: RepoType)
       (p :: * -> * -> *) wA wB.
RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wY
them') (FL (PatchInfoAnd rt p) wU wX
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wX)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wX
_ ->
                String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall a. HasCallStack => String -> a
error (String
 -> Fork
      (PatchSet rt p)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p))
      Origin
      wX
      wY)
-> String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAndG rt (Named p) wW wZ -> PatchInfo)
-> PatchInfoAndG rt (Named p) wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            (FL (PatchInfoAnd rt p) wU wZ
common2 :> FL (PatchInfoAnd rt p) wZ wZ
NilFL :> FL (PatchInfoAnd rt p) wZ wX
only_ours) ->
                case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wY
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wY
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (RL (PatchInfoAnd rt p) wU wX
-> PatchInfoAndG rt (Named p) wU wV -> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wY (rt :: RepoType)
       (p :: * -> * -> *) wA wB.
RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wX
us') (FL (PatchInfoAnd rt p) wU wY
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wY)
-> FL (PatchInfoAnd rt p) wU wY
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wY
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wY -> FL (PatchInfoAnd rt p) wU wY
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them' of
                    FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wY
_ ->
                        String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall a. HasCallStack => String -> a
error (String
 -> Fork
      (PatchSet rt p)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p))
      Origin
      wX
      wY)
-> String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                            String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
                                (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAndG rt (Named p) wW wZ -> PatchInfo)
-> PatchInfoAndG rt (Named p) wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
                    FL (PatchInfoAnd rt p) wU wZ
_ :> FL (PatchInfoAnd rt p) wZ wZ
NilFL :> FL (PatchInfoAnd rt p) wZ wY
only_theirs ->
                        PatchSet rt p Origin wZ
-> FL (PatchInfoAnd rt p) wZ wX
-> FL (PatchInfoAnd rt p) wZ wY
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork (RL (Tagged rt p) Origin wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common (FL (PatchInfoAnd rt p) wU wZ -> RL (PatchInfoAnd rt p) wU wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2))
                            FL (PatchInfoAnd rt p) wZ wX
FL (PatchInfoAnd rt p) wZ wX
only_ours (FL (PatchInfoAnd rt p) wZ wY -> FL (PatchInfoAnd rt p) wZ wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wY
only_theirs)
  where
    infoIn :: RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAndG rt p) wX wY
inWhat = (PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAndG rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
inWhat) (PatchInfo -> Bool)
-> (PatchInfoAndG rt p wA wB -> PatchInfo)
-> PatchInfoAndG rt p wA wB
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt p wA wB -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info

findCommonWithThem :: Commute p
                   => PatchSet rt p Origin wX
                   -> PatchSet rt p Origin wY
                   -> (PatchSet rt p :> FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem :: PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them = case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
    Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
        case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL ((PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them') (PatchInfo -> Bool)
-> (PatchInfoAndG rt (Named p) wU wV -> PatchInfo)
-> PatchInfoAndG rt (Named p) wU wV
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) (FL (PatchInfoAnd rt p) wU wX
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wX)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wX
_ ->
                String -> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
forall a. HasCallStack => String -> a
error (String -> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX)
-> String
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAndG rt (Named p) wW wZ -> PatchInfo)
-> PatchInfoAndG rt (Named p) wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAndG rt (Named p) wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            FL (PatchInfoAnd rt p) wU wZ
common2 :> FL (PatchInfoAnd rt p) wZ wZ
_nilfl :> FL (PatchInfoAnd rt p) wZ wX
only_ours ->
                RL (Tagged rt p) Origin wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common (FL (PatchInfoAnd rt p) wU wZ -> RL (PatchInfoAnd rt p) wU wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2) PatchSet rt p Origin wZ
-> FL (PatchInfoAnd rt p) wZ wX
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> FL (PatchInfoAnd rt p) wZ wX -> FL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL (PatchInfoAnd rt p) wZ wX
only_ours

findUncommon :: Commute p
             => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
             -> (FL (PatchInfoAnd rt p) :\/: FL (PatchInfoAnd rt p)) wX wY
findUncommon :: PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:\/:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
findUncommon PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        PatchSet rt p Origin wZ
_common :> FL (PatchInfoAnd rt p) wZ wX
us' -> case PatchSet rt p Origin wY
-> PatchSet rt p Origin wX
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wY
forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wY
them PatchSet rt p Origin wX
us of
            PatchSet rt p Origin wZ
_ :> FL (PatchInfoAnd rt p) wZ wY
them' -> FL (PatchInfoAnd rt p) wZ wX -> FL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wX
us' FL (PatchInfoAnd rt p) wZ wX
-> FL (PatchInfoAnd rt p) wZ wY
-> (:\/:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wZ wX -> a2 wZ wY -> (:\/:) a1 a2 wX wY
:\/: FL (PatchInfoAnd rt p) wZ wY
them'

countUsThem :: Commute p
            => PatchSet rt p Origin wX
            -> PatchSet rt p Origin wY
            -> (Int, Int)
countUsThem :: PatchSet rt p Origin wX -> PatchSet rt p Origin wY -> (Int, Int)
countUsThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
_ RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' -> let uu :: [PatchInfo]
uu = (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
us'
                                tt :: [PatchInfo]
tt = (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them' in
                            ([PatchInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([PatchInfo] -> Int) -> [PatchInfo] -> Int
forall a b. (a -> b) -> a -> b
$ [PatchInfo]
uu [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
tt, [PatchInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([PatchInfo] -> Int) -> [PatchInfo] -> Int
forall a b. (a -> b) -> a -> b
$ [PatchInfo]
tt [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
uu)

mergeThem :: (Commute p, Merge p)
          => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
          -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem :: PatchSet rt p Origin wX
-> PatchSet rt p Origin wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
_ RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
            case FL (PatchInfoAnd rt p) wU wX
-> FL (PatchInfoAnd rt p) wU wY
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
forall (p :: * -> * -> *) wX wY wZ.
(Commute p, Merge p, Ident p) =>
FL p wX wY -> FL p wX wZ -> (:/\:) (FL p) (FL p) wY wZ
merge2FL (RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us') (RL (PatchInfoAnd rt p) wU wY -> FL (PatchInfoAnd rt p) wU wY
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them') of
               FL (PatchInfoAnd rt p) wX wZ
them'' :/\: FL (PatchInfoAnd rt p) wY wZ
_ -> FL (PatchInfoAnd rt p) wX wZ -> Sealed (FL (PatchInfoAnd rt p) wX)
forall (a :: * -> *) wX. a wX -> Sealed a
Sealed FL (PatchInfoAnd rt p) wX wZ
them''

patchSetIntersection :: Commute p
                   => [SealedPatchSet rt p Origin]
                   -> SealedPatchSet rt p Origin
patchSetIntersection :: [SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetIntersection [] = PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin)
-> PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin Origin
-> RL (PatchInfoAnd rt p) Origin Origin
-> PatchSet rt p Origin Origin
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetIntersection [SealedPatchSet rt p Origin
x] = SealedPatchSet rt p Origin
x
patchSetIntersection (Sealed PatchSet rt p Origin wX
y : [SealedPatchSet rt p Origin]
ys) =
    case [SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
forall (p :: * -> * -> *) (rt :: RepoType).
Commute p =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetIntersection [SealedPatchSet rt p Origin]
ys of
        Sealed PatchSet rt p Origin wX
z -> case PatchSet rt p Origin wX
-> PatchSet rt p Origin wX
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
y PatchSet rt p Origin wX
z of
            Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
a RL (PatchInfoAnd rt p) wU wX
b -> case (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
a [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
b of
                [PatchInfo]
morecommon ->
                    case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> RL (PatchInfoAnd rt p) wU wX
-> (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wU wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL (\PatchInfoAnd rt p wU wV
e -> PatchInfoAnd rt p wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wU wV
e PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [PatchInfo]
morecommon) RL (PatchInfoAnd rt p) wU wX
a of
                        RL (PatchInfoAnd rt p) wU wZ
commonps :> RL (PatchInfoAnd rt p) wZ wX
_ -> PatchSet rt p Origin wZ -> SealedPatchSet rt p Origin
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p Origin wZ -> SealedPatchSet rt p Origin)
-> PatchSet rt p Origin wZ -> SealedPatchSet rt p Origin
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p Origin wZ
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wZ
commonps

patchSetUnion :: (Commute p, Merge p, Eq2 p)
            => [SealedPatchSet rt p Origin]
            -> SealedPatchSet rt p Origin
patchSetUnion :: [SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetUnion [] = PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin)
-> PatchSet rt p Origin Origin -> SealedPatchSet rt p Origin
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) Origin Origin
-> RL (PatchInfoAnd rt p) Origin Origin
-> PatchSet rt p Origin Origin
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) Origin Origin
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetUnion [SealedPatchSet rt p Origin
x] = SealedPatchSet rt p Origin
x
patchSetUnion (Sealed y :: PatchSet rt p Origin wX
y@(PatchSet RL (Tagged rt p) Origin wX
tsy RL (PatchInfoAnd rt p) wX wX
psy) : Sealed PatchSet rt p Origin wX
y2 : [SealedPatchSet rt p Origin]
ys) =
    case PatchSet rt p Origin wX
-> PatchSet rt p Origin wX -> Sealed (FL (PatchInfoAnd rt p) wX)
forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
(Commute p, Merge p) =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem PatchSet rt p Origin wX
y PatchSet rt p Origin wX
y2 of
        Sealed FL (PatchInfoAnd rt p) wX wX
p2 ->
            [SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
forall (p :: * -> * -> *) (rt :: RepoType).
(Commute p, Merge p, Eq2 p) =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetUnion ([SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin)
-> [SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
forall a b. (a -> b) -> a -> b
$ PatchSet rt p Origin wX -> SealedPatchSet rt p Origin
forall (a :: * -> *) wX. a wX -> Sealed a
seal (RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p Origin wX
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
tsy (RL (PatchInfoAnd rt p) wX wX
psy RL (PatchInfoAnd rt p) wX wX
-> FL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> RL p wX wZ
+<<+ FL (PatchInfoAnd rt p) wX wX
p2)) SealedPatchSet rt p Origin
-> [SealedPatchSet rt p Origin] -> [SealedPatchSet rt p Origin]
forall a. a -> [a] -> [a]
: [SealedPatchSet rt p Origin]
ys

areUnrelatedRepos :: Commute p
                  => PatchSet rt p Origin wX
                  -> PatchSet rt p Origin wY -> Bool
areUnrelatedRepos :: PatchSet rt p Origin wX -> PatchSet rt p Origin wY -> Bool
areUnrelatedRepos PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
c RL (PatchInfoAnd rt p) wU wX
u RL (PatchInfoAnd rt p) wU wY
t -> RL (Tagged rt p) Origin wU
-> RL (PatchInfoAnd rt p) wU wX
-> RL (PatchInfoAnd rt p) wU wY
-> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wZ (rt :: RepoType)
       (p :: * -> * -> *) wX wY (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) wX wZ
-> RL (PatchInfoAndG rt p) wX wY
-> RL (PatchInfoAndG rt p) wX wY
-> Bool
checkit RL (Tagged rt p) Origin wU
c RL (PatchInfoAnd rt p) wU wX
u RL (PatchInfoAnd rt p) wU wY
t
  where
    checkit :: RL (Tagged rt p) wX wZ
-> RL (PatchInfoAndG rt p) wX wY
-> RL (PatchInfoAndG rt p) wX wY
-> Bool
checkit (RL (Tagged rt p) wX wY
_ :<: Tagged{}) RL (PatchInfoAndG rt p) wX wY
_ RL (PatchInfoAndG rt p) wX wY
_ = Bool
False
    checkit RL (Tagged rt p) wX wZ
_ RL (PatchInfoAndG rt p) wX wY
u RL (PatchInfoAndG rt p) wX wY
t | RL (PatchInfoAndG rt p) wX wY
t RL (PatchInfoAndG rt p) wX wY -> Int -> Bool
forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` Int
5 = Bool
False
                  | RL (PatchInfoAndG rt p) wX wY
u RL (PatchInfoAndG rt p) wX wY -> Int -> Bool
forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` Int
5 = Bool
False
                  | Bool
otherwise = [PatchInfo] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PatchInfo] -> Bool) -> [PatchInfo] -> Bool
forall a b. (a -> b) -> a -> b
$ [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
intersect ((forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAndG rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
u) ((forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAndG rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAndG rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
t)

-- | Split a 'PatchSet' at the latest clean tag. The left part is what comes
-- before the tag, the right part is the tag and its non-dependencies.
contextPatches :: PatchSet rt p wX wY
               -> (PatchSet rt p :> RL (PatchInfoAnd rt p)) wX wY
contextPatches :: PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
contextPatches = PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
patchSetSplit (PatchSet rt p wX wY
 -> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY)
-> (PatchSet rt p wX wY -> PatchSet rt p wX wY)
-> PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchSet rt p wX wY -> PatchSet rt p wX wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
slightlyOptimizePatchset