1module Initialize (buildFromSource, getSortedModuleNames) where
3import Control.Applicative ((<$>))
4import Control.Monad.Error
5import Data.List (lookup,nub)
6import qualified Data.Map as Map
8import SourceSyntax.Everything
9import Data.List (intercalate,partition)
10import Parse.Parser (parseProgram, parseDependencies)
11import qualified Metadata.Libraries as Libs
12import qualified Transform.Optimize as Optimize
13import qualified Transform.Check as Check
22checkMistakes :: (Data t, Data v) => Module t v -> Either String (Module t v)
23checkMistakes modul@(Module name ex im decls) =
24 case Check.mistakes decls of
26 ms -> Left (unlines ms)
28checkTypes :: (Data t, Data v) => Module t v -> Either String (Module t v)
30 do subs <- unify hints modul
31 subs `seq` return (Optimize.optimize (renameModule modul))
33check :: (Data t, Data v) => Module t v -> Either String (Module t v)
34check = checkMistakes >=> checkTypes
36buildFromSource :: (Data t, Data v) => Bool -> String -> Either String (Module t v)
37buildFromSource noPrelude src =
38 let add = if noPrelude then id else Libs.addPrelude in
39 (check . add) =<< parseProgram src
41getSortedModuleNames :: FilePath -> IO [String]
42getSortedModuleNames root =
43 sortDeps =<< readDeps [] root
45type Deps = (String, [String])
47sortDeps :: [Deps] -> IO [String]
48sortDeps deps = go [] (nub deps)
50 msg = "A cyclical or missing module dependency or was detected in: "
52 go :: [String] -> [Deps] -> IO [String]
53 go sorted [] = return (map toFilePath sorted)
55 case partition (all (`elem` sorted) . snd) unsorted of
56 ([],m:ms) -> do putStrLn (msg ++ intercalate ", " (map fst (m:ms)) ++ show sorted ++ show unsorted)
58 (srtd,unsrtd) -> go (sorted ++ map fst srtd) unsrtd
60readDeps :: [FilePath] -> FilePath -> IO [Deps]
61readDeps seen root = do
63 case parseDependencies txt of
65 let msg = "Error resolving dependencies in " ++ root ++ ":\n" in
66 putStrLn (msg ++ err) >> exitFailure
68 do rest <- mapM (readDeps seen' . toFilePath) newDeps
69 return ((name, realDeps) : concat rest)
71 realDeps = filter (`notElem` builtIns) deps
72 newDeps = filter (\d -> d `notElem` seen && not (isNative d)) realDeps
73 seen' = root : seen ++ newDeps
74 builtIns = Map.keys Libs.libraries
77isNative name = takeWhile (/='.') name == "Native"
79toFilePath :: String -> FilePath
80toFilePath name = map swapDots name ++ ext
81 where swapDots '.' = '/'
83 ext = if isNative name then ".js" else ".elm"
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