module Hint.Parsers where
import Prelude hiding (span)
import Hint.Base
import Control.Monad.IO.Class (liftIO)
import qualified Hint.GHC as GHC
data ParseResult = ParseOk | ParseError GHC.SrcSpan GHC.Message
parseExpr :: MonadInterpreter m => String -> m ParseResult
parseExpr :: String -> m ParseResult
parseExpr = P (Maybe (LStmt GhcPs (LHsExpr GhcPs))) -> String -> m ParseResult
forall (m :: * -> *) a.
MonadInterpreter m =>
P a -> String -> m ParseResult
runParser P (Maybe (LStmt GhcPs (LHsExpr GhcPs)))
GHC.parseStmt
parseType :: MonadInterpreter m => String -> m ParseResult
parseType :: String -> m ParseResult
parseType = P (LHsType GhcPs) -> String -> m ParseResult
forall (m :: * -> *) a.
MonadInterpreter m =>
P a -> String -> m ParseResult
runParser P (LHsType GhcPs)
GHC.parseType
runParser :: MonadInterpreter m => GHC.P a -> String -> m ParseResult
runParser :: P a -> String -> m ParseResult
runParser parser :: P a
parser expr :: String
expr =
do DynFlags
dyn_fl <- RunGhc m DynFlags
forall (m :: * -> *) a. MonadInterpreter m => RunGhc m a
runGhc forall (n :: * -> *). (MonadIO n, MonadMask n) => GhcT n DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
StringBuffer
buf <- (StringBuffer -> m StringBuffer
forall (m :: * -> *) a. Monad m => a -> m a
return (StringBuffer -> m StringBuffer)
-> (String -> StringBuffer) -> String -> m StringBuffer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> StringBuffer
GHC.stringToStringBuffer) String
expr
let srcLoc :: RealSrcLoc
srcLoc = FastString -> Int -> Int -> RealSrcLoc
GHC.mkRealSrcLoc (String -> FastString
GHC.fsLit "<hint>") 1 1
let parserOpts :: ParserOpts
parserOpts = DynFlags -> ParserOpts
GHC.mkParserOpts DynFlags
dyn_fl
let parse_res :: ParseResult a
parse_res = P a -> PState -> ParseResult a
forall a. P a -> PState -> ParseResult a
GHC.unP P a
parser (ParserOpts -> StringBuffer -> RealSrcLoc -> PState
GHC.initParserState ParserOpts
parserOpts StringBuffer
buf RealSrcLoc
srcLoc)
case ParseResult a
parse_res of
GHC.POk{} -> ParseResult -> m ParseResult
forall (m :: * -> *) a. Monad m => a -> m a
return ParseResult
ParseOk
#if MIN_VERSION_ghc(8,10,0)
GHC.PFailed pst -> let errMsgs = GHC.getErrorMessages pst dyn_fl
span = foldr (GHC.combineSrcSpans . GHC.errMsgSpan) GHC.noSrcSpan errMsgs
err = GHC.vcat $ GHC.pprErrorMessages errMsgs
in pure (ParseError span err)
#else
GHC.PFailed _ span :: SrcSpan
span err :: MsgDoc
err -> ParseResult -> m ParseResult
forall (m :: * -> *) a. Monad m => a -> m a
return (SrcSpan -> MsgDoc -> ParseResult
ParseError SrcSpan
span MsgDoc
err)
#endif
failOnParseError :: MonadInterpreter m
=> (String -> m ParseResult)
-> String
-> m ()
failOnParseError :: (String -> m ParseResult) -> String -> m ()
failOnParseError parser :: String -> m ParseResult
parser expr :: String
expr = m (Maybe ()) -> m ()
forall (m :: * -> *) a. MonadInterpreter m => m (Maybe a) -> m a
mayFail m (Maybe ())
go
where go :: m (Maybe ())
go = String -> m ParseResult
parser String
expr m ParseResult -> (ParseResult -> m (Maybe ())) -> m (Maybe ())
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ case
ParseOk -> Maybe () -> m (Maybe ())
forall (m :: * -> *) a. Monad m => a -> m a
return (() -> Maybe ()
forall a. a -> Maybe a
Just ())
ParseError span :: SrcSpan
span err :: MsgDoc
err ->
do
Logger
logger <- FromSession m Logger
forall (m :: * -> *) a. MonadInterpreter m => FromSession m a
fromSession SessionData () -> Logger
forall a. SessionData a -> Logger
ghcLogger
DynFlags
dflags <- RunGhc m DynFlags
forall (m :: * -> *) a. MonadInterpreter m => RunGhc m a
runGhc forall (n :: * -> *). (MonadIO n, MonadMask n) => GhcT n DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
let logger' :: WarnReason -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO ()
logger' = Logger -> Logger
GHC.putLogMsg Logger
logger DynFlags
dflags
#if !MIN_VERSION_ghc(9,0,0)
errStyle :: PprStyle
errStyle = DynFlags -> PprStyle
GHC.defaultErrStyle DynFlags
dflags
#endif
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ WarnReason -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO ()
logger'
WarnReason
GHC.NoReason
Severity
GHC.SevError
SrcSpan
span
#if !MIN_VERSION_ghc(9,0,0)
PprStyle
errStyle
#endif
MsgDoc
err
Maybe () -> m (Maybe ())
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ()
forall a. Maybe a
Nothing