{- |
    Module      :  $Header$
    Description :  Computation of export interface
    Copyright   :  (c) 2000 - 2004 Wolfgang Lux
                       2005        Martin Engelke
                       2011 - 2016 Björn Peemöller
                       2015        Jan Tikovsky
                       2016        Finn Teegen
    License     :  BSD-3-clause

    Maintainer  :  bjp@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

    This module provides the computation of the exported interface of a
    compiled module. The function 'exportInterface' uses the expanded export
    specifications and the corresponding environments in order to compute
    the interface of the module.
-}
module Exports (exportInterface) where

import           Data.List         (nub)
import qualified Data.Map   as Map (foldrWithKey, toList)
import           Data.Maybe        (mapMaybe)
import qualified Data.Set   as Set ( Set, empty, insert, deleteMin, fromList
                                   , member, toList )

import Curry.Base.Position
import Curry.Base.SpanInfo
import Curry.Base.Ident
import Curry.Syntax

import Base.CurryKinds (fromKind')
import Base.CurryTypes (fromQualType, fromQualPredType)
import Base.Messages
import Base.Types

import Env.Class
import Env.OpPrec          (OpPrecEnv, PrecInfo (..), OpPrec (..), qualLookupP)
import Env.Instance
import Env.TypeConstructor ( TCEnv, TypeInfo (..), tcKind, clsKind
                           , qualLookupTypeInfo )
import Env.Value           (ValueEnv, ValueInfo (..), qualLookupValue)

import CompilerEnv

import Base.Kinds

-- ---------------------------------------------------------------------------
-- Computation of the interface
-- ---------------------------------------------------------------------------

-- After checking that the interface is not ambiguous, the compiler
-- generates the interface's declarations from the list of exported
-- functions and values. In order to make the interface more stable
-- against private changes in the module, we remove the hidden data
-- constructors of a data type in the interface when they occur
-- right-most in the declaration. In addition, newtypes whose constructor
-- is not exported are transformed into (abstract) data types.
--
-- If a type is imported from another module, its name is qualified with
-- the name of the module where it is defined. The same applies to an
-- exported function.

exportInterface :: CompilerEnv -> Module a -> Interface
exportInterface :: CompilerEnv -> Module a -> Interface
exportInterface env :: CompilerEnv
env (Module _ _ _ m :: ModuleIdent
m (Just (Exporting _ es :: [Export]
es)) _ _) =
  ModuleIdent
-> [Export]
-> OpPrecEnv
-> TCEnv
-> ValueEnv
-> ClassEnv
-> InstEnv
-> Interface
exportInterface' ModuleIdent
m [Export]
es (CompilerEnv -> OpPrecEnv
opPrecEnv CompilerEnv
env) (CompilerEnv -> TCEnv
tyConsEnv CompilerEnv
env) (CompilerEnv -> ValueEnv
valueEnv CompilerEnv
env)
    (CompilerEnv -> ClassEnv
classEnv CompilerEnv
env) (CompilerEnv -> InstEnv
instEnv CompilerEnv
env)
exportInterface _   (Module _ _ _ _ Nothing                 _ _) =
  String -> Interface
forall a. String -> a
internalError "Exports.exportInterface: no export specification"

exportInterface' :: ModuleIdent -> [Export] -> OpPrecEnv -> TCEnv -> ValueEnv
                 -> ClassEnv -> InstEnv -> Interface
exportInterface' :: ModuleIdent
-> [Export]
-> OpPrecEnv
-> TCEnv
-> ValueEnv
-> ClassEnv
-> InstEnv
-> Interface
exportInterface' m :: ModuleIdent
m es :: [Export]
es pEnv :: OpPrecEnv
pEnv tcEnv :: TCEnv
tcEnv vEnv :: ValueEnv
vEnv clsEnv :: ClassEnv
clsEnv inEnv :: InstEnv
inEnv = ModuleIdent -> [IImportDecl] -> [IDecl] -> Interface
Interface ModuleIdent
m [IImportDecl]
imports [IDecl]
decls'
  where
  tvs :: [Ident]
tvs     = (Ident -> Bool) -> [Ident] -> [Ident]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ident -> [Ident] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Ident]
tcs) [Ident]
identSupply
  tcs :: [Ident]
tcs     = (QualIdent -> Maybe Ident) -> [QualIdent] -> [Ident]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (ModuleIdent -> QualIdent -> Maybe Ident
localIdent ModuleIdent
m) ([QualIdent] -> [Ident]) -> [QualIdent] -> [Ident]
forall a b. (a -> b) -> a -> b
$ [IDecl] -> [QualIdent]
definedTypes [IDecl]
decls'
  imports :: [IImportDecl]
imports = (ModuleIdent -> IImportDecl) -> [ModuleIdent] -> [IImportDecl]
forall a b. (a -> b) -> [a] -> [b]
map (Position -> ModuleIdent -> IImportDecl
IImportDecl Position
NoPos) ([ModuleIdent] -> [IImportDecl]) -> [ModuleIdent] -> [IImportDecl]
forall a b. (a -> b) -> a -> b
$ [IDecl] -> [ModuleIdent]
usedModules [IDecl]
decls'
  precs :: [IDecl]
precs   = (Export -> [IDecl] -> [IDecl]) -> [IDecl] -> [Export] -> [IDecl]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ModuleIdent -> OpPrecEnv -> Export -> [IDecl] -> [IDecl]
infixDecl ModuleIdent
m OpPrecEnv
pEnv) [] [Export]
es
  types :: [IDecl]
types   = (Export -> [IDecl] -> [IDecl]) -> [IDecl] -> [Export] -> [IDecl]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ModuleIdent
-> TCEnv -> ClassEnv -> [Ident] -> Export -> [IDecl] -> [IDecl]
typeDecl ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv [Ident]
tvs) [] [Export]
es
  values :: [IDecl]
values  = (Export -> [IDecl] -> [IDecl]) -> [IDecl] -> [Export] -> [IDecl]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ModuleIdent -> ValueEnv -> [Ident] -> Export -> [IDecl] -> [IDecl]
valueDecl ModuleIdent
m ValueEnv
vEnv [Ident]
tvs) [] [Export]
es
  insts :: [IDecl]
insts   = (InstIdent -> InstInfo -> [IDecl] -> [IDecl])
-> [IDecl] -> InstEnv -> [IDecl]
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
Map.foldrWithKey (ModuleIdent
-> TCEnv -> [Ident] -> InstIdent -> InstInfo -> [IDecl] -> [IDecl]
instDecl ModuleIdent
m TCEnv
tcEnv [Ident]
tvs) [] InstEnv
inEnv
  decls :: [IDecl]
