1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings, QuasiQuotes #-}
10import qualified Data.ByteString as B
11import qualified Data.ByteString.Builder as B
12import qualified Data.ByteString.Lazy as LBS
13import qualified Data.Map as Map
14import qualified Data.Map.Utils as Map
15import qualified Data.Name as N
16import qualified Data.NonEmptyList as NE
18import Snap.Util.FileUploads
19import qualified System.Directory as Dir
20import qualified System.IO.Streams as Stream
21import Text.RawString.QQ (r)
23import qualified Artifacts as A
26import qualified AST.Source as Src
27import qualified AST.Canonical as Can
28import qualified AST.Optimized as Opt
29import qualified BackgroundWriter as BW
31import qualified Compile
32import qualified Elm.Details as Details
33import qualified Elm.Interface as I
34import qualified Elm.ModuleName as ModuleName
35import qualified Elm.Package as Pkg
37import qualified Generate
38import qualified Generate.Html as Html
39import qualified Generate.JavaScript as JS
40import qualified Generate.Mode as Mode
41import qualified Json.Encode as Encode
42import qualified Parse.Module as Parse
43import qualified Reporting
44import qualified Reporting.Annotation as A
45import Reporting.Doc ((<>))
46import qualified Reporting.Doc as D
47import qualified Reporting.Error as Error
48import qualified Reporting.Error.Import as Import
49import qualified Reporting.Exit as Exit
50import qualified Reporting.Exit.Help as Help
51import qualified Reporting.Task as Task
58allowedOrigins :: [String]
60 [ "https://elm-lang.org"
61 , "https://package.elm-lang.org"
69endpoint :: A.Artifacts -> Snap ()
71 Cors.allow POST allowedOrigins $
72 do result <- foldMultipart defaultUploadPolicy ignoreFile 0
74 ([("code",source)], 0) ->
75 do modifyResponse $ setContentType "text/html; charset=utf-8"
76 case compile artifacts source of
81 writeBuilder $ renderReport noMain
84 writeBuilder $ renderReport $
85 Help.compilerReport "/" (Error.Module name "/try" File.zeroTime source err) []
88 do modifyResponse $ setResponseStatus 400 "Bad Request"
89 modifyResponse $ setContentType "text/html; charset=utf-8"
91 "<p>Unexpected request format. This should not be possible!</p>\
92 \<p>Please report this\
93 \ <a href=\"https://github.com/elm/compiler/issues\">here</a>\
94 \ along with the URL and your browser version.</p>"
97ignoreFile :: PartInfo -> Stream.InputStream B.ByteString -> Int -> IO Int
109 | BadInput ModuleName.Raw Error.Error
112compile :: A.Artifacts -> B.ByteString -> Outcome
113compile (A.Artifacts interfaces objects) source =
114 case Parse.fromByteString Parse.Application source of
116 BadInput N._Main (Error.BadSyntax err)
118 Right modul@(Src.Module _ _ _ imports _ _ _ _ _) ->
119 case checkImports interfaces imports of
121 BadInput (Src.getName modul) (Error.BadImports err)
124 case Compile.compile Pkg.dummyName ifaces modul of
126 BadInput (Src.getName modul) err
128 Right (Compile.Artifacts canModule _ locals) ->
130 Opt.LocalGraph Nothing _ _ ->
133 Opt.LocalGraph (Just main_) _ _ ->
135 mode = Mode.Dev Nothing
136 home = Can._name canModule
137 name = ModuleName._module home
138 mains = Map.singleton home main_
139 graph = Opt.addLocalGraph locals objects
141 Success $ Html.sandwich name $ JS.generate mode graph mains
144checkImports :: Map.Map ModuleName.Raw I.Interface -> [Src.Import] -> Either (NE.List Import.Error) (Map.Map ModuleName.Raw I.Interface)
145checkImports interfaces imports =
147 importDict = Map.fromValues Src.getImportName imports
148 missing = Map.difference importDict interfaces
150 case Map.elems missing of
152 Right (Map.intersection interfaces importDict)
157 Map.keysSet (Map.difference interfaces importDict)
159 toError (Src.Import (A.At region name) _ _) =
160 Import.Error region name unimported Import.NotFound
162 Left (fmap toError (NE.List i is))
169renderReport :: Help.Report -> B.Builder
174 <meta charset="UTF-8">
175 <style>body { padding: 0; margin: 0; background-color: black; }</style>
176 <script src="https://worker.elm-lang.org/compile/errors.js"></script>
180 var app = Elm.Errors.init({flags:|] <> Encode.encodeUgly (Exit.toJson report) <> [r|});
181 app.ports.jumpTo.subscribe(function(region) {
182 window.parent.postMessage(JSON.stringify(region), '*');
195 Help.report "NO MAIN" Nothing
197 "Without a `main` value, I do not know what to show on screen!"
200 "Adding a `main` value can be as brief as:"
202 [ D.fillSep [D.cyan "import","Html"]
204 , D.fillSep [D.green "main","="]
205 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
208 "Try adding something like that!"
210 "I recommend looking through https://guide.elm-lang.org for more advice on\
211 \ how to fill in `main` values."
219loadErrorJS :: IO B.ByteString
226 Left _ -> error "problem building src/Errors.elm"
228 BW.withScope $ \scope ->
229 do root <- Dir.getCurrentDirectory
230 details <- run $ Details.load Reporting.silent scope root
231 artifacts <- run $ Build.fromPaths Reporting.silent root details (NE.List "src/Errors.elm" [])
232 javascript <- run $ Task.run $ Generate.prod root details artifacts
233 return $ LBS.toStrict $ B.toLazyByteString javascript
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