on master help sign in
Rule out duplicate fields in Validate phase and provide nice error message
commita2427f5db69c2b82efe7bc33aa46dab08c96992e authorEvan Czaplicki <info@elm-lang.org> dateThu 1 Oct 2015, 15:13 (11 years ago) parent97552fd
3 files changed+25−20
src/Generate/JavaScript/Expression.hs+7−18 src/Reporting/Error/Syntax.hs+7 src/Validate.hs+11−2
src/Generate/JavaScript/Expression.hs+7−18
@@ -127,24 +127,13 @@ generateCode expr =
127127 jsExpr $ BuiltIn.recordUpdate jsRecord jsFields
128128
129129 Record fields ->
130− do fields' <-
131− forM fields $ \(field, e) ->
132− (,) (Var.safe field) <$> generateJsExpr e
133−
134− let fieldMap =
135− List.foldl' combine Map.empty fields'
136−
137− jsExpr $ ObjectLit () $ (prop "_", hidden fieldMap) : visible fieldMap
138− where
139− combine record (field, value) =
140− Map.insertWith (++) field [value] record
141−
142− hidden fs =
143− ObjectLit () . map (prop *** ArrayLit ()) $
144− Map.toList (Map.filter (not . null) (Map.map tail fs))
145−
146− visible fs =
147− map (first prop) (Map.toList (Map.map head fs))
130+ let
131+ toField (field, value) =
132+ do jsValue <- generateJsExpr value
133+ return (prop (Var.safe field), jsValue)
134+ in
135+ do jsFields <- mapM toField fields
136+ jsExpr $ ObjectLit () jsFields
148137
149138 Binop op leftExpr rightExpr ->
150139 binop op leftExpr rightExpr
src/Reporting/Error/Syntax.hs+7
@@ -21,6 +21,7 @@ data Error
2121 | TypeWithoutDefinition String
2222 | PortWithoutAnnotation String
2323 | UnexpectedPort
24+ | DuplicateFieldName String
2425 | DuplicateValueDeclaration String
2526 | DuplicateTypeDeclaration String
2627 | DuplicateDefinition String
@@ -97,6 +98,12 @@ toReport dealiaser err =
9798 ++ "if the module is imported twice, do we send values out the port twice?"
9899 )
99100
101+ DuplicateFieldName name ->
102+ Report.simple
103+ "DUPLICATE FIELD"
104+ ("This record has more than one field named `" ++ name ++ "`.")
105+ "There can only be one. Do some renaming to make sure the names are distinct!"
106+
100107 DuplicateValueDeclaration name ->
101108 Report.simple
102109 "DUPLICATE DEFINITION"
src/Validate.hs+11−2
@@ -1,6 +1,7 @@
11{-# OPTIONS_GHC -Wall #-}
22module Validate (declarations) where
33
4+import Control.Monad (foldM)
45import qualified Data.Map as Map
56import qualified Data.Set as Set
67import qualified Data.Foldable as F
@@ -253,8 +254,16 @@ expression (A.A ann sourceExpression) =
253254 <*> T.traverse second fields
254255
255256 Record fields ->
256− Record
257− <$> T.traverse second fields
257+ let
258+ checkDups seenFields (field,_) =
259+ if Set.member field seenFields then
260+ Result.throw ann (Error.DuplicateFieldName field)
261+
262+ else
263+ return (Set.insert field seenFields)
264+ in
265+ do _ <- foldM checkDups Set.empty fields
266+ Record <$> T.traverse second fields
258267
259268 Let defs body ->
260269 Let