Skip to content

Commit bbf6210

Browse files
committed
Fix logic
Signed-off-by: Arthur Chan <[email protected]>
1 parent bb9408b commit bbf6210

File tree

3 files changed

+346
-142
lines changed

3 files changed

+346
-142
lines changed

frontends/rust/process.py

Lines changed: 32 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -21,59 +21,14 @@
2121
from pathlib import Path
2222
from typing import Dict, List, Tuple
2323

24-
def get_rs_files(project_dir: str) -> List[str]:
25-
"""Recursively find all Rust files in the project directory."""
26-
rs_files = []
27-
for root, _, files in os.walk(project_dir):
28-
for file in files:
29-
if file.endswith(".rs"):
30-
rs_files.append(os.path.join(root, file))
31-
return rs_files
32-
33-
def extract_function_line_info_from_file(file_path: str) -> Dict[Tuple[str, str], Tuple[int, int]]:
34-
"""Extract function names with their start and end line numbers from a Rust file."""
35-
info = {}
36-
pattern = re.compile(r"fn\s+(\w+)\s*\(")
37-
38-
with open(file_path, "r") as f:
39-
lines = f.readlines()
40-
41-
curr_func = None
42-
start = 0
43-
44-
for i, line in enumerate(lines, 1):
45-
match = pattern.search(line)
46-
if match:
47-
if curr_func:
48-
info[(curr_func, file_path)] = (start, i - 1)
49-
50-
curr_func = match.group(1)
51-
start = i
52-
53-
if curr_func:
54-
info[(curr_func, file_path)] = (start, len(lines))
55-
56-
return info
57-
58-
def analyze_project_functions(project_dir: str) -> Dict[Tuple[str, str], Tuple[int, int]]:
59-
"""Analyze all functions in the Rust project and map their line numbers."""
60-
all_functions = {}
61-
rs_files = get_rs_files(project_dir)
62-
63-
for rs_file in rs_files:
64-
functions = extract_function_line_info_from_file(rs_file)
65-
all_functions.update(functions)
66-
67-
return all_functions
68-
6924
def run_rust_analysis(target_directory: str) -> List[Dict]:
7025
"""Run the Rust analysis tool and retrieve JSON results."""
7126
try:
7227
result = subprocess.run(
73-
["cargo", "run", "--", target_directory],
28+
['cargo', 'run', '--', target_directory],
7429
stdout=subprocess.PIPE,
7530
stderr=subprocess.PIPE,
76-
cwd="rust_function_analyser",
31+
cwd='rust_function_analyser',
7732
text=True,
7833
check=True
7934
)
@@ -83,72 +38,55 @@ def run_rust_analysis(target_directory: str) -> List[Dict]:
8338
except ValueError:
8439
return []
8540

86-
def add_line_data(rust_results: List[Dict]):
87-
"""Add line data to functions from rust analysis result."""
88-
line_info = analyze_project_functions(target_dir)
89-
90-
for func in rust_results:
91-
func_key = (func["name"], func["file"])
92-
if func_key in line_info:
93-
func["start_line"], func["end_line"] = line_info[func_key]
94-
else:
95-
func["start_line"], func["end_line"] = 0, 0
96-
func["called_functions"] = [f.replace(" ", "") for f in func["called_functions"]]
97-
98-
def create_yaml_output(data: List[Dict], output_file="data.yaml"):
41+
def create_yaml_output(data: List[Dict], output_file='data.yaml'):
9942
"""Generate a YAML file with the analysis results."""
10043
yaml_data = {
101-
"Fuzzer filename": "",
102-
"All functions": {
103-
"Function list name": "All functions",
104-
"Elements": []
44+
'Fuzzer filename': '',
45+
'All functions': {
46+
'Function list name': 'All functions',
47+
'Elements': []
10548
}
10649
}
10750

10851
for func in data:
109-
yaml_data["All functions"]["Elements"].append({
110-
"functionName": func["name"],
111-
"functionSourceFile": func["file"],
112-
"linkageType": "",
113-
"functionLinenumber": func["start_line"],
114-
"functionLinenumberEnd": func["end_line"],
115-
"functionDepth": func["depth"],
116-
"returnType": func["return_type"],
117-
"argCount": func["arg_count"],
118-
"argTypes": func["arg_types"],
119-
"constantsTouched": [],
120-
"argNames": [],
121-
"BBCount": 0,
122-
"ICount": 0,
123-
"EdgeCount": 0,
124-
"CyclomaticComplexity": func["complexity"],
125-
"functionsReached": func["called_functions"],
126-
"functionUses": 0,
127-
"BranchProfiles": [],
128-
"Callsites": []
52+
yaml_data['All functions']['Elements'].append({
53+
'functionName': func['name'],
54+
'functionSourceFile': func['file'],
55+
'linkageType': '',
56+
'functionLinenumber': func.get('start_line', 0),
57+
'functionLinenumberEnd': func.get('end_line', 0),
58+
'functionDepth': func['depth'],
59+
'returnType': func['return_type'],
60+
'argCount': func['arg_count'],
61+
'argTypes': func['arg_types'],
62+
'constantsTouched': [],
63+
'argNames': [],
64+
'BBCount': func['bbcount'],
65+
'iCount': func['icount'],
66+
'EdgeCount': func['edge_count'],
67+
'CyclomaticComplexity': func['complexity'],
68+
'functionsReached': func['called_functions'],
69+
'functionUses': func['function_uses'],
70+
'BranchProfiles': func['branch_profiles'],
71+
'Callsites': []
12972
})
13073

131-
with open(output_file, "w") as file:
74+
with open(output_file, 'w') as file:
13275
yaml.dump(yaml_data, file, default_flow_style=False)
13376

134-
print(f"YAML output saved to {output_file}")
77+
print(f'YAML output saved to {output_file}')
13578

136-
if __name__ == "__main__":
79+
if __name__ == '__main__':
13780
if len(sys.argv) != 2:
138-
print("Usage: python3 script.py <target_directory>")
81+
print('Usage: python3 script.py <target_directory>')
13982
sys.exit(1)
14083

14184
target_dir = sys.argv[1]
14285
if not Path(target_dir).is_dir():
143-
print(f"Error: {target_dir} is not a valid directory")
86+
print(f'Error: {target_dir} is not a valid directory')
14487
sys.exit(1)
14588

14689
# Run the rust analysis frontend code
14790
rust_analysis_results = run_rust_analysis(target_dir)
14891

149-
# Manually extract the line info for each function.
150-
# This is needed because the rust analysis syn AST approach
151-
# cannot retrieve line number info on stable rust and non-nightly build
152-
add_line_data(rust_analysis_results)
153-
15492
create_yaml_output(rust_analysis_results)

frontends/rust/rust_function_analyser/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ quote = "1.0"
99
walkdir = "2.4"
1010
serde = { version = "1.0", features = ["derive"] }
1111
serde_json = "1.0"
12+
proc-macro2 = { version = "1.0", features = ["span-locations"] }

0 commit comments

Comments
 (0)