decls   = [IDecl]
precs [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++ [IDecl]
types [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++ [IDecl]
values [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++ [IDecl]
insts
  decls' :: [IDecl]
decls'  = ModuleIdent
-> TCEnv
-> ClassEnv
-> InstEnv
-> [Ident]
-> Set IInfo
-> [IDecl]
-> [IDecl]
closeInterface ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv InstEnv
inEnv [Ident]
tvs Set IInfo
forall a. Set a
Set.empty [IDecl]
decls

infixDecl :: ModuleIdent -> OpPrecEnv -> Export -> [IDecl] -> [IDecl]
infixDecl :: ModuleIdent -> OpPrecEnv -> Export -> [IDecl] -> [IDecl]
infixDecl m :: ModuleIdent
m pEnv :: OpPrecEnv
pEnv (Export             _ f :: QualIdent
f) ds :: [IDecl]
ds = ModuleIdent -> OpPrecEnv -> QualIdent -> [IDecl] -> [IDecl]
iInfixDecl ModuleIdent
m OpPrecEnv
pEnv QualIdent
f [IDecl]
ds
infixDecl m :: ModuleIdent
m pEnv :: OpPrecEnv
pEnv (ExportTypeWith _ tc :: QualIdent
tc cs :: [Ident]
cs) ds :: [IDecl]
ds =
  (Ident -> [IDecl] -> [IDecl]) -> [IDecl] -> [Ident] -> [IDecl]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (ModuleIdent -> OpPrecEnv -> QualIdent -> [IDecl] -> [IDecl]
iInfixDecl ModuleIdent
m OpPrecEnv
pEnv (QualIdent -> [IDecl] -> [IDecl])
-> (Ident -> QualIdent) -> Ident -> [IDecl] -> [IDecl]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> Ident -> QualIdent
qualifyLike QualIdent
tc) [IDecl]
ds [Ident]
cs
infixDecl _ _ _ _ = String -> [IDecl]
forall a. String -> a
internalError "Exports.infixDecl: no pattern match"

iInfixDecl :: ModuleIdent -> OpPrecEnv -> QualIdent -> [IDecl] -> [IDecl]
iInfixDecl :: ModuleIdent -> OpPrecEnv -> QualIdent -> [IDecl] -> [IDecl]
iInfixDecl m :: ModuleIdent
m pEnv :: OpPrecEnv
pEnv op :: QualIdent
op ds :: [IDecl]
ds = case QualIdent -> OpPrecEnv -> [PrecInfo]
qualLookupP QualIdent
op OpPrecEnv
pEnv of
  []                        -> [IDecl]
ds
  [PrecInfo _ (OpPrec f :: Infix
f p :: Precedence
p)] -> Position -> Infix -> Precedence -> QualIdent -> IDecl
IInfixDecl Position
NoPos Infix
f Precedence
p (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
op) IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
  _                         -> String -> [IDecl]
forall a. String -> a
internalError "Exports.infixDecl"

-- Data types and renaming types whose constructors and field labels are
-- not exported are exported as abstract types, i.e., their constructors
-- do not appear in the interface. If only some constructors or field
-- labels of a type are not exported all constructors appear in the
-- interface, but a pragma marks the constructors and field labels which
-- are not exported as hidden to prevent their use in user code.

typeDecl :: ModuleIdent -> TCEnv -> ClassEnv -> [Ident] -> Export -> [IDecl]
         -> [IDecl]
typeDecl :: ModuleIdent
-> TCEnv -> ClassEnv -> [Ident] -> Export -> [IDecl] -> [IDecl]
typeDecl _ _     _      _   (Export             _ _) ds :: [IDecl]
ds = [IDecl]
ds
typeDecl m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv clsEnv :: ClassEnv
clsEnv tvs :: [Ident]
tvs (ExportTypeWith _ tc :: QualIdent
tc xs :: [Ident]
xs) ds :: [IDecl]
ds =
  case QualIdent -> TCEnv -> [TypeInfo]
qualLookupTypeInfo QualIdent
tc TCEnv
tcEnv of
    [DataType tc' :: QualIdent
tc' k :: Kind
k cs :: [DataConstr]
cs]
      | [Ident] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Ident]
xs   -> (Position
 -> QualIdent
 -> Maybe KindExpr
 -> [Ident]
 -> [ConstrDecl]
 -> [Ident]
 -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> [ConstrDecl]
-> [Ident]
-> IDecl
forall a.
(Position
 -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> a
-> [Ident]
-> IDecl
iTypeDecl Position
-> QualIdent
-> Maybe KindExpr
-> [Ident]
-> [ConstrDecl]
-> [Ident]
-> IDecl
IDataDecl ModuleIdent
m [Ident]
tvs QualIdent
tc' Kind
k []  [] IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      | Bool
otherwise -> (Position
 -> QualIdent
 -> Maybe KindExpr
 -> [Ident]
 -> [ConstrDecl]
 -> [Ident]
 -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> [ConstrDecl]
-> [Ident]
-> IDecl
forall a.
(Position
 -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> a
-> [Ident]
-> IDecl
iTypeDecl Position
-> QualIdent
-> Maybe KindExpr
-> [Ident]
-> [ConstrDecl]
-> [Ident]
-> IDecl
IDataDecl ModuleIdent
m [Ident]
tvs QualIdent
tc' Kind
k [ConstrDecl]
cs' [Ident]
hs IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      where hs :: [Ident]
hs    = (Ident -> Bool) -> [Ident] -> [Ident]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ident -> [Ident] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Ident]
xs) ([Ident]
csIds [Ident] -> [Ident] -> [Ident]
forall a. [a] -> [a] -> [a]
++ [Ident]
ls)
            cs' :: [ConstrDecl]
cs'   = (DataConstr -> ConstrDecl) -> [DataConstr] -> [ConstrDecl]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleIdent -> Int -> [Ident] -> DataConstr -> ConstrDecl
constrDecl ModuleIdent
m Int
n [Ident]
tvs) [DataConstr]
cs
            ls :: [Ident]
ls    = [Ident] -> [Ident]
forall a. Eq a => [a] -> [a]
nub ((ConstrDecl -> [Ident]) -> [ConstrDecl] -> [Ident]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ConstrDecl -> [Ident]
recordLabels [ConstrDecl]
cs')
            csIds :: [Ident]
csIds = (DataConstr -> Ident) -> [DataConstr] -> [Ident]
forall a b. (a -> b) -> [a] -> [b]
map DataConstr -> Ident
constrIdent [DataConstr]
cs
            n :: Int
n = Kind -> Int
kindArity Kind
k
    [RenamingType tc' :: QualIdent
tc' k :: Kind
k c :: DataConstr
c]
      | [Ident] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Ident]
xs   -> (Position
 -> QualIdent
 -> Maybe KindExpr
 -> [Ident]
 -> [ConstrDecl]
 -> [Ident]
 -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> [ConstrDecl]
-> [Ident]
-> IDecl
forall a.
(Position
 -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> a
-> [Ident]
-> IDecl
iTypeDecl Position
-> QualIdent
-> Maybe KindExpr
-> [Ident]
-> [ConstrDecl]
-> [Ident]
-> IDecl
IDataDecl    ModuleIdent
m [Ident]
tvs QualIdent
tc' Kind
k [] [] IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      | Bool
otherwise -> (Position
 -> QualIdent
 -> Maybe KindExpr
 -> [Ident]
 -> NewConstrDecl
 -> [Ident]
 -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> NewConstrDecl
-> [Ident]
-> IDecl
forall a.
(Position
 -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> a
-> [Ident]
-> IDecl
iTypeDecl Position
-> QualIdent
-> Maybe KindExpr
-> [Ident]
-> NewConstrDecl
-> [Ident]
-> IDecl
INewtypeDecl ModuleIdent
m [Ident]
tvs QualIdent
tc' Kind
k NewConstrDecl
nc [Ident]
hs IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      where hs :: [Ident]
hs  = (Ident -> Bool) -> [Ident] -> [Ident]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ident -> [Ident] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Ident]
xs) (Ident
cId Ident -> [Ident] -> [Ident]
forall a. a -> [a] -> [a]
: [Ident]
ls)
            nc :: NewConstrDecl
nc  = ModuleIdent -> [Ident] -> DataConstr -> NewConstrDecl
newConstrDecl ModuleIdent
m [Ident]
tvs DataConstr
c
            ls :: [Ident]
ls  = NewConstrDecl -> [Ident]
nrecordLabels NewConstrDecl
nc
            cId :: Ident
cId = DataConstr -> Ident
constrIdent DataConstr
c
    [AliasType tc' :: QualIdent
tc' k :: Kind
k n :: Int
n ty :: Type
ty] -> Position
-> QualIdent -> Maybe KindExpr -> [Ident] -> TypeExpr -> IDecl
ITypeDecl Position
NoPos QualIdent
tc'' Maybe KindExpr
k' [Ident]
tvs' TypeExpr
ty' IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      where tc'' :: QualIdent
tc'' = ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
tc'
            k' :: Maybe KindExpr
k'   = Kind -> Int -> Maybe KindExpr
fromKind' Kind
k Int
n
            tvs' :: [Ident]
tvs' = Int -> [Ident] -> [Ident]
forall a. Int -> [a] -> [a]
take Int
n [Ident]
tvs
            ty' :: TypeExpr
ty'  = ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs' Type
ty
    [TypeClass qcls :: QualIdent
qcls k :: Kind
k ms :: [ClassMethod]
ms] -> Position
-> Context
-> QualIdent
-> Maybe KindExpr
-> Ident
-> [IMethodDecl]
-> [Ident]
-> IDecl
IClassDecl Position
NoPos Context
cx QualIdent
qcls' Maybe KindExpr
k' Ident
tv [IMethodDecl]
ms' [Ident]
hs IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
      where qcls' :: QualIdent
qcls' = ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
qcls
            cx :: Context
cx    = [ SpanInfo -> QualIdent -> TypeExpr -> Constraint
Constraint SpanInfo
NoSpanInfo (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
scls)
                        (SpanInfo -> Ident -> TypeExpr
VariableType SpanInfo
NoSpanInfo Ident
tv)
                    | QualIdent
scls <- QualIdent -> ClassEnv -> [QualIdent]
superClasses QualIdent
qcls ClassEnv
clsEnv ]
            k' :: Maybe KindExpr
k'    = Kind -> Int -> Maybe KindExpr
fromKind' Kind
k 0
            tv :: Ident
tv    = [Ident] -> Ident
forall a. [a] -> a
head [Ident]
tvs
            ms' :: [IMethodDecl]
ms'   = (ClassMethod -> IMethodDecl) -> [ClassMethod] -> [IMethodDecl]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleIdent -> [Ident] -> ClassMethod -> IMethodDecl
methodDecl ModuleIdent
m [Ident]
tvs) [ClassMethod]
ms
            hs :: [Ident]
hs    = (Ident -> Bool) -> [Ident] -> [Ident]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ident -> [Ident] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Ident]
xs) ((ClassMethod -> Ident) -> [ClassMethod] -> [Ident]
forall a b. (a -> b) -> [a] -> [b]
map ClassMethod -> Ident
methodName [ClassMethod]
ms)
    _ -> String -> [IDecl]
forall a. String -> a
internalError "Exports.typeDecl"
typeDecl _ _ _ _ _ _ = String -> [IDecl]
forall a. String -> a
internalError "Exports.typeDecl: no pattern match"

iTypeDecl
  :: (Position -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
  -> ModuleIdent -> [Ident] -> QualIdent -> Kind -> a -> [Ident] -> IDecl
iTypeDecl :: (Position
 -> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl)
-> ModuleIdent
-> [Ident]
-> QualIdent
-> Kind
-> a
-> [Ident]
-> IDecl
iTypeDecl f :: Position
-> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl
f m :: ModuleIdent
m tvs :: [Ident]
tvs tc :: QualIdent
tc k :: Kind
k x :: a
x hs :: [Ident]
hs = Position
-> QualIdent -> Maybe KindExpr -> [Ident] -> a -> [Ident] -> IDecl
f Position
NoPos (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
tc) Maybe KindExpr
k' (Int -> [Ident] -> [Ident]
forall a. Int -> [a] -> [a]
take Int
n [Ident]
tvs) a
x [Ident]
hs
  where n :: Int
n  = Kind -> Int
kindArity Kind
k
        k' :: Maybe KindExpr
k' = Kind -> Int -> Maybe KindExpr
fromKind' Kind
k Int
n

constrDecl :: ModuleIdent -> Int -> [Ident] -> DataConstr -> ConstrDecl
constrDecl :: ModuleIdent -> Int -> [Ident] -> DataConstr -> ConstrDecl
constrDecl m :: ModuleIdent
m _ tvs :: [Ident]
tvs (DataConstr c :: Ident
c [ty1 :: Type
ty1, ty2 :: Type
ty2])
  | Ident -> Bool
isInfixOp Ident
c = SpanInfo -> TypeExpr -> Ident -> TypeExpr -> ConstrDecl
ConOpDecl SpanInfo
NoSpanInfo TypeExpr
ty1' Ident
c TypeExpr
ty2'
  where [ty1' :: TypeExpr
ty1', ty2' :: TypeExpr
ty2'] = (Type -> TypeExpr) -> [Type] -> [TypeExpr]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs) [Type
ty1, Type
ty2]
constrDecl m :: ModuleIdent
m _ tvs :: [Ident]
tvs (DataConstr c :: Ident
c tys :: [Type]
tys) =
  SpanInfo -> Ident -> [TypeExpr] -> ConstrDecl
ConstrDecl SpanInfo
NoSpanInfo Ident
c [TypeExpr]
tys'
  where tys' :: [TypeExpr]
tys' = (Type -> TypeExpr) -> [Type] -> [TypeExpr]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs) [Type]
tys
constrDecl m :: ModuleIdent
m _ tvs :: [Ident]
tvs (RecordConstr c :: Ident
c ls :: [Ident]
ls tys :: [Type]
tys) =
  SpanInfo -> Ident -> [FieldDecl] -> ConstrDecl
RecordDecl SpanInfo
NoSpanInfo Ident
c [FieldDecl]
fs
  where
    tys' :: [TypeExpr]
tys' = (Type -> TypeExpr) -> [Type] -> [TypeExpr]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs) [Type]
tys
    fs :: [FieldDecl]
fs   = (Ident -> TypeExpr -> FieldDecl)
-> [Ident] -> [TypeExpr] -> [FieldDecl]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (SpanInfo -> [Ident] -> TypeExpr -> FieldDecl
FieldDecl SpanInfo
NoSpanInfo ([Ident] -> TypeExpr -> FieldDecl)
-> (Ident -> [Ident]) -> Ident -> TypeExpr -> FieldDecl
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> [Ident]
forall (m :: * -> *) a. Monad m => a -> m a
return) [Ident]
ls [TypeExpr]
tys'

newConstrDecl :: ModuleIdent -> [Ident] -> DataConstr -> NewConstrDecl
newConstrDecl :: ModuleIdent -> [Ident] -> DataConstr -> NewConstrDecl
newConstrDecl m :: ModuleIdent
m tvs :: [Ident]
tvs (DataConstr c :: Ident
c tys :: [Type]
tys)
  = SpanInfo -> Ident -> TypeExpr -> NewConstrDecl
NewConstrDecl SpanInfo
NoSpanInfo Ident
c (ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs ([Type] -> Type
forall a. [a] -> a
head [Type]
tys))
newConstrDecl m :: ModuleIdent
m tvs :: [Ident]
tvs (RecordConstr c :: Ident
c ls :: [Ident]
ls tys :: [Type]
tys)
  = SpanInfo -> Ident -> (Ident, TypeExpr) -> NewConstrDecl
NewRecordDecl SpanInfo
NoSpanInfo Ident
c ([Ident] -> Ident
forall a. [a] -> a
head [Ident]
ls, ModuleIdent -> [Ident] -> Type -> TypeExpr
fromQualType ModuleIdent
m [Ident]
tvs ([Type] -> Type
forall a. [a] -> a
head [Type]
tys))

-- When exporting a class method, we have to remove the implicit class context.
-- Due to the sorting of the predicate set, this is fortunatly very easy. The
-- implicit class context is always the minimum element as the class variable
-- is assigned the index 0 and no other constraints on it are allowed.

methodDecl :: ModuleIdent -> [Ident] -> ClassMethod -> IMethodDecl
methodDecl :: ModuleIdent -> [Ident] -> ClassMethod -> IMethodDecl
methodDecl m :: ModuleIdent
m tvs :: [Ident]
tvs (ClassMethod f :: Ident
f a :: Maybe Int
a (PredType ps :: PredSet
ps ty :: Type
ty)) = Position -> Ident -> Maybe Int -> QualTypeExpr -> IMethodDecl
IMethodDecl Position
NoPos Ident
f Maybe Int
a (QualTypeExpr -> IMethodDecl) -> QualTypeExpr -> IMethodDecl
forall a b. (a -> b) -> a -> b
$
  ModuleIdent -> [Ident] -> PredType -> QualTypeExpr
fromQualPredType ModuleIdent
m [Ident]
tvs (PredType -> QualTypeExpr) -> PredType -> QualTypeExpr
forall a b. (a -> b) -> a -> b
$ PredSet -> Type -> PredType
PredType (PredSet -> PredSet
forall a. Set a -> Set a
Set.deleteMin PredSet
ps) Type
ty

valueDecl :: ModuleIdent -> ValueEnv -> [Ident] -> Export -> [IDecl] -> [IDecl]
valueDecl :: ModuleIdent -> ValueEnv -> [Ident] -> Export -> [IDecl] -> [IDecl]
valueDecl m :: ModuleIdent
m vEnv :: ValueEnv
vEnv tvs :: [Ident]
tvs (Export     _ f :: QualIdent
f) ds :: [IDecl]
ds = case QualIdent -> ValueEnv -> [ValueInfo]
qualLookupValue QualIdent
f ValueEnv
vEnv of
  [Value _ cm :: Maybe QualIdent
cm a :: Int
a (ForAll _ pty :: PredType
pty)] ->
    Position
-> QualIdent -> Maybe Ident -> Int -> QualTypeExpr -> IDecl
IFunctionDecl Position
NoPos (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
f)
      ((QualIdent -> Ident) -> Maybe QualIdent -> Maybe Ident
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ident -> QualIdent -> Ident
forall a b. a -> b -> a
const ([Ident] -> Ident
forall a. [a] -> a
head [Ident]
tvs)) Maybe QualIdent
cm) Int
a (ModuleIdent -> [Ident] -> PredType -> QualTypeExpr
fromQualPredType ModuleIdent
m [Ident]
tvs PredType
pty) IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
  [Label _ _ _ ] -> [IDecl]
ds -- Record labels are collected somewhere else.
  _ -> String -> [IDecl]
forall a. String -> a
internalError (String -> [IDecl]) -> String -> [IDecl]
forall a b. (a -> b) -> a -> b
$ "Exports.valueDecl: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
f
valueDecl _ _ _ (ExportTypeWith _ _ _) ds :: [IDecl]
ds = [IDecl]
ds
valueDecl _ _ _ _ _ = String -> [IDecl]
forall a. String -> a
internalError "Exports.valueDecl: no pattern match"

instDecl :: ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> [IDecl]
         -> [IDecl]
instDecl :: ModuleIdent
-> TCEnv -> [Ident] -> InstIdent -> InstInfo -> [IDecl] -> [IDecl]
instDecl m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv tvs :: [Ident]
tvs ident :: InstIdent
ident@(cls :: QualIdent
cls, tc :: QualIdent
tc) info :: InstInfo
info@(m' :: ModuleIdent
m', _, _) ds :: [IDecl]
ds
  | QualIdent -> Maybe ModuleIdent
qidModule QualIdent
cls Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
/= ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m' Bool -> Bool -> Bool
&& QualIdent -> Maybe ModuleIdent
qidModule QualIdent
tc Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
/= ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m' =
    ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> IDecl
iInstDecl ModuleIdent
m TCEnv
tcEnv [Ident]
tvs InstIdent
ident InstInfo
info IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: [IDecl]
ds
  | Bool
otherwise = [IDecl]
ds

iInstDecl :: ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> IDecl
iInstDecl :: ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> IDecl
iInstDecl m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv tvs :: [Ident]
tvs (cls :: QualIdent
cls, tc :: QualIdent
tc) (m' :: ModuleIdent
m', ps :: PredSet
ps, is :: [(Ident, Int)]
is) =
  Position
-> Context
-> QualIdent
-> TypeExpr
-> [(Ident, Int)]
-> Maybe ModuleIdent
-> IDecl
IInstanceDecl Position
NoPos Context
cx (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
cls) TypeExpr
ty [(Ident, Int)]
is Maybe ModuleIdent
mm
  where pty :: PredType
pty = PredSet -> Type -> PredType
PredType PredSet
ps (Type -> PredType) -> Type -> PredType
forall a b. (a -> b) -> a -> b
$ Type -> [Type] -> Type
applyType (QualIdent -> Type
TypeConstructor QualIdent
tc) ([Type] -> Type) -> [Type] -> Type
forall a b. (a -> b) -> a -> b
$
                (Int -> Type) -> [Int] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Type
TypeVariable [0 .. Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1]
        QualTypeExpr _ cx :: Context
cx ty :: TypeExpr
ty = ModuleIdent -> [Ident] -> PredType -> QualTypeExpr
fromQualPredType ModuleIdent
m [Ident]
tvs PredType
pty
        n :: Int
n = Kind -> Int
kindArity (ModuleIdent -> QualIdent -> TCEnv -> Kind
tcKind ModuleIdent
m QualIdent
tc TCEnv
tcEnv) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Kind -> Int
kindArity (ModuleIdent -> QualIdent -> TCEnv -> Kind
clsKind ModuleIdent
m QualIdent
cls TCEnv
tcEnv)
        mm :: Maybe ModuleIdent
mm = if ModuleIdent
m ModuleIdent -> ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleIdent
m' then Maybe ModuleIdent
forall a. Maybe a
Nothing else ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m'

-- The compiler determines the list of imported modules from the set of
-- module qualifiers that are used in the interface. Careful readers
-- probably will have noticed that the functions above carefully strip
-- the module prefix from all entities that are defined in the current
-- module. Note that the list of modules returned from
-- 'usedModules' is not necessarily a subset of the modules that
-- were imported into the current module. This will happen when an
-- imported module re-exports entities from another module. E.g., given
-- the three modules
--
-- @
-- module A where { data A = A; }
-- module B(A(..)) where { import A; }
-- module C where { import B; x = A; }
-- @
--
-- the interface for module @C@ will import module @A@ but not module @B@.

usedModules :: [IDecl] -> [ModuleIdent]
usedModules :: [IDecl] -> [ModuleIdent]
usedModules ds :: [IDecl]
ds = [ModuleIdent] -> [ModuleIdent]
nub' ([IDecl] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [IDecl]
ds [])
  where nub' :: [ModuleIdent] -> [ModuleIdent]
nub' = Set ModuleIdent -> [ModuleIdent]
forall a. Set a -> [a]
Set.toList (Set ModuleIdent -> [ModuleIdent])
-> ([ModuleIdent] -> Set ModuleIdent)
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ModuleIdent] -> Set ModuleIdent
forall a. Ord a => [a] -> Set a
Set.fromList

