@@ -60,94 +60,40 @@ Its essence is described in the article [Open your name resolution][openrec].
60
60
61
61
[ openrec ] : http://ro-che.info/articles/2013-03-04-open-name-resolution.html
62
62
63
- ### Example
64
-
65
- Let's say you have a module and you want to find out whether it uses
66
- ` Prelude.head ` .
67
-
68
- ``` haskell
69
- module Main where
70
-
71
- import Language.Haskell.Exts.Annotated (
72
- fromParseResult , parseModuleWithMode , defaultParseMode ,
73
- parseFilename , prettyPrint , srcInfoSpan )
74
- import Language.Haskell.Exts (
75
- Name (Ident ), ModuleName (ModuleName ))
76
- import Language.Haskell.Names (
77
- loadBase , annotate , symbolName ,
78
- Scoped (Scoped ), NameInfo (GlobalSymbol ))
79
-
80
- import qualified Data.Map as Map (
81
- lookup )
82
-
83
- import Data.Maybe (
84
- fromMaybe , listToMaybe )
85
- import Data.List (
86
- nub )
87
- import qualified Data.Foldable as Foldable (
88
- toList )
89
- import Control.Monad (
90
- forM_ , guard )
91
-
92
- main :: IO ()
93
- main = do
94
-
95
- -- read the program's source from stdin
96
- source <- getContents
97
-
98
- -- parse the program (using haskell-src-exts)
99
- let ast = fromParseResult (
100
- parseModuleWithMode defaultParseMode {parseFilename= " stdin" } source)
101
-
102
- -- get base environment
103
- baseEnvironment <- loadBase
104
-
105
- -- get symbols defined in prelude
106
- let preludeSymbols = fromMaybe (error " Prelude not found" ) (
107
- Map. lookup (ModuleName " Prelude" ) baseEnvironment)
108
-
109
- -- find a Prelude symbol with name 'head' using the List monad
110
- let headSymbol = fromMaybe (error " Prelude.head not found" ) (
111
- listToMaybe (do
112
- preludeSymbol <- preludeSymbols
113
- guard (symbolName preludeSymbol == Ident " head" )
114
- return preludeSymbol))
115
-
116
- -- annotate the AST
117
- let annotatedAST = annotate baseEnvironment ast
118
-
119
- -- get all annotations
120
- let annotations = Foldable. toList annotatedAST
121
-
122
- -- filter head Usages in List monad and remove duplicates
123
- let headUsages = nub (do
124
- Scoped (GlobalSymbol globalSymbol _) location <- annotations
125
- guard (globalSymbol == headSymbol)
126
- return location)
127
-
128
- case headUsages of
129
- [] ->
130
- putStrLn " Congratulations! Your code doesn't use Prelude.head"
131
- _ -> forM_ headUsages (\ location ->
132
- putStrLn (" Prelude.head is used at " ++ (prettyPrint (srcInfoSpan location))))
63
+ ### Examples
133
64
134
- ```
135
-
136
- #### Example invocation
65
+ The example in ` examples/HeadUsage.hs ` shows how you would find out if a
66
+ Haskell modules given on stdin uses ` Prelude.head ` .
137
67
68
+ ```
69
+ % cabal exec -- runghc examples/HeadUsages.hs
70
+ one = head [1]
71
+ ^D
72
+ Prelude.head is used at stdin: (1:7) - (1:11)
73
+
74
+ % cabal exec -- runghc examples/HeadUsages.hs
75
+ import Prelude hiding (head)
76
+ import Data.Text
77
+
78
+ f = head (pack "foo")
79
+ ^D
80
+ Congratulations! Your code doesn't use Prelude.head
81
+ ```
138
82
139
- % ./find-heads
140
- one = head [1]
141
- ^D
142
- Prelude.head is used at stdin: (1:7) - (1:11)
83
+ The example in ` examples/ModuleExports.hs ` shows how the ` resolve ` function
84
+ behaves. It expects to find ` examples/moduleexports.Example.hs ` and
85
+ ` examples/moduleexports/Example/Internal.hs ` .
143
86
144
- % ./find-heads
145
- import Prelude hiding (head)
146
- import Data.Text
87
+ ```
88
+ % cabal exec -- runghc examples/ModuleExports.hs
89
+ Only example: fromList [(ModuleName () "Example",[])]
90
+ Only internal: fromList [(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
91
+ Example & Internal: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
92
+ Internal & Example: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
93
+ Example after Internal: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
94
+ Internal after Example: fromList [(ModuleName () "Example",[]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
95
+ ```
147
96
148
- f = head (pack "foo")
149
- ^D
150
- Congratulations! Your code doesn't use Prelude.head
151
97
152
98
### API documentation
153
99
0 commit comments