-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathScopeUtils.hs
79 lines (71 loc) · 2.54 KB
/
ScopeUtils.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module Language.Haskell.Names.ScopeUtils where
import Control.Arrow
import Language.Haskell.Names.Types
import Language.Haskell.Names.SyntaxUtils
import Language.Haskell.Exts
import qualified Language.Haskell.Names.GlobalSymbolTable as Global
import Control.Monad (guard)
import Data.List (nub)
scopeError :: Functor f => Error l -> f l -> f (Scoped l)
scopeError e f = Scoped (ScopeError e) <$> f
none :: l -> Scoped l
none = Scoped None
noScope :: (Annotated a) => a l -> a (Scoped l)
noScope = fmap none
symbolParent :: Symbol -> Maybe (Name ())
symbolParent (Selector { typeName = n }) = Just n
symbolParent (Constructor { typeName = n }) = Just n
symbolParent (Method { className = n }) = Just n
symbolParent (TypeFam { associate = as }) = as
symbolParent (DataFam { associate = as }) = as
symbolParent (PatternConstructor { patternTypeName = mn}) = mn
symbolParent (PatternSelector { patternTypeName = mn}) = mn
symbolParent _ = Nothing
computeSymbolTable
:: Bool
-- ^ If 'True' (\"qualified\"), then only the qualified names are
-- inserted.
--
-- If 'False', then both qualified and unqualified names are insterted.
-> ModuleName ()
-> [Symbol]
-> Global.Table
computeSymbolTable qual modulename symbols =
Global.fromList (qualified <> if qual then [] else unqualified) where
qualified = do
symbol <- symbols
return (Qual ()modulename (symbolName symbol),symbol)
unqualified = do
symbol <- symbols
return (UnQual () (symbolName symbol),symbol)
-- | Find a single constructor or method name in a list of symbols
resolveCName
:: [Symbol]
-> Name ()
-> (CName l -> Error l) -- ^ error for "not found" condition
-> CName l
-> (CName (Scoped l), [Symbol])
resolveCName symbols parent notFound cn =
let
vs = nub (do
symbol <- symbols
guard (Global.isValue symbol)
let name = symbolName symbol
guard (dropAnn (unCName cn) == name)
Just p <- return $ symbolParent symbol
guard (p == parent)
return symbol)
in
case vs of
[] -> (scopeError (notFound cn) cn, [])
[symbol] -> (Scoped (GlobalSymbol symbol (UnQual () (dropAnn (unCName cn)))) <$> cn, [symbol])
_ -> (scopeError (EInternal "resolveCName") cn, [])
-- | Find a list of constructor or method names in a list of symbols.
resolveCNames
:: [Symbol]
-> Name ()
-> (CName l -> Error l) -- ^ error for "not found" condition
-> [CName l]
-> ([CName (Scoped l)], [Symbol])
resolveCNames syms orig notFound =
second mconcat . unzip . map (resolveCName syms orig notFound)