class HasModule a where
  modules :: a -> [ModuleIdent] -> [ModuleIdent]

instance HasModule a => HasModule (Maybe a) where
  modules :: Maybe a -> [ModuleIdent] -> [ModuleIdent]
modules = ([ModuleIdent] -> [ModuleIdent])
-> (a -> [ModuleIdent] -> [ModuleIdent])
-> Maybe a
-> [ModuleIdent]
-> [ModuleIdent]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [ModuleIdent] -> [ModuleIdent]
forall a. a -> a
id a -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules

instance HasModule a => HasModule [a] where
  modules :: [a] -> [ModuleIdent] -> [ModuleIdent]
modules xs :: [a]
xs ms :: [ModuleIdent]
ms = (a -> [ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent] -> [a] -> [ModuleIdent]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [ModuleIdent]
ms [a]
xs

instance HasModule IDecl where
  modules :: IDecl -> [ModuleIdent] -> [ModuleIdent]
modules (IInfixDecl            _ _ _ op :: QualIdent
op) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
op
  modules (HidingDataDecl        _ tc :: QualIdent
tc _ _) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
tc
  modules (IDataDecl        _ tc :: QualIdent
tc _ _ cs :: [ConstrDecl]
cs _) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
tc ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ConstrDecl] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [ConstrDecl]
cs
  modules (INewtypeDecl     _ tc :: QualIdent
tc _ _ nc :: NewConstrDecl
nc _) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
tc ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NewConstrDecl -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules NewConstrDecl
nc
  modules (ITypeDecl          _ tc :: QualIdent
tc _ _ ty :: TypeExpr
ty) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
tc ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty
  modules (IFunctionDecl      _ f :: QualIdent
f _ _ qty :: QualTypeExpr
qty) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
f ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualTypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualTypeExpr
qty
  modules (HidingClassDecl   _ cx :: Context
cx cls :: QualIdent
cls _ _) = Context -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules Context
cx ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
cls
  modules (IClassDecl   _ cx :: Context
cx cls :: QualIdent
cls _ _ ms :: [IMethodDecl]
ms _) =
    Context -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules Context
