1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
12import Control.Monad.Except (liftIO)
13import qualified Data.ByteString as BS
14import Data.List.NonEmpty (NonEmpty((:|)))
15import qualified Data.Map as Map
16import Data.Semigroup ((<>))
17import qualified Data.Time.Calendar as Day
18import qualified Data.Time.Clock as Time
19import qualified System.Directory as Dir
21import qualified Elm.Compiler.Module as Module
22import qualified Elm.Header as Header
24import qualified Elm.Project.Json as Project
25import Elm.Project.Json (Project)
26import Elm.Project.Summary (Summary(..))
27import qualified File.IO as IO
28import qualified Reporting.Error2 as Error
29import qualified Reporting.Error.Crawl as E
30import qualified Reporting.Task as Task
40 , _time :: Time.UTCTime
41 , _source :: BS.ByteString
42 , _imports :: [Module.Raw]
46atRoot :: Task.Task_ E.Problem a -> Task.Task_ E.Error a
48 Task.mapError (\problem -> E.DependencyProblems problem []) task
54readModule :: Summary -> Module.Raw -> FilePath -> Task.Task_ E.Problem (Module.Raw, Info)
55readModule summary expectedName path =
56 do time <- liftIO $ Dir.getModificationTime path
57 source <- liftIO $ IO.readUtf8 path
58 (maybeName, info) <- parse (_project summary) path time source
59 name <- checkName path expectedName maybeName
63checkName :: FilePath -> Module.Raw -> Maybe Module.Raw -> Task.Task_ E.Problem Module.Raw
64checkName path expectedName maybeName =
67 Task.throw (E.ModuleNameMissing path expectedName)
70 if expectedName == actualName
71 then return expectedName
72 else Task.throw (E.ModuleNameMismatch path expectedName actualName)
79readOneFile :: Summary -> FilePath -> Task.Task (Maybe Module.Raw, Info)
80readOneFile summary path =
81 Task.mapError Error.Crawl $
82 do (time, source) <- readOneHelp path
83 atRoot $ parse (_project summary) path time source
86readOneHelp :: FilePath -> Task.Task_ E.Error (Time.UTCTime, BS.ByteString)
88 do exists <- IO.exists path
90 then liftIO $ (,) <$> Dir.getModificationTime path <*> IO.readUtf8 path
91 else Task.throw $ E.RootFileNotFound path
98readManyFiles :: Summary -> NonEmpty FilePath -> Task.Task (NonEmpty (Module.Raw, Info))
99readManyFiles summary files =
100 Task.mapError Error.Crawl $
101 do infos <- traverse (readManyFilesHelp summary) files
102 let insert (name, info) dict = Map.insertWith (<>) name (info :| []) dict
103 let nameTable = foldr insert Map.empty infos
104 _ <- Map.traverseWithKey detectDuplicateNames nameTable
108readManyFilesHelp :: Summary -> FilePath -> Task.Task_ E.Error (Module.Raw, Info)
109readManyFilesHelp summary path =
110 do (time, source) <- readOneHelp path
111 (maybeName, info) <- atRoot $ parse (_project summary) path time source
114 Task.throw (E.RootNameless path)
120detectDuplicateNames :: Module.Raw -> NonEmpty Info -> Task.Task_ E.Error ()
121detectDuplicateNames name (info :| otherInfos) =
127 Task.throw (E.RootModuleNameDuplicate name (map _path (info : otherInfos)))
135readSource :: Project -> BS.ByteString -> Task.Task (Maybe Module.Raw, Info)
136readSource project source =
137 Task.mapError Error.Crawl $
138 atRoot $ parse project "elm" fakeTime source
141fakeTime :: Time.UTCTime
143 Time.UTCTime (Day.fromGregorian 3000 1 1) 0
150parse :: Project -> FilePath -> Time.UTCTime -> BS.ByteString -> Task.Task_ E.Problem (Maybe Module.Raw, Info)
151parse project path time source =
152 -- TODO get regions on data extracted here
153 case Header.parse (Project.getName project) source of
154 Right (maybeDecl, deps) ->
155 do maybeName <- checkTag project path maybeDecl
156 return ( maybeName, Info path time source deps )
159 Task.throw (E.BadHeader path source msg)
162checkTag :: Project -> FilePath -> Maybe (Header.Tag, Module.Raw) -> Task.Task_ E.Problem (Maybe Module.Raw)
163checkTag project path maybeDecl =
183 Task.throw (E.PortsInPackage path name)
186 if Project.isPlatformPackage project then
190 Task.throw (E.EffectsUnexpected path name)
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