Skip to content

Commit 0c8ea06

Browse files
committed
Add additional symbol table features!
Signed-off-by: Rahul Krishna <i.m.ralk@gmail.com>
1 parent 007e360 commit 0c8ea06

File tree

4 files changed

+707
-46
lines changed

4 files changed

+707
-46
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ requires-python = ">=3.12"
1010

1111
dependencies = [
1212
"asteroid>=0.7.0",
13+
"astor>=0.8.1",
1314
"jedi>=0.19.2",
1415
"loguru>=0.7.3",
1516
"networkx>=3.5",

src/codeanalyzer/schema/py_schema.py

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
def builder(cls):
3131
"""
3232
Decorator that generates a builder class for a Pydantic models defined below.
33-
33+
3434
It creates methods like:
3535
- with_<fieldname>(value)
3636
- build() to instantiate the model
@@ -60,17 +60,20 @@ def __init__(self):
6060

6161
namespace["__init__"] = __init__
6262

63-
# Iterate over all fields in the model and create a method for each field that sets the value and returns the builder instance.
63+
# Iterate over all fields in the model and create a method for each field that sets the value and returns the builder instance.
6464
# This allows for method chaining. The method name will be "<fieldname>".
6565
for field, field_type in annotations.items():
66+
6667
def make_method(f=field, t=field_type):
6768
def method(self, value):
6869
setattr(self, f"_{f}", value)
6970
return self
71+
7072
method.__name__ = f"{f}"
7173
method.__annotations__ = {"value": t, "return": builder_name}
7274
method.__doc__ = f"Set {f} ({t.__name__})"
7375
return method
76+
7477
namespace[f"{field}"] = make_method()
7578

7679
# Create a build method that constructs the model instance using the values set in the builder.
@@ -86,6 +89,7 @@ def build(self):
8689
setattr(cls, "builder", builder_cls)
8790
return cls
8891

92+
8993
@builder
9094
class PyImport(BaseModel):
9195
"""Represents a Python import statement.
@@ -116,6 +120,7 @@ class PyImport(BaseModel):
116120
start_column: int = -1
117121
end_column: int = -1
118122

123+
119124
@builder
120125
class PyComment(BaseModel):
121126
"""
@@ -137,6 +142,31 @@ class PyComment(BaseModel):
137142
end_column: int = -1
138143
is_docstring: bool = False
139144

145+
@builder
146+
class PySymbol(BaseModel):
147+
"""
148+
Represents a symbol used or declared in Python code.
149+
150+
Attributes:
151+
name (str): The name of the symbol (e.g., 'x', 'self.x', 'os.path').
152+
scope (Literal['local', 'nonlocal', 'global', 'class', 'module']): The scope where the symbol is accessed.
153+
kind (Literal['variable', 'parameter', 'attribute', 'function', 'class', 'module']): The kind of symbol.
154+
type (Optional[str]): Inferred or annotated type, if available.
155+
qualified_name (Optional[str]): Fully qualified name (e.g., 'self.x', 'os.path.join').
156+
is_builtin (bool): Whether this is a Python builtin.
157+
lineno (int): Line number where the symbol is accessed or declared.
158+
col_offset (int): Column offset.
159+
"""
160+
name: str
161+
scope: Literal['local', 'nonlocal', 'global', 'class', 'module']
162+
kind: Literal['variable', 'parameter', 'attribute', 'function', 'class', 'module']
163+
type: Optional[str] = None
164+
qualified_name: Optional[str] = None
165+
is_builtin: bool = False
166+
lineno: int = -1
167+
col_offset: int = -1
168+
169+
140170
@builder
141171
class PyVariableDeclaration(BaseModel):
142172
"""Represents a Python variable declaration.
@@ -154,6 +184,7 @@ class PyVariableDeclaration(BaseModel):
154184
start_column: int = -1
155185
end_column: int = -1
156186

187+
157188
@builder
158189
class PyCallableParameter(BaseModel):
159190
"""Represents a parameter of a Python callable (function/method).
@@ -176,6 +207,28 @@ class PyCallableParameter(BaseModel):
176207
start_column: int = -1
177208
end_column: int = -1
178209

210+
@builder
211+
class PyCallsite(BaseModel):
212+
"""
213+
Represents a Python call site (function or method invocation) with contextual metadata.
214+
"""
215+
method_name: str
216+
receiver_expr: Optional[str] = None
217+
receiver_type: Optional[str] = None
218+
argument_types: List[str] = []
219+
return_type: Optional[str] = None
220+
callee_signature: Optional[str] = None
221+
is_public: bool = False
222+
is_protected: bool = False
223+
is_private: bool = False
224+
is_unspecified: bool = False
225+
is_static_call: bool = False
226+
is_constructor_call: bool = False
227+
start_line: int = -1
228+
start_column: int = -1
229+
end_line: int = -1
230+
end_column: int = -1
231+
179232
@builder
180233
class PyCallable(BaseModel):
181234
"""Represents a Python callable (function/method).
@@ -208,16 +261,16 @@ class PyCallable(BaseModel):
208261
start_line: int = -1
209262
end_line: int = -1
210263
code_start_line: int = -1
211-
accessed_symbols: List[str] = []
212-
call_sites: List[str] = []
213-
is_entrypoint: bool = False
264+
accessed_symbols: List[PySymbol] = []
265+
call_sites: List[PyCallsite] = []
214266
local_variables: List[PyVariableDeclaration] = []
215267
cyclomatic_complexity: int = 0
216268

217269
def __hash__(self) -> int:
218270
"""Generate a hash based on the callable's signature."""
219271
return hash(self.signature)
220272

273+
221274
@builder
222275
class PyClassAttribute(BaseModel):
223276
"""Represents a Python class attribute.
@@ -236,6 +289,7 @@ class PyClassAttribute(BaseModel):
236289
start_line: int = -1
237290
end_line: int = -1
238291

292+
239293
@builder
240294
class PyClass(BaseModel):
241295
"""Represents a Python class.
@@ -255,6 +309,7 @@ class PyClass(BaseModel):
255309
name: str
256310
signature: str # e.g., module.class_name
257311
docstring: PyComment = None
312+
code: str = None
258313
base_classes: List[str] = []
259314
methods: Dict[str, PyCallable] = {}
260315
attributes: Dict[str, PyClassAttribute] = {}
@@ -266,6 +321,7 @@ def __hash__(self):
266321
"""Generate a hash based on the class's signature."""
267322
return hash(self.signature)
268323

324+
269325
@builder
270326
class PyModule(BaseModel):
271327
"""Represents a Python module.
@@ -288,6 +344,7 @@ class PyModule(BaseModel):
288344
functions: Dict[str, PyCallable] = {}
289345
variables: List[PyVariableDeclaration] = []
290346

347+
291348
@builder
292349
class PyApplication(BaseModel):
293350
"""Represents a Python application.

0 commit comments

Comments
 (0)