-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJavaParser.py
More file actions
94 lines (73 loc) · 3.04 KB
/
JavaParser.py
File metadata and controls
94 lines (73 loc) · 3.04 KB
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
import javalang
from pathlib import Path
class JavaParser:
def __init__(self, path):
self.path = Path(path)
def parse(self):
java_files = self._collect_files()
results = {}
for file in java_files:
try:
results[str(file)] = self._parse_file(file)
except Exception as e:
results[str(file)] = f"Error parsing file: {e}"
return results
def _collect_files(self):
if self.path.is_file() and self.path.suffix == ".java":
return [self.path]
elif self.path.is_dir():
return list(self.path.rglob("*.java"))
return []
def _parse_file(self, file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
tree = javalang.parse.parse(content)
classes = []
# Classes
for _, node in tree.filter(javalang.tree.ClassDeclaration):
classes.append(self._extract_class(node, "Class"))
# Interfaces
for _, node in tree.filter(javalang.tree.InterfaceDeclaration):
classes.append(self._extract_class(node, "Interface"))
return classes
def _extract_class(self, node, kind):
class_info = {
"type": kind,
"name": node.name,
"access": self._get_access_modifier(node.modifiers),
"extends": node.extends.name if node.extends else None,
"implements": [i.name for i in node.implements] if node.implements else [],
"fields": [],
"methods": []
}
# Fields with access
for field in node.fields:
access = self._get_access_modifier(field.modifiers)
for decl in field.declarators:
class_info["fields"].append({"name": decl.name, "access": access})
# Methods with access
for method in node.methods:
access = self._get_access_modifier(method.modifiers)
class_info["methods"].append({"name": method.name, "access": access})
return class_info
def _get_access_modifier(self, modifiers):
"""Return first access modifier or 'package-private' if none"""
return " ".join(modifiers)
def print_results(self, results):
for file, classes in results.items():
print(f"\nFile: {file}")
if isinstance(classes, str):
print(f" {classes}")
continue
for cls in classes:
print(f" {cls['type']}: {cls['name']} ({cls['access']})")
if cls['extends']:
print(f" Extends: {cls['extends']}")
if cls['implements']:
print(f" Implements: {', '.join(cls['implements'])}")
print(" Fields:")
for field in cls["fields"]:
print(f" - {field['name']} ({field['access']})")
print(" Methods:")
for method in cls["methods"]:
print(f" - {method['name']} ({method['access']})")