@@ -39,31 +39,22 @@ etc.) exported by every module. For example, here are a couple of entries from
3939``` json
4040[
4141 {
42- "fixity" : null ,
43- "origin" : {
44- "name" : " map" ,
45- "module" : " GHC.Base" ,
46- "package" : " base-4.7.0.0"
47- },
48- "entity" : " value"
42+ "name" : " map" ,
43+ "entity" : " value" ,
44+ "module" : " GHC.Base"
4945 },
5046 {
51- "fixity" : null ,
52- "origin" : {
53- "name" : " IO" ,
54- "module" : " GHC.Types" ,
55- "package" : " ghc-prim-0.3.1.0"
56- },
57- "entity" : " data"
47+ "name" : " IO" ,
48+ "entity" : " newtype" ,
49+ "module" : " GHC.Types"
5850 },
5951 ...
6052]
6153```
6254
63- As you see, each entity is annotated with the module and package where it was
64- originally defined, and also with its fixity. Additionally, class methods, field
65- selectors, and data constructors are annotated with the class or type they
66- belong to.
55+ As you see, each entity is annotated with the module where it was
56+ originally defined. Additionally, class methods, field selectors, and data
57+ constructors are annotated with the class or type they belong to.
6758
6859### Generating interfaces
6960
@@ -82,9 +73,10 @@ haskell-names comes with the global package database populated with some core
8273packages:
8374
8475 % hs-gen-iface pkg list --global
76+ array-0.4.0.2
8577 base-4.7.0.0
86- ghc-prim-0.3.1.0
8778 integer-simple-0.1.1.0
79+ ghc-prim-0.3.1.0
8880
8981#### Compiling core packages by hand
9082
@@ -122,14 +114,9 @@ the package database `NamesDB` defined in `Language.Haskell.Modules.Interfaces`.
122114Name resolution
123115---------------
124116
125- There are two approaches to name resolution .
117+ The ` annotateModule ` function annotates the module with scoping information .
126118
127- A simpler one is provided by the ` annotateModule ` function which annotates the
128- module with scoping information.
129-
130- A more advanced interface is given by the ` Language.Haskell.Names.Open ` module.
131119Its essence is described in the article [ Open your name resolution] [ openrec ] .
132- It is, however, very experimental.
133120
134121[ openrec ] : http://ro-che.info/articles/2013-03-04-open-name-resolution.html
135122
@@ -139,7 +126,10 @@ Let's say you have a module and you want to find out whether it uses
139126` Prelude.head ` .
140127
141128``` haskell
129+ module Main where
130+
142131import Language.Haskell.Exts.Annotated
132+ import qualified Language.Haskell.Exts as UnAnn (Name (Ident ))
143133import Language.Haskell.Names
144134import Language.Haskell.Names.Interfaces
145135import Distribution.HaskellSuite
@@ -148,12 +138,12 @@ import Distribution.Simple.Compiler
148138import Data.Maybe
149139import Data.List
150140import Data.Proxy
151- import qualified Data.Set as Set
152141import qualified Data.Foldable as Foldable
153142import Text.Printf
154143import Control.Applicative
155144import Control.Monad
156145
146+ main :: IO ()
157147main = do
158148
159149 -- read the program's source from stdin
@@ -178,44 +168,46 @@ main = do
178168 when (null headUsages) $
179169 printf " Congratulations! Your code doesn't use Prelude.head\n "
180170
181- -- this is a computation in a ModuleT monad, because we need access to
182- -- modules' interfaces
183- findHeads :: Module SrcSpanInfo -> ModuleT Symbols IO [SrcSpanInfo ]
184- findHeads ast = do
185- -- first of all, figure out the canonical name of "Prelude.head"
186- -- (hint: it's "GHC.List.head")
187- Symbols values _types <- fromMaybe (error " Prelude not found" ) <$> getModuleInfo " Prelude"
188- let
189- headOrigName =
190- fromMaybe (error " Prelude.head not found" ) $
191- listToMaybe
192- -- this looks a bit scary, but we're just walking through all
193- -- values defined in Prelude and looking for one with unqualified
194- -- name "head"
195- [ origName
196- | SymValue { sv_origName = origName@ (OrigName _pkg (GName _mod " head" )) } <- Set. toList values
197- ]
198-
199- -- annotate our ast with name binding information
200- annotatedAst <-
201- annotateModule
202- Haskell2010 -- base language
203- [] -- set of extensions
204- ast
205-
206-
207- let
208- -- get list of all annotations
209- annotations = Foldable. toList annotatedAst
210-
211- -- look for headOrigName
212- headUsages = nub
213- [ location
214- | Scoped (GlobalValue valueInfo) location <- annotations
215- , sv_origName valueInfo == headOrigName
216- ]
171+ -- | The `findHeads` function finds all occurrences of the `head` symbol in
172+ -- a given AST of a Haskell module. It needs access to stored name information
173+ -- and therefore runs in `ModuleT`.
174+ findHeads :: Module SrcSpanInfo -> ModuleT [Symbol ] IO [SrcSpanInfo ]
175+ findHeads ast = do
176+
177+ -- First we get all symbols exported from `Prelude` with `getModuleInfo`.
178+ symbols <- fromMaybe (error " Prelude not found" ) <$>
179+ getModuleInfo " Prelude"
180+
181+ -- Then we filter those for the one with name `"head"`.
182+ let
183+ headSymbol =
184+ fromMaybe (error " Prelude.head not found" ) (listToMaybe (do
185+ symbol <- symbols
186+ guard (symbolName symbol == UnAnn. Ident " head" )
187+ return symbol))
188+
189+ -- We annotate the given ast.
190+ annotatedAst <-
191+ annotateModule
192+ Haskell2010 -- base language
193+ [] -- set of extensions
194+ ast
195+
196+ -- We get a list of all annotations from the annotated module.
197+ let
198+ annotations = Foldable. toList annotatedAst
199+
200+ -- A `GlobalSymbol` annotation means that the annotated name refers to a
201+ -- global symbol. It also contains the qualified name that corresponds
202+ -- to how it is referenced but that is not needed here.
203+ headUsages = nub (do
204+ Scoped (GlobalSymbol globalSymbol _) location <- annotations
205+ guard (globalSymbol == headSymbol)
206+ return location)
207+
208+ -- And finally we return all found usages.
209+ return headUsages
217210
218- return headUsages
219211```
220212
221213#### Example invocation
@@ -263,20 +255,18 @@ See the [list of all issues][issues].
263255* Symbol fixities are not recorded ([ #1 ] [ ] )
264256* Type variables are not resolved ([ #2 ] [ ] )
265257* Arrows are not fully supported ([ #8 ] [ ] )
266- * Type/data families and associated types are not fully supported ([ #25 ] [ ] )
267258
268259[ issues ] : https://github.com/haskell-suite/haskell-names/issues/
269260[ #1 ] : https://github.com/haskell-suite/haskell-names/issues/1
270261[ #2 ] : https://github.com/haskell-suite/haskell-names/issues/2
271262[ #8 ] : https://github.com/haskell-suite/haskell-names/issues/8
272- [ #25 ] : https://github.com/haskell-suite/haskell-names/issues/25
273263[ #32 ] : https://github.com/haskell-suite/haskell-names/issues/32
274264[ validation ] : https://github.com/haskell-suite/haskell-names/issues?labels=validation&page=1&state=open
275265
276266Maintainers
277267-----------
278268
279- [ Roman Cheplyaka ] ( https://github.com/feuerbach ) is the primary maintainer.
269+ [ Philipp Schuster ] ( https://github.com/phischu ) is the primary maintainer.
280270
281271[ Adam Bergmark] ( https://github.com/bergmark ) is the backup maintainer. Please
282272get in touch with him if the primary maintainer cannot be reached.
0 commit comments