on master help sign in
Rename Build.Interface => Build.Artifact and shuffle some functions
commit238629fe44ff5ba6edc5e00f1c7c6c88ffe7e306 authorEvan Czaplicki <info@elm-lang.org> dateTue 7 Oct 2014, 23:57 (12 years ago) parentd6054a6
5 files changed+88−92
Elm.cabal+2−2 compiler/Build/Artifact.hs+31 compiler/Build/Interface.hs−43 compiler/Elm/Compiler.hs+1−1 compiler/Metadata/Prelude.hs+54−46
Elm.cabal+2−2
@@ -98,8 +98,8 @@ Library
9898 Type.State,
9999 Type.Type,
100100 Type.Unify,
101+ Build.Artifact,
101102 Build.Flags,
102− Build.Interface,
103103 Build.Print,
104104 Build.Source,
105105 Build.Utils,
@@ -197,8 +197,8 @@ Executable elm
197197 Type.State,
198198 Type.Type,
199199 Type.Unify,
200+ Build.Artifact,
200201 Build.Flags,
201− Build.Interface,
202202 Build.Print,
203203 Build.Source,
204204 Build.Utils,
compiler/Build/Artifact.hsnew file+31
@@ -0,0 +1,31 @@
1+{-# OPTIONS_GHC -W #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+module Build.Artifact (read) where
4+
5+import Prelude hiding (read)
6+import Control.Monad.Error (MonadError, throwError, MonadIO, liftIO)
7+import qualified Data.ByteString.Lazy as LBS
8+import qualified Data.Binary as Binary
9+import System.Directory (doesFileExist)
10+
11+
12+read :: (MonadIO m, MonadError String m, Binary.Binary a) => FilePath -> m a
13+read filePath =
14+ do exists <- liftIO (doesFileExist filePath)
15+ if exists then decode else throwError notFound
16+ where
17+ decode =
18+ do bytes <- liftIO (LBS.readFile filePath)
19+ case Binary.decodeOrFail bytes of
20+ Right (_, _, binaryInfo) -> return binaryInfo
21+ Left (_, _, _) -> throwError corrupted
22+
23+ corrupted =
24+ concat
25+ [ "Error reading build artifact ", filePath, "\n"
26+ , " The file was generated by a previous build and may be outdated or corrupt.\n"
27+ , " Please remove the file and try again."
28+ ]
29+
30+ notFound =
31+ "Unable to find file " ++ filePath ++ " for deserialization!"
compiler/Build/Interface.hsdeleted−43
@@ -1,43 +0,0 @@
1−{-# OPTIONS_GHC -W #-}
2−module Build.Interface (load,isValid) where
3−
4−import qualified Data.ByteString.Lazy as L
5−import qualified Data.Binary as Binary
6−
7−import qualified Build.Print as Print
8−import qualified Elm.Compiler.Version as Compiler
9−import System.Directory (doesFileExist)
10−import AST.Module as Module
11−
12−
13−load :: Binary.Binary a => FilePath -> IO a
14−load filePath =
15− do exists <- doesFileExist filePath
16− case exists of
17− False -> Print.failure $ "Unable to find file " ++ filePath ++ " for deserialization!"
18− True -> do
19− bytes <- L.readFile filePath
20− case Binary.decodeOrFail bytes of
21− Right (_, _, binaryInfo) -> return binaryInfo
22− Left (_, offset, err) -> Print.failure $ msg offset err
23−
24− where
25− msg offset err = concat
26− [ "Error reading build artifact: ", filePath, "\n"
27− , " '", err, "' at offset ", show offset, "\n"
28− , " The file was generated by a previous build and may be outdated or corrupt.\n"
29− , " Please remove the file and try again."
30− ]
31−
32−
33−isValid :: FilePath -> (String, Module.Interface) -> Either String (String, Module.Interface)
34−isValid filePath (name, interface) =
35− let version = iVersion interface in
36− if version == Compiler.version
37− then Right (name, interface)
38− else Left $ concat
39− [ "Error reading build artifact: ", filePath, "\n"
40− , " It was generated by version ", version, " of the compiler,\n"
41− , " but you are using version ", Compiler.version, "\n"
42− , " Please remove the file and try again.\n"
43− ]
compiler/Elm/Compiler.hs+1−1
@@ -65,5 +65,5 @@ elmToJs source =
6565{-# NOINLINE interfaces #-}
6666interfaces :: Module.Interfaces
6767interfaces =
68− unsafePerformIO $ Prelude.interfaces False
68+ error "unsafePerformIO $ Prelude.interfaces False"
6969
compiler/Metadata/Prelude.hs+54−46
@@ -1,15 +1,16 @@
11{-# OPTIONS_GHC -W #-}
2+{-# LANGUAGE FlexibleContexts #-}
23module Metadata.Prelude (interfaces, add) where
34
5+import Control.Monad.Error (MonadError, throwError, MonadIO, liftIO)
46import qualified Data.Map as Map
57import qualified Data.Set as Set
6−import qualified Control.Exception as E
7−import System.Exit
8−import System.IO
9−import AST.Module as Module
8+
9+import qualified AST.Module as Module
1010import qualified AST.Variable as Var
11−import qualified Build.Interface as Interface
12−import Build.Utils (getDataFile)
11+import qualified Build.Artifact as Artifact
12+import qualified Build.Utils as Utils
13+import qualified Elm.Compiler.Version as Compiler
1314
1415
1516-- DEFINITION OF THE PRELUDE
@@ -17,8 +18,10 @@ import Build.Utils (getDataFile)
1718type ImportDict =
1819 Map.Map String ([String], Var.Listing Var.Value)
1920
21+
2022prelude :: ImportDict
21−prelude = Map.unions [ string, text, maybe, openImports ]
23+prelude =
24+ Map.unions [ string, text, maybe, openImports ]
2225 where
2326 importing :: String -> [Var.Value] -> ImportDict
2427 importing name values =
@@ -50,26 +53,28 @@ prelude = Map.unions [ string, text, maybe, openImports ]
5053
5154-- ADDING PRELUDE TO A MODULE
5255
53−add :: Bool -> Module exs body -> Module exs body
54−add noPrelude (Module moduleName path exports imports decls) =
55− Module moduleName path exports ammendedImports decls
56+add :: Bool -> Module.Module exs body -> Module.Module exs body
57+add noPrelude (Module.Module moduleName path exports imports decls) =
58+ Module.Module moduleName path exports ammendedImports decls
5659 where
5760 ammendedImports =
5861 importDictToList $
5962 foldr addImport (if noPrelude then Map.empty else prelude) imports
6063
61−importDictToList :: ImportDict -> [(String, ImportMethod)]
64+
65+importDictToList :: ImportDict -> [(String, Module.ImportMethod)]
6266importDictToList dict =
6367 concatMap toImports (Map.toList dict)
6468 where
6569 toImports (name, (qualifiers, listing@(Var.Listing explicits open))) =
66− map (\qualifier -> (name, As qualifier)) qualifiers
70+ map (\qualifier -> (name, Module.As qualifier)) qualifiers
6771 ++
6872 if open || not (null explicits)
69− then [(name, Open listing)]
73+ then [(name, Module.Open listing)]
7074 else []
7175
72−addImport :: (String, ImportMethod) -> ImportDict -> ImportDict
76+
77+addImport :: (String, Module.ImportMethod) -> ImportDict -> ImportDict
7378addImport (name, method) importDict =
7479 Map.alter mergeMethods name importDict
7580 where
@@ -82,8 +87,10 @@ addImport (name, method) importDict =
8287 Just v -> v
8388 in
8489 case method of
85− As qualifier -> Just (qualifier : qualifiers, listing)
86− Open newListing ->
90+ Module.As qualifier ->
91+ Just (qualifier : qualifiers, listing)
92+
93+ Module.Open newListing ->
8794 Just (qualifiers, mergeListings newListing listing)
8895
8996 mergeListings (Var.Listing explicits1 open1) (Var.Listing explicits2 open2) =
@@ -94,33 +101,34 @@ addImport (name, method) importDict =
94101
95102-- EXTRACT INTERFACES FROM STATIC FILE
96103
97−interfaces :: Bool -> IO Interfaces
98−interfaces noPrelude =
99− if noPrelude
100− then return Map.empty
101− else safeReadDocs =<< getDataFile "interfaces.data"
102−
103−safeReadDocs :: FilePath -> IO Interfaces
104−safeReadDocs name =
105− E.catch (readDocs name) $ \err -> do
106− let _ = err :: IOError
107− hPutStrLn stderr $ unlines $
108− [ "Error reading types for standard library from file " ++ name
109− , " If you are using a stable version of Elm, please report an issue at"
110− , " <http://github.com/elm-lang/Elm/issues> specifying version numbers for"
111− , " Elm and your OS." ]
112− exitFailure
113−
114−readDocs :: FilePath -> IO Interfaces
115−readDocs filePath = do
116− interfaces <- Interface.load filePath
117− case mapM (Interface.isValid filePath) (interfaces :: [(String, Module.Interface)]) of
118− Left err -> do
119− hPutStrLn stderr err
120− exitFailure
121−
122− Right [] -> do
123− hPutStrLn stderr "No interfaces found in serialized Prelude!"
124− exitFailure
125−
126− Right ifaces -> return $ Map.fromList ifaces
104+interfaces :: (MonadIO m, MonadError String m) => Bool -> m Module.Interfaces
105+interfaces noPrelude
106+ | noPrelude = return Map.empty
107+ | otherwise =
108+ do filePath <- liftIO (Utils.getDataFile "interfaces.data")
109+ readInterfaces filePath
110+
111+
112+readInterfaces :: (MonadIO m, MonadError String m) => FilePath -> m Module.Interfaces
113+readInterfaces filePath =
114+ do interfaces <- mapM (isValid filePath) =<< Artifact.read filePath
115+ case interfaces of
116+ [] -> throwError "No interfaces found in serialized Prelude!"
117+ _ -> return (Map.fromList interfaces)
118+
119+
120+isValid :: (MonadError String m) => FilePath -> (String, Module.Interface) -> m (String, Module.Interface)
121+isValid filePath (name, interface) =
122+ if version == Compiler.version
123+ then return (name, interface)
124+ else throwError badVersion
125+ where
126+ version = Module.iVersion interface
127+
128+ badVersion =
129+ concat
130+ [ "Error reading build artifact: ", filePath, "\n"
131+ , " It was generated by version ", version, " of the compiler,\n"
132+ , " but you are using version ", Compiler.version, "\n"
133+ , " Please remove the file and try again.\n"
134+ ]