GHC API を使ってある型コンストラクタのデータコンストラクタを得る
neco-ghc などで,Haskell 用の補完候補をより正確に計算するときに活用できないかなーと思った.
GHC 7.0.3 で試した.
あるモジュールがエクスポートしている名前は modInfoExports でとれる.
そのモジュールで定義されていれば modInfoTyThings で TyThing をとれるけど,例えば aeson の Data.Aeson のように他のモジュールからインポートしたものをエクスポートしている場合,名前は modInfoExports には含まれているけど TyThing が modInfoTyThings に含まれていない,ということが発生する.
なので,modInfoExports で得た名前に関して lookupName で改めて問い合わせて TyThing を得ている.
コンパイルするときは
% ghc -package ghc Browse.hs
と明示的に -package ghc をつけてやる必要がある.
import GHC import GHC.Paths (libdir) import MonadUtils (liftIO) import Name import Data.Maybe (catMaybes) import Control.Applicative ((<$>)) import System.Environment (getArgs) main :: IO () main = do args <- getArgs runGhc (Just libdir) $ do getSessionDynFlags >>= setSessionDynFlags mapM_ browse args browse :: GhcMonad m => String -> m () browse m = do xs <- maybe [] modInfoExports <$> lookupModuleInfo >>= collapseData liftIO $ mapM_ putStrLn xs where lookupModuleInfo = findModule (mkModuleName m) Nothing >>= getModuleInfo collapseData = fmap (map expand . catMaybes) . mapM lookupName . filter (not . isDataConName) where expand (ATyCon ty) = unwords $ (getOccString ty :) $ map getOccString $ tyConDataCons ty expand t = getOccString t
ghc-mod browse との違い
% ghc-mod browse -o Data.Aeson (.:) (.:?) (.=) Array Array Bool DotNetTime DotNetTime Error FromJSON Null Number Object Object Result String Success ToJSON Value encode fromDotNetTime fromJSON json object parseJSON toJSON
% ./Browse Data.Aeson encode json .: .:? .= Array DotNetTime DotNetTime fromDotNetTime FromJSON parseJSON Object Result Error Success ToJSON toJSON Value Object Array String Number Bool Null fromJSON object