1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
10import qualified Data.ByteString as BS
11import qualified Data.Name as Name
13import qualified AST.Source as Src
14import qualified Elm.Compiler.Imports as Imports
15import qualified Elm.Package as Pkg
16import qualified Parse.Declaration as Decl
17import qualified Parse.Keyword as Keyword
18import qualified Parse.Space as Space
19import qualified Parse.Symbol as Symbol
20import qualified Parse.Variable as Var
21import qualified Parse.Primitives as P
22import Parse.Primitives hiding (State, fromByteString)
23import qualified Reporting.Annotation as A
24import qualified Reporting.Error.Syntax as E
31fromByteString :: Pkg.Name -> BS.ByteString -> Either E.Error Src.Module
32fromByteString pkg source =
33 case P.fromByteString (chompModule pkg) E.ModuleBadEnd source of
34 Right modul -> checkModule modul
35 Left err -> Left (E.ParseError err)
44 { _header :: Maybe Header
45 , _imports :: [Src.Import]
46 , _infixes :: [A.Located Src.Infix]
47 , _decls :: [Decl.Decl]
51chompModule :: Pkg.Name -> Parser E.Module Module
53 do header <- chompHeader
54 imports <- chompImports (if pkg == Pkg.core then [] else Imports.defaults)
55 infixes <- if Pkg.isKernel pkg then chompInfixes [] else return []
56 decls <- specialize E.Declarations $ chompDecls []
57 return (Module header imports infixes decls)
64checkModule :: Module -> Either E.Error Src.Module
65checkModule (Module maybeHeader imports infixes decls) =
67 (values, unions, aliases, ports) = categorizeDecls [] [] [] [] decls
70 Just (Header name effects exports docs) ->
71 Src.Module (Just name) exports (toDocs docs decls) imports values unions aliases infixes
72 <$> checkEffects ports effects
76 Src.Module Nothing (A.At A.one Src.Open) (Src.NoDocs A.one) imports values unions aliases infixes $
79 _:_ -> Src.Ports ports
82checkEffects :: [Src.Port] -> Effects -> Either E.Error Src.Effects
83checkEffects ports effects =
87 [] -> Right Src.NoEffects
88 _:_ -> Left (E.UnexpectedPort region)
92 [] -> Left (E.NoPorts region)
93 _:_ -> Right (Src.Ports ports)
95 Manager region manager ->
97 [] -> Right (Src.Manager region manager)
98 _:_ -> Left (E.UnexpectedPort region)
101categorizeDecls :: [A.Located Src.Value] -> [A.Located Src.Union] -> [A.Located Src.Alias] -> [Src.Port] -> [Decl.Decl] -> ( [A.Located Src.Value], [A.Located Src.Union], [A.Located Src.Alias], [Src.Port] )
102categorizeDecls values unions aliases ports decls =
105 (values, unions, aliases, ports)
109 Decl.Value _ value -> categorizeDecls (value:values) unions aliases ports otherDecls
110 Decl.Union _ union -> categorizeDecls values (union:unions) aliases ports otherDecls
111 Decl.Alias _ alias -> categorizeDecls values unions (alias:aliases) ports otherDecls
112 Decl.Port _ port_ -> categorizeDecls values unions aliases (port_:ports) otherDecls
119toDocs :: Either A.Region Src.Comment -> [Decl.Decl] -> Src.Docs
120toDocs comment decls =
123 Src.YesDocs overview (getComments decls [])
129getComments :: [Decl.Decl] -> [(Name.Name,Src.Comment)] -> [(Name.Name,Src.Comment)]
130getComments decls comments =
137 Decl.Value c (A.At _ (Src.Value n _ _ _)) -> getComments otherDecls (addComment c n comments)
138 Decl.Union c (A.At _ (Src.Union n _ _ )) -> getComments otherDecls (addComment c n comments)
139 Decl.Alias c (A.At _ (Src.Alias n _ _ )) -> getComments otherDecls (addComment c n comments)
140 Decl.Port c (Src.Port n _ ) -> getComments otherDecls (addComment c n comments)
143addComment :: Maybe Src.Comment -> A.Located Name.Name -> [(Name.Name,Src.Comment)] -> [(Name.Name,Src.Comment)]
144addComment maybeComment (A.At _ name) comments =
146 Just comment -> (name, comment) : comments
154freshLine :: (Row -> Col -> E.Module) -> Parser E.Module ()
155freshLine toFreshLineError =
156 do Space.chomp E.ModuleSpace
157 Space.checkFreshLine toFreshLineError
164chompDecls :: [Decl.Decl] -> Parser E.Decl [Decl.Decl]
166 do (decl, _) <- Decl.declaration
168 [ do Space.checkFreshLine E.DeclStart
169 chompDecls (decl:decls)
171 (reverse (decl:decls))
174chompInfixes :: [A.Located Src.Infix] -> Parser E.Module [A.Located Src.Infix]
175chompInfixes infixes =
177 [ do binop <- Decl.infix_
178 chompInfixes (binop:infixes)
187chompModuleDocCommentSpace :: Parser E.Module (Either A.Region Src.Comment)
188chompModuleDocCommentSpace =
189 do (A.At region ()) <- addLocation (freshLine E.FreshLine)
192 do docComment <- Space.docComment E.ImportStart E.ModuleSpace
193 Space.chomp E.ModuleSpace
194 Space.checkFreshLine E.FreshLine
195 return (Right docComment)
205 Header (A.Located Name.Name) Effects (A.Located Src.Exposing) (Either A.Region Src.Comment)
211 | Manager A.Region Src.Manager
214chompHeader :: Parser E.Module (Maybe Header)
216 do freshLine E.FreshLine
220 -- module MyThing exposing (..)
221 do Keyword.module_ E.ModuleProblem
222 effectEnd <- getPosition
223 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
224 name <- addLocation (Var.moduleName E.ModuleName)
225 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
226 Keyword.exposing_ E.ModuleProblem
227 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
228 exports <- addLocation (specialize E.ModuleExposing exposing)
229 comment <- chompModuleDocCommentSpace
231 Header name (NoEffects (A.Region start effectEnd)) exports comment
233 -- port module MyThing exposing (..)
234 do Keyword.port_ E.PortModuleProblem
235 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
236 Keyword.module_ E.PortModuleProblem
237 effectEnd <- getPosition
238 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
239 name <- addLocation (Var.moduleName E.PortModuleName)
240 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
241 Keyword.exposing_ E.PortModuleProblem
242 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
243 exports <- addLocation (specialize E.PortModuleExposing exposing)
244 comment <- chompModuleDocCommentSpace
246 Header name (Ports (A.Region start effectEnd)) exports comment
248 -- effect module MyThing where { command = MyCmd } exposing (..)
249 do Keyword.effect_ E.Effect
250 Space.chompAndCheckIndent E.ModuleSpace E.Effect
251 Keyword.module_ E.Effect
252 effectEnd <- getPosition
253 Space.chompAndCheckIndent E.ModuleSpace E.Effect
254 name <- addLocation (Var.moduleName E.ModuleName)
255 Space.chompAndCheckIndent E.ModuleSpace E.Effect
256 Keyword.where_ E.Effect
257 Space.chompAndCheckIndent E.ModuleSpace E.Effect
258 manager <- chompManager
259 Space.chompAndCheckIndent E.ModuleSpace E.Effect
260 Keyword.exposing_ E.Effect
261 Space.chompAndCheckIndent E.ModuleSpace E.Effect
262 exports <- addLocation (specialize (const E.Effect) exposing)
263 comment <- chompModuleDocCommentSpace
265 Header name (Manager (A.Region start effectEnd) manager) exports comment
271chompManager :: Parser E.Module Src.Manager
273 do word1 0x7B {- { -} E.Effect
276 [ do cmd <- chompCommand
279 [ do word1 0x7D {-}-} E.Effect
282 , do word1 0x2C {-,-} E.Effect
284 sub <- chompSubscription
286 word1 0x7D {-}-} E.Effect
288 return (Src.Fx cmd sub)
290 , do sub <- chompSubscription
293 [ do word1 0x7D {-}-} E.Effect
296 , do word1 0x2C {-,-} E.Effect
300 word1 0x7D {-}-} E.Effect
302 return (Src.Fx cmd sub)
307chompCommand :: Parser E.Module (A.Located Name.Name)
309 do Keyword.command_ E.Effect
311 word1 0x3D {-=-} E.Effect
313 addLocation (Var.upper E.Effect)
316chompSubscription :: Parser E.Module (A.Located Name.Name)
318 do Keyword.subscription_ E.Effect
320 word1 0x3D {-=-} E.Effect
322 addLocation (Var.upper E.Effect)
325spaces_em :: Parser E.Module ()
327 Space.chompAndCheckIndent E.ModuleSpace E.Effect
334chompImports :: [Src.Import] -> Parser E.Module [Src.Import]
335chompImports imports =
337 [ do Keyword.import_ E.ImportStart
338 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentName
339 name@(A.At (A.Region _ end) _) <- addLocation (Var.moduleName E.ImportName)
340 Space.chomp E.ModuleSpace
342 [ do Space.checkFreshLine E.ImportEnd
344 Src.Import name Nothing (Src.Explicit []) : imports
345 , do Space.checkIndent end E.ImportEnd
347 [ chompAs name imports
348 , chompExposing name Nothing imports
355chompAs :: A.Located Name.Name -> [Src.Import] -> Parser E.Module [Src.Import]
356chompAs name imports =
357 do Keyword.as_ E.ImportAs
358 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentAlias
359 alias <- Var.upper E.ImportAlias
361 Space.chomp E.ModuleSpace
363 [ do Space.checkFreshLine E.ImportEnd
365 Src.Import name (Just alias) (Src.Explicit []) : imports
366 , do Space.checkIndent end E.ImportEnd
367 chompExposing name (Just alias) imports
371chompExposing :: A.Located Name.Name -> Maybe Name.Name -> [Src.Import] -> Parser E.Module [Src.Import]
372chompExposing name maybeAlias imports =
373 do Keyword.exposing_ E.ImportExposing
374 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentExposingList
375 exposed <- specialize E.ImportExposingList exposing
376 freshLine E.ImportEnd
378 Src.Import name maybeAlias exposed : imports
385exposing :: Parser E.Exposing Src.Exposing
387 do word1 0x28 {-(-} E.ExposingStart
388 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentValue
389 oneOf E.ExposingValue
390 [ do word2 0x2E 0x2E {-..-} E.ExposingValue
391 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
392 word1 0x29 {-)-} E.ExposingEnd
394 , do exposed <- addLocation chompExposed
395 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
396 exposingHelp [exposed]
400exposingHelp :: [A.Located Src.Exposed] -> Parser E.Exposing Src.Exposing
401exposingHelp revExposed =
403 [ do word1 0x2C {-,-} E.ExposingEnd
404 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentValue
405 exposed <- addLocation chompExposed
406 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
407 exposingHelp (exposed:revExposed)
408 , do word1 0x29 {-)-} E.ExposingEnd
409 return (Src.Explicit (reverse revExposed))
413chompExposed :: Parser E.Exposing Src.Exposed
415 oneOf E.ExposingValue
416 [ Src.Lower <$> Var.lower E.ExposingValue
417 , do word1 0x28 {-(-} E.ExposingValue
418 op <- Symbol.operator E.ExposingOperator E.ExposingOperatorReserved
419 word1 0x29 {-)-} E.ExposingOperatorRightParen
420 return (Src.Operator op)
421 , do name <- Var.upper E.ExposingValue
422 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
423 Src.Upper name <$> privacy
427privacy :: Parser E.Exposing Src.Privacy
430 [ do word1 0x28 {-(-} E.ExposingTypePrivacy
431 Space.chompAndCheckIndent E.ExposingSpace E.ExposingTypePrivacy
432 word2 0x2E 0x2E {-..-} E.ExposingTypePrivacy
433 Space.chompAndCheckIndent E.ExposingSpace E.ExposingTypePrivacy
434 word1 0x29 {-)-} E.ExposingTypePrivacy
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list