cx ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
cls ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [IMethodDecl] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [IMethodDecl]
ms
  modules (IInstanceDecl _ cx :: Context
cx cls :: QualIdent
cls ty :: TypeExpr
ty _ mm :: Maybe ModuleIdent
mm) =
    Context -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules Context
cx ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
cls ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe ModuleIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules Maybe ModuleIdent
mm

instance HasModule ConstrDecl where
  modules :: ConstrDecl -> [ModuleIdent] -> [ModuleIdent]
modules (ConstrDecl    _ _ tys :: [TypeExpr]
tys) = [TypeExpr] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [TypeExpr]
tys
  modules (ConOpDecl _ ty1 :: TypeExpr
ty1 _ ty2 :: TypeExpr
ty2) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty1 ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty2
  modules (RecordDecl     _ _ fs :: [FieldDecl]
fs) = [FieldDecl] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [FieldDecl]
fs

instance HasModule FieldDecl where
  modules :: FieldDecl -> [ModuleIdent] -> [ModuleIdent]
modules (FieldDecl _ _ ty :: TypeExpr
ty) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty

instance HasModule NewConstrDecl where
  modules :: NewConstrDecl -> [ModuleIdent] -> [ModuleIdent]
modules (NewConstrDecl _ _      ty :: TypeExpr
ty) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty
  modules (NewRecordDecl _ _ (_, ty :: TypeExpr
ty)) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty

