on master help sign in
Simplify Build.Interface API, do not read "interfaces.data" when the --no-prelude flag is used
c03049aEvan Czaplicki
compiler/Build/File.hs+2−3
@@ -57,9 +57,8 @@ alreadyCompiled flags filePath = do
57retrieve :: Flag.Flags -> Map.Map String M.ModuleInterface -> FilePath
57retrieve :: Flag.Flags -> Map.Map String M.ModuleInterface -> FilePath
58 -> IO (String, M.ModuleInterface)
58 -> IO (String, M.ModuleInterface)
59retrieve flags interfaces filePath = do
59retrieve flags interfaces filePath = do
60− bytes <- Interface.load (Utils.elmi flags filePath)
60+ iface <- Interface.load (Utils.elmi flags filePath)
61− let binary = Interface.decode (Utils.elmi flags filePath) =<< bytes
62− case Interface.isValid filePath =<< binary of
61+ case Interface.isValid filePath iface of
63 Right (name, interface) ->
62 Right (name, interface) ->
64 do when (Flag.print_types flags) (Print.interfaceTypes interfaces interface)
63 do when (Flag.print_types flags) (Print.interfaceTypes interfaces interface)
65 return (name, interface)
64 return (name, interface)
compiler/Build/Interface.hs+28−28
@@ -1,46 +1,46 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2−module Build.Interface (load,decode,isValid) where
2+module Build.Interface (load,isValid) where
3
3
4import qualified Data.ByteString.Lazy as L
4import qualified Data.ByteString.Lazy as L
5import qualified Data.Binary as Binary
5import qualified Data.Binary as Binary
6
6
7import qualified Elm.Internal.Version as Version
7import qualified Elm.Internal.Version as Version
8import System.Directory (doesFileExist)
8import System.Directory (doesFileExist)
9+import System.Exit
10+import System.IO
9
11
10import SourceSyntax.Module
12import SourceSyntax.Module
11
13
12−load :: FilePath -> IO (Either String L.ByteString)
14+load :: Binary.Binary a => FilePath -> IO a
13−load filePath = do
15+load filePath =
14− exists <- doesFileExist filePath
16+ do exists <- doesFileExist filePath
15− if exists
17+ case exists of
16− then do
17− byteString <- L.readFile filePath
18− return $ Right byteString
19−
20− else
21− return $ Left $ "Unable to find file " ++ filePath ++
18+ False -> failure $ "Unable to find file " ++ filePath ++ " for deserialization!"
22− " for deserialization!"
19+ True -> do
23−
20+ bytes <- L.readFile filePath
24−decode :: Binary.Binary a => FilePath -> L.ByteString -> Either String a
25−decode filePath bytes =
26− case Binary.decodeOrFail bytes of
21+ case Binary.decodeOrFail bytes of
27− Right (_, _, binaryInfo) -> Right binaryInfo
22+ Right (_, _, binaryInfo) -> return binaryInfo
28−
29− Left (_, offset, err) ->
23+ Left (_, offset, err) -> failure $ msg offset err
24+
25+ where
26+ failure err = do hPutStrLn stderr err
27+ exitFailure
28+
30− Left $ concat $
29+ msg offset err = concat
31− [ "Error reading build artifact: ", filePath, "\n"
30+ [ "Error reading build artifact: ", filePath, "\n"
32− , " The exact error was '", err, "' at offset ", show offset, ".\n"
31+ , " '", err, "' at offset ", show offset, "\n"
33− , " The file was generated by a previous build and may be outdated or corrupt.\n"
32+ , " The file was generated by a previous build and may be outdated or corrupt.\n"
34− , " Please remove the file and try again."
33+ , " Please remove the file and try again."
35− ]
34+ ]
36
35
37isValid :: FilePath -> (String, ModuleInterface) -> Either String (String, ModuleInterface)
36isValid :: FilePath -> (String, ModuleInterface) -> Either String (String, ModuleInterface)
38isValid filePath (name, interface) =
37isValid filePath (name, interface) =
38+ let version = iVersion interface in
39− if iVersion interface == Version.elmVersion
39+ if version == Version.elmVersion
40 then Right (name, interface)
40 then Right (name, interface)
41 else Left $ concat
41 else Left $ concat
42 [ "Error reading build artifact: ", filePath, "\n"
42 [ "Error reading build artifact: ", filePath, "\n"
43− , " It was generated by a different version of the compiler: "
43+ , " It was generated by version ", show version, " of the compiler,\n"
44− , show (iVersion interface), "\n"
44+ , " but you are using version ", show Version.elmVersion, "\n"
45 , " Please remove the file and try again.\n"
45 , " Please remove the file and try again.\n"
46 ]
46 ]
compiler/Metadata/Prelude.hs+16−15
@@ -28,30 +28,31 @@ prelude = text ++ map (\n -> (n, Hiding [])) modules
28
28
29interfaces :: Bool -> IO Interfaces
29interfaces :: Bool -> IO Interfaces
30interfaces noPrelude =
30interfaces noPrelude =
31− do ifaces <- safeReadDocs =<< Path.getDataFileName "interfaces.data"
32− return $ if noPrelude then Map.empty else ifaces
31+ if noPrelude
32+ then return $ Map.empty
33+ else safeReadDocs =<< Path.getDataFileName "interfaces.data"
33
34
34safeReadDocs :: FilePath -> IO Interfaces
35safeReadDocs :: FilePath -> IO Interfaces
35safeReadDocs name =
36safeReadDocs name =
36 E.catch (readDocs name) $ \err -> do
37 E.catch (readDocs name) $ \err -> do
37 let _ = err :: IOError
38 let _ = err :: IOError
39+ hPutStrLn stderr $ unlines $
38− putStrLn $ unlines [ "Error reading types for standard library!"
40+ [ "Error reading types for standard library from file " ++ name
39− , " The file should be at " ++ name
40− , " If you are using a stable version of Elm,"
41+ , " If you are using a stable version of Elm, please report an issue at"
41− , " please report an issue at github.com/evancz/Elm"
42+ , " <http://github.com/evancz/Elm/issues> specifying version numbers for"
42− , " and specify your versions of Elm and your OS" ]
43+ , " Elm and your OS." ]
43 exitFailure
44 exitFailure
44
45
45−hasInterfaces :: [(String, ModuleInterface)] -> Either String [(String, ModuleInterface)]
46−hasInterfaces [] = Left "No interfaces found in serialized Prelude!"
47−hasInterfaces ifaces = Right ifaces
48−
49readDocs :: FilePath -> IO Interfaces
46readDocs :: FilePath -> IO Interfaces
50readDocs filePath = do
47readDocs filePath = do
51− bytes <- Interface.load filePath
48+ interfaces <- Interface.load filePath
52− let interfaces = Interface.decode filePath =<< bytes
53− case mapM (Interface.isValid filePath) =<< hasInterfaces =<< interfaces of
49+ case mapM (Interface.isValid filePath) (interfaces :: [(String, ModuleInterface)]) of
54− Right ifaces -> return $ Map.fromList ifaces
55 Left err -> do
50 Left err -> do
56 hPutStrLn stderr err
51 hPutStrLn stderr err
57 exitFailure
52 exitFailure
53+
54+ Right [] -> do
55+ hPutStrLn stderr "No interfaces found in serialized Prelude!"
56+ exitFailure
57+
58+ Right ifaces -> return $ Map.fromList ifaces