Created
January 6, 2013 06:58
-
-
Save hansonkd/4465704 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SnapApp.Processing (sanatizeSourceString) where | |
import GHC | |
import Outputable | |
import HsDecls | |
import Data.List | |
import Data.Maybe | |
import Control.Monad (unless) | |
import Text.Regex.Posix | |
import System.Environment | |
import System.Directory | |
import System.FilePath | |
import GHC.Paths ( libdir ) | |
--GHC.Paths is available via cabal install ghc-paths | |
import DynFlags | |
isIrrelavent :: [String] -> Bool | |
isIrrelavent tag@(h:_) = | |
(not $ h `elem` ["GHC", "System", "Main"]) && | |
(not $ tag `elem` [["Control", "Monad", ">>="] | |
,["Control", "Monad", "=<<"]]) | |
isIrrelavent _ = False | |
functionRegex :: String | |
functionRegex = "^[A-Z][^.]*([.][A-Z][^.]*)*[.].+" | |
getFunctionMap :: String -> [String] | |
getFunctionMap inp = | |
getAllTextMatches $ inp =~ funcMapExpression :: [String] | |
where | |
funcMapExpression = "([^.]+)" | |
getUsedFunctions :: String -> [[String]] | |
getUsedFunctions inp = | |
filter isIrrelavent (map getFunctionMap fullFuncs) | |
where | |
fullFuncExpression = "([^[:space:]({[]*[.][^[:space:]);}]*)" | |
fullFuncs = getAllTextMatches $ inp =~ fullFuncExpression :: [String] | |
parseFirstLine :: String -> [[String]] | |
parseFirstLine firstLine = | |
map getFunctionMap unproc | |
where unproc = (getAllTextMatches $ firstLine =~ "[^(--+.*tags=)]([^,]+)*" :: [String]) | |
runOnFileName :: String -> IO ([[String]]) | |
runOnFileName inp = do | |
res <- sanatizeSource inp | |
case res of | |
Just (code, _, _, _) -> return $ nub (getUsedFunctions $ showSDoc (ppr code)) | |
Nothing -> return [[]] | |
sanatizeSourceString :: String -> String -> IO ([[String]]) | |
sanatizeSourceString fn contents = do | |
tmpdir <- getTemporaryDirectory | |
let tmp = tmpdir </> fn ++ ".hs" | |
exists <- doesFileExist tmp | |
unless exists $ writeFile tmp $ contents | |
runOnFileName tmp | |
sanatizeSource :: String -> IO (Maybe RenamedSource) | |
sanatizeSource inp = defaultErrorHandler defaultLogAction $ do | |
runGhc (Just libdir) $ do | |
dflags <- getSessionDynFlags | |
let dflags' = foldl xopt_set dflags | |
[Opt_Cpp, Opt_ImplicitPrelude, Opt_MagicHash] | |
setSessionDynFlags dflags | |
target <- guessTarget inp Nothing | |
setTargets [target] | |
load LoadAllTargets | |
modSum <- getModSummary $ mkModuleName "Main" | |
p <- parseModule modSum | |
t <- typecheckModule p | |
d <- desugarModule t | |
return $ renamedSource d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment