9
9
@dataclass
10
10
class Parameter :
11
11
"""Function parameter representation."""
12
+
12
13
name : str
13
14
type : str
14
15
15
16
16
17
@dataclass
17
18
class Function :
18
19
"""Vyper function representation."""
20
+
19
21
name : str
20
22
params : List [Parameter ]
21
23
return_type : Optional [str ]
@@ -25,6 +27,7 @@ class Function:
25
27
@dataclass
26
28
class Contract :
27
29
"""Vyper contract representation."""
30
+
28
31
name : str
29
32
path : str
30
33
docstring : Optional [str ]
@@ -42,27 +45,29 @@ def parse_contracts(self) -> List[Contract]:
42
45
contracts = []
43
46
for root , _ , files in os .walk (self .contracts_dir ):
44
47
for file in files :
45
- if file .endswith (' .vy' ):
48
+ if file .endswith (" .vy" ):
46
49
file_path = os .path .join (root , file )
47
50
contract = self ._parse_contract (file_path )
48
51
contracts .append (contract )
49
52
return contracts
50
53
51
54
def _parse_contract (self , file_path : str ) -> Contract :
52
55
"""Parse a single Vyper contract file."""
53
- with open (file_path , 'r' , encoding = ' utf-8' ) as f :
56
+ with open (file_path , "r" , encoding = " utf-8" ) as f :
54
57
content = f .read ()
55
58
56
- name = os .path .basename (file_path ).replace (' .vy' , '' )
59
+ name = os .path .basename (file_path ).replace (" .vy" , "" )
57
60
rel_path = os .path .relpath (file_path , self .contracts_dir )
58
-
61
+
59
62
# Extract contract docstring
60
63
docstring = self ._extract_contract_docstring (content )
61
-
64
+
62
65
# Extract functions
63
66
functions = self ._extract_functions (content )
64
-
65
- return Contract (name = name , path = rel_path , docstring = docstring , functions = functions )
67
+
68
+ return Contract (
69
+ name = name , path = rel_path , docstring = docstring , functions = functions
70
+ )
66
71
67
72
def _extract_contract_docstring (self , content : str ) -> Optional [str ]:
68
73
"""Extract the contract's main docstring."""
@@ -72,27 +77,38 @@ def _extract_contract_docstring(self, content: str) -> Optional[str]:
72
77
def _extract_functions (self , content : str ) -> List [Function ]:
73
78
"""Extract all functions from the contract."""
74
79
functions = []
75
- function_pattern = r'@external\s+def\s+([^(]+)\(([^)]*)\)(\s*->\s*[^:]+)?:\s*("""[\s\S]*?""")?'
76
-
80
+ function_pattern = (
81
+ r'@external\s+def\s+([^(]+)\(([^)]*)\)(\s*->\s*[^:]+)?:\s*("""[\s\S]*?""")?'
82
+ )
83
+
77
84
for match in re .finditer (function_pattern , content ):
78
85
name = match .group (1 ).strip ()
79
86
params_str = match .group (2 ).strip ()
80
- return_type = match .group (3 ).replace ('->' , '' ).strip () if match .group (3 ) else None
87
+ return_type = (
88
+ match .group (3 ).replace ("->" , "" ).strip () if match .group (3 ) else None
89
+ )
81
90
docstring = match .group (4 )[3 :- 3 ].strip () if match .group (4 ) else None
82
-
91
+
83
92
params = self ._parse_params (params_str )
84
- functions .append (Function (name = name , params = params , return_type = return_type , docstring = docstring ))
85
-
93
+ functions .append (
94
+ Function (
95
+ name = name ,
96
+ params = params ,
97
+ return_type = return_type ,
98
+ docstring = docstring ,
99
+ )
100
+ )
101
+
86
102
return functions
87
103
88
104
def _parse_params (self , params_str : str ) -> List [Parameter ]:
89
105
"""Parse function parameters."""
90
106
if not params_str :
91
107
return []
92
-
108
+
93
109
params = []
94
- for param in params_str .split (',' ):
95
- if ':' in param :
96
- name , type_str = param .split (':' )
110
+ for param in params_str .split ("," ):
111
+ if ":" in param :
112
+ name , type_str = param .split (":" )
97
113
params .append (Parameter (name = name .strip (), type = type_str .strip ()))
98
114
return params
0 commit comments