Skip to content

Commit c49aa2d

Browse files
committed
Merge pull request #59 from phischu/v0.5.0
All changes for version 0.5.0
2 parents bb210b8 + 63a1aec commit c49aa2d

File tree

273 files changed

+2495
-4204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

273 files changed

+2495
-4204
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Changes
22
=======
33

4+
Version 0.5.0
5+
-------------
6+
7+
* Unify type-level and value-level symbols
8+
* Remove fixities from symbol type
9+
* Properly annotate classes and instances
10+
* Inline original name into symbol type
11+
* Remove original package from symbol type
12+
* Annotate symbol references with the way they are referenced
13+
414
Version 0.4.1
515
-------------
616

README.md

Lines changed: 56 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -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
8273
packages:
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`.
122114
Name 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.
131119
Its 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+
142131
import Language.Haskell.Exts.Annotated
132+
import qualified Language.Haskell.Exts as UnAnn (Name(Ident))
143133
import Language.Haskell.Names
144134
import Language.Haskell.Names.Interfaces
145135
import Distribution.HaskellSuite
@@ -148,12 +138,12 @@ import Distribution.Simple.Compiler
148138
import Data.Maybe
149139
import Data.List
150140
import Data.Proxy
151-
import qualified Data.Set as Set
152141
import qualified Data.Foldable as Foldable
153142
import Text.Printf
154143
import Control.Applicative
155144
import Control.Monad
156145

146+
main :: IO ()
157147
main = 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

276266
Maintainers
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
282272
get in touch with him if the primary maintainer cannot be reached.

examples/HeadUsages.hs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
module Main where
2+
3+
import Language.Haskell.Exts.Annotated
4+
import qualified Language.Haskell.Exts as UnAnn (Name(Ident))
5+
import Language.Haskell.Names
6+
import Language.Haskell.Names.Interfaces
7+
import Distribution.HaskellSuite
8+
import Distribution.Simple.Compiler
9+
10+
import Data.Maybe
11+
import Data.List
12+
import Data.Proxy
13+
import qualified Data.Foldable as Foldable
14+
import Text.Printf
15+
import Control.Applicative
16+
import Control.Monad
17+
18+
main :: IO ()
19+
main = do
20+
21+
-- read the program's source from stdin
22+
source <- getContents
23+
24+
let
25+
-- parse the program (using haskell-src-exts)
26+
ast = fromParseResult $
27+
parseModuleWithMode defaultParseMode {parseFilename="stdin"} source
28+
29+
-- get all installed packages (user and global)
30+
pkgs <-
31+
(++) <$>
32+
getInstalledPackages (Proxy :: Proxy NamesDB) UserPackageDB <*>
33+
getInstalledPackages (Proxy :: Proxy NamesDB) GlobalPackageDB
34+
35+
headUsages <- evalNamesModuleT (findHeads ast) pkgs
36+
37+
forM_ headUsages $ \loc ->
38+
printf "Prelude.head is used at %s\n" (prettyPrint $ srcInfoSpan loc)
39+
40+
when (null headUsages) $
41+
printf "Congratulations! Your code doesn't use Prelude.head\n"
42+
43+
-- this is a computation in a ModuleT monad, because we need access to
44+
-- modules' interfaces
45+
findHeads :: Module SrcSpanInfo -> ModuleT [Symbol] IO [SrcSpanInfo]
46+
findHeads ast = do
47+
-- first of all, figure out the canonical name of "Prelude.head"
48+
-- (hint: it's "GHC.List.head")
49+
symbols <- fromMaybe (error "Prelude not found") <$> getModuleInfo "Prelude"
50+
let
51+
-- we walk through all values defined in Prelude and look for
52+
-- one with name "head"
53+
headSymbol =
54+
fromMaybe (error "Prelude.head not found") (listToMaybe (do
55+
symbol <- symbols
56+
guard (symbolName symbol == UnAnn.Ident "head")
57+
return symbol))
58+
59+
-- annotate our ast with name binding information
60+
annotatedAst <-
61+
annotateModule
62+
Haskell2010 -- base language
63+
[] -- set of extensions
64+
ast
65+
66+
67+
let
68+
-- get list of all annotations
69+
annotations = Foldable.toList annotatedAst
70+
71+
-- look for headSymbol
72+
headUsages = nub (do
73+
Scoped (GlobalSymbol globalSymbol _) location <- annotations
74+
guard (globalSymbol == headSymbol)
75+
return location)
76+
77+
return headUsages

haskell-names.cabal

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Name: haskell-names
2-
Version: 0.4.1
2+
Version: 0.5.0
33
License: BSD3
4-
Author: Roman Cheplyaka, Lennart Augustsson
5-
Maintainer: Roman Cheplyaka <[email protected]>
4+
Author: Philipp Schuster, Roman Cheplyaka, Lennart Augustsson
5+
Maintainer: Philipp Schuster
66
Category: Language
77
Synopsis: Name resolution library for Haskell
88
Description:

hs-gen-iface/hs-gen-iface.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Name: hs-gen-iface
2-
Version: 0.2
2+
Version: 0.5.0
33
License: MIT
44
License-file: LICENSE
55
Author: Roman Cheplyaka

hs-gen-iface/src/hs-gen-iface.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ compile buildDir mbLang exts cppOpts pkgName pkgdbs deps files = do
101101

102102
createDirectoryIfMissingVerbose silent True (dropFileName ifaceFile)
103103

104-
writeInterface ifaceFile $ qualifySymbols pkgName syms
104+
writeInterface ifaceFile syms
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"origin":{"name":"!","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"//","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"accum","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"accumArray","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"array","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"assocs","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"bounds","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"elems","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"indices","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"ixmap","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"listArray","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"value"},{"origin":{"name":"inRange","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"method","class":{"name":"Ix","module":"GHC.Arr","package":"base-4.7.0.0"}},{"origin":{"name":"index","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"method","class":{"name":"Ix","module":"GHC.Arr","package":"base-4.7.0.0"}},{"origin":{"name":"range","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"method","class":{"name":"Ix","module":"GHC.Arr","package":"base-4.7.0.0"}},{"origin":{"name":"rangeSize","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"method","class":{"name":"Ix","module":"GHC.Arr","package":"base-4.7.0.0"}},{"origin":{"name":"Array","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"data"},{"origin":{"name":"Ix","module":"GHC.Arr","package":"base-4.7.0.0"},"fixity":null,"entity":"class"}]
1+
[{"name":"inRange","class":"Ix","entity":"method","module":"GHC.Arr"},{"name":"index","class":"Ix","entity":"method","module":"GHC.Arr"},{"name":"range","class":"Ix","entity":"method","module":"GHC.Arr"},{"name":"rangeSize","class":"Ix","entity":"method","module":"GHC.Arr"},{"name":"Ix","entity":"class","module":"GHC.Arr"},{"name":"Array","entity":"data","module":"GHC.Arr"},{"name":"array","entity":"value","module":"GHC.Arr"},{"name":"listArray","entity":"value","module":"GHC.Arr"},{"name":"accumArray","entity":"value","module":"GHC.Arr"},{"name":"!","entity":"value","module":"GHC.Arr"},{"name":"bounds","entity":"value","module":"GHC.Arr"},{"name":"indices","entity":"value","module":"GHC.Arr"},{"name":"elems","entity":"value","module":"GHC.Arr"},{"name":"assocs","entity":"value","module":"GHC.Arr"},{"name":"//","entity":"value","module":"GHC.Arr"},{"name":"accum","entity":"value","module":"GHC.Arr"},{"name":"ixmap","entity":"value","module":"GHC.Arr"}]

0 commit comments

Comments
 (0)