on master help sign in
Throw errors when you have ports in a submodule
fb1a6d2Evan Czaplicki
src/Compile.hs+3−2
@@ -17,11 +17,12 @@ import qualified Type.Inference as TI
17compile
17compile
18 :: String
18 :: String
19 -> String
19 -> String
20+ -> Bool
20 -> Module.Interfaces
21 -> Module.Interfaces
21 -> String
22 -> String
22 -> Result.Result Warning.Warning Error.Error Module.CanonicalModule
23 -> Result.Result Warning.Warning Error.Error Module.CanonicalModule
23
24
24−compile user projectName interfaces source =
25+compile user projectName isRoot interfaces source =
25 do
26 do
26 -- determine if default imports should be added
27 -- determine if default imports should be added
27 -- only elm-lang/core is exempt
28 -- only elm-lang/core is exempt
@@ -31,7 +32,7 @@ compile user projectName interfaces source =
31 -- Parse the source code
32 -- Parse the source code
32 validModule <-
33 validModule <-
33 Result.mapError Error.Syntax $
34 Result.mapError Error.Syntax $
34− Parse.program needsDefaults (getOpTable interfaces) source
35+ Parse.program needsDefaults isRoot (getOpTable interfaces) source
35
36
36 -- Canonicalize all variables, pinning down where they came from.
37 -- Canonicalize all variables, pinning down where they came from.
37 canonicalModule <-
38 canonicalModule <-
src/Elm/Compiler.hs+3−2
@@ -61,15 +61,16 @@ parseDependencies sourceCode =
61compile
61compile
62 :: String
62 :: String
63 -> String
63 -> String
64+ -> Bool
64 -> String
65 -> String
65 -> Map.Map PublicModule.Name PublicModule.Interface
66 -> Map.Map PublicModule.Name PublicModule.Interface
66 -> ([Warning], Either [Error] (PublicModule.Interface, String))
67 -> ([Warning], Either [Error] (PublicModule.Interface, String))
67−compile user packageName source interfaces =
68+compile user packageName isRoot source interfaces =
68 let unwrappedInterfaces =
69 let unwrappedInterfaces =
69 Map.mapKeysMonotonic (\(PublicModule.Name name) -> name) interfaces
70 Map.mapKeysMonotonic (\(PublicModule.Name name) -> name) interfaces
70
71
71 (Result.Result warnings rawResult) =
72 (Result.Result warnings rawResult) =
72− Compile.compile user packageName unwrappedInterfaces source
73+ Compile.compile user packageName isRoot unwrappedInterfaces source
73 in
74 in
74 (,) (map Warning warnings) $
75 (,) (map Warning warnings) $
75 case rawResult of
76 case rawResult of
src/Parse/Parse.hs+3−2
@@ -21,14 +21,15 @@ import qualified Validate
21
21
22program
22program
23 :: Bool
23 :: Bool
24+ -> Bool
24 -> OpTable
25 -> OpTable
25 -> String
26 -> String
26 -> Result.Result wrn Error.Error M.ValidModule
27 -> Result.Result wrn Error.Error M.ValidModule
27−program needsDefaults table src =
28+program needsDefaults isRoot table src =
28 do (M.Module names filePath exports imports sourceDecls) <-
29 do (M.Module names filePath exports imports sourceDecls) <-
29 parseWithTable table src programParser
30 parseWithTable table src programParser
30
31
31− validDecls <- Validate.declarations sourceDecls
32+ validDecls <- Validate.declarations isRoot sourceDecls
32
33
33 let ammendedImports =
34 let ammendedImports =
34 (if needsDefaults then Imports.defaults else [], imports)
35 (if needsDefaults then Imports.defaults else [], imports)
src/Reporting/Error/Syntax.hs+11
@@ -19,6 +19,7 @@ data Error
19 | InfixDuplicate String
19 | InfixDuplicate String
20 | TypeWithoutDefinition String
20 | TypeWithoutDefinition String
21 | PortWithoutAnnotation String
21 | PortWithoutAnnotation String
22+ | UnexpectedPort
22 | DuplicateValueDeclaration String
23 | DuplicateValueDeclaration String
23 | DuplicateTypeDeclaration String
24 | DuplicateTypeDeclaration String
24 | DuplicateDefinition String
25 | DuplicateDefinition String
@@ -65,6 +66,16 @@ toReport err =
65 ++ " port " ++ portName ++ " : Signal Int"
66 ++ " port " ++ portName ++ " : Signal Int"
66 )
67 )
67
68
69+
70+ UnexpectedPort ->
71+ Report.simple
72+ "PORT ERROR"
73+ "This module has ports, but ports can only appear in the main module."
74+ ( "Ports in library code would create hidden dependencies where importing a\n"
75+ ++ "module could bring in constraints not captured in the public API. Furthermore,\n"
76+ ++ "if the module is imported twice, do we send values out the port twice?"
77+ )
78+
68 DuplicateValueDeclaration name ->
79 DuplicateValueDeclaration name ->
69 Report.simple
80 Report.simple
70 "DUPLICATE DEFINITION"
81 "DUPLICATE DEFINITION"
src/Validate.hs+9−6
@@ -23,13 +23,14 @@ import qualified Reporting.Result as Result
23-- VALIDATE DECLARATIONS
23-- VALIDATE DECLARATIONS
24
24
25declarations
25declarations
26+ :: Bool
26− :: [D.SourceDecl]
27+ -> [D.SourceDecl]
27 -> Result.Result wrn Error.Error [D.ValidDecl]
28 -> Result.Result wrn Error.Error [D.ValidDecl]
28−declarations sourceDecls =
29+declarations isRoot sourceDecls =
29 do validDecls <- validateDecls sourceDecls
30 do validDecls <- validateDecls sourceDecls
30 (\_ _ -> validDecls)
31 (\_ _ -> validDecls)
31 <$> declDuplicates validDecls
32 <$> declDuplicates validDecls
32− <*> T.traverse checkDecl validDecls
33+ <*> T.traverse (checkDecl isRoot) validDecls
33
34
34
35
35validateDecls
36validateDecls
@@ -339,8 +340,8 @@ extractValues (A.A region decl) =
339
340
340-- UNBOUND TYPE VARIABLES
341-- UNBOUND TYPE VARIABLES
341
342
342−checkDecl :: D.ValidDecl -> Result.Result wrn Error.Error ()
343+checkDecl :: Bool -> D.ValidDecl -> Result.Result wrn Error.Error ()
343−checkDecl (A.A region decl) =
344+checkDecl isRoot (A.A region decl) =
344 case decl of
345 case decl of
345 D.Definition _ ->
346 D.Definition _ ->
346 return ()
347 return ()
@@ -372,7 +373,9 @@ checkDecl (A.A region decl) =
372 (Error.UnboundTypeVarsInAlias name boundVars v vs tipe)
373 (Error.UnboundTypeVarsInAlias name boundVars v vs tipe)
373
374
374 D.Port _ ->
375 D.Port _ ->
376+ if isRoot
375− return ()
377+ then return ()
378+ else Result.throw region Error.UnexpectedPort
376
379
377 D.Fixity _ _ _ ->
380 D.Fixity _ _ _ ->
378 return ()
381 return ()