+rnImportDecl :: Module
+ -> LImportDecl RdrName
+ -> RnM (LImportDecl Name)
+rnImportDecl this_mod (L loc importDecl@(ImportDecl loc_imp_mod_name want_boot qual_only as_mod imp_details))
+ = setSrcSpan loc $
+ do iface <- loadSrcInterface doc imp_mod_name want_boot
+ let qual_mod_name = case as_mod of
+ Nothing -> imp_mod_name
+ Just another_name -> another_name
+ imp_spec = ImpDeclSpec { is_mod = imp_mod_name, is_qual = qual_only,
+ is_dloc = loc, is_as = qual_mod_name }
+ total_avails <- ifaceExportNames (mi_exports iface)
+ importDecl' <- rnImportDecl' iface imp_spec importDecl total_avails
+ return (L loc importDecl')
+ where imp_mod_name = unLoc loc_imp_mod_name
+ doc = ppr imp_mod_name <+> ptext SLIT("is directly imported")
+
+rnImportDecl' :: ModIface -> ImpDeclSpec -> ImportDecl RdrName -> NameSet -> RnM (ImportDecl Name)
+rnImportDecl' iface decl_spec (ImportDecl mod_name want_boot qual_only as_mod Nothing) all_names
+ = return $ ImportDecl mod_name want_boot qual_only as_mod Nothing
+rnImportDecl' iface decl_spec (ImportDecl mod_name want_boot qual_only as_mod (Just (want_hiding,import_items))) all_names
+ = do import_items_mbs <- mapM (srcSpanWrapper) import_items
+ let rn_import_items = concat . catMaybes $ import_items_mbs
+ return $ ImportDecl mod_name want_boot qual_only as_mod (Just (want_hiding,rn_import_items))
+ where
+ srcSpanWrapper (L span ieRdr)
+ = setSrcSpan span $
+ case get_item ieRdr of
+ Nothing
+ -> do addErr (badImportItemErr iface decl_spec ieRdr)
+ return Nothing
+ Just ieNames
+ -> return (Just [L span ie | ie <- ieNames])
+ occ_env :: OccEnv Name -- Maps OccName to corresponding Name
+ occ_env = mkOccEnv [(nameOccName n, n) | n <- nameSetToList all_names]
+ -- This env will have entries for data constructors too,
+ -- they won't make any difference because naked entities like T
+ -- in an import list map to TcOccs, not VarOccs.
+
+ sub_env :: NameEnv [Name]
+ sub_env = mkSubNameEnv all_names
+
+ get_item :: IE RdrName -> Maybe [IE Name]
+ -- Empty result for a bad item.
+ -- Singleton result is typical case.
+ -- Can have two when we are hiding, and mention C which might be
+ -- both a class and a data constructor.
+ get_item item@(IEModuleContents _)
+ = Nothing
+ get_item (IEThingAll tc)
+ = do name <- check_name tc
+ return [IEThingAll name]
+ get_item (IEThingAbs tc)
+ | want_hiding -- hiding ( C )
+ -- Here the 'C' can be a data constructor
+ -- *or* a type/class, or even both
+ = case catMaybes [check_name tc, check_name (setRdrNameSpace tc srcDataName)] of
+ [] -> Nothing
+ names -> return [ IEThingAbs n | n <- names ]
+ | otherwise
+ = do name <- check_name tc
+ return [IEThingAbs name]
+ get_item (IEThingWith n ns) -- import (C (A,B))
+ = do name <- check_name n
+ let env = mkOccEnv [(nameOccName s, s) | s <- subNames sub_env name]
+ mb_names = map (lookupOccEnv env . rdrNameOcc) ns
+ names <- sequence mb_names
+ return [IEThingWith name names]
+ get_item (IEVar n)
+ = do name <- check_name n
+ return [IEVar name]
+
+ check_name :: RdrName -> Maybe Name
+ check_name rdrName
+ = lookupOccEnv occ_env (rdrNameOcc rdrName)
+
+