on eb97f2a help sign in
elk/src/Elm/Compiler.hs
206 lines 5.2 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2module Elm.Compiler
3 ( version
4 , parseDependencies, Tag(..)
5 , compile, Context(..), Result(..)
6 , Localizer, dummyLocalizer
7 , Error, errorToString, errorToJson, printError
8 , Warning, warningToString, warningToJson, printWarning
9 )
10 where
12import qualified Data.Aeson as Json
13import qualified Data.Map as Map
14import qualified Data.Text.Lazy as LazyText
15import System.IO (Handle)
17import qualified AST.Module as Module
18import qualified AST.Module.Name as ModuleName
19import qualified Compile
20import qualified Docs.Check as Docs
21import qualified Elm.Compiler.Imports as Imports
22import qualified Elm.Compiler.Module as PublicModule
23import qualified Elm.Compiler.Version
24import qualified Elm.Docs as Docs
25import qualified Elm.Package as Package
26import qualified Generate.JavaScript as JS
27import qualified Parse.Module as Parse
28import qualified Parse.Parse as Parse
29import qualified Reporting.Annotation as A
30import qualified Reporting.Bag as Bag
31import qualified Reporting.Error as Error
32import qualified Reporting.Render.Type as RenderType
33import qualified Reporting.Report as Report
34import qualified Reporting.Result as Result
35import qualified Reporting.Warning as Warning
39-- VERSION
42version :: Package.Version
43version =
44 Elm.Compiler.Version.version
48-- DEPENDENCIES
51data Tag
52 = Normal
53 | Effect
54 | Port
57parseDependencies
58 :: Package.Name
59 -> String
60 -> Either [Error] (Tag, PublicModule.Raw, [PublicModule.Raw])
61parseDependencies pkgName sourceCode =
62 let
63 (Result.Result _ _ answer) =
64 Parse.parse sourceCode Parse.header
65 in
66 Result.answerToEither (Error . A.map Error.Syntax) (getDeps pkgName) answer
69getDeps
70 :: Package.Name
71 -> Module.Header [Module.UserImport]
72 -> (Tag, PublicModule.Raw, [PublicModule.Raw])
73getDeps pkgName (Module.Header sourceTag name _ _ _ imports) =
74 let
75 tag =
76 case sourceTag of
77 Module.Normal -> Normal
78 Module.Port _ -> Port
79 Module.Effect _ -> Effect
81 deps =
82 if pkgName == Package.core then
83 map (fst . A.drop) imports
84 else
85 map (fst . A.drop) imports ++ map fst Imports.defaults
86 in
87 ( tag, name, deps )
91-- COMPILATION
94{-| Compiles Elm source code to JavaScript. -}
95compile
96 :: Context
97 -> String
98 -> PublicModule.Interfaces
99 -> (Localizer, [Warning], Either [Error] Result)
101compile context source interfaces =
102 let
103 (Context packageName isExposed dependencies) =
104 context
106 (Result.Result oneLocalizer warnings answer) =
107 do modul <- Compile.compile packageName dependencies interfaces source
108 docs <- Result.format Error.Docs (docsGen isExposed modul)
110 let interface = Module.toInterface packageName modul
111 let javascript = JS.generate modul
113 return (Result docs interface javascript)
114 in
115 ( Result.oneToValue dummyLocalizer Localizer oneLocalizer
116 , Bag.toList Warning warnings
117 , Result.answerToEither Error id answer
118 )
121data Context = Context
122 { _packageName :: Package.Name
123 , _isExposed :: Bool
124 , _dependencies :: [PublicModule.Canonical]
125 }
128data Result = Result
129 { _docs :: Maybe Docs.Documentation
130 , _interface :: PublicModule.Interface
131 , _js :: LazyText.Text
132 }
135docsGen :: Bool -> Module.Optimized -> Docs.Result w (Maybe Docs.Documentation)
136docsGen isExposed (Module.Module name _ info) =
137 if not isExposed then
138 Result.ok Nothing
140 else
141 let
142 toDocs checked =
143 Just (Docs.fromCheckedDocs (ModuleName._module name) checked)
144 in
145 toDocs <$> Docs.check (Module.exports info) (Module.docs info)
149-- DEALIASER
152newtype Localizer =
153 Localizer RenderType.Localizer
156dummyLocalizer :: Localizer
157dummyLocalizer =
158 Localizer Map.empty
162-- ERRORS
165newtype Error =
166 Error (A.Located Error.Error)
169errorToString :: Localizer -> String -> String -> Error -> String
170errorToString (Localizer localizer) location source (Error (A.A region err)) =
171 Report.toString location region (Error.toReport localizer err) source
174printError :: Handle -> Localizer -> String -> String -> Error -> IO ()
175printError handle (Localizer localizer) location source (Error (A.A region err)) =
176 Report.toHandle handle location region (Error.toReport localizer err) source
179errorToJson :: Localizer -> String -> Error -> Json.Value
180errorToJson (Localizer localizer) location (Error err) =
181 Error.toJson localizer location err
185-- WARNINGS
188newtype Warning =
189 Warning (A.Located Warning.Warning)
192warningToString :: Localizer -> String -> String -> Warning -> String
193warningToString (Localizer localizer) location source (Warning (A.A region wrn)) =
194 Report.toString location region (Warning.toReport localizer wrn) source
197printWarning :: Handle -> Localizer -> String -> String -> Warning -> IO ()
198printWarning handle (Localizer localizer) location source (Warning (A.A region wrn)) =
199 Report.toHandle handle location region (Warning.toReport localizer wrn) source
202warningToJson :: Localizer -> String -> Warning -> Json.Value
203warningToJson (Localizer localizer) location (Warning wrn) =
204 Warning.toJson localizer location wrn