instance HasModule IMethodDecl where
  modules :: IMethodDecl -> [ModuleIdent] -> [ModuleIdent]
modules (IMethodDecl _ _ _ qty :: QualTypeExpr
qty) = QualTypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualTypeExpr
qty

instance HasModule Constraint where
  modules :: Constraint -> [ModuleIdent] -> [ModuleIdent]
modules (Constraint _ cls :: QualIdent
cls ty :: TypeExpr
ty) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
cls ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty

instance HasModule TypeExpr where
  modules :: TypeExpr -> [ModuleIdent] -> [ModuleIdent]
modules (ConstructorType _ tc :: QualIdent
tc) = QualIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules QualIdent
tc
  modules (ApplyType  _ ty1 :: TypeExpr
ty1 ty2 :: TypeExpr
ty2) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty1 ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty2
  modules (VariableType     _ _) = [ModuleIdent] -> [ModuleIdent]
forall a. a -> a
id
  modules (TupleType      _ tys :: [TypeExpr]
tys) = [TypeExpr] -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules [TypeExpr]
tys
  modules (ListType        _ ty :: TypeExpr
ty) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty
  modules (ArrowType  _ ty1 :: TypeExpr
ty1 ty2 :: TypeExpr
ty2) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty1 ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty2
  modules (ParenType       _ ty :: TypeExpr
ty) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty
  modules (ForallType    _ _ ty :: TypeExpr
ty) = TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty

instance HasModule QualTypeExpr where
  modules :: QualTypeExpr -> [ModuleIdent] -> [ModuleIdent]
modules (QualTypeExpr _ cx :: Context
cx ty :: TypeExpr
ty) = Context -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules Context
cx ([ModuleIdent] -> [ModuleIdent])
-> ([ModuleIdent] -> [ModuleIdent])
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules TypeExpr
ty

instance HasModule QualIdent where
  modules :: QualIdent -> [ModuleIdent] -> [ModuleIdent]
