@@ -1,15 +1,16 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2+{-# LANGUAGE FlexibleContexts #-}
2module Metadata.Prelude (interfaces, add) where
3module Metadata.Prelude (interfaces, add) where
5+import Control.Monad.Error (MonadError, throwError, MonadIO, liftIO)
4import qualified Data.Map as Map
6import qualified Data.Map as Map
5import qualified Data.Set as Set
7import qualified Data.Set as Set
6−import qualified Control.Exception as E
8+
9−import AST.Module as Module
9+import qualified AST.Module as Module
10import qualified AST.Variable as Var
10import qualified AST.Variable as Var
11−import qualified Build.Interface as Interface
11+import qualified Build.Artifact as Artifact
12−import Build.Utils (getDataFile)
12+import qualified Build.Utils as Utils
13+import qualified Elm.Compiler.Version as Compiler
15-- DEFINITION OF THE PRELUDE
16-- DEFINITION OF THE PRELUDE
@@ -17,8 +18,10 @@ import Build.Utils (getDataFile)
17type ImportDict =
18type ImportDict =
18 Map.Map String ([String], Var.Listing Var.Value)
19 Map.Map String ([String], Var.Listing Var.Value)
20prelude :: ImportDict
22prelude :: ImportDict
21−prelude = Map.unions [ string, text, maybe, openImports ]
24+ Map.unions [ string, text, maybe, openImports ]
23 importing :: String -> [Var.Value] -> ImportDict
26 importing :: String -> [Var.Value] -> ImportDict
24 importing name values =
27 importing name values =
@@ -50,26 +53,28 @@ prelude = Map.unions [ string, text, maybe, openImports ]
51-- ADDING PRELUDE TO A MODULE
54-- ADDING PRELUDE TO A MODULE
53−add :: Bool -> Module exs body -> Module exs body
56+add :: Bool -> Module.Module exs body -> Module.Module exs body
54−add noPrelude (Module moduleName path exports imports decls) =
57+add noPrelude (Module.Module moduleName path exports imports decls) =
55− Module moduleName path exports ammendedImports decls
58+ Module.Module moduleName path exports ammendedImports decls
57 ammendedImports =
60 ammendedImports =
58 importDictToList $
61 importDictToList $
59 foldr addImport (if noPrelude then Map.empty else prelude) imports
62 foldr addImport (if noPrelude then Map.empty else prelude) imports
61−importDictToList :: ImportDict -> [(String, ImportMethod)]
65+importDictToList :: ImportDict -> [(String, Module.ImportMethod)]
62importDictToList dict =
66importDictToList dict =
63 concatMap toImports (Map.toList dict)
67 concatMap toImports (Map.toList dict)
65 toImports (name, (qualifiers, listing@(Var.Listing explicits open))) =
69 toImports (name, (qualifiers, listing@(Var.Listing explicits open))) =
66− map (\qualifier -> (name, As qualifier)) qualifiers
70+ map (\qualifier -> (name, Module.As qualifier)) qualifiers
68 if open || not (null explicits)
72 if open || not (null explicits)
69− then [(name, Open listing)]
73+ then [(name, Module.Open listing)]
72−addImport :: (String, ImportMethod) -> ImportDict -> ImportDict
77+addImport :: (String, Module.ImportMethod) -> ImportDict -> ImportDict
73addImport (name, method) importDict =
78addImport (name, method) importDict =
74 Map.alter mergeMethods name importDict
79 Map.alter mergeMethods name importDict
@@ -82,8 +87,10 @@ addImport (name, method) importDict =
82 Just v -> v
87 Just v -> v
84 case method of
89 case method of
90+ Module.As qualifier ->
85− As qualifier -> Just (qualifier : qualifiers, listing)
91+ Just (qualifier : qualifiers, listing)
86− Open newListing ->
93+ Module.Open newListing ->
87 Just (qualifiers, mergeListings newListing listing)
94 Just (qualifiers, mergeListings newListing listing)
89 mergeListings (Var.Listing explicits1 open1) (Var.Listing explicits2 open2) =
96 mergeListings (Var.Listing explicits1 open1) (Var.Listing explicits2 open2) =
@@ -94,33 +101,34 @@ addImport (name, method) importDict =
95-- EXTRACT INTERFACES FROM STATIC FILE
102-- EXTRACT INTERFACES FROM STATIC FILE
97−interfaces :: Bool -> IO Interfaces
104+interfaces :: (MonadIO m, MonadError String m) => Bool -> m Module.Interfaces
98−interfaces noPrelude =
105+interfaces noPrelude
100− then return Map.empty
106+ | noPrelude = return Map.empty
101− else safeReadDocs =<< getDataFile "interfaces.data"
108+ do filePath <- liftIO (Utils.getDataFile "interfaces.data")
102−
109+ readInterfaces filePath
103−safeReadDocs :: FilePath -> IO Interfaces
110+
104−safeReadDocs name =
111+
105− E.catch (readDocs name) $ \err -> do
112+readInterfaces :: (MonadIO m, MonadError String m) => FilePath -> m Module.Interfaces
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." ]
114−readDocs :: FilePath -> IO Interfaces
115−readDocs filePath = do
113+readInterfaces filePath =
116− interfaces <- Interface.load filePath
114+ do interfaces <- mapM (isValid filePath) =<< Artifact.read filePath
117− case mapM (Interface.isValid filePath) (interfaces :: [(String, Module.Interface)]) of
115+ case interfaces of
119− hPutStrLn stderr err
123− hPutStrLn stderr "No interfaces found in serialized Prelude!"
116+ [] -> throwError "No interfaces found in serialized Prelude!"
126− Right ifaces -> return $ Map.fromList ifaces
117+ _ -> return (Map.fromList interfaces)
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
126+ version = Module.iVersion interface
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"