+listModuleTags :: GHC.Module -> GHCi [TagInfo]
+listModuleTags m = do
+ is_interpreted <- GHC.moduleIsInterpreted m
+ -- should we just skip these?
+ when (not is_interpreted) $
+ let mName = GHC.moduleNameString (GHC.moduleName m) in
+ ghcError (CmdLineError ("module '" ++ mName ++ "' is not interpreted"))
+ mbModInfo <- GHC.getModuleInfo m
+ case mbModInfo of
+ Nothing -> return []
+ Just mInfo -> do
+ mb_print_unqual <- GHC.mkPrintUnqualifiedForModule mInfo
+ let unqual = fromMaybe GHC.alwaysQualify mb_print_unqual
+ let names = fromMaybe [] $GHC.modInfoTopLevelScope mInfo
+ let localNames = filter ((m==) . nameModule) names
+ mbTyThings <- mapM GHC.lookupName localNames
+ return $! [ tagInfo unqual exported kind name loc
+ | tyThing <- catMaybes mbTyThings
+ , let name = getName tyThing
+ , let exported = GHC.modInfoIsExportedName mInfo name
+ , let kind = tyThing2TagKind tyThing
+ , let loc = srcSpanStart (nameSrcSpan name)
+ , isGoodSrcLoc loc
+ ]
+
+ where
+ tyThing2TagKind (AnId _) = 'v'
+ tyThing2TagKind (ADataCon _) = 'd'
+ tyThing2TagKind (ATyCon _) = 't'
+ tyThing2TagKind (AClass _) = 'c'
+
+
+data TagInfo = TagInfo
+ { tagExported :: Bool -- is tag exported
+ , tagKind :: Char -- tag kind
+ , tagName :: String -- tag name
+ , tagFile :: String -- file name
+ , tagLine :: Int -- line number
+ , tagCol :: Int -- column number
+ , tagSrcInfo :: Maybe (String,Integer) -- source code line and char offset
+ }
+