@@ -1,54 +1,18 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2−{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}
2+{-# LANGUAGE OverloadedStrings #-}
9−import Control.Concurrent (readMVar)
9+import Control.Monad (msum)
10−import Control.Monad (liftM2, msum)
11−import qualified Data.ByteString as B
12−import qualified Data.ByteString.Builder as B
13−import qualified Data.ByteString.Lazy as LBS
14−import qualified Data.HashSet as HashSet
15−import qualified Data.Map as Map
16−import qualified Data.Map.Utils as Map
17−import qualified Data.Name as N
18−import qualified Data.NonEmptyList as NE
19−import qualified Data.OneOrMore as OneOrMore
20−import Network.URI (parseURI)
21import Snap.Core
10import Snap.Core
22import Snap.Http.Server
11import Snap.Http.Server
23−import Snap.Util.CORS (CORSOptions(..), HashableMethod(..), OriginList(Origins), applyCORS, mkOriginSet)
24−import Snap.Util.FileUploads
25−import qualified System.Directory as Dir
26−import qualified System.IO.Streams as Stream
27−import Text.RawString.QQ (r)
29−import qualified AST.Source as Src
13+import qualified Artifacts
30−import qualified AST.Canonical as Can
31−import qualified AST.Optimized as Opt
14+import qualified Endpoint.Compile as Compile
32−import qualified BackgroundWriter as BW
33−import qualified Build
34−import qualified Compile
35−import qualified Elm.Details as Details
15+import qualified Endpoint.Repl as Repl
36−import qualified Elm.Interface as I
37−import qualified Elm.ModuleName as ModuleName
38−import qualified Elm.Package as Pkg
40−import qualified Generate
41−import qualified Generate.Html as Html
42−import qualified Generate.JavaScript as Generate
43−import qualified Generate.Mode as Mode
44−import qualified Json.Encode as Encode
45−import qualified Parse.Module as Parse
46−import qualified Reporting
47−import qualified Reporting.Annotation as A
48−import qualified Reporting.Error as Error
49−import qualified Reporting.Error.Import as Import
50−import qualified Reporting.Exit as Exit
51−import qualified Reporting.Task as Task
@@ -57,10 +21,13 @@ import qualified Reporting.Task as Task
58main :: IO ()
22main :: IO ()
60− do artifacts <- loadArtifacts
24+ do rArtifacts <- Artifacts.loadRepl
61− errorJS <- compileErrorViewer
25+ cArtifacts <- Artifacts.loadCompile
26+ errorJS <- Compile.loadErrorJS
62 httpServe config $ msum $
27 httpServe config $ msum $
63− [ path "compile" $ compile artifacts
28+ [ ifTop $ status
29+ , path "repl" $ Repl.endpoint rArtifacts
30+ , path "compile" $ Compile.endpoint cArtifacts
64 , path "compile/errors.js" $ writeBS errorJS
31 , path "compile/errors.js" $ writeBS errorJS
65 , notFound
32 , notFound
@@ -68,235 +35,17 @@ main =
69config :: Config Snap a
36config :: Config Snap a
73− |> setAccessLog ConfigNoLog
38+ setPort 8000 $ setAccessLog ConfigNoLog $ setErrorLog ConfigNoLog $ defaultConfig
74− |> setErrorLog ConfigNoLog
77−(|>) :: a -> (a -> b) -> b
41+status :: Snap ()
78−(|>) value func =
42+status =
79− func value
43+ do modifyResponse $ setContentType "text/plain"
80−
44+ writeBuilder "Status: OK"
86notFound :: Snap ()
47notFound :: Snap ()
88 do modifyResponse $ setResponseStatus 404 "Not Found"
49 do modifyResponse $ setResponseStatus 404 "Not Found"
89 modifyResponse $ setContentType "text/html; charset=utf-8"
50 modifyResponse $ setContentType "text/html; charset=utf-8"
90− writeBS "Not Found"
51+ writeBuilder "Not Found"
97−compile :: Artifacts -> Snap ()
99− applyCORS corsOptions $ method POST $
100− do result <- foldMultipart defaultUploadPolicy ignoreFile 0
102− ([("code",source)], 0) ->
103− do modifyResponse $ setContentType "text/html; charset=utf-8"
104− case compileToBuilder artifacts source of
105− Right builder -> writeBuilder builder
106− Left exit -> writeBuilder (exitToHtmlBuilder exit)
109− do modifyResponse $ setResponseStatus 400 "Bad Request"
110− modifyResponse $ setContentType "text/html; charset=utf-8"
112− "<p>Unexpected request format. This should not be possible!</p>\
113− \<p>Please report this\
114− \ <a href=\"https://github.com/elm/compiler/issues\">here</a>\
115− \ along with the URL and your browser version.</p>"
118−ignoreFile :: PartInfo -> Stream.InputStream B.ByteString -> Int -> IO Int
119−ignoreFile _ _ count =
123−exitToHtmlBuilder :: Exit.Worker -> B.Builder
124−exitToHtmlBuilder exit =
127− Encode.encodeUgly $ Exit.toJson $ Exit.workerToReport exit
132− <meta charset="UTF-8">
133− <style>body { padding: 0; margin: 0; background-color: black; }</style>
134− <script src="https://worker.elm-lang.org/compile/errors.js"></script>
137− <script>Elm.Errors.init({flags:|] <> json <> [r|});</script>
143−-- COMPILE TO BUILDER
146−compileToBuilder :: Artifacts -> B.ByteString -> Either Exit.Worker B.Builder
147−compileToBuilder (Artifacts interfaces objects) source =
148− case Parse.fromByteString Parse.Application source of
150− Left $ toInputError N._Main source (Error.BadSyntax err)
152− Right modul@(Src.Module _ _ _ imports _ _ _ _ _) ->
153− case checkImports interfaces imports of
155− Left $ toInputError (Src.getName modul) source (Error.BadImports err)
158− case Compile.compile Pkg.dummyName ifaces modul of
160− Left $ toInputError (Src.getName modul) source err
162− Right (Compile.Artifacts canModule _ locals) ->
164− Opt.LocalGraph Nothing _ _ ->
165− Left Exit.WorkerNoMain
167− Opt.LocalGraph (Just main_) _ _ ->
169− mode = Mode.Dev Nothing
170− home = Can._name canModule
171− name = ModuleName._module home
172− mains = Map.singleton home main_
173− graph = Opt.addLocalGraph locals objects
175− Right $ Html.sandwich name $ Generate.generate mode graph mains
178−checkImports :: Map.Map ModuleName.Raw I.Interface -> [Src.Import] -> Either (NE.List Import.Error) (Map.Map ModuleName.Raw I.Interface)
179−checkImports interfaces imports =
181− importDict = Map.fromValues Src.getImportName imports
182− missing = Map.difference importDict interfaces
184− case Map.elems missing of
186− Right (Map.intersection interfaces importDict)
190− unimported = Map.keysSet (Map.difference interfaces importDict)
191− toError (Src.Import (A.At region name) _ _) =
192− Import.Error region name unimported Import.NotFound
194− Left (fmap toError (NE.List i is))
197−toInputError :: ModuleName.Raw -> B.ByteString -> Error.Error -> Exit.Worker
198−toInputError name source err =
199− Exit.WorkerInputError $
200− Error.Module name "/try" File.zeroTime source err
204−-- COMPILE ERROR VIEWER
207−compileErrorViewer :: IO B.ByteString
214− Left _ -> error "problem building reactor/src/Errors.elm"
216− Dir.withCurrentDirectory "../reactor" $ BW.withScope $ \scope ->
218− details <- run $ Details.load Reporting.silent scope root
219− artifacts <- run $ Build.fromMains Reporting.silent root details (NE.List "src/Errors.elm" [])
220− javascript <- run $ Task.run $ Generate.prod root details artifacts
221− return $ LBS.toStrict $ B.toLazyByteString javascript
228−corsOptions :: (Monad m) => CORSOptions m
231− allowedOrigins = toOriginList [ "https://elm-lang.org", "https://package.elm-lang.org" ]
232− allowedMethods = HashSet.singleton (HashableMethod POST)
235− { corsAllowOrigin = return allowedOrigins
236− , corsAllowCredentials = return True
237− , corsExposeHeaders = return HashSet.empty
238− , corsAllowedMethods = return allowedMethods
239− , corsAllowedHeaders = return
243−toOriginList :: [String] -> OriginList
244−toOriginList origins =
245− Origins $ mkOriginSet $
246− case traverse parseURI origins of
248− Nothing -> error "invalid entry given to toOriginList list"
257− { _ifaces :: Map.Map ModuleName.Raw I.Interface
258− , _graph :: Opt.GlobalGraph
262−loadArtifacts :: IO Artifacts
264− BW.withScope $ \scope ->
265− do style <- Reporting.terminal
266− root <- Dir.getCurrentDirectory
267− result <- Details.load style scope root
270− error "Ran into some problem loading elm.json details"
273− do omvar <- Details.loadObjects root details
274− imvar <- Details.loadInterfaces root details
275− mdeps <- readMVar imvar
276− mobjs <- readMVar omvar
277− case liftM2 (,) mdeps mobjs of
279− error "Ran into some weird problem loading elm.json details"
281− Just (deps, objs) ->
282− return $ Artifacts (toInterfaces deps) objs
285−toInterfaces :: Map.Map ModuleName.Canonical I.DependencyInterface -> Map.Map ModuleName.Raw I.Interface
287− Map.mapMaybe toUnique $ Map.fromListWith OneOrMore.more $
288− Map.elems (Map.mapMaybeWithKey getPublic deps)
291−getPublic :: ModuleName.Canonical -> I.DependencyInterface -> Maybe (ModuleName.Raw, OneOrMore.OneOrMore I.Interface)
292−getPublic (ModuleName.Canonical _ name) dep =
294− I.Public iface -> Just (name, OneOrMore.one iface)
295− I.Private _ _ _ -> Nothing
298−toUnique :: OneOrMore.OneOrMore a -> Maybe a
301− OneOrMore.One value -> Just value
302− OneOrMore.More _ _ -> Nothing