-
Notifications
You must be signed in to change notification settings - Fork 16
/
Import.elm
96 lines (72 loc) · 2.3 KB
/
Import.elm
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module Import (parse, Import, Exposed(..)) where
import Regex exposing (find, HowMany(..), Match, regex)
import Array
import String
import Set
import Dict
parse : String -> Dict.Dict String Import
parse source =
search source
|> List.map .submatches
|> List.map process
|> imports
imports : List RawImport -> Dict.Dict String Import
imports rawImports =
let toDict list =
Dict.union (Dict.fromList (List.map toImport list)) defaultImports
in
toDict rawImports
(=>) name exposed =
(name, Import Nothing exposed)
defaultImports : Dict.Dict String Import
defaultImports =
Dict.fromList
[ "Basics" => Every
, "Debug" => None
, "List" => Some (Set.fromList ["List", "::"])
, "Maybe" => Some (Set.singleton "Maybe")
, "Result" => Some (Set.singleton "Result")
, "Signal" => Some (Set.singleton "Signal")
]
type alias RawImport =
{ name : String
, alias : Maybe String
, exposed : Maybe (List String)
}
type alias Import =
{ alias : Maybe String, exposed : Exposed }
type Exposed = None | Some (Set.Set String) | Every
toImport : RawImport -> (String, Import)
toImport { name, alias, exposed } =
let exposedSet =
case exposed of
Nothing -> None
Just [".."] -> Every
Just vars -> Some (Set.fromList vars)
in
(name, Import alias exposedSet)
join : Maybe (Maybe a) -> Maybe a
join mx =
case mx of
Just x -> x
Nothing -> Nothing
exposes : String -> Maybe (List String)
exposes s =
if s == ""
then Nothing
else String.split "," s |> List.map String.trim |> Just
process : List (Maybe String) -> RawImport
process submatches =
let submatches' = Array.fromList submatches
name = Maybe.withDefault "" (join (Array.get 0 submatches'))
alias = join (Array.get 1 submatches')
exposedStart = Maybe.withDefault "" (join (Array.get 2 submatches'))
exposedEnd = Maybe.withDefault "" (join (Array.get 3 submatches'))
exposed = (exposedStart ++ exposedEnd) |> String.trim |> exposes
in
{ name = name, alias = alias, exposed = exposed }
search : String -> List Match
search file =
let pattern = regex "(?:^|\\n)import\\s([\\w\\.]+)(?:\\sas\\s(\\w+))?(?:\\sexposing\\s*\\(((?:\\s*(?:\\w+|\\(.+\\))\\s*,)*)\\s*((?:\\.\\.|\\w+|\\(.+\\)))\\s*\\))?"
in
find All pattern file