-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExtractTypeSignature.hs
113 lines (95 loc) · 3.95 KB
/
ExtractTypeSignature.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module ExtractTypeSignature where
import System.Environment
import Control.Monad.IO.Class
import Data.Char
import Text.Regex
import Text.Regex.Posix
import Data.Map (Map)
type Document = [String]
type TypeSignature = String
data Scope = EmptyScope
| Class String [Scope]
| Module String [Scope]
| Method String TypeSignature deriving (Show, Eq)
type Wait = String
-- head contexts is the current Context
-- as encounter Wait, tail contexts
-- Wait is "end" in most cases
type Context = Map Scope Wait
type Contexts = [Context]
extractTypeSignature :: String -> String -> Maybe String
extractTypeSignature ptn str = case typeSignatureMatch ptn str of
Just v -> Just $ toDoc v
Nothing -> Nothing
toDoc :: String -> String
toDoc str = subRegex (mkRegex "=>")
(subRegex (mkRegex ",")
(subRegex (mkRegex "\\[")
(subRegex (mkRegex "\\]")
(subRegex (mkRegex ":") str
" ::") "") "") " ->") "->"
scopeToDoc :: Scope -> String
scopeToDoc (Class klass scopes) = unlines $ map (\x -> (klass ++ scopeToDoc x)) scopes
scopeToDoc (Module mdl scopes) = unlines $ map (\x -> (mdl ++ scopeToDoc x)) scopes
scopeToDoc (Method meth typesig) = "#" ++ meth ++ " :: " ++ typesig
--
-- EmptyScope
-- Class className [EmptyScope]
-- Class className [Method name typesig, Method name typesig ...]
--
toScopeList :: Scope -> [Scope]
toScopeList s = filter (\x -> x /= EmptyScope) $ replicate 1 s
walk :: [String] -> Scope
walk = foldl accum EmptyScope
accum :: Scope -> String -> Scope
accum EmptyScope str = mkScope str
accum (Class x [EmptyScope]) str = Class x $ toScopeList $ accum EmptyScope str
accum (Module x [EmptyScope]) str = Class x $ toScopeList $ accum EmptyScope str
accum (Class x s) str = Class x (s ++ (toScopeList $ accum EmptyScope str))
accum (Module x s) str = Module x (s ++ (toScopeList $ accum EmptyScope str))
encounterClass :: String -> Bool
encounterClass str = str =~ "class" :: Bool
encounterModule :: String -> Bool
encounterModule str = str =~ "module" :: Bool
encounterMethod :: String -> Bool
encounterMethod str = str =~ "typesig" :: Bool
mkScope :: String -> Scope
mkScope str
| encounterClass str = mkClassScope str
| encounterModule str = mkModuleScope str
| encounterMethod str = mkMethodScope str
-- any line with no class, module and typesig
| otherwise = EmptyScope
mkClassScope :: String -> Scope
mkClassScope str = Class (getClassName str) [EmptyScope]
mkModuleScope :: String -> Scope
mkModuleScope str = Module (getModuleName str) [EmptyScope]
mkMethodScope :: String -> Scope
mkMethodScope str = Method (getMethodName str) (getMethodTypesignature str)
getClassName :: String -> String
getClassName str = case str =~ "class " :: (String, String, String) of
(_, _, klass) -> klass
getModuleName :: String -> String
getModuleName str = case str =~ "module " :: (String, String, String) of
(_, _, mdl) -> mdl
getMethodName :: String -> String
getMethodName str = case str =~ "(?<==)(.*)(?=:)" :: (String, String, String) of
(_, name, _) -> name
getMethodTypesignature :: String -> String
getMethodTypesignature str = case str =~ ": " :: (String, String, String) of
(_, _, sig) -> toDoc sig
typeSignatureMatch :: String -> String -> Maybe String
typeSignatureMatch ptn str = case matchRegexAll (mkRegex ptn) str of
Just (_, _, v, _) -> Just v
Nothing -> Nothing
compactMaybe :: [Maybe a] -> [a]
compactMaybe [] = []
compactMaybe (x:xs) = case x of
Just v -> [v] ++ compactMaybe xs
Nothing -> compactMaybe xs
extractTypeSignatures :: String -> [String] -> [String]
extractTypeSignatures ptn strs = compactMaybe (map (\x -> (extractTypeSignature ptn x)) strs)
extractTypeSignatureWithSpecifiedPattern :: String -> (String -> Maybe String)
extractTypeSignatureWithSpecifiedPattern = extractTypeSignature
typeSignaturePattern1 :: String
typeSignaturePattern1 = "typesig "