on master help sign in
Properly report region on bad exports
commite0e0b2ed772b063d23ceb2fdf2d530f469e600f2 authorEvan Czaplicki <info@elm-lang.org> dateFri 8 May 2015, 17:02 (11 years ago) parent14570e6
3 files changed+84−52
src/AST/Module.hs+8−3 src/Canonicalize.hs+73−47 src/Parse/Module.hs+3−2
src/AST/Module.hs+8−3
@@ -38,14 +38,19 @@ type CanonicalAdt = (Var.Canonical, AdtInfo Var.Canonical)
3838-- MODULES
3939
4040type SourceModule =
41− Module [UserImport] (Var.Listing Var.Value) [Decl.SourceDecl]
41+ Module
42+ [UserImport]
43+ (Var.Listing (A.Located Var.Value))
44+ [Decl.SourceDecl]
45+
4246
4347type ValidModule =
4448 Module
4549 ([DefaultImport], [UserImport])
46− (Var.Listing Var.Value)
50+ (Var.Listing (A.Located Var.Value))
4751 [Decl.ValidDecl]
4852
53+
4954type CanonicalModule =
5055 Module [Name] [Var.Value] CanonicalBody
5156
@@ -73,7 +78,7 @@ data CanonicalBody = CanonicalBody
7378{-| Basic info needed to identify modules and determine dependencies. -}
7479data Header imports = Header
7580 { _names :: Name
76− , _exports :: Var.Listing Var.Value
81+ , _exports :: Var.Listing (A.Located Var.Value)
7782 , _imports :: imports
7883 }
7984
src/Canonicalize.hs+73−47
@@ -120,80 +120,106 @@ warnUnusedImport uses (A.A region (name, _method)) =
120120
121121resolveExports
122122 :: [Var.Value]
123− -> Var.Listing Var.Value
123+ -> Var.Listing (A.Located Var.Value)
124124 -> Result.ResultErr [Var.Value]
125125resolveExports fullList (Var.Listing partialList open) =
126126 if open
127127 then Result.ok fullList
128128 else
129129 (\xs ys zs -> xs ++ ys ++ zs)
130− <$> getValueExports
130+ <$> T.traverse getValueExport values
131131 <*> (concat <$> T.traverse getAliasExport aliases)
132132 <*> T.traverse getAdtExport adts
133133 where
134134 (allValues, allAliases, allAdts) =
135− splitValues fullList
135+ maybeUnzip3 (map splitValue fullList)
136136
137137 (values, aliases, adts) =
138− splitValues partialList
138+ maybeUnzip3 (map splitLocatedValue partialList)
139139
140− getValueExports =
141− case Set.toList (Set.difference values' allValues') of
142− [] -> Result.ok (map Var.Value values)
143− xs -> manyNotFound xs allValues
144− where
145− allValues' = Set.fromList allValues
146− values' = Set.fromList values
140+ allValuesSet = Set.fromList allValues
141+ adtTypes = map fst allAdts
147142
148− getAliasExport alias
143+ getValueExport (A.A region name) =
144+ if Set.member name allValuesSet
145+ then Result.ok (Var.Value name)
146+ else manyNotFound region [name] allValues
147+
148+ getAliasExport (A.A region alias)
149149 | alias `elem` allAliases =
150− let recordConstructor =
151− if alias `elem` allValues then [Var.Value alias] else []
152− in
153− Result.ok (Var.Alias alias : recordConstructor)
150+ Result.ok $ (:) (Var.Alias alias) $
151+ if alias `elem` allValues then [Var.Value alias] else []
152+
153+ | List.elem alias adtTypes =
154+ Result.ok [Var.Union alias (Var.Listing [] False)]
154155
155156 | otherwise =
156− case List.find (\(name, _ctors) -> name == alias) allAdts of
157− Nothing -> manyNotFound [alias] allAliases
158− Just (name, _ctor) ->
159− Result.ok [Var.Union name (Var.Listing [] False)]
160−
161− getAdtExport (name, Var.Listing ctors open) =
162− case lookup name allAdts of
163− Nothing -> manyNotFound [name] (map fst allAdts)
157+ manyNotFound region [alias] (allAliases ++ adtTypes)
158+
159+ getAdtExport (A.A region (name, Var.Listing ctors open)) =
160+ case List.lookup name allAdts of
161+ Nothing ->
162+ manyNotFound region [name] adtTypes
163+
164164 Just (Var.Listing allCtors _)
165165 | open ->
166166 Result.ok (Var.Union name (Var.Listing allCtors False))
167167 | otherwise ->
168168 case filter (`notElem` allCtors) ctors of
169− [] -> Result.ok (Var.Union name (Var.Listing ctors False))
170− unfoundCtors -> manyNotFound unfoundCtors allCtors
169+ [] ->
170+ Result.ok (Var.Union name (Var.Listing ctors False))
171+ unfoundCtors ->
172+ manyNotFound region unfoundCtors allCtors
171173
172− manyNotFound nameList possibilities =
173− Result.errors (map (notFound possibilities) nameList)
174+ manyNotFound region nameList possibilities =
175+ Result.errors (map (notFound region possibilities) nameList)
174176
175− notFound possibilities name =
176− A.A undefined $ CError.Export name $
177+ notFound region possibilities name =
178+ A.A region $ CError.Export name $
177179 CError.nearbyNames id name possibilities
178180
179181
180−splitValues
181− :: [Var.Value]
182− -> ([String], [String], [(String, Var.Listing String)])
183−splitValues mixedValues =
184− case mixedValues of
185− [] -> ([], [], [])
186− x:xs ->
187− let (values, aliases, adts) = splitValues xs in
188− case x of
189− Var.Value name ->
190− (name : values, aliases, adts)
191−
192− Var.Alias name ->
193− (values, name : aliases, adts)
194−
195− Var.Union name listing ->
196− (values, aliases, (name, listing) : adts)
182+-- GROUPING VALUES
183+
184+maybeUnzip3 :: [(Maybe a, Maybe b, Maybe c)] -> ([a],[b],[c])
185+maybeUnzip3 tuples =
186+ let (as, bs, cs) = unzip3 tuples
187+ in
188+ (Maybe.catMaybes as, Maybe.catMaybes bs, Maybe.catMaybes cs)
189+
190+
191+splitValue
192+ :: Var.Value
193+ -> ( Maybe String, Maybe String, Maybe (String, Var.Listing String) )
194+splitValue value =
195+ case value of
196+ Var.Value name ->
197+ (Just name, Nothing, Nothing)
198+
199+ Var.Alias name ->
200+ (Nothing, Just name, Nothing)
201+
202+ Var.Union name listing ->
203+ (Nothing, Nothing, Just (name, listing))
204+
205+
206+splitLocatedValue
207+ :: A.Located Var.Value
208+ ->
209+ ( Maybe (A.Located String)
210+ , Maybe (A.Located String)
211+ , Maybe (A.Located (String, Var.Listing String))
212+ )
213+splitLocatedValue (A.A region value) =
214+ case value of
215+ Var.Value name ->
216+ (Just (A.A region name), Nothing, Nothing)
217+
218+ Var.Alias name ->
219+ (Nothing, Just (A.A region name), Nothing)
220+
221+ Var.Union name listing ->
222+ (Nothing, Nothing, Just (A.A region (name, listing)))
197223
198224
199225-- DECLARATIONS
src/Parse/Module.hs+3−2
@@ -6,6 +6,7 @@ import Text.Parsec hiding (newline, spaces)
66import Parse.Helpers
77import qualified AST.Module as Module
88import qualified AST.Variable as Var
9+import Reporting.Annotation as A
910
1011
1112getModuleName :: String -> Maybe String
@@ -29,13 +30,13 @@ header =
2930 return (Module.Header names exports imports')
3031
3132
32−moduleDecl :: IParser ([String], Var.Listing Var.Value)
33+moduleDecl :: IParser ([String], Var.Listing (A.Located Var.Value))
3334moduleDecl =
3435 do try (reserved "module")
3536 whitespace
3637 names <- dotSep1 capVar <?> "name of module"
3738 whitespace
38− exports <- option Var.openListing (listing value)
39+ exports <- option Var.openListing (listing (addLocation value))
3940 whitespace <?> "reserved word 'where'"
4041 reserved "where"
4142 return (names, exports)