@@ -1,8 +1,8 @@
1-----------------------------------------------------------------------------
1-----------------------------------------------------------------------------
3-- Module : Language.PureScript.Sugar.Names
3-- Module : Language.PureScript.Sugar.Names
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
4+-- Copyright : (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess
5−-- License : MIT
5+-- License : MIT (http://opensource.org/licenses/MIT)
7-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
7-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8-- Stability : experimental
8-- Stability : experimental
@@ -49,9 +49,13 @@ type ExportEnvironment = M.Map ModuleName Exports
49data Exports = Exports
49data Exports = Exports
52+ -- The filename of the module these exports are for
54+ moduleSourceSpan :: SourceSpan
52 -- The types exported from each module
56 -- The types exported from each module
54− exportedTypes :: [(ProperName, [ProperName])]
58+ , exportedTypes :: [(ProperName, [ProperName])]
56 -- The classes exported from each module
60 -- The classes exported from each module
@@ -102,11 +106,11 @@ updateExportedModule env mn update = do
103-- Adds an empty module to an ExportEnvironment.
107-- Adds an empty module to an ExportEnvironment.
105−addEmptyModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> m ExportEnvironment
109+addEmptyModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> SourceSpan -> m ExportEnvironment
106−addEmptyModule env name =
110+addEmptyModule env name ss =
107− if name `M.member` env
111+ case name `M.lookup` env of
108− then throwError . errorMessage $ RedefinedModule name
112+ Just m -> throwError . errorMessage $ RedefinedModule name [moduleSourceSpan m, ss]
109− else return $ M.insert name (Exports [] [] [] []) env
113+ Nothing -> return $ M.insert name (Exports ss [] [] [] []) env
112-- Adds a type belonging to a module to the export environment.
116-- Adds a type belonging to a module to the export environment.
@@ -164,9 +168,9 @@ desugarImports modules = do
164 mapM (renameInModule' unfilteredExports exports) modules'
168 mapM (renameInModule' unfilteredExports exports) modules'
166 moduleReexports :: Module -> Module
170 moduleReexports :: Module -> Module
167− moduleReexports (Module coms mn decls exps) =
171+ moduleReexports (Module ss coms mn decls exps) =
168 let importedMods = catMaybes findImports'
172 let importedMods = catMaybes findImports'
169− in (Module coms mn (decls ++ (concatMap reexports importedMods)) exps)
173+ in (Module ss coms mn (decls ++ (concatMap reexports importedMods)) exps)
171 imports :: [Declaration]
175 imports :: [Declaration]
172 imports = filter isImportDecl decls
176 imports = filter isImportDecl decls
@@ -174,7 +178,7 @@ desugarImports modules = do
174 findImports' = go <$> modules
178 findImports' = go <$> modules
176 go :: Module -> Maybe (Declaration, Module)
180 go :: Module -> Maybe (Declaration, Module)
177− go m@(Module _ mn' _ (Just exps'))
181+ go m@(Module _ _ mn' _ (Just exps'))
178 | any isModExport exps', Just d <- find ((== mn') . importedModName) imports = Just (d, m)
182 | any isModExport exps', Just d <- find ((== mn') . importedModName) imports = Just (d, m)
180 importedModName :: Declaration -> ModuleName
184 importedModName :: Declaration -> ModuleName
@@ -183,14 +187,14 @@ desugarImports modules = do
183 importedModName _ = error "Not an import decl"
187 importedModName _ = error "Not an import decl"
184 go _ = Nothing
188 go _ = Nothing
185 reexports :: (Declaration, Module) -> [Declaration]
189 reexports :: (Declaration, Module) -> [Declaration]
186− reexports (ImportDeclaration _ (Hiding refs) _, (Module coms' mn' ds' (Just exps'))) =
190+ reexports (ImportDeclaration _ (Hiding refs) _, (Module ss' coms' mn' ds' (Just exps'))) =
187 case nonHiddenRefs of
191 case nonHiddenRefs of
189− _ -> reexports (ImportDeclaration mn' Implicit Nothing, Module coms' mn' ds' (Just nonHiddenRefs))
193+ _ -> reexports (ImportDeclaration mn' Implicit Nothing, Module ss' coms' mn' ds' (Just nonHiddenRefs))
191 nonHiddenRefs :: [DeclarationRef]
195 nonHiddenRefs :: [DeclarationRef]
192 nonHiddenRefs = filter isModExport exps' \\ filter isModExport refs
196 nonHiddenRefs = filter isModExport exps' \\ filter isModExport refs
193− reexports (ImportDeclaration _ ty qual, Module _ _ _ (Just exps')) =
197+ reexports (ImportDeclaration _ ty qual, Module _ _ _ _ (Just exps')) =
194 let ty' = case ty of
198 let ty' = case ty of
195 Explicit _ -> Explicit []
199 Explicit _ -> Explicit []
@@ -199,7 +203,7 @@ desugarImports modules = do
199 go :: DeclarationRef -> Maybe ModuleName
203 go :: DeclarationRef -> Maybe ModuleName
200 go (ModuleRef mn') = Just mn'
204 go (ModuleRef mn') = Just mn'
201 go _ = Nothing
205 go _ = Nothing
202− reexports (PositionedDeclaration _ _ d, m@(Module _ _ _ (Just _))) = reexports (d, m)
206+ reexports (PositionedDeclaration _ _ d, m@(Module _ _ _ _ (Just _))) = reexports (d, m)
203 reexports _ = []
207 reexports _ = []
205 isModExport :: DeclarationRef -> Bool
209 isModExport :: DeclarationRef -> Bool
@@ -210,7 +214,7 @@ desugarImports modules = do
210 -- exported members remain. If the module does not explicitly export anything, everything is
214 -- exported members remain. If the module does not explicitly export anything, everything is
211 -- exported.
215 -- exported.
212 filterModuleExports :: ExportEnvironment -> Module -> m ExportEnvironment
216 filterModuleExports :: ExportEnvironment -> Module -> m ExportEnvironment
213− filterModuleExports env (Module _ mn _ (Just exps))
217+ filterModuleExports env (Module _ _ mn _ (Just exps))
214 | any isSelfModuleExport exps, Just exps' <- M.lookup mn env =
218 | any isSelfModuleExport exps, Just exps' <- M.lookup mn env =
215 let moduleNames = filter (/= mn) $ (\(ModuleRef mn') -> mn') <$> filter isModExport exps
219 let moduleNames = filter (/= mn) $ (\(ModuleRef mn') -> mn') <$> filter isModExport exps
216 in return $ M.insert mn (exps' {exportedModules = moduleNames}) env
220 in return $ M.insert mn (exps' {exportedModules = moduleNames}) env
@@ -219,13 +223,13 @@ desugarImports modules = do
219 isSelfModuleExport (ModuleRef mn') | mn' == mn = True
223 isSelfModuleExport (ModuleRef mn') | mn' == mn = True
220 isSelfModuleExport (PositionedDeclarationRef _ _ ref) = isSelfModuleExport ref
224 isSelfModuleExport (PositionedDeclarationRef _ _ ref) = isSelfModuleExport ref
221 isSelfModuleExport _ = False
225 isSelfModuleExport _ = False
222− filterModuleExports env (Module _ mn _ (Just exps)) = filterExports mn exps env
226+ filterModuleExports env (Module _ _ mn _ (Just exps)) = filterExports mn exps env
223 filterModuleExports env _ = return env
227 filterModuleExports env _ = return env
225 -- Rename and check all the names within a module. We tweak the global exports environment so
229 -- Rename and check all the names within a module. We tweak the global exports environment so
226 -- the module has access to an unfiltered list of its own members.
230 -- the module has access to an unfiltered list of its own members.
227 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module
231 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module
228− renameInModule' unfilteredExports exports m@(Module _ mn _ _) =
232+ renameInModule' unfilteredExports exports m@(Module _ _ mn _ _) =
229 rethrow (onErrorMessages (ErrorInModule mn)) $ do
233 rethrow (onErrorMessages (ErrorInModule mn)) $ do
230 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
234 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
231 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
235 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
@@ -237,7 +241,7 @@ desugarImports modules = do
237-- as it will also make all data constructor exports explicit.
241-- as it will also make all data constructor exports explicit.
239elaborateExports :: Exports -> Module -> Module
243elaborateExports :: Exports -> Module -> Module
240−elaborateExports exps (Module coms mn decls _) = Module coms mn decls (Just $
244+elaborateExports exps (Module ss coms mn decls _) = Module ss coms mn decls (Just $
241 map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (exportedTypes exps) ++
245 map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (exportedTypes exps) ++
242 map TypeClassRef (exportedTypeClasses exps) ++
246 map TypeClassRef (exportedTypeClasses exps) ++
243 map ValueRef (exportedValues exps) ++
247 map ValueRef (exportedValues exps) ++
@@ -248,7 +252,7 @@ elaborateExports exps (Module coms mn decls _) = Module coms mn decls (Just $
248-- This ensures transitive instances are included when using a member from a module.
252-- This ensures transitive instances are included when using a member from a module.
250elaborateImports :: Module -> Module
254elaborateImports :: Module -> Module
251−elaborateImports (Module coms mn decls exps) = Module coms mn decls' exps
255+elaborateImports (Module ss coms mn decls exps) = Module ss coms mn decls' exps
253 decls' :: [Declaration]
257 decls' :: [Declaration]
@@ -265,8 +269,8 @@ elaborateImports (Module coms mn decls exps) = Module coms mn decls' exps
265-- qualified names are valid.
269-- qualified names are valid.
267renameInModule :: forall m. (Applicative m, MonadError MultipleErrors m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module
271renameInModule :: forall m. (Applicative m, MonadError MultipleErrors m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module
268−renameInModule imports exports (Module coms mn decls exps) =
272+renameInModule imports exports (Module ss coms mn decls exps) =
269− Module coms mn <$> parU decls go <*> pure exps
273+ Module ss coms mn <$> parU decls go <*> pure exps
271 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
275 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
@@ -372,14 +376,14 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
374 -- The exported types from the Prim module
378 -- The exported types from the Prim module
375− primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] [] []
379+ primExports = Exports (internalModuleSourceSpan "<Prim>") (mkTypeEntry `map` M.keys primTypes) [] [] []
377 mkTypeEntry (Qualified _ name) = (name, [])
381 mkTypeEntry (Qualified _ name) = (name, [])
379 -- Add all of the exported declarations from a module to the global export environment
383 -- Add all of the exported declarations from a module to the global export environment
380 addModule :: ExportEnvironment -> Module -> m ExportEnvironment
384 addModule :: ExportEnvironment -> Module -> m ExportEnvironment
381− addModule env (Module _ mn ds _) = do
385+ addModule env (Module ss _ mn ds _) = do
382− env' <- addEmptyModule env mn
386+ env' <- addEmptyModule env mn ss
383 rethrow (onErrorMessages (ErrorInModule mn)) $ foldM (addDecl mn) env' ds
387 rethrow (onErrorMessages (ErrorInModule mn)) $ foldM (addDecl mn) env' ds
385 -- Add a declaration from a module to the global export environment
389 -- Add a declaration from a module to the global export environment
@@ -475,7 +479,7 @@ findImports = foldl (findImports' Nothing) M.empty
475-- Constructs a local environment for a module.
479-- Constructs a local environment for a module.
477resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment
481resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment
478−resolveImports env (Module _ currentModule decls _) =
482+resolveImports env (Module _ _ currentModule decls _) =
479 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
483 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)