{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Language.Haskell.GHC.ExactPrint.Preprocess
(
stripLinePragmas
, getCppTokensAsComments
, getPreprocessedSrcDirect
, readFileGhc
, CppOptions(..)
, defaultCppOptions
) where
import qualified GHC as GHC hiding (parseModule)
import qualified Control.Monad.IO.Class as GHC
import qualified GHC.Data.FastString as GHC
import qualified GHC.Data.StringBuffer as GHC
import qualified GHC.Driver.Config.Parser as GHC
import qualified GHC.Driver.Env as GHC
import qualified GHC.Driver.Errors.Types as GHC
import qualified GHC.Driver.Phases as GHC
import qualified GHC.Driver.Pipeline as GHC
import qualified GHC.Parser.Lexer as GHC
import qualified GHC.Settings as GHC
import qualified GHC.Types.Error as GHC
import qualified GHC.Types.SourceError as GHC
import qualified GHC.Types.SourceFile as GHC
import qualified GHC.Types.SrcLoc as GHC
import qualified GHC.Utils.Error as GHC
import qualified GHC.Utils.Fingerprint as GHC
import qualified GHC.Utils.Outputable as GHC
import GHC.Types.SrcLoc (mkSrcSpan, mkSrcLoc)
import GHC.Data.FastString (mkFastString)
import Data.List (isPrefixOf)
import Data.Maybe
import Language.Haskell.GHC.ExactPrint.Types
import Language.Haskell.GHC.ExactPrint.Utils
import qualified Data.Set as Set
data CppOptions = CppOptions
{ CppOptions -> [String]
cppDefine :: [String]
, CppOptions -> [String]
cppInclude :: [FilePath]
, CppOptions -> [String]
cppFile :: [FilePath]
}
defaultCppOptions :: CppOptions
defaultCppOptions :: CppOptions
defaultCppOptions = [String] -> [String] -> [String] -> CppOptions
CppOptions [] [] []
stripLinePragmas :: String -> (String, [GHC.LEpaComment])
stripLinePragmas :: String -> (String, [LEpaComment])
stripLinePragmas = ([String], [Maybe LEpaComment]) -> (String, [LEpaComment])
forall {a}. ([String], [Maybe a]) -> (String, [a])
unlines' (([String], [Maybe LEpaComment]) -> (String, [LEpaComment]))
-> (String -> ([String], [Maybe LEpaComment]))
-> String
-> (String, [LEpaComment])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(String, Maybe LEpaComment)] -> ([String], [Maybe LEpaComment])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(String, Maybe LEpaComment)] -> ([String], [Maybe LEpaComment]))
-> (String -> [(String, Maybe LEpaComment)])
-> String
-> ([String], [Maybe LEpaComment])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [(String, Maybe LEpaComment)]
findLines ([String] -> [(String, Maybe LEpaComment)])
-> (String -> [String]) -> String -> [(String, Maybe LEpaComment)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines
where
unlines' :: ([String], [Maybe a]) -> (String, [a])
unlines' ([String]
a, [Maybe a]
b) = ([String] -> String
unlines [String]
a, [Maybe a] -> [a]
forall a. [Maybe a] -> [a]
catMaybes [Maybe a]
b)
findLines :: [String] -> [(String, Maybe GHC.LEpaComment)]
findLines :: [String] -> [(String, Maybe LEpaComment)]
findLines = (Int -> String -> (String, Maybe LEpaComment))
-> [Int] -> [String] -> [(String, Maybe LEpaComment)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> String -> (String, Maybe LEpaComment)
checkLine [Int
1..]
checkLine :: Int -> String -> (String, Maybe GHC.LEpaComment)
checkLine :: Int -> String -> (String, Maybe LEpaComment)
checkLine Int
line String
s
| String
"{-# LINE" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s =
let (String
pragma, String
res) = String -> (String, String)
getPragma String
s
size :: Int
size = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
pragma
mSrcLoc :: Int -> Int -> SrcLoc
mSrcLoc = FastString -> Int -> Int -> SrcLoc
mkSrcLoc (String -> FastString
mkFastString String
"LINE")
ss :: SrcSpan
ss = SrcLoc -> SrcLoc -> SrcSpan
mkSrcSpan (Int -> Int -> SrcLoc
mSrcLoc Int
line Int
1) (Int -> Int -> SrcLoc
mSrcLoc Int
line (Int
sizeInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))
in (String
res, LEpaComment -> Maybe LEpaComment
forall a. a -> Maybe a
Just (LEpaComment -> Maybe LEpaComment)
-> LEpaComment -> Maybe LEpaComment
forall a b. (a -> b) -> a -> b
$ String -> NoCommentsLocation -> RealSrcSpan -> LEpaComment
mkLEpaComment String
pragma (SrcSpan -> NoCommentsLocation
forall a. SrcSpan -> EpaLocation' a
GHC.spanAsAnchor SrcSpan
ss) (SrcSpan -> RealSrcSpan
GHC.realSrcSpan SrcSpan
ss))
| String
"#!" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s =
let mSrcLoc :: Int -> Int -> SrcLoc
mSrcLoc = FastString -> Int -> Int -> SrcLoc
mkSrcLoc (String -> FastString
mkFastString String
"SHEBANG")
ss :: SrcSpan
ss = SrcLoc -> SrcLoc -> SrcSpan
mkSrcSpan (Int -> Int -> SrcLoc
mSrcLoc Int
line Int
1) (Int -> Int -> SrcLoc
mSrcLoc Int
line (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s))
in
(String
"",LEpaComment -> Maybe LEpaComment
forall a. a -> Maybe a
Just (LEpaComment -> Maybe LEpaComment)
-> LEpaComment -> Maybe LEpaComment
forall a b. (a -> b) -> a -> b
$ String -> NoCommentsLocation -> RealSrcSpan -> LEpaComment
mkLEpaComment String
s (SrcSpan -> NoCommentsLocation
forall a. SrcSpan -> EpaLocation' a
GHC.spanAsAnchor SrcSpan
ss) (SrcSpan -> RealSrcSpan
GHC.realSrcSpan SrcSpan
ss))
| Bool
otherwise = (String
s, Maybe LEpaComment
forall a. Maybe a
Nothing)
getPragma :: String -> (String, String)
getPragma :: String -> (String, String)
getPragma [] = String -> (String, String)
forall a. HasCallStack => String -> a
error String
"Input must not be empty"
getPragma s :: String
s@(Char
x:String
xs)
| String
"#-}" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s = (String
"#-}", String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
3 String
s)
| Bool
otherwise =
let (String
prag, String
remline) = String -> (String, String)
getPragma String
xs
in (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
prag, Char
' 'Char -> String -> String
forall a. a -> [a] -> [a]
:String
remline)
getCppTokensAsComments :: GHC.GhcMonad m
=> CppOptions
-> FilePath
-> m [GHC.LEpaComment]
CppOptions
cppOptions String
sourceFile = do
source <- IO StringBuffer -> m StringBuffer
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
GHC.liftIO (IO StringBuffer -> m StringBuffer)
-> IO StringBuffer -> m StringBuffer
forall a b. (a -> b) -> a -> b
$ String -> IO StringBuffer
GHC.hGetStringBuffer String
sourceFile
let startLoc = FastString -> Int -> Int -> RealSrcLoc
GHC.mkRealSrcLoc (String -> FastString
GHC.mkFastString String
sourceFile) Int
1 Int
1
(_txt,strSrcBuf,flags2') <- getPreprocessedSrcDirectPrim cppOptions sourceFile
let flags2 = DynFlags -> ParserOpts
GHC.initParserOpts DynFlags
flags2'
directiveToks <- GHC.liftIO $ getPreprocessorAsComments sourceFile
nonDirectiveToks <- tokeniseOriginalSrc startLoc flags2 source
case GHC.lexTokenStream flags2 strSrcBuf startLoc of
GHC.POk PState
_ [Located Token]
ts ->
do
let toks :: [(Located Token, String)]
toks = RealSrcLoc
-> StringBuffer -> [Located Token] -> [(Located Token, String)]
GHC.addSourceToTokens RealSrcLoc
startLoc StringBuffer
source [Located Token]
ts
cppCommentToks :: [(Located Token, String)]
cppCommentToks = [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
getCppTokens [(Located Token, String)]
directiveToks [(Located Token, String)]
nonDirectiveToks [(Located Token, String)]
toks
[LEpaComment] -> m [LEpaComment]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([LEpaComment] -> m [LEpaComment])
-> [LEpaComment] -> m [LEpaComment]
forall a b. (a -> b) -> a -> b
$ (LEpaComment -> Bool) -> [LEpaComment] -> [LEpaComment]
forall a. (a -> Bool) -> [a] -> [a]
filter LEpaComment -> Bool
goodComment
([LEpaComment] -> [LEpaComment]) -> [LEpaComment] -> [LEpaComment]
forall a b. (a -> b) -> a -> b
$ ((Located Token, String) -> LEpaComment)
-> [(Located Token, String)] -> [LEpaComment]
forall a b. (a -> b) -> [a] -> [b]
map (RealLocated Token -> LEpaComment
GHC.commentToAnnotation (RealLocated Token -> LEpaComment)
-> ((Located Token, String) -> RealLocated Token)
-> (Located Token, String)
-> LEpaComment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located Token -> RealLocated Token
forall a. Located a -> RealLocated a
toRealLocated (Located Token -> RealLocated Token)
-> ((Located Token, String) -> Located Token)
-> (Located Token, String)
-> RealLocated Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Located Token, String) -> Located Token
forall a b. (a, b) -> a
fst) [(Located Token, String)]
cppCommentToks
GHC.PFailed PState
pst -> PState -> m [LEpaComment]
forall (m :: * -> *) b. MonadIO m => PState -> m b
parseError PState
pst
goodComment :: GHC.LEpaComment -> Bool
LEpaComment
c = [Comment] -> Bool
isGoodComment (LEpaComment -> [Comment]
tokComment LEpaComment
c)
where
isGoodComment :: [Comment] -> Bool
isGoodComment :: [Comment] -> Bool
isGoodComment [] = Bool
False
isGoodComment [Comment String
"" NoCommentsLocation
_ RealSrcSpan
_ Maybe String
_] = Bool
False
isGoodComment [Comment]
_ = Bool
True
toRealLocated :: GHC.Located a -> GHC.RealLocated a
toRealLocated :: forall a. Located a -> RealLocated a
toRealLocated (GHC.L (GHC.RealSrcSpan RealSrcSpan
s Maybe BufSpan
_) a
x) = RealSrcSpan -> a -> GenLocated RealSrcSpan a
forall l e. l -> e -> GenLocated l e
GHC.L RealSrcSpan
s a
x
toRealLocated (GHC.L SrcSpan
_ a
x) = RealSrcSpan -> a -> GenLocated RealSrcSpan a
forall l e. l -> e -> GenLocated l e
GHC.L RealSrcSpan
badRealSrcSpan a
x
getCppTokens ::
[(GHC.Located GHC.Token, String)]
-> [(GHC.Located GHC.Token, String)]
-> [(GHC.Located GHC.Token, String)]
-> [(GHC.Located GHC.Token, String)]
getCppTokens :: [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
getCppTokens [(Located Token, String)]
directiveToks [(Located Token, String)]
origSrcToks [(Located Token, String)]
postCppToks = [(Located Token, String)]
toks
where
locFn :: (GenLocated SrcSpan e, b) -> (GenLocated SrcSpan e, b) -> Ordering
locFn (GHC.L SrcSpan
l1 e
_,b
_) (GHC.L SrcSpan
l2 e
_,b
_) = RealSrcSpan -> RealSrcSpan -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (SrcSpan -> RealSrcSpan
rs SrcSpan
l1) (SrcSpan -> RealSrcSpan
rs SrcSpan
l2)
m1Toks :: [(Located Token, String)]
m1Toks = ((Located Token, String) -> (Located Token, String) -> Ordering)
-> [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy (Located Token, String) -> (Located Token, String) -> Ordering
forall {e} {b} {e} {b}.
(GenLocated SrcSpan e, b) -> (GenLocated SrcSpan e, b) -> Ordering
locFn [(Located Token, String)]
postCppToks [(Located Token, String)]
directiveToks
origSpans :: [RealSrcSpan]
origSpans = ((Located Token, String) -> RealSrcSpan)
-> [(Located Token, String)] -> [RealSrcSpan]
forall a b. (a -> b) -> [a] -> [b]
map (\(GHC.L SrcSpan
l Token
_,String
_) -> SrcSpan -> RealSrcSpan
rs SrcSpan
l) [(Located Token, String)]
origSrcToks
m1Spans :: [RealSrcSpan]
m1Spans = ((Located Token, String) -> RealSrcSpan)
-> [(Located Token, String)] -> [RealSrcSpan]
forall a b. (a -> b) -> [a] -> [b]
map (\(GHC.L SrcSpan
l Token
_,String
_) -> SrcSpan -> RealSrcSpan
rs SrcSpan
l) [(Located Token, String)]
m1Toks
missingSpans :: Set RealSrcSpan
missingSpans = [RealSrcSpan] -> Set RealSrcSpan
forall a. Ord a => [a] -> Set a
Set.fromList [RealSrcSpan]
origSpans Set RealSrcSpan -> Set RealSrcSpan -> Set RealSrcSpan
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ [RealSrcSpan] -> Set RealSrcSpan
forall a. Ord a => [a] -> Set a
Set.fromList [RealSrcSpan]
m1Spans
missingToks :: [(Located Token, String)]
missingToks = ((Located Token, String) -> Bool)
-> [(Located Token, String)] -> [(Located Token, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(GHC.L SrcSpan
l Token
_,String
_) -> RealSrcSpan -> Set RealSrcSpan -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member (SrcSpan -> RealSrcSpan
rs SrcSpan
l) Set RealSrcSpan
missingSpans) [(Located Token, String)]
origSrcToks
missingAsComments :: [(Located Token, String)]
missingAsComments = ((Located Token, String) -> (Located Token, String))
-> [(Located Token, String)] -> [(Located Token, String)]
forall a b. (a -> b) -> [a] -> [b]
map (Located Token, String) -> (Located Token, String)
mkCommentTok [(Located Token, String)]
missingToks
where
mkCommentTok :: (GHC.Located GHC.Token,String) -> (GHC.Located GHC.Token,String)
mkCommentTok :: (Located Token, String) -> (Located Token, String)
mkCommentTok (GHC.L SrcSpan
l Token
_,String
s) = (SrcSpan -> Token -> Located Token
forall l e. l -> e -> GenLocated l e
GHC.L SrcSpan
l (String -> PsSpan -> Token
GHC.ITlineComment String
s (SrcSpan -> PsSpan
makeBufSpan SrcSpan
l)),String
s)
toks :: [(Located Token, String)]
toks = ((Located Token, String) -> (Located Token, String) -> Ordering)
-> [(Located Token, String)]
-> [(Located Token, String)]
-> [(Located Token, String)]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy (Located Token, String) -> (Located Token, String) -> Ordering
forall {e} {b} {e} {b}.
(GenLocated SrcSpan e, b) -> (GenLocated SrcSpan e, b) -> Ordering
locFn [(Located Token, String)]
directiveToks [(Located Token, String)]
missingAsComments
tokeniseOriginalSrc ::
GHC.GhcMonad m
=> GHC.RealSrcLoc -> GHC.ParserOpts -> GHC.StringBuffer
-> m [(GHC.Located GHC.Token, String)]
tokeniseOriginalSrc :: forall (m :: * -> *).
GhcMonad m =>
RealSrcLoc
-> ParserOpts -> StringBuffer -> m [(Located Token, String)]
tokeniseOriginalSrc RealSrcLoc
startLoc ParserOpts
flags StringBuffer
buf = do
let src :: StringBuffer
src = StringBuffer -> StringBuffer
stripPreprocessorDirectives StringBuffer
buf
case ParserOpts
-> StringBuffer -> RealSrcLoc -> ParseResult [Located Token]
GHC.lexTokenStream ParserOpts
flags StringBuffer
src RealSrcLoc
startLoc of
GHC.POk PState
_ [Located Token]
ts -> [(Located Token, String)] -> m [(Located Token, String)]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Located Token, String)] -> m [(Located Token, String)])
-> [(Located Token, String)] -> m [(Located Token, String)]
forall a b. (a -> b) -> a -> b
$ RealSrcLoc
-> StringBuffer -> [Located Token] -> [(Located Token, String)]
GHC.addSourceToTokens RealSrcLoc
startLoc StringBuffer
src [Located Token]
ts
GHC.PFailed PState
pst -> PState -> m [(Located Token, String)]
forall (m :: * -> *) b. MonadIO m => PState -> m b
parseError PState
pst
stripPreprocessorDirectives :: GHC.StringBuffer -> GHC.StringBuffer
stripPreprocessorDirectives :: StringBuffer -> StringBuffer
stripPreprocessorDirectives StringBuffer
buf = StringBuffer
buf'
where
srcByLine :: [String]
srcByLine = String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ StringBuffer -> String
sbufToString StringBuffer
buf
noDirectivesLines :: [String]
noDirectivesLines = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
line -> case String
line of Char
'#' : String
_ -> String
""; String
_ -> String
line) [String]
srcByLine
buf' :: StringBuffer
buf' = String -> StringBuffer
GHC.stringToStringBuffer (String -> StringBuffer) -> String -> StringBuffer
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [String]
noDirectivesLines
sbufToString :: GHC.StringBuffer -> String
sbufToString :: StringBuffer -> String
sbufToString sb :: StringBuffer
sb@(GHC.StringBuffer ForeignPtr Word8
_buf Int
len Int
_cur) = StringBuffer -> Int -> String
GHC.lexemeToString StringBuffer
sb Int
len
getPreprocessedSrcDirect :: (GHC.GhcMonad m)
=> CppOptions
-> FilePath
-> m (String, GHC.DynFlags)
getPreprocessedSrcDirect :: forall (m :: * -> *).
GhcMonad m =>
CppOptions -> String -> m (String, DynFlags)
getPreprocessedSrcDirect CppOptions
cppOptions String
src =
(\(String
s,StringBuffer
_,DynFlags
d) -> (String
s,DynFlags
d)) ((String, StringBuffer, DynFlags) -> (String, DynFlags))
-> m (String, StringBuffer, DynFlags) -> m (String, DynFlags)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CppOptions -> String -> m (String, StringBuffer, DynFlags)
forall (m :: * -> *).
GhcMonad m =>
CppOptions -> String -> m (String, StringBuffer, DynFlags)
getPreprocessedSrcDirectPrim CppOptions
cppOptions String
src
getPreprocessedSrcDirectPrim :: (GHC.GhcMonad m)
=> CppOptions
-> FilePath
-> m (String, GHC.StringBuffer, GHC.DynFlags)
getPreprocessedSrcDirectPrim :: forall (m :: * -> *).
GhcMonad m =>
CppOptions -> String -> m (String, StringBuffer, DynFlags)
getPreprocessedSrcDirectPrim CppOptions
cppOptions String
src_fn = do
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
GHC.getSession
let dfs = HscEnv -> DynFlags
GHC.hsc_dflags HscEnv
hsc_env
new_env = HscEnv
hsc_env { GHC.hsc_dflags = injectCppOptions cppOptions dfs }
r <- GHC.liftIO $ GHC.preprocess new_env src_fn Nothing (Just (GHC.Cpp GHC.HsSrcFile))
case r of
Left DriverMessages
err -> String -> m (String, StringBuffer, DynFlags)
forall a. HasCallStack => String -> a
error (String -> m (String, StringBuffer, DynFlags))
-> String -> m (String, StringBuffer, DynFlags)
forall a b. (a -> b) -> a -> b
$ DriverMessages -> String
showErrorMessages DriverMessages
err
Right (DynFlags
dflags', String
hspp_fn) -> do
buf <- IO StringBuffer -> m StringBuffer
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
GHC.liftIO (IO StringBuffer -> m StringBuffer)
-> IO StringBuffer -> m StringBuffer
forall a b. (a -> b) -> a -> b
$ String -> IO StringBuffer
GHC.hGetStringBuffer String
hspp_fn
txt <- GHC.liftIO $ readFileGhc hspp_fn
return (txt, buf, dflags')
showErrorMessages :: GHC.Messages GHC.DriverMessage -> String
showErrorMessages :: DriverMessages -> String
showErrorMessages DriverMessages
msgs =
SDocContext -> SDoc -> String
GHC.renderWithContext SDocContext
GHC.defaultSDocContext
(SDoc -> String) -> SDoc -> String
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
GHC.vcat
([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ Bag (MsgEnvelope DriverMessage) -> [SDoc]
forall e. Diagnostic e => Bag (MsgEnvelope e) -> [SDoc]
GHC.pprMsgEnvelopeBagWithLocDefault
(Bag (MsgEnvelope DriverMessage) -> [SDoc])
-> Bag (MsgEnvelope DriverMessage) -> [SDoc]
forall a b. (a -> b) -> a -> b
$ DriverMessages -> Bag (MsgEnvelope DriverMessage)
forall e. Messages e -> Bag (MsgEnvelope e)
GHC.getMessages
(DriverMessages -> Bag (MsgEnvelope DriverMessage))
-> DriverMessages -> Bag (MsgEnvelope DriverMessage)
forall a b. (a -> b) -> a -> b
$ DriverMessages
msgs
injectCppOptions :: CppOptions -> GHC.DynFlags -> GHC.DynFlags
injectCppOptions :: CppOptions -> DynFlags -> DynFlags
injectCppOptions CppOptions{[String]
cppDefine :: CppOptions -> [String]
cppInclude :: CppOptions -> [String]
cppFile :: CppOptions -> [String]
cppDefine :: [String]
cppInclude :: [String]
cppFile :: [String]
..} DynFlags
dflags = DynFlags
folded_opt
where
mkDefine :: String -> String
mkDefine = (String
"-D" String -> String -> String
forall a. [a] -> [a] -> [a]
++)
mkIncludeDir :: String -> String
mkIncludeDir = (String
"-I" String -> String -> String
forall a. [a] -> [a] -> [a]
++)
mkInclude :: String -> String
mkInclude = (String
"-include" String -> String -> String
forall a. [a] -> [a] -> [a]
++)
file_flags :: [String]
file_flags = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
mkDefine [String]
cppDefine [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
mkIncludeDir [String]
cppInclude [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
mkInclude [String]
cppFile
addFs :: [String -> DynFlags -> DynFlags]
addFs = [String -> DynFlags -> DynFlags
addOptP, String -> DynFlags -> DynFlags
addOptJSP, String -> DynFlags -> DynFlags
addOptCmmP]
folded_opt :: DynFlags
folded_opt = ((DynFlags -> DynFlags) -> DynFlags -> DynFlags)
-> DynFlags -> [DynFlags -> DynFlags] -> DynFlags
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (DynFlags -> DynFlags) -> DynFlags -> DynFlags
forall a b. (a -> b) -> a -> b
($) DynFlags
dflags ([String -> DynFlags -> DynFlags]
addFs [String -> DynFlags -> DynFlags]
-> [String] -> [DynFlags -> DynFlags]
forall a b. [a -> b] -> [a] -> [b]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [String]
file_flags)
addOptP :: String -> GHC.DynFlags -> GHC.DynFlags
addOptP :: String -> DynFlags -> DynFlags
addOptP String
f = (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
alterToolSettings ((ToolSettings -> ToolSettings) -> DynFlags -> DynFlags)
-> (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
forall a b. (a -> b) -> a -> b
$ \ToolSettings
s -> ToolSettings
s
{ GHC.toolSettings_opt_P = f : GHC.toolSettings_opt_P s
, GHC.toolSettings_opt_P_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_P s)
}
addOptJSP :: String -> GHC.DynFlags -> GHC.DynFlags
addOptJSP :: String -> DynFlags -> DynFlags
addOptJSP String
f = (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
alterToolSettings ((ToolSettings -> ToolSettings) -> DynFlags -> DynFlags)
-> (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
forall a b. (a -> b) -> a -> b
$ \ToolSettings
s -> ToolSettings
s
{ GHC.toolSettings_opt_JSP = f : GHC.toolSettings_opt_JSP s
, GHC.toolSettings_opt_JSP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_JSP s)
}
addOptCmmP :: String -> GHC.DynFlags -> GHC.DynFlags
addOptCmmP :: String -> DynFlags -> DynFlags
addOptCmmP String
f = (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
alterToolSettings ((ToolSettings -> ToolSettings) -> DynFlags -> DynFlags)
-> (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
forall a b. (a -> b) -> a -> b
$ \ToolSettings
s -> ToolSettings
s
{ GHC.toolSettings_opt_CmmP = f : GHC.toolSettings_opt_CmmP s
, GHC.toolSettings_opt_CmmP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_CmmP s)
}
alterToolSettings :: (GHC.ToolSettings -> GHC.ToolSettings) -> GHC.DynFlags -> GHC.DynFlags
alterToolSettings :: (ToolSettings -> ToolSettings) -> DynFlags -> DynFlags
alterToolSettings ToolSettings -> ToolSettings
f DynFlags
dynFlags = DynFlags
dynFlags { GHC.toolSettings = f (GHC.toolSettings dynFlags) }
getPreprocessorAsComments :: FilePath -> IO [(GHC.Located GHC.Token, String)]
String
srcFile = do
fcontents <- String -> IO String
readFileGhc String
srcFile
let directives = ((Int, String) -> Bool) -> [(Int, String)] -> [(Int, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Int
_lineNum,String
line) -> case String
line of Char
'#' : String
_ -> Bool
True; String
_ -> Bool
False)
([(Int, String)] -> [(Int, String)])
-> [(Int, String)] -> [(Int, String)]
forall a b. (a -> b) -> a -> b
$ [Int] -> [String] -> [(Int, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..] (String -> [String]
lines String
fcontents)
let mkTok (Int
lineNum,String
line) = (SrcSpan -> Token -> Located Token
forall l e. l -> e -> GenLocated l e
GHC.L SrcSpan
l (String -> PsSpan -> Token
GHC.ITlineComment String
line (SrcSpan -> PsSpan
makeBufSpan SrcSpan
l)),String
line)
where
start :: SrcLoc
start = FastString -> Int -> Int -> SrcLoc
GHC.mkSrcLoc (String -> FastString
GHC.mkFastString String
srcFile) Int
lineNum Int
1
end :: SrcLoc
end = FastString -> Int -> Int -> SrcLoc
GHC.mkSrcLoc (String -> FastString
GHC.mkFastString String
srcFile) Int
lineNum (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
line)
l :: SrcSpan
l = SrcLoc -> SrcLoc -> SrcSpan
GHC.mkSrcSpan SrcLoc
start SrcLoc
end
let toks = ((Int, String) -> (Located Token, String))
-> [(Int, String)] -> [(Located Token, String)]
forall a b. (a -> b) -> [a] -> [b]
map (Int, String) -> (Located Token, String)
mkTok [(Int, String)]
directives
return toks
makeBufSpan :: GHC.SrcSpan -> GHC.PsSpan
makeBufSpan :: SrcSpan -> PsSpan
makeBufSpan SrcSpan
ss = PsSpan
pspan
where
bl :: BufPos
bl = Int -> BufPos
GHC.BufPos Int
0
pspan :: PsSpan
pspan = RealSrcSpan -> BufSpan -> PsSpan
GHC.PsSpan (SrcSpan -> RealSrcSpan
GHC.realSrcSpan SrcSpan
ss) (BufPos -> BufPos -> BufSpan
GHC.BufSpan BufPos
bl BufPos
bl)
parseError :: (GHC.MonadIO m) => GHC.PState -> m b
parseError :: forall (m :: * -> *) b. MonadIO m => PState -> m b
parseError PState
pst = Messages GhcMessage -> m b
forall (io :: * -> *) a. MonadIO io => Messages GhcMessage -> io a
GHC.throwErrors ((PsMessage -> GhcMessage)
-> Messages PsMessage -> Messages GhcMessage
forall a b. (a -> b) -> Messages a -> Messages b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PsMessage -> GhcMessage
GHC.GhcPsMessage (PState -> Messages PsMessage
GHC.getPsErrorMessages PState
pst))
readFileGhc :: FilePath -> IO String
readFileGhc :: String -> IO String
readFileGhc String
file = do
buf@(GHC.StringBuffer _ len _) <- String -> IO StringBuffer
GHC.hGetStringBuffer String
file
return (GHC.lexemeToString buf len)
mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy :: forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy a -> a -> Ordering
_cmp [] [a]
ys = [a]
ys
mergeBy a -> a -> Ordering
_cmp [a]
xs [] = [a]
xs
mergeBy a -> a -> Ordering
cmp (allx :: [a]
allx@(a
x:[a]
xs)) (ally :: [a]
ally@(a
y:[a]
ys))
| (a
x a -> a -> Ordering
`cmp` a
y) Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
<= Ordering
EQ = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> Ordering) -> [a] -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy a -> a -> Ordering
cmp [a]
xs [a]
ally
| Bool
otherwise = a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> Ordering) -> [a] -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy a -> a -> Ordering
cmp [a]
allx [a]
ys