{-# LANGUAGE TemplateHaskell #-}

-- |
-- Data types for names
--
module Language.PureScript.Names where

import Prelude

import Codec.Serialise (Serialise)
import Control.Applicative ((<|>))
import Control.Monad.Supply.Class (MonadSupply(..))
import Control.DeepSeq (NFData)
import Data.Functor.Contravariant (contramap)
import Data.Vector qualified as V

import GHC.Generics (Generic)
import Data.Aeson (FromJSON(..), FromJSONKey(..), Options(..), SumEncoding(..), ToJSON(..), ToJSONKey(..), defaultOptions, parseJSON2, toJSON2, withArray)
import Data.Aeson.TH (deriveJSON)
import Data.Text (Text)
import Data.Text qualified as T

import Language.PureScript.AST.SourcePos (SourcePos, pattern SourcePos)

-- | A sum of the possible name types, useful for error and lint messages.
data Name
  = IdentName Ident
  | ValOpName (OpName 'ValueOpName)
  | TyName (ProperName 'TypeName)
  | TyOpName (OpName 'TypeOpName)
  | DctorName (ProperName 'ConstructorName)
  | TyClassName (ProperName 'ClassName)
  | ModName ModuleName
  deriving (Name -> Name -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Name -> Name -> Bool
$c/= :: Name -> Name -> Bool
== :: Name -> Name -> Bool
$c== :: Name -> Name -> Bool
Eq, Eq Name
Name -> Name -> Bool
Name -> Name -> Ordering
Name -> Name -> Name
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Name -> Name -> Name
$cmin :: Name -> Name -> Name
max :: Name -> Name -> Name
$cmax :: Name -> Name -> Name
>= :: Name -> Name -> Bool
$c>= :: Name -> Name -> Bool
> :: Name -> Name -> Bool
$c> :: Name -> Name -> Bool
<= :: Name -> Name -> Bool
$c<= :: Name -> Name -> Bool
< :: Name -> Name -> Bool
$c< :: Name -> Name -> Bool
compare :: Name -> Name -> Ordering
$ccompare :: Name -> Name -> Ordering
Ord, Int -> Name -> ShowS
[Name] -> ShowS
Name -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Name] -> ShowS
$cshowList :: [Name] -> ShowS
show :: Name -> String
$cshow :: Name -> String
showsPrec :: Int -> Name -> ShowS
$cshowsPrec :: Int -> Name -> ShowS
Show, forall x. Rep Name x -> Name
forall x. Name -> Rep Name x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Name x -> Name
$cfrom :: forall x. Name -> Rep Name x
Generic)

instance NFData Name
instance Serialise Name

getIdentName :: Name -> Maybe Ident
getIdentName :: Name -> Maybe Ident
getIdentName (IdentName Ident
name) = forall a. a -> Maybe a
Just Ident
name
getIdentName Name
_ = forall a. Maybe a
Nothing

getValOpName :: Name -> Maybe (OpName 'ValueOpName)
getValOpName :: Name -> Maybe (OpName 'ValueOpName)
getValOpName (ValOpName OpName 'ValueOpName
name) = forall a. a -> Maybe a
Just OpName 'ValueOpName
name
getValOpName Name
_ = forall a. Maybe a
Nothing

getTypeName :: Name -> Maybe (ProperName 'TypeName)
getTypeName :: Name -> Maybe (ProperName 'TypeName)
getTypeName (TyName ProperName 'TypeName
name) = forall a. a -> Maybe a
Just ProperName 'TypeName
name
getTypeName Name
_ = forall a. Maybe a
Nothing

getTypeOpName :: Name -> Maybe (OpName 'TypeOpName)
getTypeOpName :: Name -> Maybe (OpName 'TypeOpName)
getTypeOpName (TyOpName OpName 'TypeOpName
name) = forall a. a -> Maybe a
Just OpName 'TypeOpName
name
getTypeOpName Name
_ = forall a. Maybe a
Nothing

getDctorName :: Name -> Maybe (ProperName 'ConstructorName)
getDctorName :: Name -> Maybe (ProperName 'ConstructorName)
getDctorName (DctorName ProperName 'ConstructorName
name) = forall a. a -> Maybe a
Just ProperName 'ConstructorName
name
getDctorName Name
_ = forall a. Maybe a
Nothing

getClassName :: Name -> Maybe (ProperName 'ClassName)
getClassName :: Name -> Maybe (ProperName 'ClassName)
getClassName (TyClassName ProperName 'ClassName
name) = forall a. a -> Maybe a
Just ProperName 'ClassName
name
getClassName Name
_ = forall a. Maybe a
Nothing

-- |
-- This type is meant to be extended with any new uses for idents that come
-- along. Adding constructors to this type is cheaper than adding them to
-- `Ident` because functions that match on `Ident` can ignore all
-- `InternalIdent`s with a single pattern, and thus don't have to change if
-- a new `InternalIdentData` constructor is created.
--
data InternalIdentData
  -- Used by CoreFn.Laziness
  = RuntimeLazyFactory | Lazy !Text
  deriving (Int -> InternalIdentData -> ShowS
[InternalIdentData] -> ShowS
InternalIdentData -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InternalIdentData] -> ShowS
$cshowList :: [InternalIdentData] -> ShowS
show :: InternalIdentData -> String
$cshow :: InternalIdentData -> String
showsPrec :: Int -> InternalIdentData -> ShowS
$cshowsPrec :: Int -> InternalIdentData -> ShowS
Show, InternalIdentData -> InternalIdentData -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InternalIdentData -> InternalIdentData -> Bool
$c/= :: InternalIdentData -> InternalIdentData -> Bool
== :: InternalIdentData -> InternalIdentData -> Bool
$c== :: InternalIdentData -> InternalIdentData -> Bool
Eq, Eq InternalIdentData
InternalIdentData -> InternalIdentData -> Bool
InternalIdentData -> InternalIdentData -> Ordering
InternalIdentData -> InternalIdentData -> InternalIdentData
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: InternalIdentData -> InternalIdentData -> InternalIdentData
$cmin :: InternalIdentData -> InternalIdentData -> InternalIdentData
max :: InternalIdentData -> InternalIdentData -> InternalIdentData
$cmax :: InternalIdentData -> InternalIdentData -> InternalIdentData
>= :: InternalIdentData -> InternalIdentData -> Bool
$c>= :: InternalIdentData -> InternalIdentData -> Bool
> :: InternalIdentData -> InternalIdentData -> Bool
$c> :: InternalIdentData -> InternalIdentData -> Bool
<= :: InternalIdentData -> InternalIdentData -> Bool
$c<= :: InternalIdentData -> InternalIdentData -> Bool
< :: InternalIdentData -> InternalIdentData -> Bool
$c< :: InternalIdentData -> InternalIdentData -> Bool
compare :: InternalIdentData -> InternalIdentData -> Ordering
$ccompare :: InternalIdentData -> InternalIdentData -> Ordering
Ord, forall x. Rep InternalIdentData x -> InternalIdentData
forall x. InternalIdentData -> Rep InternalIdentData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InternalIdentData x -> InternalIdentData
$cfrom :: forall x. InternalIdentData -> Rep InternalIdentData x
Generic)

instance NFData InternalIdentData
instance Serialise InternalIdentData

-- |
-- Names for value identifiers
--
data Ident
  -- |
  -- An alphanumeric identifier
  --
  = Ident Text
  -- |
  -- A generated name for an identifier
  --
  | GenIdent (Maybe Text) Integer
  -- |
  -- A generated name used only for type-checking
  --
  | UnusedIdent
  -- |
  -- A generated name used only for internal transformations
  --
  | InternalIdent !InternalIdentData
  deriving (Int -> Ident -> ShowS
[Ident] -> ShowS
Ident -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ident] -> ShowS
$cshowList :: [Ident] -> ShowS
show :: Ident -> String
$cshow :: Ident -> String
showsPrec :: Int -> Ident -> ShowS
$cshowsPrec :: Int -> Ident -> ShowS
Show, Ident -> Ident -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ident -> Ident -> Bool
$c/= :: Ident -> Ident -> Bool
== :: Ident -> Ident -> Bool
$c== :: Ident -> Ident -> Bool
Eq, Eq Ident
Ident -> Ident -> Bool
Ident -> Ident -> Ordering
Ident -> Ident -> Ident
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Ident -> Ident -> Ident
$cmin :: Ident -> Ident -> Ident
max :: Ident -> Ident -> Ident
$cmax :: Ident -> Ident -> Ident
>= :: Ident -> Ident -> Bool
$c>= :: Ident -> Ident -> Bool
> :: Ident -> Ident -> Bool
$c> :: Ident -> Ident -> Bool
<= :: Ident -> Ident -> Bool
$c<= :: Ident -> Ident -> Bool
< :: Ident -> Ident -> Bool
$c< :: Ident -> Ident -> Bool
compare :: Ident -> Ident -> Ordering
$ccompare :: Ident -> Ident -> Ordering
Ord, forall x. Rep Ident x -> Ident
forall x. Ident -> Rep Ident x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Ident x -> Ident
$cfrom :: forall x. Ident -> Rep Ident x
Generic)

instance NFData Ident
instance Serialise Ident

unusedIdent :: Text
unusedIdent :: Text
unusedIdent = Text
"$__unused"

runIdent :: Ident -> Text
runIdent :: Ident -> Text
runIdent (Ident Text
i) = Text
i
runIdent (GenIdent Maybe Text
Nothing Integer
n) = Text
"$" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show Integer
n)
runIdent (GenIdent (Just Text
name) Integer
n) = Text
"$" forall a. Semigroup a => a -> a -> a
<> Text
name forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show Integer
n)
runIdent Ident
UnusedIdent = Text
unusedIdent
runIdent InternalIdent{} = forall a. HasCallStack => String -> a
error String
"unexpected InternalIdent"

showIdent :: Ident -> Text
showIdent :: Ident -> Text
showIdent = Ident -> Text
runIdent

freshIdent :: MonadSupply m => Text -> m Ident
freshIdent :: forall (m :: * -> *). MonadSupply m => Text -> m Ident
freshIdent Text
name = Maybe Text -> Integer -> Ident
GenIdent (forall a. a -> Maybe a
Just Text
name) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadSupply m => m Integer
fresh

freshIdent' :: MonadSupply m => m Ident
freshIdent' :: forall (m :: * -> *). MonadSupply m => m Ident
freshIdent' = Maybe Text -> Integer -> Ident
GenIdent forall a. Maybe a
Nothing forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadSupply m => m Integer
fresh

isPlainIdent :: Ident -> Bool
isPlainIdent :: Ident -> Bool
isPlainIdent Ident{} = Bool
True
isPlainIdent Ident
_ = Bool
False

-- |
-- Operator alias names.
--
newtype OpName (a :: OpNameType) = OpName { forall (a :: OpNameType). OpName a -> Text
runOpName :: Text }
  deriving (Int -> OpName a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: OpNameType). Int -> OpName a -> ShowS
forall (a :: OpNameType). [OpName a] -> ShowS
forall (a :: OpNameType). OpName a -> String
showList :: [OpName a] -> ShowS
$cshowList :: forall (a :: OpNameType). [OpName a] -> ShowS
show :: OpName a -> String
$cshow :: forall (a :: OpNameType). OpName a -> String
showsPrec :: Int -> OpName a -> ShowS
$cshowsPrec :: forall (a :: OpNameType). Int -> OpName a -> ShowS
Show, OpName a -> OpName a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: OpNameType). OpName a -> OpName a -> Bool
/= :: OpName a -> OpName a -> Bool
$c/= :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
== :: OpName a -> OpName a -> Bool
$c== :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
Eq, OpName a -> OpName a -> Bool
OpName a -> OpName a -> Ordering
OpName a -> OpName a -> OpName a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (a :: OpNameType). Eq (OpName a)
forall (a :: OpNameType). OpName a -> OpName a -> Bool
forall (a :: OpNameType). OpName a -> OpName a -> Ordering
forall (a :: OpNameType). OpName a -> OpName a -> OpName a
min :: OpName a -> OpName a -> OpName a
$cmin :: forall (a :: OpNameType). OpName a -> OpName a -> OpName a
max :: OpName a -> OpName a -> OpName a
$cmax :: forall (a :: OpNameType). OpName a -> OpName a -> OpName a
>= :: OpName a -> OpName a -> Bool
$c>= :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
> :: OpName a -> OpName a -> Bool
$c> :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
<= :: OpName a -> OpName a -> Bool
$c<= :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
< :: OpName a -> OpName a -> Bool
$c< :: forall (a :: OpNameType). OpName a -> OpName a -> Bool
compare :: OpName a -> OpName a -> Ordering
$ccompare :: forall (a :: OpNameType). OpName a -> OpName a -> Ordering
Ord, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (a :: OpNameType) x. Rep (OpName a) x -> OpName a
forall (a :: OpNameType) x. OpName a -> Rep (OpName a) x
$cto :: forall (a :: OpNameType) x. Rep (OpName a) x -> OpName a
$cfrom :: forall (a :: OpNameType) x. OpName a -> Rep (OpName a) x
Generic)

instance NFData (OpName a)
instance Serialise (OpName a)

instance ToJSON (OpName a) where
  toJSON :: OpName a -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: OpNameType). OpName a -> Text
runOpName

instance FromJSON (OpName a) where
  parseJSON :: Value -> Parser (OpName a)
parseJSON = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (a :: OpNameType). Text -> OpName a
OpName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromJSON a => Value -> Parser a
parseJSON

showOp :: OpName a -> Text
showOp :: forall (a :: OpNameType). OpName a -> Text
showOp OpName a
op = Text
"(" forall a. Semigroup a => a -> a -> a
<> forall (a :: OpNameType). OpName a -> Text
runOpName OpName a
op forall a. Semigroup a => a -> a -> a
<> Text
")"

-- |
-- The closed set of operator alias types.
--
data OpNameType = ValueOpName | TypeOpName | AnyOpName

eraseOpName :: OpName a -> OpName 'AnyOpName
eraseOpName :: forall (a :: OpNameType). OpName a -> OpName 'AnyOpName
eraseOpName = forall (a :: OpNameType). Text -> OpName a
OpName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: OpNameType). OpName a -> Text
runOpName

coerceOpName :: OpName a -> OpName b
coerceOpName :: forall (a :: OpNameType) (b :: OpNameType). OpName a -> OpName b
coerceOpName = forall (a :: OpNameType). Text -> OpName a
OpName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: OpNameType). OpName a -> Text
runOpName

-- |
-- Proper names, i.e. capitalized names for e.g. module names, type//data constructors.
--
newtype ProperName (a :: ProperNameType) = ProperName { forall (a :: ProperNameType). ProperName a -> Text
runProperName :: Text }
  deriving (Int -> ProperName a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: ProperNameType). Int -> ProperName a -> ShowS
forall (a :: ProperNameType). [ProperName a] -> ShowS
forall (a :: ProperNameType). ProperName a -> String
showList :: [ProperName a] -> ShowS
$cshowList :: forall (a :: ProperNameType). [ProperName a] -> ShowS
show :: ProperName a -> String
$cshow :: forall (a :: ProperNameType). ProperName a -> String
showsPrec :: Int -> ProperName a -> ShowS
$cshowsPrec :: forall (a :: ProperNameType). Int -> ProperName a -> ShowS
Show, ProperName a -> ProperName a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
/= :: ProperName a -> ProperName a -> Bool
$c/= :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
== :: ProperName a -> ProperName a -> Bool
$c== :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
Eq, ProperName a -> ProperName a -> Bool
ProperName a -> ProperName a -> Ordering
ProperName a -> ProperName a -> ProperName a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (a :: ProperNameType). Eq (ProperName a)
forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
forall (a :: ProperNameType).
ProperName a -> ProperName a -> Ordering
forall (a :: ProperNameType).
ProperName a -> ProperName a -> ProperName a
min :: ProperName a -> ProperName a -> ProperName a
$cmin :: forall (a :: ProperNameType).
ProperName a -> ProperName a -> ProperName a
max :: ProperName a -> ProperName a -> ProperName a
$cmax :: forall (a :: ProperNameType).
ProperName a -> ProperName a -> ProperName a
>= :: ProperName a -> ProperName a -> Bool
$c>= :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
> :: ProperName a -> ProperName a -> Bool
$c> :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
<= :: ProperName a -> ProperName a -> Bool
$c<= :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
< :: ProperName a -> ProperName a -> Bool
$c< :: forall (a :: ProperNameType). ProperName a -> ProperName a -> Bool
compare :: ProperName a -> ProperName a -> Ordering
$ccompare :: forall (a :: ProperNameType).
ProperName a -> ProperName a -> Ordering
Ord, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (a :: ProperNameType) x.
Rep (ProperName a) x -> ProperName a
forall (a :: ProperNameType) x.
ProperName a -> Rep (ProperName a) x
$cto :: forall (a :: ProperNameType) x.
Rep (ProperName a) x -> ProperName a
$cfrom :: forall (a :: ProperNameType) x.
ProperName a -> Rep (ProperName a) x
Generic)

instance NFData (ProperName a)
instance Serialise (ProperName a)

instance ToJSON (ProperName a) where
  toJSON :: ProperName a -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: ProperNameType). ProperName a -> Text
runProperName

instance FromJSON (ProperName a) where
  parseJSON :: Value -> Parser (ProperName a)
parseJSON = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (a :: ProperNameType). Text -> ProperName a
ProperName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromJSON a => Value -> Parser a
parseJSON

-- |
-- The closed set of proper name types.
--
data ProperNameType
  = TypeName
  | ConstructorName
  | ClassName
  | Namespace

-- |
-- Coerces a ProperName from one ProperNameType to another. This should be used
-- with care, and is primarily used to convert ClassNames into TypeNames after
-- classes have been desugared.
--
coerceProperName :: ProperName a -> ProperName b
coerceProperName :: forall (a :: ProperNameType) (b :: ProperNameType).
ProperName a -> ProperName b
coerceProperName = forall (a :: ProperNameType). Text -> ProperName a
ProperName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: ProperNameType). ProperName a -> Text
runProperName

-- |
-- Module names
--
newtype ModuleName = ModuleName Text
  deriving (Int -> ModuleName -> ShowS
[ModuleName] -> ShowS
ModuleName -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModuleName] -> ShowS
$cshowList :: [ModuleName] -> ShowS
show :: ModuleName -> String
$cshow :: ModuleName -> String
showsPrec :: Int -> ModuleName -> ShowS
$cshowsPrec :: Int -> ModuleName -> ShowS
Show, ModuleName -> ModuleName -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModuleName -> ModuleName -> Bool
$c/= :: ModuleName -> ModuleName -> Bool
== :: ModuleName -> ModuleName -> Bool
$c== :: ModuleName -> ModuleName -> Bool
Eq, Eq ModuleName
ModuleName -> ModuleName -> Bool
ModuleName -> ModuleName -> Ordering
ModuleName -> ModuleName -> ModuleName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ModuleName -> ModuleName -> ModuleName
$cmin :: ModuleName -> ModuleName -> ModuleName
max :: ModuleName -> ModuleName -> ModuleName
$cmax :: ModuleName -> ModuleName -> ModuleName
>= :: ModuleName -> ModuleName -> Bool
$c>= :: ModuleName -> ModuleName -> Bool
> :: ModuleName -> ModuleName -> Bool
$c> :: ModuleName -> ModuleName -> Bool
<= :: ModuleName -> ModuleName -> Bool
$c<= :: ModuleName -> ModuleName -> Bool
< :: ModuleName -> ModuleName -> Bool
$c< :: ModuleName -> ModuleName -> Bool
compare :: ModuleName -> ModuleName -> Ordering
$ccompare :: ModuleName -> ModuleName -> Ordering
Ord, forall x. Rep ModuleName x -> ModuleName
forall x. ModuleName -> Rep ModuleName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ModuleName x -> ModuleName
$cfrom :: forall x. ModuleName -> Rep ModuleName x
Generic)
  deriving newtype [ModuleName] -> Encoding
ModuleName -> Encoding
forall s. Decoder s [ModuleName]
forall s. Decoder s ModuleName
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
decodeList :: forall s. Decoder s [ModuleName]
$cdecodeList :: forall s. Decoder s [ModuleName]
encodeList :: [ModuleName] -> Encoding
$cencodeList :: [ModuleName] -> Encoding
decode :: forall s. Decoder s ModuleName
$cdecode :: forall s. Decoder s ModuleName
encode :: ModuleName -> Encoding
$cencode :: ModuleName -> Encoding
Serialise

instance NFData ModuleName

runModuleName :: ModuleName -> Text
runModuleName :: ModuleName -> Text
runModuleName (ModuleName Text
name) = Text
name

moduleNameFromString :: Text -> ModuleName
moduleNameFromString :: Text -> ModuleName
moduleNameFromString = Text -> ModuleName
ModuleName

isBuiltinModuleName :: ModuleName -> Bool
isBuiltinModuleName :: ModuleName -> Bool
isBuiltinModuleName (ModuleName Text
mn) = Text
mn forall a. Eq a => a -> a -> Bool
== Text
"Prim" Bool -> Bool -> Bool
|| Text
"Prim." Text -> Text -> Bool
`T.isPrefixOf` Text
mn

data QualifiedBy
  = BySourcePos SourcePos
  | ByModuleName ModuleName
  deriving (Int -> QualifiedBy -> ShowS
[QualifiedBy] -> ShowS
QualifiedBy -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QualifiedBy] -> ShowS
$cshowList :: [QualifiedBy] -> ShowS
show :: QualifiedBy -> String
$cshow :: QualifiedBy -> String
showsPrec :: Int -> QualifiedBy -> ShowS
$cshowsPrec :: Int -> QualifiedBy -> ShowS
Show, QualifiedBy -> QualifiedBy -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QualifiedBy -> QualifiedBy -> Bool
$c/= :: QualifiedBy -> QualifiedBy -> Bool
== :: QualifiedBy -> QualifiedBy -> Bool
$c== :: QualifiedBy -> QualifiedBy -> Bool
Eq, Eq QualifiedBy
QualifiedBy -> QualifiedBy -> Bool
QualifiedBy -> QualifiedBy -> Ordering
QualifiedBy -> QualifiedBy -> QualifiedBy
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: QualifiedBy -> QualifiedBy -> QualifiedBy
$cmin :: QualifiedBy -> QualifiedBy -> QualifiedBy
max :: QualifiedBy -> QualifiedBy -> QualifiedBy
$cmax :: QualifiedBy -> QualifiedBy -> QualifiedBy
>= :: QualifiedBy -> QualifiedBy -> Bool
$c>= :: QualifiedBy -> QualifiedBy -> Bool
> :: QualifiedBy -> QualifiedBy -> Bool
$c> :: QualifiedBy -> QualifiedBy -> Bool
<= :: QualifiedBy -> QualifiedBy -> Bool
$c<= :: QualifiedBy -> QualifiedBy -> Bool
< :: QualifiedBy -> QualifiedBy -> Bool
$c< :: QualifiedBy -> QualifiedBy -> Bool
compare :: QualifiedBy -> QualifiedBy -> Ordering
$ccompare :: QualifiedBy -> QualifiedBy -> Ordering
Ord, forall x. Rep QualifiedBy x -> QualifiedBy
forall x. QualifiedBy -> Rep QualifiedBy x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep QualifiedBy x -> QualifiedBy
$cfrom :: forall x. QualifiedBy -> Rep QualifiedBy x
Generic)

pattern ByNullSourcePos :: QualifiedBy
pattern $bByNullSourcePos :: QualifiedBy
$mByNullSourcePos :: forall {r}. QualifiedBy -> ((# #) -> r) -> ((# #) -> r) -> r
ByNullSourcePos = BySourcePos (SourcePos 0 0)

instance NFData QualifiedBy
instance Serialise QualifiedBy

isBySourcePos :: QualifiedBy -> Bool
isBySourcePos :: QualifiedBy -> Bool
isBySourcePos (BySourcePos SourcePos
_) = Bool
True
isBySourcePos QualifiedBy
_ = Bool
False

byMaybeModuleName :: Maybe ModuleName -> QualifiedBy
byMaybeModuleName :: Maybe ModuleName -> QualifiedBy
byMaybeModuleName (Just ModuleName
mn) = ModuleName -> QualifiedBy
ByModuleName ModuleName
mn
byMaybeModuleName Maybe ModuleName
Nothing = QualifiedBy
ByNullSourcePos

toMaybeModuleName :: QualifiedBy -> Maybe ModuleName
toMaybeModuleName :: QualifiedBy -> Maybe ModuleName
toMaybeModuleName (ByModuleName ModuleName
mn) = forall a. a -> Maybe a
Just ModuleName
mn
toMaybeModuleName (BySourcePos SourcePos
_) = forall a. Maybe a
Nothing

-- |
-- A qualified name, i.e. a name with an optional module name
--
data Qualified a = Qualified QualifiedBy a
  deriving (Int -> Qualified a -> ShowS
forall a. Show a => Int -> Qualified a -> ShowS
forall a. Show a => [Qualified a] -> ShowS
forall a. Show a => Qualified a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Qualified a] -> ShowS
$cshowList :: forall a. Show a => [Qualified a] -> ShowS
show :: Qualified a -> String
$cshow :: forall a. Show a => Qualified a -> String
showsPrec :: Int -> Qualified a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Qualified a -> ShowS
Show, Qualified a -> Qualified a -> Bool
forall a. Eq a => Qualified a -> Qualified a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Qualified a -> Qualified a -> Bool
$c/= :: forall a. Eq a => Qualified a -> Qualified a -> Bool
== :: Qualified a -> Qualified a -> Bool
$c== :: forall a. Eq a => Qualified a -> Qualified a -> Bool
Eq, Qualified a -> Qualified a -> Bool
Qualified a -> Qualified a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (Qualified a)
forall a. Ord a => Qualified a -> Qualified a -> Bool
forall a. Ord a => Qualified a -> Qualified a -> Ordering
forall a. Ord a => Qualified a -> Qualified a -> Qualified a
min :: Qualified a -> Qualified a -> Qualified a
$cmin :: forall a. Ord a => Qualified a -> Qualified a -> Qualified a
max :: Qualified a -> Qualified a -> Qualified a
$cmax :: forall a. Ord a => Qualified a -> Qualified a -> Qualified a
>= :: Qualified a -> Qualified a -> Bool
$c>= :: forall a. Ord a => Qualified a -> Qualified a -> Bool
> :: Qualified a -> Qualified a -> Bool
$c> :: forall a. Ord a => Qualified a -> Qualified a -> Bool
<= :: Qualified a -> Qualified a -> Bool
$c<= :: forall a. Ord a => Qualified a -> Qualified a -> Bool
< :: Qualified a -> Qualified a -> Bool
$c< :: forall a. Ord a => Qualified a -> Qualified a -> Bool
compare :: Qualified a -> Qualified a -> Ordering
$ccompare :: forall a. Ord a => Qualified a -> Qualified a -> Ordering
Ord, forall a b. a -> Qualified b -> Qualified a
forall a b. (a -> b) -> Qualified a -> Qualified b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Qualified b -> Qualified a
$c<$ :: forall a b. a -> Qualified b -> Qualified a
fmap :: forall a b. (a -> b) -> Qualified a -> Qualified b
$cfmap :: forall a b. (a -> b) -> Qualified a -> Qualified b
Functor, forall a. Eq a => a -> Qualified a -> Bool
forall a. Num a => Qualified a -> a
forall a. Ord a => Qualified a -> a
forall m. Monoid m => Qualified m -> m
forall a. Qualified a -> Bool
forall a. Qualified a -> Int
forall a. Qualified a -> [a]
forall a. (a -> a -> a) -> Qualified a -> a
forall m a. Monoid m => (a -> m) -> Qualified a -> m
forall b a. (b -> a -> b) -> b -> Qualified a -> b
forall a b. (a -> b -> b) -> b -> Qualified a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => Qualified a -> a
$cproduct :: forall a. Num a => Qualified a -> a
sum :: forall a. Num a => Qualified a -> a
$csum :: forall a. Num a => Qualified a -> a
minimum :: forall a. Ord a => Qualified a -> a
$cminimum :: forall a. Ord a => Qualified a -> a
maximum :: forall a. Ord a => Qualified a -> a
$cmaximum :: forall a. Ord a => Qualified a -> a
elem :: forall a. Eq a => a -> Qualified a -> Bool
$celem :: forall a. Eq a => a -> Qualified a -> Bool
length :: forall a. Qualified a -> Int
$clength :: forall a. Qualified a -> Int
null :: forall a. Qualified a -> Bool
$cnull :: forall a. Qualified a -> Bool
toList :: forall a. Qualified a -> [a]
$ctoList :: forall a. Qualified a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Qualified a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Qualified a -> a
foldr1 :: forall a. (a -> a -> a) -> Qualified a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Qualified a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Qualified a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Qualified a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Qualified a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Qualified a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Qualified a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Qualified a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Qualified a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Qualified a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Qualified a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Qualified a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Qualified a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Qualified a -> m
fold :: forall m. Monoid m => Qualified m -> m
$cfold :: forall m. Monoid m => Qualified m -> m
Foldable, Functor Qualified
Foldable Qualified
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Qualified (m a) -> m (Qualified a)
forall (f :: * -> *) a.
Applicative f =>
Qualified (f a) -> f (Qualified a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Qualified a -> m (Qualified b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Qualified a -> f (Qualified b)
sequence :: forall (m :: * -> *) a.
Monad m =>
Qualified (m a) -> m (Qualified a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
Qualified (m a) -> m (Qualified a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Qualified a -> m (Qualified b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Qualified a -> m (Qualified b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Qualified (f a) -> f (Qualified a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Qualified (f a) -> f (Qualified a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Qualified a -> f (Qualified b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Qualified a -> f (Qualified b)
Traversable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Qualified a) x -> Qualified a
forall a x. Qualified a -> Rep (Qualified a) x
$cto :: forall a x. Rep (Qualified a) x -> Qualified a
$cfrom :: forall a x. Qualified a -> Rep (Qualified a) x
Generic)

instance NFData a => NFData (Qualified a)
instance Serialise a => Serialise (Qualified a)

showQualified :: (a -> Text) -> Qualified a -> Text
showQualified :: forall a. (a -> Text) -> Qualified a -> Text
showQualified a -> Text
f (Qualified (BySourcePos  SourcePos
_) a
a) = a -> Text
f a
a
showQualified a -> Text
f (Qualified (ByModuleName ModuleName
name) a
a) = ModuleName -> Text
runModuleName ModuleName
name forall a. Semigroup a => a -> a -> a
<> Text
"." forall a. Semigroup a => a -> a -> a
<> a -> Text
f a
a

getQual :: Qualified a -> Maybe ModuleName
getQual :: forall a. Qualified a -> Maybe ModuleName
getQual (Qualified QualifiedBy
qb a
_) = QualifiedBy -> Maybe ModuleName
toMaybeModuleName QualifiedBy
qb

-- |
-- Provide a default module name, if a name is unqualified
--
qualify :: ModuleName -> Qualified a -> (ModuleName, a)
qualify :: forall a. ModuleName -> Qualified a -> (ModuleName, a)
qualify ModuleName
m (Qualified (BySourcePos SourcePos
_) a
a) = (ModuleName
m, a
a)
qualify ModuleName
_ (Qualified (ByModuleName ModuleName
m) a
a) = (ModuleName
m, a
a)

-- |
-- Makes a qualified value from a name and module name.
--
mkQualified :: a -> ModuleName -> Qualified a
mkQualified :: forall a. a -> ModuleName -> Qualified a
mkQualified a
name ModuleName
mn = forall a. QualifiedBy -> a -> Qualified a
Qualified (ModuleName -> QualifiedBy
ByModuleName ModuleName
mn) a
name

-- | Remove the module name from a qualified name
disqualify :: Qualified a -> a
disqualify :: forall a. Qualified a -> a
disqualify (Qualified QualifiedBy
_ a
a) = a
a

-- |
-- Remove the qualification from a value when it is qualified with a particular
-- module name.
--
disqualifyFor :: Maybe ModuleName -> Qualified a -> Maybe a
disqualifyFor :: forall a. Maybe ModuleName -> Qualified a -> Maybe a
disqualifyFor Maybe ModuleName
mn (Qualified QualifiedBy
qb a
a) | Maybe ModuleName
mn forall a. Eq a => a -> a -> Bool
== QualifiedBy -> Maybe ModuleName
toMaybeModuleName QualifiedBy
qb = forall a. a -> Maybe a
Just a
a
disqualifyFor Maybe ModuleName
_ Qualified a
_ = forall a. Maybe a
Nothing

-- |
-- Checks whether a qualified value is actually qualified with a module reference
--
isQualified :: Qualified a -> Bool
isQualified :: forall a. Qualified a -> Bool
isQualified (Qualified (BySourcePos  SourcePos
_) a
_) = Bool
False
isQualified Qualified a
_ = Bool
True

-- |
-- Checks whether a qualified value is not actually qualified with a module reference
--
isUnqualified :: Qualified a -> Bool
isUnqualified :: forall a. Qualified a -> Bool
isUnqualified = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Qualified a -> Bool
isQualified

-- |
-- Checks whether a qualified value is qualified with a particular module
--
isQualifiedWith :: ModuleName -> Qualified a -> Bool
isQualifiedWith :: forall a. ModuleName -> Qualified a -> Bool
isQualifiedWith ModuleName
mn (Qualified (ByModuleName ModuleName
mn') a
_) = ModuleName
mn forall a. Eq a => a -> a -> Bool
== ModuleName
mn'
isQualifiedWith ModuleName
_ Qualified a
_ = Bool
False

instance ToJSON a => ToJSON (Qualified a) where
  toJSON :: Qualified a -> Value
toJSON (Qualified QualifiedBy
qb a
a) = case QualifiedBy
qb of
    ByModuleName ModuleName
mn -> forall (f :: * -> * -> *) a b.
(ToJSON2 f, ToJSON a, ToJSON b) =>
f a b -> Value
toJSON2 (ModuleName
mn, a
a)
    BySourcePos SourcePos
ss -> forall (f :: * -> * -> *) a b.
(ToJSON2 f, ToJSON a, ToJSON b) =>
f a b -> Value
toJSON2 (SourcePos
ss, a
a)

instance FromJSON a => FromJSON (Qualified a) where
  parseJSON :: Value -> Parser (Qualified a)
parseJSON Value
v = Parser (Qualified a)
byModule forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Qualified a)
bySourcePos forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Qualified a)
byMaybeModuleName'
    where
    byModule :: Parser (Qualified a)
byModule = do
      (ModuleName
mn, a
a) <- forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Value -> Parser (f a b)
parseJSON2 Value
v
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. QualifiedBy -> a -> Qualified a
Qualified (ModuleName -> QualifiedBy
ByModuleName ModuleName
mn) a
a
    bySourcePos :: Parser (Qualified a)
bySourcePos = do
      (SourcePos
ss, a
a) <- forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Value -> Parser (f a b)
parseJSON2 Value
v
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. QualifiedBy -> a -> Qualified a
Qualified (SourcePos -> QualifiedBy
BySourcePos SourcePos
ss) a
a
    byMaybeModuleName' :: Parser (Qualified a)
byMaybeModuleName' = do
      (Maybe ModuleName
mn, a
a) <- forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Value -> Parser (f a b)
parseJSON2 Value
v
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. QualifiedBy -> a -> Qualified a
Qualified (Maybe ModuleName -> QualifiedBy
byMaybeModuleName Maybe ModuleName
mn) a
a

instance ToJSON ModuleName where
  toJSON :: ModuleName -> Value
toJSON (ModuleName Text
name) = forall a. ToJSON a => a -> Value
toJSON (Text -> Text -> [Text]
T.splitOn Text
"." Text
name)

instance FromJSON ModuleName where
  parseJSON :: Value -> Parser ModuleName
parseJSON = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"ModuleName" forall a b. (a -> b) -> a -> b
$ \Array
names -> do
    Vector Text
names' <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall a. FromJSON a => Value -> Parser a
parseJSON Array
names
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> ModuleName
ModuleName (Text -> [Text] -> Text
T.intercalate Text
"." (forall a. Vector a -> [a]
V.toList Vector Text
names')))

instance ToJSONKey ModuleName where
  toJSONKey :: ToJSONKeyFunction ModuleName
toJSONKey = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ModuleName -> Text
runModuleName forall a. ToJSONKey a => ToJSONKeyFunction a
toJSONKey

instance FromJSONKey ModuleName where
  fromJSONKey :: FromJSONKeyFunction ModuleName
fromJSONKey = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ModuleName
moduleNameFromString forall a. FromJSONKey a => FromJSONKeyFunction a
fromJSONKey

$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''InternalIdentData)
$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''Ident)