1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
11import qualified Data.ByteString as BS
12import qualified Data.Name as Name
14import qualified AST.Source as Src
15import qualified Elm.Compiler.Imports as Imports
16import qualified Elm.Package as Pkg
17import qualified Parse.Declaration as Decl
18import qualified Parse.Keyword as Keyword
19import qualified Parse.Space as Space
20import qualified Parse.Symbol as Symbol
21import qualified Parse.Variable as Var
22import qualified Parse.Primitives as P
23import Parse.Primitives hiding (State, fromByteString)
24import qualified Reporting.Annotation as A
25import qualified Reporting.Error.Syntax as E
32fromByteString :: Pkg.Name -> BS.ByteString -> Either E.Error Src.Module
33fromByteString pkg source =
34 case P.fromByteString (chompModule pkg) E.ModuleBadEnd source of
35 Right modul -> checkModule modul
36 Left err -> Left (E.ParseError err)
45 { _header :: Maybe Header
46 , _imports :: [Src.Import]
47 , _infixes :: [A.Located Src.Infix]
48 , _decls :: [Decl.Decl]
52chompModule :: Pkg.Name -> Parser E.Module Module
54 do header <- chompHeader
55 imports <- chompImports (if pkg == Pkg.core then [] else Imports.defaults)
56 infixes <- if Pkg.isKernel pkg then chompInfixes [] else return []
57 decls <- specialize E.Declarations $ chompDecls []
58 return (Module header imports infixes decls)
65checkModule :: Module -> Either E.Error Src.Module
66checkModule (Module maybeHeader imports infixes decls) =
68 (values, unions, aliases, ports) = categorizeDecls [] [] [] [] decls
71 Just (Header name effects exports docs) ->
72 Src.Module (Just name) exports (toDocs docs decls) imports values unions aliases infixes
73 <$> checkEffects ports effects
77 Src.Module Nothing (A.At A.one Src.Open) (Src.NoDocs A.one) imports values unions aliases infixes $
80 _:_ -> Src.Ports ports
83checkEffects :: [Src.Port] -> Effects -> Either E.Error Src.Effects
84checkEffects ports effects =
88 [] -> Right Src.NoEffects
89 _:_ -> Left (E.UnexpectedPort region)
93 [] -> Left (E.NoPorts region)
94 _:_ -> Right (Src.Ports ports)
96 Manager region manager ->
98 [] -> Right (Src.Manager region manager)
99 _:_ -> Left (E.UnexpectedPort region)
102categorizeDecls :: [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] )
103categorizeDecls values unions aliases ports decls =
106 (values, unions, aliases, ports)
110 Decl.Value _ value -> categorizeDecls (value:values) unions aliases ports otherDecls
111 Decl.Union _ union -> categorizeDecls values (union:unions) aliases ports otherDecls
112 Decl.Alias _ alias -> categorizeDecls values unions (alias:aliases) ports otherDecls
113 Decl.Port _ port_ -> categorizeDecls values unions aliases (port_:ports) otherDecls
120toDocs :: Either A.Region Src.Comment -> [Decl.Decl] -> Src.Docs
121toDocs comment decls =
124 Src.YesDocs overview (getComments decls [])
130getComments :: [Decl.Decl] -> [(Name.Name,Src.Comment)] -> [(Name.Name,Src.Comment)]
131getComments decls comments =
138 Decl.Value c (A.At _ (Src.Value n _ _ _)) -> getComments otherDecls (addComment c n comments)
139 Decl.Union c (A.At _ (Src.Union n _ _ )) -> getComments otherDecls (addComment c n comments)
140 Decl.Alias c (A.At _ (Src.Alias n _ _ )) -> getComments otherDecls (addComment c n comments)
141 Decl.Port c (Src.Port n _ ) -> getComments otherDecls (addComment c n comments)
144addComment :: Maybe Src.Comment -> A.Located Name.Name -> [(Name.Name,Src.Comment)] -> [(Name.Name,Src.Comment)]
145addComment maybeComment (A.At _ name) comments =
147 Just comment -> (name, comment) : comments
155freshLine :: (Row -> Col -> E.Module) -> Parser E.Module ()
156freshLine toFreshLineError =
157 do Space.chomp E.ModuleSpace
158 Space.checkFreshLine toFreshLineError
165chompDecls :: [Decl.Decl] -> Parser E.Decl [Decl.Decl]
167 do (decl, _) <- Decl.declaration
169 [ do Space.checkFreshLine E.DeclStart
170 chompDecls (decl:decls)
172 (reverse (decl:decls))
175chompInfixes :: [A.Located Src.Infix] -> Parser E.Module [A.Located Src.Infix]
176chompInfixes infixes =
178 [ do binop <- Decl.infix_
179 chompInfixes (binop:infixes)
188chompModuleDocCommentSpace :: Parser E.Module (Either A.Region Src.Comment)
189chompModuleDocCommentSpace =
190 do (A.At region ()) <- addLocation (freshLine E.FreshLine)
193 do docComment <- Space.docComment E.ImportStart E.ModuleSpace
194 Space.chomp E.ModuleSpace
195 Space.checkFreshLine E.FreshLine
196 return (Right docComment)
206 Header (A.Located Name.Name) Effects (A.Located Src.Exposing) (Either A.Region Src.Comment)
212 | Manager A.Region Src.Manager
215chompHeader :: Parser E.Module (Maybe Header)
217 do freshLine E.FreshLine
221 -- module MyThing exposing (..)
222 do Keyword.module_ E.ModuleProblem
223 effectEnd <- getPosition
224 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
225 name <- addLocation (Var.moduleName E.ModuleName)
226 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
227 Keyword.exposing_ E.ModuleProblem
228 Space.chompAndCheckIndent E.ModuleSpace E.ModuleProblem
229 exports <- addLocation (specialize E.ModuleExposing exposing)
230 comment <- chompModuleDocCommentSpace
232 Header name (NoEffects (A.Region start effectEnd)) exports comment
234 -- port module MyThing exposing (..)
235 do Keyword.port_ E.PortModuleProblem
236 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
237 Keyword.module_ E.PortModuleProblem
238 effectEnd <- getPosition
239 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
240 name <- addLocation (Var.moduleName E.PortModuleName)
241 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
242 Keyword.exposing_ E.PortModuleProblem
243 Space.chompAndCheckIndent E.ModuleSpace E.PortModuleProblem
244 exports <- addLocation (specialize E.PortModuleExposing exposing)
245 comment <- chompModuleDocCommentSpace
247 Header name (Ports (A.Region start effectEnd)) exports comment
249 -- effect module MyThing where { command = MyCmd } exposing (..)
250 do Keyword.effect_ E.Effect
251 Space.chompAndCheckIndent E.ModuleSpace E.Effect
252 Keyword.module_ E.Effect
253 effectEnd <- getPosition
254 Space.chompAndCheckIndent E.ModuleSpace E.Effect
255 name <- addLocation (Var.moduleName E.ModuleName)
256 Space.chompAndCheckIndent E.ModuleSpace E.Effect
257 Keyword.where_ E.Effect
258 Space.chompAndCheckIndent E.ModuleSpace E.Effect
259 manager <- chompManager
260 Space.chompAndCheckIndent E.ModuleSpace E.Effect
261 Keyword.exposing_ E.Effect
262 Space.chompAndCheckIndent E.ModuleSpace E.Effect
263 exports <- addLocation (specialize (const E.Effect) exposing)
264 comment <- chompModuleDocCommentSpace
266 Header name (Manager (A.Region start effectEnd) manager) exports comment
272chompManager :: Parser E.Module Src.Manager
274 do word1 0x7B {- { -} E.Effect
277 [ do cmd <- chompCommand
280 [ do word1 0x7D {-}-} E.Effect
283 , do word1 0x2C {-,-} E.Effect
285 sub <- chompSubscription
287 word1 0x7D {-}-} E.Effect
289 return (Src.Fx cmd sub)
291 , do sub <- chompSubscription
294 [ do word1 0x7D {-}-} E.Effect
297 , do word1 0x2C {-,-} E.Effect
301 word1 0x7D {-}-} E.Effect
303 return (Src.Fx cmd sub)
308chompCommand :: Parser E.Module (A.Located Name.Name)
310 do Keyword.command_ E.Effect
312 word1 0x3D {-=-} E.Effect
314 addLocation (Var.upper E.Effect)
317chompSubscription :: Parser E.Module (A.Located Name.Name)
319 do Keyword.subscription_ E.Effect
321 word1 0x3D {-=-} E.Effect
323 addLocation (Var.upper E.Effect)
326spaces_em :: Parser E.Module ()
328 Space.chompAndCheckIndent E.ModuleSpace E.Effect
335chompImports :: [Src.Import] -> Parser E.Module [Src.Import]
338 [ do i <- chompImport
344chompImport :: Parser E.Module Src.Import
346 do Keyword.import_ E.ImportStart
347 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentName
348 name@(A.At (A.Region _ end) _) <- addLocation (Var.moduleName E.ImportName)
349 Space.chomp E.ModuleSpace
351 [ do Space.checkFreshLine E.ImportEnd
352 return $ Src.Import name Nothing (Src.Explicit [])
353 , do Space.checkIndent end E.ImportEnd
356 , chompExposing name Nothing
361chompAs :: A.Located Name.Name -> Parser E.Module Src.Import
363 do Keyword.as_ E.ImportAs
364 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentAlias
365 alias <- Var.upper E.ImportAlias
367 Space.chomp E.ModuleSpace
369 [ do Space.checkFreshLine E.ImportEnd
370 return $ Src.Import name (Just alias) (Src.Explicit [])
371 , do Space.checkIndent end E.ImportEnd
372 chompExposing name (Just alias)
376chompExposing :: A.Located Name.Name -> Maybe Name.Name -> Parser E.Module Src.Import
377chompExposing name maybeAlias =
378 do Keyword.exposing_ E.ImportExposing
379 Space.chompAndCheckIndent E.ModuleSpace E.ImportIndentExposingList
380 exposed <- specialize E.ImportExposingList exposing
381 freshLine E.ImportEnd
382 return $ Src.Import name maybeAlias exposed
389exposing :: Parser E.Exposing Src.Exposing
391 do word1 0x28 {-(-} E.ExposingStart
392 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentValue
393 oneOf E.ExposingValue
394 [ do word2 0x2E 0x2E {-..-} E.ExposingValue
395 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
396 word1 0x29 {-)-} E.ExposingEnd
398 , do exposed <- addLocation chompExposed
399 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
400 exposingHelp [exposed]
404exposingHelp :: [A.Located Src.Exposed] -> Parser E.Exposing Src.Exposing
405exposingHelp revExposed =
407 [ do word1 0x2C {-,-} E.ExposingEnd
408 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentValue
409 exposed <- addLocation chompExposed
410 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
411 exposingHelp (exposed:revExposed)
412 , do word1 0x29 {-)-} E.ExposingEnd
413 return (Src.Explicit (reverse revExposed))
417chompExposed :: Parser E.Exposing Src.Exposed
419 oneOf E.ExposingValue
420 [ Src.Lower <$> Var.lower E.ExposingValue
421 , do word1 0x28 {-(-} E.ExposingValue
422 op <- Symbol.operator E.ExposingOperator E.ExposingOperatorReserved
423 word1 0x29 {-)-} E.ExposingOperatorRightParen
424 return (Src.Operator op)
425 , do name <- Var.upper E.ExposingValue
426 Space.chompAndCheckIndent E.ExposingSpace E.ExposingIndentEnd
427 Src.Upper name <$> privacy
431privacy :: Parser E.Exposing Src.Privacy
434 [ do word1 0x28 {-(-} E.ExposingTypePrivacy
435 Space.chompAndCheckIndent E.ExposingSpace E.ExposingTypePrivacy
436 word2 0x2E 0x2E {-..-} E.ExposingTypePrivacy
437 Space.chompAndCheckIndent E.ExposingSpace E.ExposingTypePrivacy
438 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