2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
4 \section[MkIface]{Print an interface for a module}
7 #include "HsVersions.h"
23 import Bag ( emptyBag, snocBag, bagToList )
24 import Class ( GenClass(..){-instance NamedThing-}, GenClassOp(..) )
25 import CmdLineOpts ( opt_ProduceHi )
26 import FieldLabel ( FieldLabel{-instance NamedThing-} )
27 import FiniteMap ( fmToList, eltsFM )
29 import Id ( idType, dataConRawArgTys, dataConFieldLabels,
30 dataConStrictMarks, StrictnessMark(..),
31 GenId{-instance NamedThing/Outputable-}
33 import Name ( origName, nameOf, moduleOf,
34 exportFlagOn, nameExportFlag, ExportFlag(..),
35 isLexSym, isLocallyDefined, isWiredInName,
36 RdrName(..){-instance Outputable-},
37 OrigName(..){-instance Ord-},
38 Name{-instance NamedThing-}
40 import ParseUtils ( UsagesMap(..), VersionsMap(..) )
41 import PprEnv -- not sure how much...
42 import PprStyle ( PprStyle(..) )
43 import PprType -- most of it (??)
44 --import PrelMods ( modulesWithBuiltins )
45 import PrelInfo ( builtinNameInfo )
46 import Pretty ( prettyToUn )
47 import Unpretty -- ditto
48 import RnHsSyn ( RenamedHsModule(..), RnName{-instance NamedThing-} )
49 import TcModule ( TcIfaceInfo(..) )
50 import TcInstUtil ( InstInfo(..) )
51 import TyCon ( TyCon(..){-instance NamedThing-}, NewOrData(..) )
52 import Type ( mkSigmaTy, mkDictTy, getAppTyCon, splitForAllTy )
53 import Util ( sortLt, zipWithEqual, zipWith3Equal, assertPanic, panic{-ToDo:rm-}, pprTrace{-ToDo:rm-} )
55 uppSemid x = uppBeside (prettyToUn (ppr PprInterface x)) uppSemi -- micro util
56 ppr_ty ty = prettyToUn (pprType PprInterface ty)
57 ppr_tyvar tv = prettyToUn (ppr PprInterface tv)
59 = case (origName "ppr_name" n) of { OrigName m s ->
60 uppBesides [uppPStr m, uppChar '.', uppPStr s] }
63 We have a function @startIface@ to open the output file and put
64 (something like) ``interface Foo'' in it. It gives back a handle
65 for subsequent additions to the interface file.
67 We then have one-function-per-block-of-interface-stuff, e.g.,
68 @ifaceExportList@ produces the @__exports__@ section; it appends
69 to the handle provided by @startIface@.
73 -> IO (Maybe Handle) -- Nothing <=> don't do an interface
74 endIface :: Maybe Handle -> IO ()
85 -> (Name -> ExportFlag)
96 ifaceDecls :: Maybe Handle
97 -> TcIfaceInfo -- info produced by typechecker, for interfaces
101 -> TcIfaceInfo -- as above
106 ifacePragmas = panic "ifacePragmas" -- stub
111 = case opt_ProduceHi of
112 Nothing -> return Nothing -- not producing any .hi file
114 openFile fn WriteMode >>= \ if_hdl ->
115 hPutStr if_hdl ("interface "++ _UNPK_ mod) >>
118 endIface Nothing = return ()
119 endIface (Just if_hdl) = hPutStr if_hdl "\n" >> hClose if_hdl
123 ifaceUsages Nothing{-no iface handle-} _ = return ()
125 ifaceUsages (Just if_hdl) usages
129 = hPutStr if_hdl "\n__usages__\n" >>
130 hPutStr if_hdl (uppShow 0 (uppAboves (map upp_uses usages_list)))
132 usages_list = fmToList usages -- NO: filter has_no_builtins (...)
134 -- has_no_builtins (m, _)
135 -- = m `notElem` modulesWithBuiltins
136 -- -- Don't *have* to do this; save gratuitous spillage in
137 -- -- every interface. Could be flag-controlled...
139 upp_uses (m, (mv, versions))
140 = uppBesides [uppPStr m, uppSP, uppInt mv, uppPStr SLIT(" :: "),
141 upp_versions (fmToList versions), uppSemi]
144 = uppIntersperse uppSP [ uppCat [uppPStr n, uppInt v] | (n,v) <- nvs ]
148 ifaceVersions Nothing{-no iface handle-} _ = return ()
150 ifaceVersions (Just if_hdl) version_info
154 = hPutStr if_hdl "\n__versions__\n" >>
155 hPutStr if_hdl (uppShow 0 (upp_versions version_list))
156 -- NB: when compiling Prelude.hs, this will spew out
157 -- stuff for [], (), (,), etc. [i.e., builtins], which
158 -- we'd rather it didn't. The version-mangling in
159 -- the driver will ignore them.
161 version_list = fmToList version_info
164 = uppAboves [ uppPStr n | (n,v) <- nvs ]
168 ifaceInstanceModules Nothing{-no iface handle-} _ = return ()
169 ifaceInstanceModules (Just _) [] = return ()
171 ifaceInstanceModules (Just if_hdl) imods
172 = hPutStr if_hdl "\n__instance_modules__\n" >>
173 hPutStr if_hdl (uppShow 0 (uppCat (map uppPStr imods)))
176 Export list: grab the Names of things that are marked Exported, sort
177 (so the interface file doesn't ``wobble'' from one compilation to the
178 next...), and print. Note that the ``module'' now contains all the
179 imported things that we are dealing with, thus including any entities
180 that we are re-exporting from somewhere else.
182 ifaceExportList Nothing{-no iface handle-} _ _ = return ()
184 ifaceExportList (Just if_hdl)
185 export_fn -- sadly, just the HsModule isn't enough,
186 -- because it will have no record of exported
188 (HsModule _ _ _ _ _ typedecls _ classdecls _ _ _ binds sigs _)
190 (vals_wired, tcs_wired)
191 = case builtinNameInfo of { ((vals_fm,tcs_fm), _, _) ->
192 ([ getName rn | rn <- eltsFM vals_fm ]
193 ,[ getName rn | rn <- eltsFM tcs_fm ]) }
195 name_flag_pairs :: Bag (OrigName, ExportFlag)
202 (from_binds binds emptyBag{-init accum-})
209 sorted_pairs = sortLt lexical_lt (bagToList name_flag_pairs)
212 hPutStr if_hdl "\n__exports__\n" >>
213 hPutStr if_hdl (uppShow 0 (uppAboves (map upp_pair sorted_pairs)))
215 from_ty (TyData _ n _ _ _ _ _) acc = maybe_add acc n
216 from_ty (TyNew _ n _ _ _ _ _) acc = maybe_add acc n
217 from_ty (TySynonym n _ _ _) acc = maybe_add acc n
219 from_cls (ClassDecl _ n _ _ _ _ _) acc = maybe_add acc n
221 from_sig (Sig n _ _ _) acc = maybe_add acc n
223 from_binds bs acc = maybe_add_list acc (collectTopLevelBinders bs)
227 | exportFlagOn ef = acc `snocBag` (origName "maybe_add" n, ef)
233 maybe_add :: Bag (OrigName, ExportFlag) -> RnName -> Bag (OrigName, ExportFlag)
236 | exportFlagOn ef = acc `snocBag` (origName "maybe_add" n, ef)
240 ef = nameExportFlag n
243 maybe_add_list acc [] = acc
244 maybe_add_list acc (n:ns) = maybe_add (maybe_add_list acc ns) n
247 lexical_lt (n1,_) (n2,_) = n1 < n2
250 upp_pair (OrigName m n, ef)
251 = uppBesides [uppPStr m, uppSP, uppPStr n, uppSP, upp_export ef]
253 upp_export ExportAll = uppPStr SLIT("(..)")
254 upp_export ExportAbs = uppNil
258 ifaceFixities Nothing{-no iface handle-} _ = return ()
260 ifaceFixities (Just if_hdl) (HsModule _ _ _ _ fixities _ _ _ _ _ _ _ _ _)
262 pp_fixities = foldr go [] fixities
264 if null pp_fixities then
267 hPutStr if_hdl "\n__fixities__\n" >>
268 hPutStr if_hdl (uppShow 0 (uppAboves pp_fixities))
270 go (InfixL v i) acc = (if isLocallyDefined v then (:) (print_fix "l" i v) else id) acc
271 go (InfixR v i) acc = (if isLocallyDefined v then (:) (print_fix "r" i v) else id) acc
272 go (InfixN v i) acc = (if isLocallyDefined v then (:) (print_fix "" i v) else id) acc
274 print_fix suff prec var
275 = uppBesides [uppPStr SLIT("infix"), uppStr suff, uppSP, uppInt prec, uppSP, ppr_name var, uppSemi]
279 non_wired x = not (isWiredInName (getName x)) --ToDo:move?
281 ifaceDecls Nothing{-no iface handle-} _ = return ()
283 ifaceDecls (Just if_hdl) (vals, tycons, classes, _)
284 = ASSERT(all isLocallyDefined vals)
285 ASSERT(all isLocallyDefined tycons)
286 ASSERT(all isLocallyDefined classes)
288 nonwired_classes = filter non_wired classes
289 nonwired_tycons = filter non_wired tycons
290 nonwired_vals = filter non_wired vals
292 lt_lexical a b = origName "lt_lexical" a < origName "lt_lexical" b
294 sorted_classes = sortLt lt_lexical nonwired_classes
295 sorted_tycons = sortLt lt_lexical nonwired_tycons
296 sorted_vals = sortLt lt_lexical nonwired_vals
298 if (null sorted_classes && null sorted_tycons && null sorted_vals) then
299 -- You could have a module with just (re-)exports/instances in it
302 hPutStr if_hdl "\n__declarations__\n" >>
303 hPutStr if_hdl (uppShow 0 (uppAboves [
304 uppAboves (map ppr_class sorted_classes),
305 uppAboves (map ppr_tycon sorted_tycons),
306 uppAboves [ppr_val v (idType v) | v <- sorted_vals]]))
310 ifaceInstances Nothing{-no iface handle-} _ = return ()
312 ifaceInstances (Just if_hdl) (_, _, _, insts)
314 togo_insts = filter is_togo_inst (bagToList insts)
316 sorted_insts = sortLt lt_inst togo_insts
318 if null togo_insts then
321 hPutStr if_hdl "\n__instances__\n" >>
322 hPutStr if_hdl (uppShow 0 (uppAboves (map pp_inst sorted_insts)))
324 is_togo_inst (InstInfo clas _ ty _ _ _ _ _ from_here _ _ _)
325 = from_here -- && ...
328 lt_inst (InstInfo clas1 _ ty1 _ _ _ _ _ _ _ _ _)
329 (InstInfo clas2 _ ty2 _ _ _ _ _ _ _ _ _)
331 tycon1 = fst (getAppTyCon ty1)
332 tycon2 = fst (getAppTyCon ty2)
334 case (origName "lt_inst" clas1 `cmp` origName "lt_inst" clas2) of
337 EQ_ -> origName "lt_inst2" tycon1 < origName "lt_inst2" tycon2
340 pp_inst (InstInfo clas tvs ty theta _ _ _ _ _ _ _ _)
342 forall_ty = mkSigmaTy tvs theta (mkDictTy clas ty)
343 renumbered_ty = initNmbr (nmbrType forall_ty)
345 case (splitForAllTy renumbered_ty) of { (rtvs, rrho_ty) ->
346 uppBesides [uppPStr SLIT("instance "), ppr_forall rtvs, ppr_ty rrho_ty, uppSemi] }
349 %************************************************************************
351 \subsection{Printing tycons, classes, ...}
353 %************************************************************************
356 ppr_class :: Class -> Unpretty
359 = --pprTrace "ppr_class:" (ppr PprDebug c) $
360 case (initNmbr (nmbrClass c)) of { -- renumber it!
361 Class _ n tyvar super_classes sdsels ops sels defms insts links ->
363 uppCat [uppPStr SLIT("class"), ppr_context tyvar super_classes,
364 ppr_name n, ppr_tyvar tyvar,
367 else uppCat [uppStr "where {", uppCat (map ppr_op ops), uppStr "};"]]
370 ppr_context :: TyVar -> [Class] -> Unpretty
372 ppr_context tv [] = uppNil
373 -- ppr_context tv [sc] = uppBeside (ppr_assert tv sc) (uppPStr SLIT(" =>"))
374 ppr_context tv super_classes
375 = uppBesides [uppStr "{{",
376 uppIntersperse upp'SP{-'-} (map (ppr_assert tv) super_classes),
379 ppr_assert tv (Class _ n _ _ _ _ _ _ _ _) = uppCat [ppr_name n, ppr_tyvar tv]
381 clas_mod = moduleOf (origName "ppr_class" c)
383 ppr_op (ClassOp o _ ty) = pp_sig (Qual clas_mod o) ty
387 ppr_val v ty -- renumber the type first!
388 = --pprTrace "ppr_val:" (ppr PprDebug v) $
389 pp_sig v (initNmbr (nmbrType ty))
392 = case (splitForAllTy ty) of { (tvs, rho_ty) ->
393 uppBesides [ppr_name op, uppPStr SLIT(" :: "), ppr_forall tvs, ppr_ty rho_ty, uppSemi] }
395 ppr_forall [] = uppNil
396 ppr_forall tvs = uppBesides [ uppStr "__forall__ [", uppInterleave uppComma (map ppr_tyvar tvs), uppStr "] " ]
401 = --pprTrace "ppr_tycon:" (ppr PprDebug tycon) $
402 ppr_tc (initNmbr (nmbrTyCon tycon))
404 ------------------------
405 ppr_tc (PrimTyCon _ n _ _)
406 = uppCat [ uppStr "{- data", ppr_name n, uppStr " *built-in* -}" ]
409 = uppCat [ uppStr "{- data", ppr_name FunTyCon, uppStr " *built-in* -}" ]
411 ppr_tc (TupleTyCon _ n _)
412 = uppCat [ uppStr "{- ", ppr_name n, uppStr "-}" ]
414 ppr_tc (SynTyCon _ n _ _ tvs expand)
416 pp_tyvars = map ppr_tyvar tvs
418 uppBesides [uppPStr SLIT("type "), ppr_name n, uppSP, uppIntersperse uppSP pp_tyvars,
419 uppPStr SLIT(" = "), ppr_ty expand, uppSemi]
421 ppr_tc this_tycon@(DataTyCon u n k tvs ctxt cons derivings data_or_new)
422 = uppCat [pp_data_or_new,
425 uppIntersperse uppSP (map ppr_tyvar tvs),
426 uppEquals, pp_condecls,
428 -- NB: we do not print deriving info in interfaces
430 pp_data_or_new = case data_or_new of
431 DataType -> uppPStr SLIT("data")
432 NewType -> uppPStr SLIT("newtype")
434 ppr_context [] = uppNil
435 -- ppr_context [(c,t)] = uppCat [ppr_name c, ppr_ty t, uppPStr SLIT("=>")]
437 = uppBesides[uppStr "{{",
438 uppInterleave uppComma [uppCat [ppr_name c, ppr_ty t] | (c,t) <- cs],
439 uppStr "}}", uppPStr SLIT(" =>")]
445 uppCat ((ppr_con c) : (map ppr_next_con cs))
447 ppr_next_con con = uppCat [uppChar '|', ppr_con con]
451 con_arg_tys = dataConRawArgTys con
452 labels = dataConFieldLabels con -- none if not a record
453 strict_marks = dataConStrictMarks con
455 uppCat [ppr_name con, ppr_fields labels strict_marks con_arg_tys]
457 ppr_fields labels strict_marks con_arg_tys
458 = if null labels then -- not a record thingy
459 uppIntersperse uppSP (zipWithEqual "ppr_fields" ppr_bang_ty strict_marks con_arg_tys)
461 uppCat [ uppChar '{',
462 uppInterleave uppComma (zipWith3Equal "ppr_field" ppr_field labels strict_marks con_arg_tys),
466 = uppBeside (case b of { MarkedStrict -> uppChar '!'; _ -> uppNil })
467 (prettyToUn (pprParendType PprInterface t))
470 = uppBesides [ppr_name l, uppPStr SLIT(" :: "),
471 case b of { MarkedStrict -> uppChar '!'; _ -> uppNil },