on fcf5cef help sign in
elk/src/Elm/Compiler.hs
213 lines 5.5 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)
16import qualified Text.Parsec.Error as Parsec
18import qualified AST.Module as Module
19import qualified AST.Module.Name as ModuleName
20import qualified Compile
21import qualified Docs.Check as Docs
22import qualified Elm.Compiler.Imports as Imports
23import qualified Elm.Compiler.Module as PublicModule
24import qualified Elm.Compiler.Version
25import qualified Elm.Docs as Docs
26import qualified Elm.Package as Package
27import qualified Generate.JavaScript as JS
28import qualified Parse.Helpers as Parse (parse)
29import qualified Parse.Module as Parse (header)
30import qualified Reporting.Annotation as A
31import qualified Reporting.Bag as Bag
32import qualified Reporting.Error as Error
33import qualified Reporting.Error.Syntax as SyntaxError
34import qualified Reporting.Region as Region
35import qualified Reporting.Render.Type as RenderType
36import qualified Reporting.Report as Report
37import qualified Reporting.Result as Result
38import qualified Reporting.Warning as Warning
42-- VERSION
45version :: Package.Version
46version =
47 Elm.Compiler.Version.version
51-- DEPENDENCIES
54data Tag
55 = Normal
56 | Effect
57 | Port
60parseDependencies
61 :: Package.Name
62 -> String
63 -> Either Error (Tag, PublicModule.Raw, [PublicModule.Raw])
64parseDependencies pkgName sourceCode =
65 case Parse.parse Parse.header sourceCode of
66 Right header ->
67 Right $ getDeps pkgName header
69 Left parseError ->
70 let
71 pos = Region.fromSourcePos (Parsec.errorPos parseError)
72 msgs = Parsec.errorMessages parseError
73 err = Error.Syntax (SyntaxError.Parse msgs)
74 in
75 Left (Error (A.at pos pos err))
78getDeps
79 :: Package.Name
80 -> Module.Header [Module.UserImport]
81 -> (Tag, PublicModule.Raw, [PublicModule.Raw])
82getDeps pkgName (Module.Header sourceTag name _ _ _ imports) =
83 let
84 tag =
85 case sourceTag of
86 Module.Normal -> Normal
87 Module.Port _ -> Port
88 Module.Effect _ -> Effect
90 deps =
91 if pkgName == Package.core then
92 map (fst . A.drop) imports
93 else
94 map (fst . A.drop) imports ++ map fst Imports.defaults
95 in
96 ( tag, name, deps )
100-- COMPILATION
103{-| Compiles Elm source code to JavaScript. -}
104compile
105 :: Context
106 -> String
107 -> PublicModule.Interfaces
108 -> (Localizer, [Warning], Either [Error] Result)
110compile context source interfaces =
111 let
112 (Context packageName isExposed dependencies) =
113 context
115 (Result.Result oneLocalizer warnings answer) =
116 do modul <- Compile.compile packageName dependencies interfaces source
117 docs <- Result.format Error.Docs (docsGen isExposed modul)
119 let interface = Module.toInterface packageName modul
120 let javascript = JS.generate modul
122 return (Result docs interface javascript)
123 in
124 ( Result.oneToValue dummyLocalizer Localizer oneLocalizer
125 , Bag.toList Warning warnings
126 , Result.answerToEither Error id answer
127 )
130data Context = Context
131 { _packageName :: Package.Name
132 , _isExposed :: Bool
133 , _dependencies :: [PublicModule.Canonical]
134 }
137data Result = Result
138 { _docs :: Maybe Docs.Documentation
139 , _interface :: PublicModule.Interface
140 , _js :: LazyText.Text
141 }
144docsGen :: Bool -> Module.Optimized -> Docs.Result w (Maybe Docs.Documentation)
145docsGen isExposed (Module.Module name _ info) =
146 if not isExposed then
147 Result.ok Nothing
149 else
150 let
151 toDocs checked =
152 Just (Docs.fromCheckedDocs (ModuleName._module name) checked)
153 in
154 toDocs <$> Docs.check (Module.exports info) (Module.docs info)
158-- DEALIASER
161newtype Localizer =
162 Localizer RenderType.Localizer
165dummyLocalizer :: Localizer
166dummyLocalizer =
167 Localizer Map.empty
171-- ERRORS
174newtype Error =
175 Error (A.Located Error.Error)
178errorToString :: Localizer -> String -> String -> Error -> String
179errorToString (Localizer localizer) location source (Error (A.A region err)) =
180 Report.toString location region (Error.toReport localizer err) source
183printError :: Handle -> Localizer -> String -> String -> Error -> IO ()
184printError handle (Localizer localizer) location source (Error (A.A region err)) =
185 Report.toHandle handle location region (Error.toReport localizer err) source
188errorToJson :: Localizer -> String -> Error -> Json.Value
189errorToJson (Localizer localizer) location (Error err) =
190 Error.toJson localizer location err
194-- WARNINGS
197newtype Warning =
198 Warning (A.Located Warning.Warning)
201warningToString :: Localizer -> String -> String -> Warning -> String
202warningToString (Localizer localizer) location source (Warning (A.A region wrn)) =
203 Report.toString location region (Warning.toReport localizer wrn) source
206printWarning :: Handle -> Localizer -> String -> String -> Warning -> IO ()
207printWarning handle (Localizer localizer) location source (Warning (A.A region wrn)) =
208 Report.toHandle handle location region (Warning.toReport localizer wrn) source
211warningToJson :: Localizer -> String -> Warning -> Json.Value
212warningToJson (Localizer localizer) location (Warning wrn) =
213 Warning.toJson localizer location wrn