hint-0.3.2.0: src/Hint/Annotations.hs
-- - extract annotations from modules etc. with the GHC API.
-- - requires GHC >= 6.11
--
-- austin seipp <as@nijoruj.org>
module Hint.Annotations
( getModuleAnnotations -- :: (Data a, MonadInterpreter m) => a -> String -> m [a]
, getValAnnotations -- :: (Data a, MonadInterpreter m) => a -> String -> m [a]
) where
import Control.Monad
import Data.Data
import Annotations
import Serialized
import Hint.Base
import HscTypes (hsc_mod_graph, ms_mod)
import qualified Hint.GHC as GHC
-- | Get the annotations associated with a particular module.
--
-- For example, given:
--
-- @
-- RBRACE-\# ANN module (1 :: Int) \#-LBRACE
-- module SomeModule(g, h) where
-- ...
-- @
--
-- Then after using 'loadModule' to load SomeModule into scope:
--
-- @
-- x <- getModuleAnnotations (as :: Int) "SomeModule"
-- liftIO $ print x
-- -- result is [1]
-- @
getModuleAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a]
getModuleAnnotations _ x = do
mods <- liftM hsc_mod_graph $ runGhc GHC.getSession
let x' = filter ((==) x . GHC.moduleNameString . GHC.moduleName . ms_mod) mods
v <- mapM (anns . ModuleTarget . ms_mod) x'
return $ concat v
-- | Get the annotations associated with a particular function
--
-- For example, given:
--
-- @
-- module SomeModule(g, h) where
--
-- LBRACE-\# ANN g (Just 1 :: Maybe Int) \#-RBRACE
-- g = f [f]
--
-- LBRACE-\# ANN h (Just 2 :: Maybe Int) \#-RBRACE
-- h = f
-- @
--
-- Then after using 'loadModule' to bring SomeModule into scope:
--
-- @
-- x <- liftM concat $ mapM (getValAnnotations (as :: Maybe Int)) [\"g\",\"h\"]
-- liftIO $ print x
-- -- result is [Just 2, Just 1]
-- @
--
-- This can also work on data constructors and types with annotations.
getValAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a]
getValAnnotations _ x = do
x' <- runGhc1 GHC.parseName x
v <- mapM (anns . NamedTarget) x'
return $ concat v
anns :: (MonadInterpreter m, Data a) => AnnTarget GHC.Name -> m [a]
anns = runGhc1 (GHC.findGlobalAnns deserializeWithData)