2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[RnUtils]{Functions used by both renaming passes}
7 #include "HsVersions.h"
10 mkGlobalNameFun, mkNameFun,
11 GlobalNameMapper(..), GlobalNameMappers(..),
12 PreludeNameMapper(..), PreludeNameMappers(..),
14 dupNamesErr -- used in various places
19 import Bag ( bagToList, Bag )
20 import FiniteMap ( lookupFM, listToFM )
21 import Name ( Name{-instances-} )
22 import Outputable ( pprNonOp )
23 import PprStyle ( PprStyle(..) )
25 import ProtoName ( ProtoName(..) )
26 import Util ( cmpPString, removeDups, pprPanic, panic )
30 type GlobalNameMapper = ProtoName -> Maybe Name
31 type GlobalNameMappers = (GlobalNameMapper, GlobalNameMapper)
33 type PreludeNameMapper = FAST_STRING -> Maybe Name
34 type PreludeNameMappers = (PreludeNameMapper, -- Values
35 PreludeNameMapper -- Types and classes
40 mkGlobalNameFun :: FAST_STRING -- The module name
41 -> PreludeNameMapper -- The prelude things
42 -> [(ProtoName, Name)] -- The local and imported things
43 -> GlobalNameMapper -- The global name function
45 mkGlobalNameFun this_module prel_nf alist
48 the_fun (Prel n) = Just n
49 the_fun (Unk s) = case (unk_fun s) of
52 the_fun (Imp m d _ _) = imp_fun (d, m) -- NB: module-name 2nd!
54 -- Things in the domain of the prelude function shouldn't be put
55 -- in the unk_fun; because the prel_nf will catch them.
56 -- This can arise if, for example, an interface gives a signature
57 -- for a prelude thing.
59 -- Neither should they be in the domain of the imp_fun, because
60 -- prelude things will have been converted to Prel x rather than
63 -- So we strip out prelude things from the alist; this is not just
64 -- desirable, it's essential because get_orig and get_local don't handle
67 non_prel_alist = filter non_prel alist
69 non_prel (Prel _, _) = False
72 -- unk_fun looks up local names (just strings),
73 -- imp_fun looks up original names: (string,string) pairs
74 unk_fun = lookupFM (listToFM [(get_local pn,n) | (pn,n) <- non_prel_alist])
75 imp_fun = lookupFM (listToFM [(get_orig pn,n) | (pn,n) <- non_prel_alist])
77 -- the lists *are* sorted by *some* ordering (by local
78 -- names), but not generally, and not in some way we
79 -- are going to rely on.
81 get_local :: ProtoName -> FAST_STRING
83 get_local (Imp _ _ _ l) = l
84 get_local (Prel n) = pprPanic "get_local: " (ppr PprShowAll n)
86 get_orig :: ProtoName -> (FAST_STRING, FAST_STRING) -- **NB**! module-name 2nd!
87 get_orig (Unk s) = (s, this_module)
88 get_orig (Imp m d _ _) = (d, m)
89 get_orig (Prel n) = pprPanic "get_orig: " (ppr PprShowAll n)
93 @mkNameFun@ builds a function from @ProtoName@s to things, where a
94 ``thing'' is either a @ProtoName@ (in the case of values), or a
95 @(ProtoName, ProtoName -> ProtoName)@ pair in the case of types and
99 \item The name of the interface
100 \item A bag of new string-to-thing bindings to add,
102 \item An extractor function, to get a @ProtoName@ out of a thing,
103 for use in error messages.
105 The function it returns only expects to see @Unk@ things.
107 @mkNameFun@ checks for clashes in the domain of the new bindings.
109 ToDo: it should check for clashes with the prelude bindings too.
112 mkNameFun :: Bag (FAST_STRING, thing) -- Value bindings
113 -> (FAST_STRING -> Maybe thing, -- The function to use
114 [[(FAST_STRING,thing)]]) -- Duplicates, if any
117 = case (removeDups cmp (bagToList the_bag)) of { (no_dup_list, dups) ->
118 case (lookupFM (listToFM no_dup_list)) of { the_fun ->
121 cmp :: (FAST_STRING, a) -> (FAST_STRING, a) -> TAG_
123 cmp (s1,_) (s2,_) = _CMP_STRING_ s1 s2
127 dupNamesErr descriptor ((first_pname,locn1) : dup_things) sty
128 = ppAboves (first_item : map dup_item dup_things)
131 = ppBesides [ ppr PprForUser locn1,
132 ppStr ": multiple declarations of a ", ppStr descriptor, ppStr ": ",
133 pprNonOp sty first_pname ]
135 dup_item (pname, locn)
136 = ppBesides [ ppr PprForUser locn,
137 ppStr ": here was another declaration of `", pprNonOp sty pname, ppStr "'" ]