8641f1ff3ff514b8955fff552c844bc0f84e4cd8
[ghc.git] / compiler / hsSyn / HsImpExp.hs
1 {-
2 (c) The University of Glasgow 2006
3 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4
5
6 HsImpExp: Abstract syntax: imports, exports, interfaces
7 -}
8
9 {-# LANGUAGE DeriveDataTypeable #-}
10
11 module HsImpExp where
12
13 import Module ( ModuleName )
14 import HsDoc ( HsDocString )
15 import OccName ( HasOccName(..), isTcOcc, isSymOcc, isDataOcc )
16 import BasicTypes ( SourceText(..), StringLiteral(..), pprWithSourceText )
17 import FieldLabel ( FieldLbl(..) )
18
19 import Outputable
20 import FastString
21 import SrcLoc
22
23 import Data.Data
24
25 {-
26 ************************************************************************
27 * *
28 \subsection{Import and export declaration lists}
29 * *
30 ************************************************************************
31
32 One per \tr{import} declaration in a module.
33 -}
34
35 -- | Located Import Declaration
36 type LImportDecl name = Located (ImportDecl name)
37 -- ^ When in a list this may have
38 --
39 -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi'
40
41 -- For details on above see note [Api annotations] in ApiAnnotation
42
43 -- | Import Declaration
44 --
45 -- A single Haskell @import@ declaration.
46 data ImportDecl name
47 = ImportDecl {
48 ideclSourceSrc :: SourceText,
49 -- Note [Pragma source text] in BasicTypes
50 ideclName :: Located ModuleName, -- ^ Module name.
51 ideclPkgQual :: Maybe StringLiteral, -- ^ Package qualifier.
52 ideclSource :: Bool, -- ^ True <=> {-\# SOURCE \#-} import
53 ideclSafe :: Bool, -- ^ True => safe import
54 ideclQualified :: Bool, -- ^ True => qualified
55 ideclImplicit :: Bool, -- ^ True => implicit import (of Prelude)
56 ideclAs :: Maybe (Located ModuleName), -- ^ as Module
57 ideclHiding :: Maybe (Bool, Located [LIE name])
58 -- ^ (True => hiding, names)
59 }
60 -- ^
61 -- 'ApiAnnotation.AnnKeywordId's
62 --
63 -- - 'ApiAnnotation.AnnImport'
64 --
65 -- - 'ApiAnnotation.AnnOpen', 'ApiAnnotation.AnnClose' for ideclSource
66 --
67 -- - 'ApiAnnotation.AnnSafe','ApiAnnotation.AnnQualified',
68 -- 'ApiAnnotation.AnnPackageName','ApiAnnotation.AnnAs',
69 -- 'ApiAnnotation.AnnVal'
70 --
71 -- - 'ApiAnnotation.AnnHiding','ApiAnnotation.AnnOpen',
72 -- 'ApiAnnotation.AnnClose' attached
73 -- to location in ideclHiding
74
75 -- For details on above see note [Api annotations] in ApiAnnotation
76 deriving Data
77
78 simpleImportDecl :: ModuleName -> ImportDecl name
79 simpleImportDecl mn = ImportDecl {
80 ideclSourceSrc = NoSourceText,
81 ideclName = noLoc mn,
82 ideclPkgQual = Nothing,
83 ideclSource = False,
84 ideclSafe = False,
85 ideclImplicit = False,
86 ideclQualified = False,
87 ideclAs = Nothing,
88 ideclHiding = Nothing
89 }
90
91 instance (OutputableBndr name, HasOccName name) => Outputable (ImportDecl name) where
92 ppr (ImportDecl { ideclSourceSrc = mSrcText, ideclName = mod'
93 , ideclPkgQual = pkg
94 , ideclSource = from, ideclSafe = safe
95 , ideclQualified = qual, ideclImplicit = implicit
96 , ideclAs = as, ideclHiding = spec })
97 = hang (hsep [text "import", ppr_imp from, pp_implicit implicit, pp_safe safe,
98 pp_qual qual, pp_pkg pkg, ppr mod', pp_as as])
99 4 (pp_spec spec)
100 where
101 pp_implicit False = empty
102 pp_implicit True = ptext (sLit ("(implicit)"))
103
104 pp_pkg Nothing = empty
105 pp_pkg (Just (StringLiteral st p))
106 = pprWithSourceText st (doubleQuotes (ftext p))
107
108 pp_qual False = empty
109 pp_qual True = text "qualified"
110
111 pp_safe False = empty
112 pp_safe True = text "safe"
113
114 pp_as Nothing = empty
115 pp_as (Just a) = text "as" <+> ppr a
116
117 ppr_imp True = case mSrcText of
118 NoSourceText -> text "{-# SOURCE #-}"
119 SourceText src -> text src <+> text "#-}"
120 ppr_imp False = empty
121
122 pp_spec Nothing = empty
123 pp_spec (Just (False, (L _ ies))) = ppr_ies ies
124 pp_spec (Just (True, (L _ ies))) = text "hiding" <+> ppr_ies ies
125
126 ppr_ies [] = text "()"
127 ppr_ies ies = char '(' <+> interpp'SP ies <+> char ')'
128
129 {-
130 ************************************************************************
131 * *
132 \subsection{Imported and exported entities}
133 * *
134 ************************************************************************
135 -}
136
137 -- | Located Import or Export
138 type LIE name = Located (IE name)
139 -- ^ When in a list this may have
140 --
141 -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnComma'
142
143 -- For details on above see note [Api annotations] in ApiAnnotation
144
145 -- | Imported or exported entity.
146 data IE name
147 = IEVar (Located name)
148 -- ^ Imported or Exported Variable
149 --
150 -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnPattern',
151 -- 'ApiAnnotation.AnnType'
152
153 -- For details on above see note [Api annotations] in ApiAnnotation
154 -- See Note [Located RdrNames] in HsExpr
155 | IEThingAbs (Located name)
156 -- ^ Imported or exported Thing with Absent list
157 --
158 -- The thing is a Class/Type (can't tell)
159 -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnPattern',
160 -- 'ApiAnnotation.AnnType','ApiAnnotation.AnnVal'
161
162 -- For details on above see note [Api annotations] in ApiAnnotation
163 -- See Note [Located RdrNames] in HsExpr
164 | IEThingAll (Located name)
165 -- ^ Imported or exported Thing with All imported or exported
166 --
167 -- The thing is a Class/Type and the All refers to methods/constructors
168 --
169 -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnOpen',
170 -- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnClose',
171 -- 'ApiAnnotation.AnnType'
172
173 -- For details on above see note [Api annotations] in ApiAnnotation
174 -- See Note [Located RdrNames] in HsExpr
175
176 | IEThingWith (Located name)
177 IEWildcard
178 [Located name]
179 [Located (FieldLbl name)]
180 -- ^ Imported or exported Thing With given imported or exported
181 --
182 -- The thing is a Class/Type and the imported or exported things are
183 -- methods/constructors and record fields; see Note [IEThingWith]
184 -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnOpen',
185 -- 'ApiAnnotation.AnnClose',
186 -- 'ApiAnnotation.AnnComma',
187 -- 'ApiAnnotation.AnnType'
188
189 -- For details on above see note [Api annotations] in ApiAnnotation
190 | IEModuleContents (Located ModuleName)
191 -- ^ Imported or exported module contents
192 --
193 -- (Export Only)
194 --
195 -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnModule'
196
197 -- For details on above see note [Api annotations] in ApiAnnotation
198 | IEGroup Int HsDocString -- ^ Doc section heading
199 | IEDoc HsDocString -- ^ Some documentation
200 | IEDocNamed String -- ^ Reference to named doc
201 deriving (Eq, Data)
202
203 -- | Imported or Exported Wildcard
204 data IEWildcard = NoIEWildcard | IEWildcard Int deriving (Eq, Data)
205
206 {-
207 Note [IEThingWith]
208 ~~~~~~~~~~~~~~~~~~
209
210 A definition like
211
212 module M ( T(MkT, x) ) where
213 data T = MkT { x :: Int }
214
215 gives rise to
216
217 IEThingWith T [MkT] [FieldLabel "x" False x)] (without DuplicateRecordFields)
218 IEThingWith T [MkT] [FieldLabel "x" True $sel:x:MkT)] (with DuplicateRecordFields)
219
220 See Note [Representing fields in AvailInfo] in Avail for more details.
221 -}
222
223 ieName :: IE name -> name
224 ieName (IEVar (L _ n)) = n
225 ieName (IEThingAbs (L _ n)) = n
226 ieName (IEThingWith (L _ n) _ _ _) = n
227 ieName (IEThingAll (L _ n)) = n
228 ieName _ = panic "ieName failed pattern match!"
229
230 ieNames :: IE a -> [a]
231 ieNames (IEVar (L _ n) ) = [n]
232 ieNames (IEThingAbs (L _ n) ) = [n]
233 ieNames (IEThingAll (L _ n) ) = [n]
234 ieNames (IEThingWith (L _ n) _ ns _) = n : map unLoc ns
235 ieNames (IEModuleContents _ ) = []
236 ieNames (IEGroup _ _ ) = []
237 ieNames (IEDoc _ ) = []
238 ieNames (IEDocNamed _ ) = []
239
240 pprImpExp :: (HasOccName name, OutputableBndr name) => name -> SDoc
241 pprImpExp name = type_pref <+> pprPrefixOcc name
242 where
243 occ = occName name
244 type_pref | isTcOcc occ && isSymOcc occ = text "type"
245 | otherwise = empty
246
247 instance (HasOccName name, OutputableBndr name) => Outputable (IE name) where
248 ppr (IEVar var)
249 -- This is a messy test, should perhaps create IEPatternVar
250 = (if isDataOcc $ occName $ unLoc var then text "pattern" else empty)
251 <+> pprPrefixOcc (unLoc var)
252 ppr (IEThingAbs thing) = pprImpExp (unLoc thing)
253 ppr (IEThingAll thing) = hcat [pprImpExp (unLoc thing), text "(..)"]
254 ppr (IEThingWith thing wc withs flds)
255 = pprImpExp (unLoc thing) <> parens (fsep (punctuate comma
256 (ppWiths ++
257 map (ppr . flLabel . unLoc) flds)))
258 where
259 ppWiths =
260 case wc of
261 NoIEWildcard ->
262 map (pprImpExp . unLoc) withs
263 IEWildcard pos ->
264 let (bs, as) = splitAt pos (map (pprImpExp . unLoc) withs)
265 in bs ++ [text ".."] ++ as
266 ppr (IEModuleContents mod')
267 = text "module" <+> ppr mod'
268 ppr (IEGroup n _) = text ("<IEGroup: " ++ show n ++ ">")
269 ppr (IEDoc doc) = ppr doc
270 ppr (IEDocNamed string) = text ("<IEDocNamed: " ++ string ++ ">")