{-# LANGUAGE ScopedTypeVariables #-}

module Unison.Codebase.CodeLookup.Util where

import Data.Map qualified as Map
import Unison.Codebase.CodeLookup
import Unison.DataDeclaration qualified as DataDeclaration
import Unison.Prelude
import Unison.Reference qualified as Reference
import Unison.Term qualified as Term
import Unison.UnisonFile qualified as UF
import Unison.UnisonFile.Type (TypecheckedUnisonFile)
import Unison.Var (Var)

fromTypecheckedUnisonFile :: forall m v a. (Var v, Monad m) => TypecheckedUnisonFile v a -> CodeLookup v m a
fromTypecheckedUnisonFile :: forall (m :: * -> *) v a.
(Var v, Monad m) =>
TypecheckedUnisonFile v a -> CodeLookup v m a
fromTypecheckedUnisonFile TypecheckedUnisonFile v a
tuf = (Id -> m (Maybe (Term v a)))
-> (Id -> m (Maybe (Decl v a))) -> CodeLookup v m a
forall v (m :: * -> *) a.
(Id -> m (Maybe (Term v a)))
-> (Id -> m (Maybe (Decl v a))) -> CodeLookup v m a
CodeLookup Id -> m (Maybe (Term v a))
tm Id -> m (Maybe (Decl v a))
ty
  where
    tm :: Reference.Id -> m (Maybe (Term.Term v a))
    tm :: Id -> m (Maybe (Term v a))
tm Id
id = Maybe (Term v a) -> m (Maybe (Term v a))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Term v a) -> m (Maybe (Term v a)))
-> Maybe (Term v a) -> m (Maybe (Term v a))
forall a b. (a -> b) -> a -> b
$ Id -> Map Id (Term v a) -> Maybe (Term v a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Id
id Map Id (Term v a)
termMap
    ty :: Reference.Id -> m (Maybe (DataDeclaration.Decl v a))
    ty :: Id -> m (Maybe (Decl v a))
ty Id
id = Maybe (Decl v a) -> m (Maybe (Decl v a))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Decl v a) -> m (Maybe (Decl v a)))
-> Maybe (Decl v a) -> m (Maybe (Decl v a))
forall a b. (a -> b) -> a -> b
$ Id -> Map Id (Decl v a) -> Maybe (Decl v a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Id
id Map Id (Decl v a)
dataDeclMap Maybe (Decl v a) -> Maybe (Decl v a) -> Maybe (Decl v a)
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Id -> Map Id (Decl v a) -> Maybe (Decl v a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Id
id Map Id (Decl v a)
effectDeclMap
    dataDeclMap :: Map Id (Decl v a)
dataDeclMap =
      [(Id, Decl v a)] -> Map Id (Decl v a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
        [ (Id
id, DataDeclaration v a -> Decl v a
forall a b. b -> Either a b
Right DataDeclaration v a
dd)
          | (v
_, (Reference.DerivedId Id
id, DataDeclaration v a
dd)) <-
              Map v (Reference, DataDeclaration v a)
-> [(v, (Reference, DataDeclaration v a))]
forall k a. Map k a -> [(k, a)]
Map.toList (TypecheckedUnisonFile v a -> Map v (Reference, DataDeclaration v a)
forall v a.
TypecheckedUnisonFile v a -> Map v (Reference, DataDeclaration v a)
UF.dataDeclarations' TypecheckedUnisonFile v a
tuf)
        ]
    effectDeclMap :: Map Id (Decl v a)
effectDeclMap =
      [(Id, Decl v a)] -> Map Id (Decl v a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
        [ (Id
id, EffectDeclaration v a -> Decl v a
forall a b. a -> Either a b
Left EffectDeclaration v a
ad)
          | (v
_, (Reference.DerivedId Id
id, EffectDeclaration v a
ad)) <-
              Map v (Reference, EffectDeclaration v a)
-> [(v, (Reference, EffectDeclaration v a))]
forall k a. Map k a -> [(k, a)]
Map.toList (TypecheckedUnisonFile v a
-> Map v (Reference, EffectDeclaration v a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (Reference, EffectDeclaration v a)
UF.effectDeclarations' TypecheckedUnisonFile v a
tuf)
        ]
    termMap :: Map Reference.Id (Term.Term v a)
    termMap :: Map Id (Term v a)
termMap = [(Id, Term v a)] -> Map Id (Term v a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Id
id, Term v a
tm) | (a
_a, Id
id, Maybe WatchKind
_wk, Term v a
tm, Type v a
_tp) <- Map v (a, Id, Maybe WatchKind, Term v a, Type v a)
-> [(a, Id, Maybe WatchKind, Term v a, Type v a)]
forall a. Map v a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Map v (a, Id, Maybe WatchKind, Term v a, Type v a)
 -> [(a, Id, Maybe WatchKind, Term v a, Type v a)])
-> Map v (a, Id, Maybe WatchKind, Term v a, Type v a)
-> [(a, Id, Maybe WatchKind, Term v a, Type v a)]
forall a b. (a -> b) -> a -> b
$ TypecheckedUnisonFile v a
-> Map v (a, Id, Maybe WatchKind, Term v a, Type v a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (a, Id, Maybe WatchKind, Term v a, Type v a)
UF.hashTermsId TypecheckedUnisonFile v a
tuf]