haskell-names does name and module resolution for haskell-src-exts AST.
Namely, it can do the following:
resolve.where clause) or globally (and then give its origin).
This is called annotate.If you're building a development version, then you might also need to install a development version of haskell-src-exts.
An environment is a map from module name to list of symbols the module exports.
Symbols are for example types, classes, functions etc. We persist these lists in
a JSON format.
For example, here are a couple of entries from Prelude.names:
[
{
"name": "map",
"entity": "value",
"module": "GHC.Base"
},
{
"name": "IO",
"entity": "newtype",
"module": "GHC.Types"
},
...
]
As you see, each entity is annotated with the module where it was originally defined. Additionally, class methods, field selectors, and data constructors are annotated with the class or type they belong to.
haskell-names provides functions readSymbols and writeSymbols
to read and write interface files.
The annotate function annotates the given module with scoping information.
Its essence is described in the article Open your name resolution.
The example in examples/HeadUsage.hs shows how you would find out if a
Haskell modules given on stdin uses Prelude.head.
% cabal exec -- runghc examples/HeadUsages.hs
one = head [1]
^D
Prelude.head is used at stdin: (1:7) - (1:11)
% cabal exec -- runghc examples/HeadUsages.hs
import Prelude hiding (head)
import Data.Text
f = head (pack "foo")
^D
Congratulations! Your code doesn't use Prelude.head
The example in examples/ModuleExports.hs shows how the resolve function
behaves. It expects to find examples/moduleexports.Example.hs and
examples/moduleexports/Example/Internal.hs.
% cabal exec -- runghc examples/ModuleExports.hs
Only example: fromList [(ModuleName () "Example",[])]
Only internal: fromList [(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
Example & Internal: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
Internal & Example: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
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"}])]
Internal after Example: fromList [(ModuleName () "Example",[]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
The core module you need is Language.Haskell.Names
Other modules are more experimental, less documented, and you probably don't need them anyway.
See the list of all issues.
Philipp Schuster is the primary maintainer.
Adam Bergmark is the backup maintainer. Please get in touch with him if the primary maintainer cannot be reached.
Haskell
99.9%
haskell-names does name and module resolution for haskell-src-exts AST.
Namely, it can do the following:
resolve.where clause) or globally (and then give its origin).
This is called annotate.If you're building a development version, then you might also need to install a development version of haskell-src-exts.
An environment is a map from module name to list of symbols the module exports.
Symbols are for example types, classes, functions etc. We persist these lists in
a JSON format.
For example, here are a couple of entries from Prelude.names:
[
{
"name": "map",
"entity": "value",
"module": "GHC.Base"
},
{
"name": "IO",
"entity": "newtype",
"module": "GHC.Types"
},
...
]
As you see, each entity is annotated with the module where it was originally defined. Additionally, class methods, field selectors, and data constructors are annotated with the class or type they belong to.
haskell-names provides functions readSymbols and writeSymbols
to read and write interface files.
The annotate function annotates the given module with scoping information.
Its essence is described in the article Open your name resolution.
The example in examples/HeadUsage.hs shows how you would find out if a
Haskell modules given on stdin uses Prelude.head.
% cabal exec -- runghc examples/HeadUsages.hs
one = head [1]
^D
Prelude.head is used at stdin: (1:7) - (1:11)
% cabal exec -- runghc examples/HeadUsages.hs
import Prelude hiding (head)
import Data.Text
f = head (pack "foo")
^D
Congratulations! Your code doesn't use Prelude.head
The example in examples/ModuleExports.hs shows how the resolve function
behaves. It expects to find examples/moduleexports.Example.hs and
examples/moduleexports/Example/Internal.hs.
% cabal exec -- runghc examples/ModuleExports.hs
Only example: fromList [(ModuleName () "Example",[])]
Only internal: fromList [(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
Example & Internal: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
Internal & Example: fromList [(ModuleName () "Example",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
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"}])]
Internal after Example: fromList [(ModuleName () "Example",[]),(ModuleName () "Example.Internal",[Value {symbolModule = ModuleName () "Example.Internal", symbolName = Ident () "details"}])]
The core module you need is Language.Haskell.Names
Other modules are more experimental, less documented, and you probably don't need them anyway.
See the list of all issues.
Philipp Schuster is the primary maintainer.
Adam Bergmark is the backup maintainer. Please get in touch with him if the primary maintainer cannot be reached.
Haskell
99.9%