"info" and "type" can display it even if the source file is broken.

This commit is contained in:
Kazu Yamamoto 2010-11-17 17:07:33 +09:00
parent ae22ff40d4
commit 39409f2239
3 changed files with 85 additions and 45 deletions

View File

@ -27,8 +27,8 @@ usage = "ghc-mod version 0.5.0\n"
++ "\t ghc-mod [-l] lang\n"
++ "\t ghc-mod [-l] browse <module> [<module> ...]\n"
++ "\t ghc-mod check <HaskellFile>\n"
++ "\t ghc-mod type <HaskellFile> <expression>\n"
++ "\t ghc-mod info <HaskellFile> <expression>\n"
++ "\t ghc-mod type <HaskellFile> <module> <expression>\n"
++ "\t ghc-mod info <HaskellFile> <module> <expression>\n"
++ "\t ghc-mod [-h opt] lint <HaskellFile>\n"
++ "\t ghc-mod boot\n"
++ "\t ghc-mod help\n"
@ -75,8 +75,8 @@ main = flip catches handlers $ do
"browse" -> concat <$> mapM (browseModule opt) (tail cmdArg)
"list" -> listModules opt
"check" -> withFile (checkSyntax opt) (safelist cmdArg 1)
"type" -> withFile (typeExpr opt (safelist cmdArg 2)) (safelist cmdArg 1)
"info" -> withFile (infoExpr opt (safelist cmdArg 2)) (safelist cmdArg 1)
"type" -> withFile (typeExpr opt (safelist cmdArg 2) (safelist cmdArg 3)) (safelist cmdArg 1)
"info" -> withFile (infoExpr opt (safelist cmdArg 2) (safelist cmdArg 3)) (safelist cmdArg 1)
"lint" -> withFile (lintSyntax opt) (safelist cmdArg 1)
"lang" -> listLanguages opt
"boot" -> do

54
Info.hs
View File

@ -9,35 +9,47 @@ import Types
import NameSet
import HscTypes
import Data.List
import Control.Exception
type Expression = String
type ModuleString = String
----------------------------------------------------------------
typeExpr :: Options -> String -> String -> IO String
typeExpr _ expr file = (++ "\n") <$> typeOf file expr
typeExpr :: Options -> ModuleString -> Expression -> FilePath -> IO String
typeExpr _ modstr expr file = (++ "\n") <$> typeOf file modstr expr
typeOf :: String -> String -> IO String
typeOf fileName expr = withGHC $ do
initSession []
typeOf :: FilePath -> ModuleString-> Expression -> IO String
typeOf fileName modstr expr = withGHC $ valid `gcatch` invalid
where
valid = makeTypeOf LoadAllTargets
invalid = constE invalid0
invalid0 = makeTypeOf $ LoadDependenciesOf (mkModuleName modstr)
makeTypeOf x = do
initSession ["-w"]
setTargetFile fileName
load LoadAllTargets
loadWithLogger (\_ -> return ()) x
setContextFromTarget
pretty <$> exprType expr
where
pretty = showSDocForUser neverQualify . pprTypeForUser False
----------------------------------------------------------------
infoExpr :: Options -> String -> String -> IO String
infoExpr _ expr file = (++ "\n") <$> info file expr
infoExpr :: Options -> ModuleString -> Expression -> FilePath -> IO String
infoExpr _ modstr expr file = (++ "\n") <$> info file modstr expr
info :: String -> String -> IO String
info fileName expr = withGHC $ do
initSession []
info :: FilePath -> ModuleString -> FilePath -> IO String
info fileName modstr expr = withGHC $ valid `gcatch` invalid
where
valid = makeInfo LoadAllTargets
invalid = constE invalid0
invalid0 = makeInfo $ LoadDependenciesOf (mkModuleName modstr)
makeInfo x = do
initSession ["-w"]
setTargetFile fileName
load LoadAllTargets
loadWithLogger (\_ -> return ()) x
setContextFromTarget
infoThing expr
where
-- ghc/InteractiveUI.hs
infoThing str = do
names <- parseName str
@ -68,5 +80,15 @@ pprInfo pefas (thing, fixity, insts)
setContextFromTarget :: Ghc ()
setContextFromTarget = do
ms <- depanal [] False
mdl <- findModule (ms_mod_name (head ms)) Nothing
setContext [mdl] []
mdls <- mapM toModule ms
setContext (catMaybes mdls) []
where
toModule ms = lookupMod `gcatch` nothing
where
lookupMod = lookupModule (ms_mod_name ms) Nothing >>= return . Just
nothing = constE $ return Nothing
----------------------------------------------------------------
constE :: a -> (SomeException -> a)
constE func = \_ -> func

View File

@ -14,19 +14,31 @@
(interactive "P")
(if (not (ghc-which ghc-module-command))
(message "%s not found" ghc-module-command)
(let ((modname (ghc-find-module-name)))
(if (not modname)
(message "module should be specified")
(ghc-show-type0 ask modname)))))
(defun ghc-show-type0 (ask modname)
(let* ((expr0 (thing-at-point 'symbol))
(expr (if ask (ghc-read-expression expr0) expr0))
(cdir default-directory)
(file (buffer-name)))
(with-temp-buffer
(cd cdir)
(call-process ghc-module-command nil t nil "type" file expr)
(message (buffer-substring (point-min) (1- (point-max))))))))
(call-process ghc-module-command nil t nil "type" file modname expr)
(message (buffer-substring (point-min) (1- (point-max)))))))
(defun ghc-show-info (&optional ask)
(interactive "P")
(if (not (ghc-which ghc-module-command))
(message "%s not found" ghc-module-command)
(let ((modname (ghc-find-module-name)))
(if (not modname)
(message "module should be specified")
(ghc-show-info0 ask modname)))))
(defun ghc-show-info0 (ask modname)
(let* ((expr0 (thing-at-point 'symbol))
(expr (if ask (ghc-read-expression expr0) expr0))
(cdir default-directory)
@ -37,12 +49,18 @@
(insert
(with-temp-buffer
(cd cdir)
(call-process ghc-module-command nil t nil "info" file expr)
(call-process ghc-module-command nil t nil "info" file modname expr)
(buffer-substring (point-min) (1- (point-max))))))
(display-buffer buf))))
(display-buffer buf)))
(defun ghc-read-expression (default)
(let ((prompt (format "Expression (%s): " default)))
(read-string prompt default nil)))
(defun ghc-find-module-name ()
(save-excursion
(goto-char (point-min))
(if (re-search-forward "^module[ ]+\\([^ ]+\\)" nil t)
(match-string-no-properties 1))))
(provide 'ghc-info)