on 1433e40 help sign in
elk/src/AST/Module.hs
235 lines 4.7 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module AST.Module
4 ( Header(..), defaultHeader, Module(..)
6 , Source, SourceInfo(..), SourceTag(..), SourceSettings, emptySettings
7 , Valid, ValidInfo(..)
8 , Canonical, Optimized, Info(..)
10 , UserImport, DefaultImport, ImportMethod(..)
12 , Types
13 , Aliases
14 , Unions, UnionInfo, CanonicalUnion
16 , Interfaces, Interface(..), toInterface
17 )
18 where
20import Data.Binary
21import qualified Data.Map as Map
22import Data.Text (Text)
24import qualified AST.Declaration as Decl
25import qualified AST.Effects as Effects
26import qualified AST.Expression.Canonical as Canonical
27import qualified AST.Expression.Optimized as Optimized
28import qualified AST.Module.Name as Name
29import qualified AST.Type as Type
30import qualified AST.Variable as Var
31import qualified Docs.AST as Docs
32import qualified Elm.Package as Package
33import qualified Elm.Compiler.Version as Compiler
34import qualified Reporting.Annotation as A
35import qualified Reporting.Region as R
39-- HEADERS FOR PARSING
42{-| Basic info needed to identify modules and determine dependencies. -}
43data Header imports =
44 Header
45 { _tag :: SourceTag
46 , _name :: Name.Raw
47 , _exports :: Var.Listing (A.Located Var.Value)
48 , _settings :: SourceSettings
49 , _docs :: Maybe (A.Located Text)
50 , _imports :: imports
51 }
54instance Show (Header a) where
55 show header =
56 show (_name header)
59defaultHeader :: imports -> Header imports
60defaultHeader imports_ =
61 Header Normal "Main" Var.openListing emptySettings Nothing imports_
65-- MODULES
68data Module phase =
69 Module
70 { name :: Name.Canonical
71 , path :: FilePath
72 , info :: phase
73 }
76type Source =
77 Module SourceInfo
80data SourceInfo =
81 Source
82 { srcTag :: SourceTag
83 , srcSettings :: SourceSettings
84 , srcDocs :: Maybe (A.Located Text)
85 , srcExports :: Var.Listing (A.Located Var.Value)
86 , srcImports :: [UserImport]
87 , srcDecls :: [Decl.Source]
88 }
91data SourceTag
92 = Normal
93 | Effect R.Region
94 | Port R.Region
97type SourceSettings =
98 A.Located [(A.Located Text, A.Located Text)]
101emptySettings :: SourceSettings
102emptySettings =
103 A.A (error "region of empty settings should not be needed") []
106type Valid =
107 Module ValidInfo
110data ValidInfo =
111 Valid
112 { validDocs :: Maybe (A.Located Text)
113 , validExports :: Var.Listing (A.Located Var.Value)
114 , validImports :: ([DefaultImport], [UserImport])
115 , validDecls :: Decl.Valid
116 , validEffects :: Effects.Raw
117 }
120type Canonical =
121 Module (Info Canonical.Expr)
124type Optimized =
125 Module (Info [Optimized.Def])
129-- IMPORTS
132type UserImport = A.Located (Name.Raw, ImportMethod)
135type DefaultImport = (Name.Raw, ImportMethod)
138data ImportMethod =
139 ImportMethod
140 { alias :: Maybe Text
141 , exposedVars :: !(Var.Listing Var.Value)
142 }
146-- LATE PHASE MODULE INFORMATION
149data Info program =
150 Info
151 { docs :: Maybe (A.Located Docs.Centralized)
152 , exports :: [Var.Value]
153 , imports :: [Name.Raw]
154 , program :: program
155 , types :: Types
156 , fixities :: [Decl.Infix]
157 , aliases :: Aliases
158 , unions :: Unions
159 , effects :: Effects.Canonical
160 }
163type Types =
164 Map.Map Text Type.Canonical
167type Aliases =
168 Map.Map Text ([Text], Type.Canonical)
171type Unions =
172 Map.Map Text (UnionInfo Text)
175type UnionInfo v =
176 ( [Text], [(v, [Type.Canonical])] )
179type CanonicalUnion =
180 ( Var.Canonical, UnionInfo Var.Canonical )
184-- INTERFACES
187type Interfaces =
188 Map.Map Name.Canonical Interface
191{-| Key facts about a module, used when reading info from .elmi files. -}
192data Interface =
193 Interface
194 { iVersion :: Package.Version
195 , iPackage :: Package.Name
196 , iExports :: [Var.Value]
197 , iImports :: [Name.Raw]
198 , iTypes :: Types
199 , iUnions :: Unions
200 , iAliases :: Aliases
201 , iFixities :: [Decl.Infix]
202 }
205toInterface :: Package.Name -> Optimized -> Interface
206toInterface pkgName modul =
207 let
208 myInfo =
209 info modul
210 in
211 Interface
212 { iVersion = Compiler.version
213 , iPackage = pkgName
214 , iExports = exports myInfo
215 , iImports = imports myInfo
216 , iTypes = types myInfo
217 , iUnions = unions myInfo
218 , iAliases = aliases myInfo
219 , iFixities = fixities myInfo
220 }
223instance Binary Interface where
224 get =
225 Interface <$> get <*> get <*> get <*> get <*> get <*> get <*> get <*> get
227 put modul =
228 do put (iVersion modul)
229 put (iPackage modul)
230 put (iExports modul)
231 put (iImports modul)
232 put (iTypes modul)
233 put (iUnions modul)
234 put (iAliases modul)
235 put (iFixities modul)