module Unison.Merge.FindConflictedAlias
( findConflictedAlias,
)
where
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Unison.Merge.DiffOp (DiffOp (..))
import Unison.Merge.Updated qualified
import Unison.Prelude
import Unison.Util.BiMultimap (BiMultimap)
import Unison.Util.BiMultimap qualified as BiMultimap
import Unison.Util.Defn (Defn (..))
import Unison.Util.Defns (Defns (..), DefnsF3)
findConflictedAlias ::
forall name synhashed term typ.
(Ord name, forall ref. Eq (synhashed ref), Ord term, Ord typ) =>
Defns (BiMultimap term name) (BiMultimap typ name) ->
DefnsF3 (Map name) DiffOp synhashed term typ ->
Maybe (Defn (name, name) (name, name))
findConflictedAlias :: forall name (synhashed :: * -> *) term typ.
(Ord name, forall ref. Eq (synhashed ref), Ord term, Ord typ) =>
Defns (BiMultimap term name) (BiMultimap typ name)
-> DefnsF3 (Map name) DiffOp synhashed term typ
-> Maybe (Defn (name, name) (name, name))
findConflictedAlias Defns (BiMultimap term name) (BiMultimap typ name)
defns DefnsF3 (Map name) DiffOp synhashed term typ
diff =
[Maybe (Defn (name, name) (name, name))]
-> Maybe (Defn (name, name) (name, name))
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [(name, name) -> Defn (name, name) (name, name)
forall term typ. term -> Defn term typ
TermDefn ((name, name) -> Defn (name, name) (name, name))
-> Maybe (name, name) -> Maybe (Defn (name, name) (name, name))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BiMultimap term name
-> Map name (DiffOp (synhashed term)) -> Maybe (name, name)
forall ref.
(Eq (synhashed ref), Ord ref) =>
BiMultimap ref name
-> Map name (DiffOp (synhashed ref)) -> Maybe (name, name)
go Defns (BiMultimap term name) (BiMultimap typ name)
defns.terms DefnsF3 (Map name) DiffOp synhashed term typ
diff.terms, (name, name) -> Defn (name, name) (name, name)
forall term typ. typ -> Defn term typ
TypeDefn ((name, name) -> Defn (name, name) (name, name))
-> Maybe (name, name) -> Maybe (Defn (name, name) (name, name))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BiMultimap typ name
-> Map name (DiffOp (synhashed typ)) -> Maybe (name, name)
forall ref.
(Eq (synhashed ref), Ord ref) =>
BiMultimap ref name
-> Map name (DiffOp (synhashed ref)) -> Maybe (name, name)
go Defns (BiMultimap term name) (BiMultimap typ name)
defns.types DefnsF3 (Map name) DiffOp synhashed term typ
diff.types]
where
go ::
forall ref.
(Eq (synhashed ref), Ord ref) =>
BiMultimap ref name ->
Map name (DiffOp (synhashed ref)) ->
Maybe (name, name)
go :: forall ref.
(Eq (synhashed ref), Ord ref) =>
BiMultimap ref name
-> Map name (DiffOp (synhashed ref)) -> Maybe (name, name)
go BiMultimap ref name
namespace Map name (DiffOp (synhashed ref))
diff =
[Maybe (name, name)] -> Maybe (name, name)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum (((name, DiffOp (synhashed ref)) -> Maybe (name, name))
-> [(name, DiffOp (synhashed ref))] -> [Maybe (name, name)]
forall a b. (a -> b) -> [a] -> [b]
map (name, DiffOp (synhashed ref)) -> Maybe (name, name)
f (Map name (DiffOp (synhashed ref))
-> [(name, DiffOp (synhashed ref))]
forall k a. Map k a -> [(k, a)]
Map.toList Map name (DiffOp (synhashed ref))
diff))
where
f :: (name, DiffOp (synhashed ref)) -> Maybe (name, name)
f :: (name, DiffOp (synhashed ref)) -> Maybe (name, name)
f (name
name, DiffOp (synhashed ref)
op) =
case DiffOp (synhashed ref)
op of
DiffOp'Add synhashed ref
_ -> Maybe (name, name)
forall a. Maybe a
Nothing
DiffOp'Delete synhashed ref
_ -> Maybe (name, name)
forall a. Maybe a
Nothing
DiffOp'Update Updated (synhashed ref)
hashed1 ->
name -> BiMultimap ref name -> Set name
forall a b. (Ord a, Ord b) => b -> BiMultimap a b -> Set b
BiMultimap.lookupPreimage name
name BiMultimap ref name
namespace
Set name -> (Set name -> Set name) -> Set name
forall a b. a -> (a -> b) -> b
& name -> Set name -> Set name
forall a. Ord a => a -> Set a -> Set a
Set.delete name
name
Set name -> (Set name -> [name]) -> [name]
forall a b. a -> (a -> b) -> b
& Set name -> [name]
forall a. Set a -> [a]
Set.toList
[name] -> ([name] -> [Maybe (name, name)]) -> [Maybe (name, name)]
forall a b. a -> (a -> b) -> b
& (name -> Maybe (name, name)) -> [name] -> [Maybe (name, name)]
forall a b. (a -> b) -> [a] -> [b]
map (synhashed ref -> name -> Maybe (name, name)
g Updated (synhashed ref)
hashed1.new)
[Maybe (name, name)]
-> ([Maybe (name, name)] -> Maybe (name, name))
-> Maybe (name, name)
forall a b. a -> (a -> b) -> b
& [Maybe (name, name)] -> Maybe (name, name)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum
where
g :: synhashed ref -> name -> Maybe (name, name)
g :: synhashed ref -> name -> Maybe (name, name)
g synhashed ref
hashed1 name
alias =
case name
-> Map name (DiffOp (synhashed ref))
-> Maybe (DiffOp (synhashed ref))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup name
alias Map name (DiffOp (synhashed ref))
diff of
Just (DiffOp'Update Updated (synhashed ref)
hashed2) | synhashed ref
hashed1 synhashed ref -> synhashed ref -> Bool
forall a. Eq a => a -> a -> Bool
== Updated (synhashed ref)
hashed2.new -> Maybe (name, name)
forall a. Maybe a
Nothing
Just (DiffOp'Delete synhashed ref
_) -> Maybe (name, name)
forall a. Maybe a
Nothing
Maybe (DiffOp (synhashed ref))
_ -> (name, name) -> Maybe (name, name)
forall a. a -> Maybe a
Just (name
name, name
alias)