module Unison.PrettyPrintEnv.FQN (Imports, Prefix, Suffix, elideFQN) where

import Data.Map qualified as Map
import Unison.HashQualified qualified as HQ
import Unison.Name (Name)
import Unison.Prelude
import Unison.Syntax.Name qualified as Name (unsafeParseText)

-- Type aliases relating to Fully-Qualified Names, e.g. 'Acme.API.foo'
-- Used primarily by the FQN elision code - see TermPrinter.PrintAnnotation.

-- Note that a Suffix can include dots.
type Suffix = Text

-- Each member of a Prefix list is dot-free.
type Prefix = [Text]

-- Keys are FQNs, values are shorter names which are equivalent, thanks to use
-- statements that are in scope.
type Imports = Map Name Suffix

-- Give the shortened version of an FQN, if there's been a `use` statement for that FQN.
elideFQN :: Imports -> HQ.HashQualified Name -> HQ.HashQualified Name
elideFQN :: Imports -> HashQualified Name -> HashQualified Name
elideFQN Imports
imports HashQualified Name
hq =
  let hash :: Maybe ShortHash
hash = HashQualified Name -> Maybe ShortHash
forall n. HashQualified n -> Maybe ShortHash
HQ.toHash HashQualified Name
hq
      name' :: Maybe Name
name' = do
        Name
name <- HashQualified Name -> Maybe Name
forall n. HashQualified n -> Maybe n
HQ.toName HashQualified Name
hq
        let hit :: Maybe Name
hit = (Text -> Name) -> Maybe Text -> Maybe Name
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HasCallStack => Text -> Name
Text -> Name
Name.unsafeParseText (Name -> Imports -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name Imports
imports)
        -- Cut out the "const id $" to get tracing of FQN elision attempts.
        let t :: Maybe Name -> Maybe Name
t = (Maybe Name -> Maybe Name)
-> (Any -> Any) -> Maybe Name -> Maybe Name
forall a b. a -> b -> a
const Maybe Name -> Maybe Name
forall a. a -> a
id ((Any -> Any) -> Maybe Name -> Maybe Name)
-> (Any -> Any) -> Maybe Name -> Maybe Name
forall a b. (a -> b) -> a -> b
$ [Char] -> Any -> Any
forall a. [Char] -> a -> a
trace ([Char]
"hit: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe Name -> [Char]
forall a. Show a => a -> [Char]
show Maybe Name
hit [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" finding: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ HashQualified Name -> [Char]
forall a. Show a => a -> [Char]
show HashQualified Name
hq [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" in imports: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Imports -> [Char]
forall a. Show a => a -> [Char]
show Imports
imports)
        Maybe Name -> Maybe Name
t (Name -> Maybe Name
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Name -> Maybe Name) -> Name -> Maybe Name
forall a b. (a -> b) -> a -> b
$ Name -> Maybe Name -> Name
forall a. a -> Maybe a -> a
fromMaybe Name
name Maybe Name
hit)
   in Maybe Name -> Maybe ShortHash -> HashQualified Name
HQ.fromNameHash Maybe Name
name' Maybe ShortHash
hash