~ubuntu-branches/ubuntu/precise/haskell-language-haskell-extract/precise

« back to all changes in this revision

Viewing changes to src/Language/Haskell/Extract.hs

  • Committer: Package Import Robot
  • Author(s): Kiwamu Okabe
  • Date: 2011-11-02 15:02:25 UTC
  • Revision ID: package-import@ubuntu.com-20111102150225-0zpkow88c46ni340
Tags: upstream-0.2.1
ImportĀ upstreamĀ versionĀ 0.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module Language.Haskell.Extract (
 
2
  functionExtractor,
 
3
  functionExtractorMap,
 
4
  locationModule
 
5
) where
 
6
import Language.Haskell.TH
 
7
import Language.Haskell.Exts.Parser
 
8
import Language.Haskell.Exts (parseFileContentsWithMode)
 
9
import Language.Haskell.Exts.Syntax
 
10
import Text.Regex.Posix
 
11
import Data.Maybe
 
12
import Data.List
 
13
import Language.Haskell.Exts.Extension
 
14
 
 
15
extractAllFunctions :: String -> String-> [String]
 
16
extractAllFunctions pattern file  = 
 
17
--  allMatchingFunctions pattern . parsedModule
 
18
  nub $ filter (\f->f=~pattern::Bool) $ map (fst . head . lex) $ lines file
 
19
 
 
20
-- nub $ filter ("prop_" `isPrefixOf`) $
 
21
-- map (fst . head . lex) $ lines ct
 
22
 
 
23
 
 
24
parsedModule moduleCode = 
 
25
  let pMod = parseFileContentsWithMode (defaultParseMode { extensions = knownExtensions } ) moduleCode
 
26
      moduleOrDefault (ParseFailed _ _) = Module (SrcLoc "unknown" 1 1) (ModuleName "unknown") [] Nothing Nothing [] []
 
27
      moduleOrDefault (ParseOk m) = m
 
28
  in moduleOrDefault pMod 
 
29
 
 
30
allFunctions =  onlyJust extractNameOfFunctionFromDecl . hsModuleDecls 
 
31
allMatchingFunctions pattern = filter (\f->f=~pattern::Bool) . allFunctions 
 
32
 
 
33
 
 
34
 
 
35
extractNameOfFunctionFromDecl :: Decl -> Maybe String
 
36
extractNameOfFunctionFromDecl (PatBind _ (PVar (Ident n)) _ _ _ ) = Just n
 
37
extractNameOfFunctionFromDecl (FunBind ms) = Just $ head $ [n | (Language.Haskell.Exts.Syntax.Match _ (Ident n) _ _ _ _)  <- ms]
 
38
extractNameOfFunctionFromDecl _ = Nothing
 
39
 
 
40
onlyJust f = map fromJust . filter isJust . map f
 
41
 
 
42
hsModuleDecls (Module _ _ _ _ _ _ d) = d
 
43
 
 
44
-- | Extract the names and functions from the module where this function is called.
 
45
-- 
 
46
--  > foo = "test"
 
47
--  > boo = "testing"
 
48
--  > bar = $(functionExtractor "oo$")
 
49
-- 
 
50
-- will automagically extract the functions ending with "oo" such as
 
51
-- 
 
52
-- > bar = [("foo",foo), ("boo",boo)]
 
53
functionExtractor :: String -> ExpQ
 
54
functionExtractor pattern =
 
55
  do loc <- location
 
56
     moduleCode <- runIO $ readFile $ loc_filename loc
 
57
     let functions = extractAllFunctions pattern moduleCode
 
58
         makePair n = TupE [ LitE $ StringL n , VarE $ mkName n]
 
59
     return $ ListE $ map makePair functions
 
60
 
 
61
 
 
62
-- functionExtractor' :: String -> Q [String]
 
63
-- functionExtractor' pattern =
 
64
--   do loc <- location
 
65
--      moduleCode <- runIO $ readFile $ loc_filename loc
 
66
--      let functions = extractAllFunctions pattern moduleCode
 
67
--      return functions
 
68
 
 
69
-- | Extract the names and functions from the module and apply a function to every pair.
 
70
-- 
 
71
-- Is very useful if the common denominator of the functions is just a type class.
 
72
--
 
73
-- > secondTypeclassTest =
 
74
-- >   do let expected = ["45", "88.8", "\"hej\""]
 
75
-- >          actual = $(functionExtractorMap "^tc" [|\n f -> show f|] )
 
76
-- >      expected @=? actual
 
77
-- > 
 
78
-- > tcInt :: Integer
 
79
-- > tcInt = 45
 
80
-- > 
 
81
-- > tcDouble :: Double
 
82
-- > tcDouble = 88.8
 
83
-- > 
 
84
-- > tcString :: String
 
85
-- > tcString = "hej"
 
86
functionExtractorMap :: String -> ExpQ -> ExpQ
 
87
functionExtractorMap pattern funcName =
 
88
  do loc <- location
 
89
     moduleCode <- runIO $ readFile $ loc_filename loc
 
90
     let functions :: [String]
 
91
         functions = extractAllFunctions pattern moduleCode
 
92
     fn <- funcName
 
93
     let makePair n = AppE (AppE (fn) (LitE $ StringL n)) (VarE $ mkName n)
 
94
     return $ ListE $ map makePair functions 
 
95
 
 
96
-- functionExtractorExpMap :: String -> (Exp -> ExpQ) -> ExpQ
 
97
-- functionExtractorExpMap pattern func =
 
98
--   do loc <- location
 
99
--      moduleCode <- runIO $ readFile $ loc_filename loc
 
100
--      let functions :: [String]
 
101
--          functions = extractAllFunctions pattern moduleCode
 
102
--      fn <- funcName
 
103
--      let makePair n = AppE (AppE (fn) (LitE $ StringL n)) (VarE $ mkName n)
 
104
--      return $ ListE $ map makePair functions   
 
105
 
 
106
-- | Extract the name of the current module.
 
107
locationModule :: ExpQ
 
108
locationModule =
 
109
  do loc <- location
 
110
     return $ LitE $ StringL $ loc_module loc