[project @ 1996-04-08 16:15:43 by partain]
[ghc-hetmet.git] / ghc / compiler / rename / RnNames.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[RnNames]{Extracting imported and top-level names in scope}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module RnNames (
10         getGlobalNames,
11         GlobalNameInfo(..)
12     ) where
13
14 import PreludeGlaST     ( returnPrimIO, thenPrimIO, MutableVar(..) )
15
16 import Ubiq
17
18 import HsSyn
19 import RdrHsSyn
20 import RnHsSyn
21
22 import RnMonad
23 import RnIfaces         ( IfaceCache(..), cacheInterface, ParsedIface )
24 import RnUtils          ( RnEnv(..), emptyRnEnv, extendGlobalRnEnv, qualNameErr, dupNamesErr )
25
26 import Bag              ( emptyBag, unitBag, unionBags, unionManyBags, mapBag, listToBag, bagToList )
27 import ErrUtils         ( Error(..), Warning(..), addShortErrLocLine )
28 import FiniteMap        ( fmToList )
29 import Name             ( RdrName(..), Name, isQual, mkTopLevName,
30                           mkImportedName, nameExportFlag,
31                           getLocalName, getSrcLoc, pprNonOp
32                         )
33 import PrelInfo         ( BuiltinNames(..), BuiltinKeys(..) )
34 import PrelMods         ( fromPrelude )
35 import Pretty
36 import SrcLoc           ( SrcLoc )
37 import UniqSupply       ( splitUniqSupply )
38 import Util             ( equivClasses, panic )
39 \end{code}
40
41
42 \begin{code}
43 type GlobalNameInfo = (BuiltinNames,
44                        BuiltinKeys,
45                        Name -> ExportFlag,
46                        Name -> [RdrName])
47
48 type RnM_Info s r = RnMonad GlobalNameInfo s r
49
50 getGlobalNames ::
51            IfaceCache           
52         -> GlobalNameInfo       
53         -> UniqSupply
54         -> RdrNameHsModule
55         -> PrimIO (RnEnv,
56                    [Module],
57                    Bag RenamedFixityDecl,
58                    Bag Error,
59                    Bag Warning)
60
61 getGlobalNames iface_var info us
62                (HsModule mod _ _ imports _ ty_decls _ cls_decls _ _ _ binds _ _)
63   = case initRn True mod emptyRnEnv us1 
64                 (setExtraRn info $
65                  getSourceNames ty_decls cls_decls binds)
66     of { ((src_vals, src_tcs), src_errs, src_warns) ->
67
68     getImportedNames iface_var info us2 imports `thenPrimIO`
69         \ (imp_vals, imp_tcs, imp_mods, imp_fixes, imp_errs, imp_warns) ->
70
71     let
72         unqual_vals = mapBag (\rn -> (Unqual (getLocalName rn), rn)) src_vals
73         unqual_tcs  = mapBag (\rn -> (Unqual (getLocalName rn), rn)) src_tcs
74
75         all_vals = bagToList (unqual_vals `unionBags` imp_vals)
76         all_tcs  = bagToList (unqual_tcs  `unionBags` imp_tcs)
77
78         (all_env, dups) = extendGlobalRnEnv emptyRnEnv all_vals all_tcs
79
80         dup_errs = map dup_err (equivClasses cmp_rdr (bagToList dups))
81         cmp_rdr (rdr1,_,_) (rdr2,_,_) = cmp rdr1 rdr2
82         dup_err ((rdr,rn,rn'):rest) = globalDupNamesErr rdr (rn:rn': [rn|(_,_,rn)<-rest])
83
84         all_errs  = src_errs `unionBags` imp_errs `unionBags` listToBag dup_errs
85         all_warns = src_warns `unionBags` imp_warns
86     in
87     returnPrimIO (all_env, bagToList imp_mods, imp_fixes, all_errs, all_warns)
88     }
89   where
90     (us1, us2) = splitUniqSupply us
91 \end{code}
92
93 *********************************************************
94 *                                                       *
95 \subsection{Top-level source names}
96 *                                                       *
97 *********************************************************
98
99 \begin{code}
100 getSourceNames ::
101            [RdrNameTyDecl]
102         -> [RdrNameClassDecl]
103         -> RdrNameHsBinds
104         -> RnM_Info s (Bag RnName,      -- values
105                        Bag RnName)      -- tycons/classes
106
107 getSourceNames ty_decls cls_decls binds
108   = mapAndUnzipRn getTyDeclNames ty_decls   `thenRn` \ (tycon_s, constrs_s) ->
109     mapAndUnzipRn getClassNames cls_decls  `thenRn` \ (cls_s, cls_ops_s) ->
110     getTopBindsNames binds                         `thenRn` \ bind_names ->
111     returnRn (unionManyBags constrs_s `unionBags`
112               unionManyBags cls_ops_s `unionBags` bind_names,
113               listToBag tycon_s `unionBags` listToBag cls_s)
114
115
116 getTyDeclNames :: RdrNameTyDecl
117                -> RnM_Info s (RnName, Bag RnName)       -- tycon and constrs
118
119 getTyDeclNames (TyData _ tycon _ condecls _ _ src_loc)
120   = newGlobalName src_loc Nothing tycon `thenRn` \ tycon_name ->
121     mapRn (getConDeclName (Just (nameExportFlag tycon_name)))
122                                condecls `thenRn` \ con_names ->
123     returnRn (RnData tycon_name con_names,
124               listToBag (map (\ n -> RnConstr n tycon_name) con_names))
125
126 getTyDeclNames (TyNew _ tycon _ condecls _ _ src_loc)
127   = newGlobalName src_loc Nothing tycon `thenRn` \ tycon_name ->
128     mapRn (getConDeclName (Just (nameExportFlag tycon_name)))
129                                condecls `thenRn` \ con_names ->
130     returnRn (RnData tycon_name con_names,
131               listToBag (map (\ n -> RnConstr n tycon_name) con_names))
132
133 getTyDeclNames (TySynonym tycon _ _ src_loc)
134   = newGlobalName src_loc Nothing tycon `thenRn` \ tycon_name ->
135     returnRn (RnSyn tycon_name, emptyBag)
136
137 getConDeclName exp (ConDecl con _ src_loc)
138   = newGlobalName src_loc exp con
139 getConDeclName exp (ConOpDecl _ op _ src_loc)
140   = newGlobalName src_loc exp op
141 getConDeclName exp (NewConDecl con _ src_loc)
142   = newGlobalName src_loc exp con
143 getConDeclName exp (RecConDecl con fields src_loc)
144   = panic "getConDeclName:RecConDecl"
145     newGlobalName src_loc exp con
146
147
148 getClassNames :: RdrNameClassDecl
149               -> RnM_Info s (RnName, Bag RnName)        -- class and class ops
150
151 getClassNames (ClassDecl _ cname _ sigs _ _ src_loc)
152   = newGlobalName src_loc Nothing cname `thenRn` \ class_name ->
153     getClassOpNames (Just (nameExportFlag class_name))
154                                   sigs  `thenRn` \ op_names ->
155     returnRn (RnClass class_name op_names,
156               listToBag (map (\ n -> RnClassOp n class_name) op_names))
157
158 getClassOpNames exp []
159   = returnRn []
160 getClassOpNames exp (ClassOpSig op _ _ src_loc : sigs)
161   = newGlobalName src_loc exp op `thenRn` \ op_name ->
162     getClassOpNames exp sigs     `thenRn` \ op_names ->
163     returnRn (op_name : op_names)
164 getClassOpNames exp (_ : sigs)
165   = getClassOpNames exp sigs
166 \end{code}
167
168 *********************************************************
169 *                                                       *
170 \subsection{Bindings}
171 *                                                       *
172 *********************************************************
173
174 \begin{code}
175 getTopBindsNames :: RdrNameHsBinds
176                  -> RnM_Info s (Bag RnName)
177
178 getTopBindsNames binds = doBinds binds
179
180 doBinds EmptyBinds           = returnRn emptyBag
181 doBinds (SingleBind bind)    = doBind bind
182 doBinds (BindWith bind sigs) = doBind bind
183 doBinds (ThenBinds binds1 binds2)
184   = andRn unionBags (doBinds binds1) (doBinds binds2)
185
186 doBind EmptyBind          = returnRn emptyBag
187 doBind (NonRecBind mbind) = doMBinds mbind
188 doBind (RecBind mbind)    = doMBinds mbind
189
190 doMBinds EmptyMonoBinds                         = returnRn emptyBag
191 doMBinds (PatMonoBind pat grhss_and_binds locn) = doPat locn pat
192 doMBinds (FunMonoBind p_name _ locn)            = doName locn p_name
193 doMBinds (AndMonoBinds mbinds1 mbinds2)
194   = andRn unionBags (doMBinds mbinds1) (doMBinds mbinds2)
195
196 doPats locn pats
197   = mapRn (doPat locn) pats     `thenRn` \ pats_s ->
198     returnRn (unionManyBags pats_s)
199
200 doPat locn WildPatIn             = returnRn emptyBag
201 doPat locn (LitPatIn _)          = returnRn emptyBag
202 doPat locn (LazyPatIn pat)       = doPat locn pat
203 doPat locn (VarPatIn var)        = doName locn var
204 doPat locn (NegPatIn pat)        = doPat locn pat
205 doPat locn (ParPatIn pat)        = doPat locn pat
206 doPat locn (ListPatIn pats)      = doPats locn pats
207 doPat locn (TuplePatIn pats)     = doPats locn pats
208 doPat locn (ConPatIn name pats)  = doPats locn pats
209 doPat locn (ConOpPatIn p1 op p2)
210   = andRn unionBags (doPat locn p1) (doPat locn p2)
211 doPat locn (AsPatIn as_name pat)
212   = andRn unionBags (doName locn as_name) (doPat locn pat)
213 doPat locn (RecPatIn name fields)
214   = mapRn (doField locn) fields `thenRn` \ fields_s ->
215     returnRn (unionManyBags fields_s)
216
217 doField locn (field, _, True{-pun-}) = doName locn field
218 doField locn (field, pat, _)         = doPat locn pat
219
220 doName locn rdr
221   = newGlobalName locn Nothing rdr `thenRn` \ name ->
222     returnRn (unitBag (RnName name))
223 \end{code}
224
225 *********************************************************
226 *                                                       *
227 \subsection{Creating a new global name}
228 *                                                       *
229 *********************************************************
230
231 \begin{code}
232 newGlobalName :: SrcLoc -> Maybe ExportFlag
233               -> RdrName -> RnM_Info s Name
234
235 newGlobalName locn maybe_exp rdr
236   = getExtraRn                  `thenRn` \ (_,_,exp_fn,occ_fn) ->
237     getModuleRn                 `thenRn` \ mod ->
238     getSourceRn                 `thenRn` \ source -> 
239     rnGetUnique                 `thenRn` \ u ->
240     let
241         src_unqual = getLocalName rdr
242
243         src_orig   = if fromPrelude mod
244                      then (Unqual src_unqual)
245                      else (Qual mod src_unqual)
246
247         exp = case maybe_exp of
248                Just exp -> exp
249                Nothing  -> exp_fn n
250
251         n = if source then
252                 mkTopLevName u src_orig locn exp (occ_fn n)
253             else
254                 mkImportedName u rdr locn exp (occ_fn n)
255     in
256     addErrIfRn (source && isQual rdr)
257                (qualNameErr "name in definition" (rdr, locn)) `thenRn_`
258     returnRn n    
259 \end{code}
260
261 *********************************************************
262 *                                                       *
263 \subsection{Imported names}
264 *                                                       *
265 *********************************************************
266
267 \begin{code}
268 getImportedNames ::
269            IfaceCache
270         -> GlobalNameInfo                       -- builtin and knot name info
271         -> UniqSupply
272         -> [RdrNameImportDecl]                  -- import declarations
273         -> PrimIO (Bag (RdrName,RnName),        -- imported values in scope
274                    Bag (RdrName,RnName),        -- imported tycons/classes in scope
275                    Bag Module,                  -- directly imported modules
276                    Bag RenamedFixityDecl,       -- fixity info for imported names
277                    Bag Error,
278                    Bag Warning)
279
280 getImportedNames iface_var info us imports 
281   = returnPrimIO (builtin_vals, builtin_tcs, emptyBag, emptyBag, emptyBag, emptyBag)
282   where
283     -- For now jsut add the builtin names ...
284     (b_names,_,_,_) = info
285     builtin_vals = listToBag [(Unqual s, rn) | (s,rn) <- fmToList b_names, not (isRnTyCon rn)]
286     builtin_tcs  = listToBag [(Unqual s, rn) | (s,rn) <- fmToList b_names, isRnTyCon rn]
287 \end{code}
288
289
290 \begin{code}
291 globalDupNamesErr rdr rns sty
292   = ppHang (ppBesides [pprNonOp sty rdr, ppStr " multiply defined:"])
293          4 (ppAboves (map pp_def rns))
294   where
295     pp_def rn = addShortErrLocLine (getSrcLoc rn) (\ sty -> ppr sty rn) sty
296
297     -- ToDo: print import src locs for imported names
298 \end{code}