Skip to content

Commit ae87135

Browse files
committed
Create a dedicated preprocessor function, to apply all the necessary preprocessors
1 parent acc834c commit ae87135

File tree

2 files changed

+49
-39
lines changed

2 files changed

+49
-39
lines changed

src/Development/IDE/Core/Compile.hs

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import qualified HeaderInfo as Hdr
3838
import MkIface
3939
import StringBuffer as SB
4040
import TidyPgm
41-
import qualified GHC.LanguageExtensions as LangExt
4241

4342
import Control.Monad.Extra
4443
import Control.Monad.Except
@@ -264,6 +263,7 @@ getModSummaryFromBuffer fp contents dflags parsed = do
264263
then (HsBootFile, \newExt -> stem <.> newExt ++ "-boot")
265264
else (HsSrcFile , \newExt -> stem <.> newExt)
266265

266+
267267
-- | Given a buffer, flags, file path and module summary, produce a
268268
-- parsed module (or errors) and any parse warnings.
269269
parseFileContents
@@ -273,27 +273,8 @@ parseFileContents
273273
-> Maybe SB.StringBuffer -- ^ Haskell module source text (full Unicode is supported)
274274
-> ExceptT [FileDiagnostic] m ([FileDiagnostic], ParsedModule)
275275
parseFileContents sourcePlugin filename mbContents = do
276+
(contents, dflags) <- preprocessor filename mbContents
276277
let loc = mkRealSrcLoc (mkFastString filename) 1 1
277-
contents <- liftIO $ maybe (hGetStringBuffer filename) return mbContents
278-
let isOnDisk = isNothing mbContents
279-
280-
-- unlit content if literate Haskell ending
281-
(isOnDisk, contents) <- if ".lhs" `isSuffixOf` filename
282-
then do
283-
dflags <- getDynFlags
284-
newcontent <- liftIO $ runLhs dflags filename mbContents
285-
return (False, newcontent)
286-
else return (isOnDisk, contents)
287-
288-
dflags <- ExceptT $ parsePragmasIntoDynFlags filename contents
289-
(contents, dflags) <-
290-
if not $ xopt LangExt.Cpp dflags then
291-
return (contents, dflags)
292-
else do
293-
contents <- liftIO $ runCpp dflags filename $ if isOnDisk then Nothing else Just contents
294-
dflags <- ExceptT $ parsePragmasIntoDynFlags filename contents
295-
return (contents, dflags)
296-
297278
case unP Parser.parseModule (mkPState dflags contents loc) of
298279
PFailed _ locErr msgErr ->
299280
throwE $ diagFromErrMsg "parser" dflags $ mkPlainErrMsg dflags locErr msgErr
@@ -330,16 +311,3 @@ parseFileContents sourcePlugin filename mbContents = do
330311
}
331312
warnings = diagFromErrMsgs "parser" dflags warns
332313
pure (warnings, pm)
333-
334-
335-
-- | This reads the pragma information directly from the provided buffer.
336-
parsePragmasIntoDynFlags
337-
:: GhcMonad m
338-
=> FilePath
339-
-> SB.StringBuffer
340-
-> m (Either [FileDiagnostic] DynFlags)
341-
parsePragmasIntoDynFlags fp contents = catchSrcErrors "pragmas" $ do
342-
dflags0 <- getSessionDynFlags
343-
let opts = Hdr.getOptions dflags0 contents fp
344-
(dflags, _, _) <- parseDynamicFilePragma dflags0 opts
345-
return dflags

src/Development/IDE/Core/Preprocessor.hs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@
44
{-# LANGUAGE RankNTypes #-}
55
{-# LANGUAGE CPP #-}
66

7-
-- | Based on https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/API.
8-
-- Given a list of paths to find libraries, and a file to compile, produce a list of 'CoreModule' values.
97
module Development.IDE.Core.Preprocessor
10-
( runLhs
11-
, runCpp
8+
( preprocessor
129
) where
1310

1411
import Development.IDE.GHC.CPP
@@ -22,8 +19,53 @@ import Data.List.Extra
2219
import System.FilePath
2320
import System.IO.Extra
2421
import Data.Char
25-
22+
import DynFlags
23+
import qualified HeaderInfo as Hdr
24+
import Development.IDE.Types.Diagnostics
25+
import Development.IDE.GHC.Error
2626
import SysTools (Option (..), runUnlit)
27+
import Control.Monad.Trans.Except
28+
import qualified GHC.LanguageExtensions as LangExt
29+
import Data.Maybe
30+
31+
32+
-- | Given a file and some contents, apply any necessary preprocessors,
33+
-- e.g. unlit/cpp. Return the resulting buffer and the DynFlags it implies.
34+
preprocessor :: GhcMonad m => FilePath -> Maybe StringBuffer -> ExceptT [FileDiagnostic] m (StringBuffer, DynFlags)
35+
preprocessor filename mbContents = do
36+
contents <- liftIO $ maybe (hGetStringBuffer filename) return mbContents
37+
let isOnDisk = isNothing mbContents
38+
39+
-- unlit content if literate Haskell ending
40+
(isOnDisk, contents) <- if ".lhs" `isSuffixOf` filename
41+
then do
42+
dflags <- getDynFlags
43+
newcontent <- liftIO $ runLhs dflags filename mbContents
44+
return (False, newcontent)
45+
else return (isOnDisk, contents)
46+
47+
dflags <- ExceptT $ parsePragmasIntoDynFlags filename contents
48+
if not $ xopt LangExt.Cpp dflags then
49+
return (contents, dflags)
50+
else do
51+
contents <- liftIO $ runCpp dflags filename $ if isOnDisk then Nothing else Just contents
52+
dflags <- ExceptT $ parsePragmasIntoDynFlags filename contents
53+
return (contents, dflags)
54+
55+
56+
-- | This reads the pragma information directly from the provided buffer.
57+
parsePragmasIntoDynFlags
58+
:: GhcMonad m
59+
=> FilePath
60+
-> SB.StringBuffer
61+
-> m (Either [FileDiagnostic] DynFlags)
62+
parsePragmasIntoDynFlags fp contents = catchSrcErrors "pragmas" $ do
63+
dflags0 <- getSessionDynFlags
64+
let opts = Hdr.getOptions dflags0 contents fp
65+
(dflags, _, _) <- parseDynamicFilePragma dflags0 opts
66+
return dflags
67+
68+
2769

2870
-- | Run (unlit) literate haskell preprocessor on a file, or buffer if set
2971
runLhs :: DynFlags -> FilePath -> Maybe SB.StringBuffer -> IO SB.StringBuffer

0 commit comments

Comments
 (0)