@@ -359,19 +359,14 @@ filterExports mn exps env = do
359 else throwError $ mkErrorStack ("Cannot export undefined value '" ++ show name ++ "'") Nothing
359 else throwError $ mkErrorStack ("Cannot export undefined value '" ++ show name ++ "'") Nothing
360 filterValues _ result _ = return result
360 filterValues _ result _ = return result
363−-- Type representing a set of declarations being explicitly imported from a module
365−type ExplicitImports = [DeclarationRef]
368-- Finds the imports within a module, mapping the imported module name to an optional set of
363-- Finds the imports within a module, mapping the imported module name to an optional set of
369-- explicitly imported declarations.
364-- explicitly imported declarations.
371−findImports :: [Declaration] -> M.Map ModuleName (Maybe SourcePos, Maybe ExplicitImports, Maybe ModuleName)
366+findImports :: [Declaration] -> M.Map ModuleName (Maybe SourcePos, ImportDeclarationType, Maybe ModuleName)
372findImports = foldl (findImports' Nothing) M.empty
367findImports = foldl (findImports' Nothing) M.empty
374− findImports' pos result (ImportDeclaration mn expl qual) = M.insert mn (pos, expl, qual) result
369+ findImports' pos result (ImportDeclaration mn typ qual) = M.insert mn (pos, typ, qual) result
375 findImports' _ result (PositionedDeclaration pos d) = findImports' (Just pos) result d
370 findImports' _ result (PositionedDeclaration pos d) = findImports' (Just pos) result d
376 findImports' _ result _ = result
371 findImports' _ result _ = result
@@ -386,13 +381,13 @@ resolveImports env (Module currentModule decls _) =
386 -- A Map from module name to the source position for the import, the list of imports from that
381 -- A Map from module name to the source position for the import, the list of imports from that
387 -- module (where Nothing indicates everything is to be imported), and optionally a qualified name
382 -- module (where Nothing indicates everything is to be imported), and optionally a qualified name
388 -- for the module
383 -- for the module
389− scope :: M.Map ModuleName (Maybe SourcePos, Maybe ExplicitImports, Maybe ModuleName)
384+ scope :: M.Map ModuleName (Maybe SourcePos, ImportDeclarationType, Maybe ModuleName)
390− scope = M.insert currentModule (Nothing, Nothing, Nothing) (findImports decls)
385+ scope = M.insert currentModule (Nothing, Unqualified, Nothing) (findImports decls)
392− resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourcePos, Maybe ExplicitImports, Maybe ModuleName)) -> Either ErrorStack ImportEnvironment
387+ resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourcePos, ImportDeclarationType, Maybe ModuleName)) -> Either ErrorStack ImportEnvironment
393− resolveImport' imp (mn, (pos, explImports, impQual)) = do
388+ resolveImport' imp (mn, (pos, typ, impQual)) = do
394 modExports <- positioned $ maybe (throwError $ mkErrorStack ("Cannot import unknown module '" ++ show mn ++ "'") Nothing) return $ mn `M.lookup` env
389 modExports <- positioned $ maybe (throwError $ mkErrorStack ("Cannot import unknown module '" ++ show mn ++ "'") Nothing) return $ mn `M.lookup` env
395− positioned $ resolveImport currentModule mn modExports imp impQual explImports
390+ positioned $ resolveImport currentModule mn modExports imp impQual typ
397 positioned err = case pos of
392 positioned err = case pos of
398 Nothing -> err
393 Nothing -> err
@@ -401,37 +396,77 @@ resolveImports env (Module currentModule decls _) =
402-- Extends the local environment for a module by resolving an import of another module.
397-- Extends the local environment for a module by resolving an import of another module.
404−resolveImport :: ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> Maybe ExplicitImports-> Either ErrorStack ImportEnvironment
399+resolveImport :: ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> Either ErrorStack ImportEnvironment
405−resolveImport currentModule importModule exps imps impQual = maybe importAll (foldM importExplicit imps)
400+resolveImport currentModule importModule exps imps impQual =
408− -- Import everything from a module
404+ resolveByType :: ImportDeclarationType -> Either ErrorStack ImportEnvironment
405+ resolveByType Unqualified = importAll importExplicit
406+ resolveByType (Qualifying explImports) = (checkedRefs >=> foldM importExplicit imps) explImports
407+ resolveByType (Hiding hiddenImports) = do
408+ hiddenImports' <- checkedRefs hiddenImports
409+ importAll (importNonHidden hiddenImports')
411+ importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
412+ importNonHidden hidden m ref =
413+ if isHidden hidden ref
415+ else importExplicit m ref
417+ isHidden :: [DeclarationRef] -> DeclarationRef -> Bool
418+ isHidden hidden ref@(TypeRef _ _) =
420+ checkTypeRef _ True _ = True
421+ checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
422+ checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
423+ checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
424+ checkTypeRef (PositionedDeclarationRef _ r) acc hiddenRef = checkTypeRef r acc hiddenRef
425+ checkTypeRef _ acc _ = acc
426+ in foldl (checkTypeRef ref) False hidden
427+ isHidden hidden ref = ref `elem` hidden
429+ -- Import all symbols
409− importAll :: Either ErrorStack ImportEnvironment
430+ importAll :: (ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment) -> Either ErrorStack ImportEnvironment
410− importAll = do
431+ importAll importer = do
411− imp' <- foldM (\m (name, dctors) -> importExplicit m (TypeRef name (Just dctors))) imps (exportedTypes exps)
432+ imp' <- foldM (\m (name, dctors) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)
412− imp'' <- foldM (\m name -> importExplicit m (ValueRef name)) imp' (exportedValues exps)
433+ imp'' <- foldM (\m name -> importer m (ValueRef name)) imp' (exportedValues exps)
413− foldM (\m name -> importExplicit m (TypeClassRef name)) imp'' (exportedTypeClasses exps)
434+ foldM (\m name -> importer m (TypeClassRef name)) imp'' (exportedTypeClasses exps)
415 -- Import something explicitly
436 -- Import something explicitly
416 importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
437 importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
417 importExplicit imp (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ importExplicit imp r
438 importExplicit imp (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ importExplicit imp r
418 importExplicit imp (ValueRef name) = do
439 importExplicit imp (ValueRef name) = do
419− _ <- checkImportExists "value" values name
420 values' <- updateImports (importedValues imp) name
440 values' <- updateImports (importedValues imp) name
421 return $ imp { importedValues = values' }
441 return $ imp { importedValues = values' }
422 importExplicit imp (TypeRef name dctors) = do
442 importExplicit imp (TypeRef name dctors) = do
423− _ <- checkImportExists "type" availableTypes name
424 types' <- updateImports (importedTypes imp) name
443 types' <- updateImports (importedTypes imp) name
425 let allDctors = allExportedDataConstructors name
444 let allDctors = allExportedDataConstructors name
426 dctors' <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
445 dctors' <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
427 dctors'' <- foldM updateImports (importedDataConstructors imp) dctors'
446 dctors'' <- foldM updateImports (importedDataConstructors imp) dctors'
428 return $ imp { importedTypes = types', importedDataConstructors = dctors'' }
447 return $ imp { importedTypes = types', importedDataConstructors = dctors'' }
429 importExplicit imp (TypeClassRef name) = do
448 importExplicit imp (TypeClassRef name) = do
430− _ <- checkImportExists "type class" classes name
431 typeClasses' <- updateImports (importedTypeClasses imp) name
449 typeClasses' <- updateImports (importedTypeClasses imp) name
432 return $ imp { importedTypeClasses = typeClasses' }
450 return $ imp { importedTypeClasses = typeClasses' }
433 importExplicit _ _ = error "Invalid argument to importExplicit"
451 importExplicit _ _ = error "Invalid argument to importExplicit"
453+ -- Check if DeclarationRef points to an existent symbol
454+ checkedRefs :: [DeclarationRef] -> Either ErrorStack [DeclarationRef]
455+ checkedRefs refs = mapM check refs
457+ check (PositionedDeclarationRef pos r) = do
458+ rethrowWithPosition pos $ check r
459+ check ref@(ValueRef name) =
460+ checkImportExists "value" values name >> return ref
461+ check ref@(TypeRef name dctors) = do
462+ _ <- checkImportExists "type" availableTypes name
463+ let allDctors = allExportedDataConstructors name
464+ _ <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
466+ check ref@(TypeClassRef name) =
467+ checkImportExists "type class" classes name >> return ref
468+ check _ = error "Invalid argument to checkRefIsValid"
435 -- Find all exported data constructors for a given type
470 -- Find all exported data constructors for a given type
436 allExportedDataConstructors :: ProperName -> [ProperName]
471 allExportedDataConstructors :: ProperName -> [ProperName]
437 allExportedDataConstructors name = fromMaybe [] $ name `lookup` exportedTypes exps
472 allExportedDataConstructors name = fromMaybe [] $ name `lookup` exportedTypes exps
@@ -444,7 +479,7 @@ resolveImport currentModule importModule exps imps impQual = maybe importAll (fo
444 Just x@(Qualified (Just mn) _) -> throwError $ mkErrorStack err Nothing
479 Just x@(Qualified (Just mn) _) -> throwError $ mkErrorStack err Nothing
446 err = if mn == currentModule || importModule == currentModule
481 err = if mn == currentModule || importModule == currentModule
447− then "Definition '" ++ show name ++ "' conflicts with import '" ++ show (Qualified (Just importModule) name) ++ "'"
482+ then "Definition '" ++ show name ++ "' conflicts with import '" ++ show (Qualified (Just mn) name) ++ "'"
448 else "Conflicting imports for '" ++ show name ++ "': '" ++ show x ++ "', '" ++ show (Qualified (Just importModule) name) ++ "'"
483 else "Conflicting imports for '" ++ show name ++ "': '" ++ show x ++ "', '" ++ show (Qualified (Just importModule) name) ++ "'"
450 -- The available values, types, and classes in the module being imported
485 -- The available values, types, and classes in the module being imported