@@ -1,21 +1,20 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2module Nitpick.TopLevelTypes (topLevelTypes) where
2module Nitpick.TopLevelTypes (topLevelTypes) where
4−import Control.Monad (foldM, when)
4+import qualified Data.Foldable as F
5import Data.Map ((!))
5import Data.Map ((!))
6import qualified Data.Map as Map
6import qualified Data.Map as Map
7−import qualified Data.Maybe as Maybe
9−import qualified AST.Expression.Valid as Valid
8+import qualified AST.Expression.Canonical as Can
10−import qualified AST.Declaration as Decl
9+import qualified AST.Expression.General as Expr
11import qualified AST.Module.Name as ModuleName
10import qualified AST.Module.Name as ModuleName
12import qualified AST.Pattern as P
11import qualified AST.Pattern as P
13import qualified AST.Type as Type
12import qualified AST.Type as Type
14import qualified AST.Variable as Var
13import qualified AST.Variable as Var
14+import qualified Canonicalize.Effects as Effects
15import qualified Elm.Package as Pkg
15import qualified Elm.Package as Pkg
16import qualified Reporting.Annotation as A
16import qualified Reporting.Annotation as A
17import qualified Reporting.Error.Type as Error
17import qualified Reporting.Error.Type as Error
18−import qualified Reporting.Region as R
19import qualified Reporting.Result as Result
18import qualified Reporting.Result as Result
20import qualified Reporting.Warning as Warning
19import qualified Reporting.Warning as Warning
@@ -25,52 +24,85 @@ type Result =
25 Result.Result () Warning.Warning Error.Error
24 Result.Result () Warning.Warning Error.Error
28+ Map.Map String Type.Canonical
28-- CHECK TOP LEVEL TYPES
32-- CHECK TOP LEVEL TYPES
31−topLevelTypes :: Map.Map String Type.Canonical -> Decl.Valid -> Result ()
35+topLevelTypes :: TypeDict -> Can.SortedDefs -> Result [Can.Def]
32−topLevelTypes typeEnv (Decl.Decls defs _ _ _) =
36+topLevelTypes typeEnv sortedDefs =
33− do maybeMainRegion <- foldM (warnMissingAnnotation typeEnv) Nothing defs
37+ let
34− maybe (return ()) (checkMainType typeEnv) maybeMainRegion
38+ check =
39+ checkAnnotation typeEnv
44+ <* F.traverse_ check defs
46+ Can.YesMain before main after ->
48+ <* F.traverse_ check before
49+ <* F.traverse_ check after
51+ mainDef <- checkMain typeEnv main
53+ return (before ++ mainDef : after)
38−-- MISSING ANNOTATIONS
41−warnMissingAnnotation
57+-- MISSING ANNOTATIONS
42− :: Map.Map String Type.Canonical
58+
44− -> A.Commented Valid.Def
45− -> Result (Maybe R.Region)
46−warnMissingAnnotation typeEnv maybeMainRegion (A.A (region,_) def) =
48− Valid.Def (A.A _ (P.Var name)) _ maybeType ->
49− do when (Maybe.isNothing maybeType) $
50− Result.warn region (Warning.MissingTypeAnnotation name (typeEnv ! name)) ()
52− return (if name == "main" then Just region else maybeMainRegion)
60+checkAnnotation :: TypeDict -> Can.Def -> Result ()
61+checkAnnotation typeEnv (Can.Def _ (A.A region pattern) _ maybeType) =
62+ case (pattern, maybeType) of
63+ (P.Var name, Nothing) ->
66+ Warning.MissingTypeAnnotation name (typeEnv ! name)
68+ Result.warn region warning ()
55− return maybeMainRegion
71+ return ()
59-- CHECK MAIN TYPE
75-- CHECK MAIN TYPE
62−checkMainType :: Map.Map String Type.Canonical -> R.Region -> Result ()
78+checkMain :: TypeDict -> Can.Def -> Result Can.Def
63−checkMainType typeEnv region =
79+checkMain typeEnv (Can.Def facts pattern@(A.A region _) body maybeType) =
66 typeEnv ! "main"
82 typeEnv ! "main"
68− case Type.deepDealias tipe of
69− Type.App name [_] | name `elem` [program, vdomNode] ->
84+ makeError tipe maybeMsg =
85+ A.A region (Error.BadFlags tipe maybeMsg)
88+ case Type.deepDealias mainType of
90+ | name == vdomNode ->
93+ | name == program && arg == never ->
97+ return (Expr.Flags arg)
98+ <* Effects.checkForeignType makeError arg
73− Result.throw region (Error.BadMain tipe)
101+ Result.throw region (Error.BadMain mainType)
103+ do kind <- getMainKind
104+ let newBody = A.A undefined (Expr.Program kind body)
105+ return (Can.Def facts pattern newBody maybeType)
76program :: Type.Canonical
108program :: Type.Canonical
@@ -78,6 +110,11 @@ program =
78 Type.Type (Var.inCore ["Platform"] "Program")
110 Type.Type (Var.inCore ["Platform"] "Program")
113+never :: Type.Canonical
115+ Type.Type (Var.inCore ["Basics"] "Never")
81vdomNode :: Type.Canonical
118vdomNode :: Type.Canonical
82vdomNode =
119vdomNode =