module Unison.Codebase.Editor.HandleInput.DebugDefinition
  ( debugTerm,
    debugDecl,
  )
where

import Control.Monad.Reader
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.NamesUtils qualified as Cli
import Unison.Codebase qualified as Codebase
import Unison.Codebase.Editor.Output (Output (..))
import Unison.ConstructorReference (GConstructorReference (ConstructorReference))
import Unison.DataDeclaration.ConstructorId (ConstructorId)
import Unison.HashQualified qualified as HQ
import Unison.Name (Name)
import Unison.NamesWithHistory qualified as Names
import Unison.Prelude
import Unison.Reference (TermReference, TypeReference)
import Unison.Reference qualified as Reference
import Unison.Referent qualified as Referent

debugTermReference :: Bool -> TermReference -> Cli ()
debugTermReference :: Bool -> TermReference -> Cli ()
debugTermReference Bool
verbose TermReference
ref = do
  Cli.Env {Codebase IO Symbol Ann
codebase :: Codebase IO Symbol Ann
$sel:codebase:Env :: Env -> Codebase IO Symbol Ann
codebase} <- Cli Env
forall r (m :: * -> *). MonadReader r m => m r
ask
  case TermReference
ref of
    Reference.DerivedId Id' Hash
refId -> do
      Transaction (Maybe (Term Symbol Ann))
-> Cli (Maybe (Term Symbol Ann))
forall a. Transaction a -> Cli a
Cli.runTransaction (Codebase IO Symbol Ann
-> Id' Hash -> Transaction (Maybe (Term Symbol Ann))
forall (m :: * -> *) v a.
Codebase m v a -> Id' Hash -> Transaction (Maybe (Term v a))
Codebase.getTerm Codebase IO Symbol Ann
codebase Id' Hash
refId) Cli (Maybe (Term Symbol Ann))
-> (Maybe (Term Symbol Ann) -> Cli ()) -> Cli ()
forall a b. Cli a -> (a -> Cli b) -> Cli b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Term Symbol Ann)
Nothing -> Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ ShortHash -> Output
TermNotFound' (TermReference -> ShortHash
Reference.toShortHash TermReference
ref)
        Just Term Symbol Ann
term -> do
          Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ Bool -> Either Text (Term Symbol Ann) -> Output
DebugTerm Bool
verbose (Term Symbol Ann -> Either Text (Term Symbol Ann)
forall a b. b -> Either a b
Right Term Symbol Ann
term)
    Reference.Builtin Text
builtinTxt -> do
      Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ Bool -> Either Text (Term Symbol Ann) -> Output
DebugTerm Bool
verbose (Text -> Either Text (Term Symbol Ann)
forall a b. a -> Either a b
Left Text
builtinTxt)

debugTypeReference :: TypeReference -> Maybe ConstructorId -> Cli ()
debugTypeReference :: TermReference -> Maybe ConstructorId -> Cli ()
debugTypeReference TermReference
ref Maybe ConstructorId
mayConId = do
  Cli.Env {Codebase IO Symbol Ann
$sel:codebase:Env :: Env -> Codebase IO Symbol Ann
codebase :: Codebase IO Symbol Ann
codebase} <- Cli Env
forall r (m :: * -> *). MonadReader r m => m r
ask
  case TermReference
ref of
    Reference.DerivedId Id' Hash
refId -> do
      Transaction (Maybe (Decl Symbol Ann))
-> Cli (Maybe (Decl Symbol Ann))
forall a. Transaction a -> Cli a
Cli.runTransaction (Codebase IO Symbol Ann
-> Id' Hash -> Transaction (Maybe (Decl Symbol Ann))
forall (m :: * -> *) v a.
Codebase m v a -> Id' Hash -> Transaction (Maybe (Decl v a))
Codebase.getTypeDeclaration Codebase IO Symbol Ann
codebase Id' Hash
refId) Cli (Maybe (Decl Symbol Ann))
-> (Maybe (Decl Symbol Ann) -> Cli ()) -> Cli ()
forall a b. Cli a -> (a -> Cli b) -> Cli b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Decl Symbol Ann)
Nothing -> Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ ShortHash -> Output
TypeNotFound' (TermReference -> ShortHash
Reference.toShortHash TermReference
ref)
        Just Decl Symbol Ann
decl -> do
          Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ Either Text (Decl Symbol Ann) -> Maybe ConstructorId -> Output
DebugDecl (Decl Symbol Ann -> Either Text (Decl Symbol Ann)
forall a b. b -> Either a b
Right Decl Symbol Ann
decl) Maybe ConstructorId
mayConId
    Reference.Builtin Text
builtinTxt -> do
      Output -> Cli ()
Cli.respond (Output -> Cli ()) -> Output -> Cli ()
forall a b. (a -> b) -> a -> b
$ Either Text (Decl Symbol Ann) -> Maybe ConstructorId -> Output
DebugDecl (Text -> Either Text (Decl Symbol Ann)
forall a b. a -> Either a b
Left Text
builtinTxt) Maybe ConstructorId
mayConId

debugTerm :: Bool -> HQ.HashQualified Name -> Cli ()
debugTerm :: Bool -> HashQualified Name -> Cli ()
debugTerm Bool
verbose HashQualified Name
hqName = do
  Names
names <- Cli Names
Cli.currentNames
  let matches :: Set Referent
matches = SearchType -> HashQualified Name -> Names -> Set Referent
Names.lookupHQTerm SearchType
Names.IncludeSuffixes HashQualified Name
hqName Names
names
  Set Referent -> (Referent -> Cli ()) -> Cli ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set Referent
matches \case
    Referent.Ref TermReference
termReference -> Bool -> TermReference -> Cli ()
debugTermReference Bool
verbose TermReference
termReference
    Referent.Con (ConstructorReference TermReference
typeRef ConstructorId
conId) ConstructorType
_conTyp -> TermReference -> Maybe ConstructorId -> Cli ()
debugTypeReference TermReference
typeRef (ConstructorId -> Maybe ConstructorId
forall a. a -> Maybe a
Just ConstructorId
conId)

debugDecl :: HQ.HashQualified Name -> Cli ()
debugDecl :: HashQualified Name -> Cli ()
debugDecl HashQualified Name
hqName = do
  Names
names <- Cli Names
Cli.currentNames
  let matches :: Set TermReference
matches = SearchType -> HashQualified Name -> Names -> Set TermReference
Names.lookupHQType SearchType
Names.IncludeSuffixes HashQualified Name
hqName Names
names
  Set TermReference -> (TermReference -> Cli ()) -> Cli ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set TermReference
matches \TermReference
typeRef -> TermReference -> Maybe ConstructorId -> Cli ()
debugTypeReference TermReference
typeRef Maybe ConstructorId
forall a. Maybe a
Nothing