Add a class HasDynFlags(getDynFlags)
[ghc.git] / compiler / basicTypes / Avail.hs
1 --
2 -- (c) The University of Glasgow
3 --
4
5 {-# OPTIONS -fno-warn-tabs #-}
6 -- The above warning supression flag is a temporary kludge.
7 -- While working on this module you are encouraged to remove it and
8 -- detab the module (please do the detabbing in a separate patch). See
9 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
10 -- for details
11
12 module Avail (
13 Avails,
14 AvailInfo(..),
15 availsToNameSet,
16 availsToNameEnv,
17 availName, availNames,
18 stableAvailCmp,
19 gresFromAvails,
20 gresFromAvail
21 ) where
22
23 import Name
24 import NameEnv
25 import NameSet
26 import RdrName
27
28 import Outputable
29 import Util
30
31 -- -----------------------------------------------------------------------------
32 -- The AvailInfo type
33
34 -- | Records what things are "available", i.e. in scope
35 data AvailInfo = Avail Name -- ^ An ordinary identifier in scope
36 | AvailTC Name
37 [Name] -- ^ A type or class in scope. Parameters:
38 --
39 -- 1) The name of the type or class
40 -- 2) The available pieces of type or class.
41 --
42 -- The AvailTC Invariant:
43 -- * If the type or class is itself
44 -- to be in scope, it must be
45 -- *first* in this list. Thus,
46 -- typically: @AvailTC Eq [Eq, ==, \/=]@
47 deriving( Eq )
48 -- Equality used when deciding if the
49 -- interface has changed
50
51 -- | A collection of 'AvailInfo' - several things that are \"available\"
52 type Avails = [AvailInfo]
53
54 -- | Compare lexicographically
55 stableAvailCmp :: AvailInfo -> AvailInfo -> Ordering
56 stableAvailCmp (Avail n1) (Avail n2) = n1 `stableNameCmp` n2
57 stableAvailCmp (Avail {}) (AvailTC {}) = LT
58 stableAvailCmp (AvailTC n ns) (AvailTC m ms) = (n `stableNameCmp` m) `thenCmp`
59 (cmpList stableNameCmp ns ms)
60 stableAvailCmp (AvailTC {}) (Avail {}) = GT
61
62
63 -- -----------------------------------------------------------------------------
64 -- Operations on AvailInfo
65
66 availsToNameSet :: [AvailInfo] -> NameSet
67 availsToNameSet avails = foldr add emptyNameSet avails
68 where add avail set = addListToNameSet set (availNames avail)
69
70 availsToNameEnv :: [AvailInfo] -> NameEnv AvailInfo
71 availsToNameEnv avails = foldr add emptyNameEnv avails
72 where add avail env = extendNameEnvList env
73 (zip (availNames avail) (repeat avail))
74
75 -- | Just the main name made available, i.e. not the available pieces
76 -- of type or class brought into scope by the 'GenAvailInfo'
77 availName :: AvailInfo -> Name
78 availName (Avail n) = n
79 availName (AvailTC n _) = n
80
81 -- | All names made available by the availability information
82 availNames :: AvailInfo -> [Name]
83 availNames (Avail n) = [n]
84 availNames (AvailTC _ ns) = ns
85
86 -- | make a 'GlobalRdrEnv' where all the elements point to the same
87 -- Provenance (useful for "hiding" imports, or imports with
88 -- no details).
89 gresFromAvails :: Provenance -> [AvailInfo] -> [GlobalRdrElt]
90 gresFromAvails prov avails
91 = concatMap (gresFromAvail (const prov)) avails
92
93 gresFromAvail :: (Name -> Provenance) -> AvailInfo -> [GlobalRdrElt]
94 gresFromAvail prov_fn avail
95 = [ GRE {gre_name = n,
96 gre_par = parent n avail,
97 gre_prov = prov_fn n}
98 | n <- availNames avail ]
99 where
100 parent _ (Avail _) = NoParent
101 parent n (AvailTC m _) | n == m = NoParent
102 | otherwise = ParentIs m
103
104 -- -----------------------------------------------------------------------------
105 -- Printing
106
107 instance Outputable AvailInfo where
108 ppr = pprAvail
109
110 pprAvail :: AvailInfo -> SDoc
111 pprAvail (Avail n) = ppr n
112 pprAvail (AvailTC n ns) = ppr n <> braces (hsep (punctuate comma (map ppr ns)))
113
114