modules = Maybe ModuleIdent -> [ModuleIdent] -> [ModuleIdent]
forall a. HasModule a => a -> [ModuleIdent] -> [ModuleIdent]
modules (Maybe ModuleIdent -> [ModuleIdent] -> [ModuleIdent])
-> (QualIdent -> Maybe ModuleIdent)
-> QualIdent
-> [ModuleIdent]
-> [ModuleIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> Maybe ModuleIdent
qidModule

instance HasModule ModuleIdent where
  modules :: ModuleIdent -> [ModuleIdent] -> [ModuleIdent]
modules = (:)

-- After the interface declarations have been computed, the compiler
-- eventually must add hidden (data) type and class declarations to the
-- interface for all those types and classs which were used in the interface
-- but not exported from the current module, so that these type constructors
-- can always be distinguished from type variables. Besides hidden type and
-- class declarations, the compiler also adds instance declarations to the
-- interface. Since class and instance declarations added to an interface can
-- require the inclusion of further classes by their respective contexts,
-- closing an interface is implemented as a fix-point computation which
-- starts from the initial interface.

data IInfo = IOther | IType QualIdent | IClass QualIdent | IInst InstIdent
  deriving (IInfo -> IInfo -> Bool
(IInfo -> IInfo -> Bool) -> (IInfo -> IInfo -> Bool) -> Eq IInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IInfo -> IInfo -> Bool
$c/= :: IInfo -> IInfo -> Bool
== :: IInfo -> IInfo -> Bool
$c== :: IInfo -> IInfo -> Bool
Eq, Eq IInfo
Eq IInfo =>
(IInfo -> IInfo -> Ordering)
-> (IInfo -> IInfo -> Bool)
-> (IInfo -> IInfo -> Bool)
-> (IInfo -> IInfo -> Bool)
-> (IInfo -> IInfo -> Bool)
-> (IInfo -> IInfo -> IInfo)
-> (IInfo -> IInfo -> IInfo)
-> Ord IInfo
IInfo -> IInfo -> Bool
IInfo -> IInfo -> Ordering
IInfo -> IInfo -> IInfo
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 :: IInfo -> IInfo -> IInfo
$cmin :: IInfo -> IInfo -> IInfo
max :: IInfo -> IInfo -> IInfo
$cmax :: IInfo -> IInfo -> IInfo
>= :: IInfo -> IInfo -> Bool
$c>= :: IInfo -> IInfo -> Bool
> :: IInfo -> IInfo -> Bool
$c> :: IInfo -> IInfo -> Bool
<= :: IInfo -> IInfo -> Bool
$c<= :: IInfo -> IInfo -> Bool
< :: IInfo -> IInfo -> Bool
$c< :: IInfo -> IInfo -> Bool
compare :: IInfo -> IInfo -> Ordering
$ccompare :: IInfo -> IInfo -> Ordering
$cp1Ord :: Eq IInfo
Ord)

iInfo :: IDecl -> IInfo
iInfo :: IDecl -> IInfo
iInfo (IInfixDecl           _ _ _ _) = IInfo
IOther
iInfo (HidingDataDecl      _ tc :: QualIdent
tc _ _) = QualIdent -> IInfo
IType QualIdent
tc
iInfo (IDataDecl       _ tc :: QualIdent
tc _ _ _ _) = QualIdent -> IInfo
IType QualIdent
tc
iInfo (INewtypeDecl    _ tc :: QualIdent
tc _ _ _ _) = QualIdent -> IInfo
IType QualIdent
tc
iInfo (ITypeDecl          _ _ _ _ _) = IInfo
IOther
iInfo (HidingClassDecl  _ _ cls :: QualIdent
cls _ _) = QualIdent -> IInfo
IClass QualIdent
cls
iInfo (IClassDecl   _ _ cls :: QualIdent
cls _ _ _ _) = QualIdent -> IInfo
IClass QualIdent
cls
iInfo (IInstanceDecl _ _ cls :: QualIdent
cls ty :: TypeExpr
ty _ _) = InstIdent -> IInfo
IInst (QualIdent
cls, TypeExpr -> QualIdent
typeConstr TypeExpr
ty)
iInfo (IFunctionDecl      _ _ _ _ _) = IInfo
IOther

closeInterface :: ModuleIdent -> TCEnv -> ClassEnv -> InstEnv -> [Ident]
               -> Set.Set IInfo -> [IDecl] -> [IDecl]
closeInterface :: ModuleIdent
-> TCEnv
-> ClassEnv
-> InstEnv
-> [Ident]
-> Set IInfo
-> [IDecl]
-> [IDecl]
closeInterface _ _ _ _ _ _ [] = []
closeInterface m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv clsEnv :: ClassEnv
clsEnv inEnv :: InstEnv
inEnv tvs :: [Ident]
tvs is :: Set IInfo
is (d :: IDecl
d:ds :: [IDecl]
ds)
  | IInfo
i IInfo -> IInfo -> Bool
forall a. Eq a => a -> a -> Bool
== IInfo
IOther       =
    IDecl
d IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: ModuleIdent
-> TCEnv
-> ClassEnv
-> InstEnv
-> [Ident]
-> Set IInfo
-> [IDecl]
-> [IDecl]
closeInterface ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv InstEnv
inEnv [Ident]
tvs Set IInfo
is ([IDecl]
ds [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++ [IDecl]
ds')
  | IInfo
i IInfo -> Set IInfo -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set IInfo
is = ModuleIdent
-> TCEnv
-> ClassEnv
-> InstEnv
-> [Ident]
-> Set IInfo
-> [IDecl]
-> [IDecl]
closeInterface ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv InstEnv
inEnv [Ident]
tvs Set IInfo
is [IDecl]
ds
  | Bool
otherwise         =
    IDecl
d IDecl -> [IDecl] -> [IDecl]
forall a. a -> [a] -> [a]
: ModuleIdent
-> TCEnv
-> ClassEnv
-> InstEnv
-> [Ident]
-> Set IInfo
-> [IDecl]
-> [IDecl]
closeInterface ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv InstEnv
inEnv [Ident]
tvs (IInfo -> Set IInfo -> Set IInfo
forall a. Ord a => a -> Set a -> Set a
Set.insert IInfo
i Set IInfo
is) ([IDecl]
ds [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++ [IDecl]
ds')
  where i :: IInfo
i   = IDecl -> IInfo
iInfo IDecl
d
        ds' :: [IDecl]
ds' = ModuleIdent -> TCEnv -> ClassEnv -> [Ident] -> IDecl -> [IDecl]
hiddenTypes ModuleIdent
m TCEnv
tcEnv ClassEnv
clsEnv [Ident]
tvs IDecl
d [IDecl] -> [IDecl] -> [IDecl]
forall a. [a] -> [a] -> [a]
++
                ModuleIdent
-> TCEnv -> InstEnv -> [Ident] -> Set IInfo -> IInfo -> [IDecl]
instances ModuleIdent
m TCEnv
tcEnv InstEnv
inEnv [Ident]
tvs Set IInfo
is IInfo
i

hiddenTypes :: ModuleIdent -> TCEnv -> ClassEnv -> [Ident] -> IDecl -> [IDecl]
hiddenTypes :: ModuleIdent -> TCEnv -> ClassEnv -> [Ident] -> IDecl -> [IDecl]
hiddenTypes m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv clsEnv :: ClassEnv
clsEnv tvs :: [Ident]
tvs d :: IDecl
d =
  (QualIdent -> IDecl) -> [QualIdent] -> [IDecl]
forall a b. (a -> b) -> [a] -> [b]
map QualIdent -> IDecl
hiddenTypeDecl ([QualIdent] -> [IDecl]) -> [QualIdent] -> [IDecl]
forall a b. (a -> b) -> a -> b
$ (QualIdent -> Bool) -> [QualIdent] -> [QualIdent]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (QualIdent -> Bool) -> QualIdent -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualIdent -> Bool
isPrimTypeId) (IDecl -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes IDecl
d [])
  where hiddenTypeDecl :: QualIdent -> IDecl
hiddenTypeDecl tc :: QualIdent
tc = case QualIdent -> TCEnv -> [TypeInfo]
qualLookupTypeInfo (ModuleIdent -> QualIdent -> QualIdent
qualQualify ModuleIdent
m QualIdent
tc) TCEnv
tcEnv of
          [DataType       _ k :: Kind
k _] -> Kind -> IDecl
hidingDataDecl Kind
k
          [RenamingType   _ k :: Kind
k _] -> Kind -> IDecl
hidingDataDecl Kind
k
          [TypeClass    cls :: QualIdent
cls k :: Kind
k _] -> Kind -> [QualIdent] -> IDecl
hidingClassDecl Kind
k ([QualIdent] -> IDecl) -> [QualIdent] -> IDecl
forall a b. (a -> b) -> a -> b
$ QualIdent -> ClassEnv -> [QualIdent]
superClasses QualIdent
cls ClassEnv
clsEnv
          _                      ->
            String -> IDecl
forall a. String -> a
internalError (String -> IDecl) -> String -> IDecl
forall a b. (a -> b) -> a -> b
$ "Exports.hiddenTypeDecl: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ QualIdent -> String
forall a. Show a => a -> String
show QualIdent
tc
          where hidingDataDecl :: Kind -> IDecl
hidingDataDecl k :: Kind
k =
                  let n :: Int
n = Kind -> Int
kindArity Kind
k
                      k' :: Maybe KindExpr
k' = Kind -> Int -> Maybe KindExpr
fromKind' Kind
k Int
n
                  in  Position -> QualIdent -> Maybe KindExpr -> [Ident] -> IDecl
HidingDataDecl Position
NoPos QualIdent
tc Maybe KindExpr
k' ([Ident] -> IDecl) -> [Ident] -> IDecl
forall a b. (a -> b) -> a -> b
$ Int -> [Ident] -> [Ident]
forall a. Int -> [a] -> [a]
take Int
n [Ident]
tvs
                hidingClassDecl :: Kind -> [QualIdent] -> IDecl
hidingClassDecl k :: Kind
k sclss :: [QualIdent]
sclss =
                  let cx :: Context
cx = [ SpanInfo -> QualIdent -> TypeExpr -> Constraint
Constraint SpanInfo
NoSpanInfo (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
scls)
                               (SpanInfo -> Ident -> TypeExpr
VariableType SpanInfo
NoSpanInfo Ident
tv)
                           | QualIdent
scls <- [QualIdent]
sclss ]
                      tv :: Ident
tv = [Ident] -> Ident
forall a. [a] -> a
head [Ident]
tvs
                      k' :: Maybe KindExpr
k' = Kind -> Int -> Maybe KindExpr
fromKind' Kind
k 0
                  in  Position
-> Context -> QualIdent -> Maybe KindExpr -> Ident -> IDecl
HidingClassDecl Position
NoPos Context
cx QualIdent
tc Maybe KindExpr
k' Ident
tv

instances :: ModuleIdent -> TCEnv -> InstEnv -> [Ident] -> Set.Set IInfo
          -> IInfo -> [IDecl]
instances :: ModuleIdent
-> TCEnv -> InstEnv -> [Ident] -> Set IInfo -> IInfo -> [IDecl]
instances _ _ _ _ _ IOther = []
instances m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv inEnv :: InstEnv
inEnv tvs :: [Ident]
tvs is :: Set IInfo
is (IType tc :: QualIdent
tc) =
  [ ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> IDecl
iInstDecl ModuleIdent
m TCEnv
tcEnv [Ident]
tvs InstIdent
ident InstInfo
info
  | (ident :: InstIdent
ident@(cls :: QualIdent
cls, tc' :: QualIdent
tc'), info :: InstInfo
info@(m' :: ModuleIdent
m', _, _)) <- InstEnv -> [(InstIdent, InstInfo)]
forall k a. Map k a -> [(k, a)]
Map.toList InstEnv
inEnv,
    ModuleIdent -> QualIdent -> QualIdent
qualQualify ModuleIdent
m QualIdent
tc QualIdent -> QualIdent -> Bool
forall a. Eq a => a -> a -> Bool
== QualIdent
tc',
    if QualIdent -> Maybe ModuleIdent
qidModule QualIdent
cls Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m' then IInfo -> Set IInfo -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member (QualIdent -> IInfo
IClass (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
cls)) Set IInfo
is
                                else QualIdent -> Maybe ModuleIdent
qidModule QualIdent
tc' Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m' ]
instances m :: ModuleIdent
m tcEnv :: TCEnv
tcEnv inEnv :: InstEnv
inEnv tvs :: [Ident]
tvs is :: Set IInfo
is (IClass cls :: QualIdent
cls) =
  [ ModuleIdent -> TCEnv -> [Ident] -> InstIdent -> InstInfo -> IDecl
iInstDecl ModuleIdent
m TCEnv
tcEnv [Ident]
tvs InstIdent
ident InstInfo
info
  | (ident :: InstIdent
ident@(cls' :: QualIdent
cls', tc :: QualIdent
tc), info :: InstInfo
info@(m' :: ModuleIdent
m', _, _)) <- InstEnv -> [(InstIdent, InstInfo)]
forall k a. Map k a -> [(k, a)]
Map.toList InstEnv
inEnv,
    ModuleIdent -> QualIdent -> QualIdent
qualQualify ModuleIdent
m QualIdent
cls QualIdent -> QualIdent -> Bool
forall a. Eq a => a -> a -> Bool
== QualIdent
cls',
    QualIdent -> Maybe ModuleIdent
qidModule QualIdent
cls' Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m',
    ModuleIdent
m ModuleIdent -> ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
/= ModuleIdent
m' Bool -> Bool -> Bool
|| QualIdent -> Bool
isPrimTypeId QualIdent
tc
            Bool -> Bool -> Bool
|| QualIdent -> Maybe ModuleIdent
qidModule QualIdent
tc Maybe ModuleIdent -> Maybe ModuleIdent -> Bool
forall a. Eq a => a -> a -> Bool
/= ModuleIdent -> Maybe ModuleIdent
forall a. a -> Maybe a
Just ModuleIdent
m
            Bool -> Bool -> Bool
|| IInfo -> Set IInfo -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member (QualIdent -> IInfo
IType (ModuleIdent -> QualIdent -> QualIdent
qualUnqualify ModuleIdent
m QualIdent
tc)) Set IInfo
is ]
instances _ _ _ _ _ (IInst _) = []

definedTypes :: [IDecl] -> [QualIdent]
definedTypes :: [IDecl] -> [QualIdent]
definedTypes ds :: [IDecl]
ds = (IDecl -> [QualIdent] -> [QualIdent])
-> [QualIdent] -> [IDecl] -> [QualIdent]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr IDecl -> [QualIdent] -> [QualIdent]
definedType [] [IDecl]
ds
  where
  definedType :: IDecl -> [QualIdent] -> [QualIdent]
  definedType :: IDecl -> [QualIdent] -> [QualIdent]
definedType (HidingDataDecl     _ tc :: QualIdent
tc _ _) tcs :: [QualIdent]
tcs = QualIdent
tc QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType (IDataDecl      _ tc :: QualIdent
tc _ _ _ _) tcs :: [QualIdent]
tcs = QualIdent
tc QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType (INewtypeDecl   _ tc :: QualIdent
tc _ _ _ _) tcs :: [QualIdent]
tcs = QualIdent
tc QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType (ITypeDecl      _ tc :: QualIdent
tc _ _ _  ) tcs :: [QualIdent]
tcs = QualIdent
tc QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType (HidingClassDecl _ _ cls :: QualIdent
cls _ _) tcs :: [QualIdent]
tcs = QualIdent
cls QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType (IClassDecl  _ _ cls :: QualIdent
cls _ _ _ _) tcs :: [QualIdent]
tcs = QualIdent
cls QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
: [QualIdent]
tcs
  definedType _                             tcs :: [QualIdent]
tcs = [QualIdent]
tcs

class HasType a where
  usedTypes :: a -> [QualIdent] -> [QualIdent]

instance HasType a => HasType (Maybe a) where
  usedTypes :: Maybe a -> [QualIdent] -> [QualIdent]
usedTypes = ([QualIdent] -> [QualIdent])
-> (a -> [QualIdent] -> [QualIdent])
-> Maybe a
-> [QualIdent]
-> [QualIdent]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [QualIdent] -> [QualIdent]
forall a. a -> a
id a -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes

instance HasType a => HasType [a] where
  usedTypes :: [a] -> [QualIdent] -> [QualIdent]
usedTypes xs :: [a]
xs tcs :: [QualIdent]
tcs = (a -> [QualIdent] -> [QualIdent])
-> [QualIdent] -> [a] -> [QualIdent]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [QualIdent]
tcs [a]
xs

instance HasType IDecl where
  usedTypes :: IDecl -> [QualIdent] -> [QualIdent]
usedTypes (IInfixDecl            _ _ _ _) = [QualIdent] -> [QualIdent]
forall a. a -> a
id
  usedTypes (HidingDataDecl        _ _ _ _) = [QualIdent] -> [QualIdent]
forall a. a -> a
id
  usedTypes (IDataDecl        _ _ _ _ cs :: [ConstrDecl]
cs _) = [ConstrDecl] -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [ConstrDecl]
cs
  usedTypes (INewtypeDecl     _ _ _ _ nc :: NewConstrDecl
nc _) = NewConstrDecl -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes NewConstrDecl
nc
  usedTypes (ITypeDecl          _ _ _ _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty
  usedTypes (IFunctionDecl     _ _ _ _ qty :: QualTypeExpr
qty) = QualTypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes QualTypeExpr
qty
  usedTypes (HidingClassDecl    _ cx :: Context
cx _ _ _) = Context -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes Context
cx
  usedTypes (IClassDecl    _ cx :: Context
cx _ _ _ ms :: [IMethodDecl]
ms _) = Context -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes Context
cx ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [IMethodDecl] -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [IMethodDecl]
ms
  usedTypes (IInstanceDecl _ cx :: Context
cx cls :: QualIdent
cls ty :: TypeExpr
ty _ _) =
    Context -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes Context
cx ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QualIdent
cls QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
:) ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty

instance HasType ConstrDecl where
  usedTypes :: ConstrDecl -> [QualIdent] -> [QualIdent]
usedTypes (ConstrDecl    _ _ tys :: [TypeExpr]
tys) = [TypeExpr] -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [TypeExpr]
tys
  usedTypes (ConOpDecl _ ty1 :: TypeExpr
ty1 _ ty2 :: TypeExpr
ty2) =
    TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty1 ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty2
  usedTypes (RecordDecl     _ _ fs :: [FieldDecl]
fs) = [FieldDecl] -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [FieldDecl]
fs

instance HasType FieldDecl where
  usedTypes :: FieldDecl -> [QualIdent] -> [QualIdent]
usedTypes (FieldDecl _ _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty

instance HasType NewConstrDecl where
  usedTypes :: NewConstrDecl -> [QualIdent] -> [QualIdent]
usedTypes (NewConstrDecl      _ _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty
  usedTypes (NewRecordDecl _ _ (_, ty :: TypeExpr
ty)) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty

instance HasType IMethodDecl where
  usedTypes :: IMethodDecl -> [QualIdent] -> [QualIdent]
usedTypes (IMethodDecl _ _ _ qty :: QualTypeExpr
qty) = QualTypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes QualTypeExpr
qty

instance HasType Constraint where
  usedTypes :: Constraint -> [QualIdent] -> [QualIdent]
usedTypes (Constraint _ cls :: QualIdent
cls ty :: TypeExpr
ty) = (QualIdent
cls QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
:) ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty

instance HasType TypeExpr where
  usedTypes :: TypeExpr -> [QualIdent] -> [QualIdent]
usedTypes (ConstructorType _ tc :: QualIdent
tc) = (QualIdent
tc QualIdent -> [QualIdent] -> [QualIdent]
forall a. a -> [a] -> [a]
:)
  usedTypes (ApplyType _ ty1 :: TypeExpr
ty1 ty2 :: TypeExpr
ty2) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty1 ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty2
  usedTypes (VariableType     _ _) = [QualIdent] -> [QualIdent]
forall a. a -> a
id
  usedTypes (TupleType      _ tys :: [TypeExpr]
tys) = [TypeExpr] -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes [TypeExpr]
tys
  usedTypes (ListType        _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty
  usedTypes (ArrowType  _ ty1 :: TypeExpr
ty1 ty2 :: TypeExpr
ty2) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty1 ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty2
  usedTypes (ParenType       _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty
  usedTypes (ForallType    _ _ ty :: TypeExpr
ty) = TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty

instance HasType QualTypeExpr where
  usedTypes :: QualTypeExpr -> [QualIdent] -> [QualIdent]
usedTypes (QualTypeExpr _ cx :: Context
cx ty :: TypeExpr
ty) = Context -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes Context
cx ([QualIdent] -> [QualIdent])
-> ([QualIdent] -> [QualIdent]) -> [QualIdent] -> [QualIdent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeExpr -> [QualIdent] -> [QualIdent]
forall a. HasType a => a -> [QualIdent] -> [QualIdent]
usedTypes TypeExpr
ty