on fe1e5d2 help sign in
elk/src/Elm/Compiler/Module.hs
142 lines 2.8 kB history raw
1module Elm.Compiler.Module
2 ( Interface, Interfaces
3 , Name(Name)
4 , nameToPath
5 , nameToString, nameFromString
6 , hyphenate, dehyphenate
7 , defaultImports
8 , interfaceAliasedTypes
9 , CanonicalName, canonicalName
10 )
11 where
13import Control.Monad (mzero)
14import qualified Data.Aeson as Json
15import Data.Binary
16import qualified Data.Char as Char
17import qualified Data.List as List
18import qualified Data.Map as Map
19import qualified Data.Text as Text
20import System.FilePath ((</>))
22import qualified AST.Module as Module
23import qualified AST.Module.Name as ModuleName
24import qualified Elm.Compiler.Imports as Imports
25import qualified Elm.Compiler.Type as Type
26import qualified Elm.Compiler.Type.Extract as Extract
27import qualified Elm.Package as Package
31-- INTERFACES
34type Interface = Module.Interface
37type Interfaces = Module.Interfaces
40interfaceAliasedTypes :: Interface -> Map.Map String Type.Type
41interfaceAliasedTypes interface =
42 Map.map Extract.toAliasedType (Module.iTypes interface)
46-- NAMES
49newtype Name = Name ModuleName.Raw
50 deriving (Eq, Ord)
53type CanonicalName = ModuleName.Canonical
56canonicalName :: Package.Name -> Name -> CanonicalName
57canonicalName pkgName (Name name) =
58 ModuleName.Canonical pkgName name
61defaultImports :: [Name]
62defaultImports =
63 map (Name . fst) Imports.defaults
67-- STRING CONVERSIONS for NAMES
70nameToPath :: Name -> FilePath
71nameToPath (Name names) =
72 List.foldl1 (</>) names
75nameToString :: Name -> String
76nameToString (Name names) =
77 List.intercalate "." names
80nameFromString :: String -> Maybe Name
81nameFromString =
82 fromString '.'
85hyphenate :: Name -> String
86hyphenate (Name names) =
87 List.intercalate "-" names
90dehyphenate :: String -> Maybe Name
91dehyphenate =
92 fromString '-'
95fromString :: Char -> String -> Maybe Name
96fromString sep raw =
97 Name `fmap` mapM isLegit names
98 where
99 names =
100 filter (/= [sep]) (List.groupBy (\a b -> a /= sep && b /= sep) raw)
102 isLegit name =
103 case name of
104 [] -> Nothing
105 char:rest ->
106 if Char.isUpper char && all legitChar rest
107 then Just name
108 else Nothing
110 legitChar char =
111 Char.isAlphaNum char || char `elem` "_'"
115-- JSON for NAME
118instance Json.ToJSON Name where
119 toJSON name =
120 Json.toJSON (nameToString name)
123instance Json.FromJSON Name where
124 parseJSON (Json.String text) =
125 let rawName = Text.unpack text in
126 case nameFromString rawName of
127 Nothing -> fail (rawName ++ " is not a valid module name")
128 Just name -> return name
130 parseJSON _ = mzero
134-- BINARY for NAME
137instance Binary Name where
138 get =
139 fmap Name get
141 put (Name names) =
142 put names