diff --git a/api/analyzers/source_analyzer.py b/api/analyzers/source_analyzer.py index 12502ab..4e1385b 100644 --- a/api/analyzers/source_analyzer.py +++ b/api/analyzers/source_analyzer.py @@ -143,20 +143,23 @@ def second_pass(self, graph: Graph, files: list[Path], path: Path) -> None: logging.info(f'Processing file ({i + 1}/{files_len}): {file_path}') for _, entity in file.entities.items(): entity.resolved_symbol(lambda key, symbol: analyzers[file_path.suffix].resolve_symbol(self.files, lsps[file_path.suffix], file_path, path, key, symbol)) - for key, symbols in entity.resolved_symbols.items(): + for key, symbols in entity.symbols.items(): for symbol in symbols: + if len(symbol.resolved_symbol) == 0: + continue + resolved_symbol = next(iter(symbol.resolved_symbol)) if key == "base_class": - graph.connect_entities("EXTENDS", entity.id, symbol.id) + graph.connect_entities("EXTENDS", entity.id, resolved_symbol.id) elif key == "implement_interface": - graph.connect_entities("IMPLEMENTS", entity.id, symbol.id) + graph.connect_entities("IMPLEMENTS", entity.id, resolved_symbol.id) elif key == "extend_interface": - graph.connect_entities("EXTENDS", entity.id, symbol.id) + graph.connect_entities("EXTENDS", entity.id, resolved_symbol.id) elif key == "call": - graph.connect_entities("CALLS", entity.id, symbol.id) + graph.connect_entities("CALLS", entity.id, resolved_symbol.id, {"line": symbol.symbol.start_point.row, "text": symbol.symbol.text.decode("utf-8")}) elif key == "return_type": - graph.connect_entities("RETURNS", entity.id, symbol.id) + graph.connect_entities("RETURNS", entity.id, resolved_symbol.id) elif key == "parameters": - graph.connect_entities("PARAMETERS", entity.id, symbol.id) + graph.connect_entities("PARAMETERS", entity.id, resolved_symbol.id) def analyze_files(self, files: list[Path], path: Path, graph: Graph) -> None: self.first_pass(path, files, [], graph) diff --git a/api/entities/entity.py b/api/entities/entity.py index e271693..77f1cc9 100644 --- a/api/entities/entity.py +++ b/api/entities/entity.py @@ -1,23 +1,24 @@ from typing import Callable, Self from tree_sitter import Node +class Symbol: + def __init__(self, symbol: Node): + self.symbol = symbol + self.resolved_symbol = set() + + def add_resolve_symbol(self, resolved_symbol): + self.resolved_symbol.add(resolved_symbol) class Entity: def __init__(self, node: Node): self.node = node - self.symbols: dict[str, list[Node]] = {} - self.resolved_symbols: dict[str, set[Self]] = {} + self.symbols: dict[str, list[Symbol]] = {} self.children: dict[Node, Self] = {} def add_symbol(self, key: str, symbol: Node): if key not in self.symbols: self.symbols[key] = [] - self.symbols[key].append(symbol) - - def add_resolved_symbol(self, key: str, symbol: Self): - if key not in self.resolved_symbols: - self.resolved_symbols[key] = set() - self.resolved_symbols[key].add(symbol) + self.symbols[key].append(Symbol(symbol)) def add_child(self, child: Self): child.parent = self @@ -25,7 +26,6 @@ def add_child(self, child: Self): def resolved_symbol(self, f: Callable[[str, Node], list[Self]]): for key, symbols in self.symbols.items(): - self.resolved_symbols[key] = set() for symbol in symbols: - for resolved_symbol in f(key, symbol): - self.resolved_symbols[key].add(resolved_symbol) \ No newline at end of file + for resolved_symbol in f(key, symbol.symbol): + symbol.add_resolve_symbol(resolved_symbol) \ No newline at end of file diff --git a/api/graph.py b/api/graph.py index 7c91405..a9aa57f 100644 --- a/api/graph.py +++ b/api/graph.py @@ -479,7 +479,7 @@ def set_file_coverage(self, path: str, name: str, ext: str, coverage: float) -> res = self._query(q, params) - def connect_entities(self, relation: str, src_id: int, dest_id: int) -> None: + def connect_entities(self, relation: str, src_id: int, dest_id: int, properties: dict = {}) -> None: """ Establish a relationship between src and dest @@ -491,9 +491,10 @@ def connect_entities(self, relation: str, src_id: int, dest_id: int) -> None: q = f"""MATCH (src), (dest) WHERE ID(src) = $src_id AND ID(dest) = $dest_id MERGE (src)-[e:{relation}]->(dest) + SET e += $properties RETURN e""" - params = {'src_id': src_id, 'dest_id': dest_id} + params = {'src_id': src_id, 'dest_id': dest_id, "properties": properties} self._query(q, params) def function_calls_function(self, caller_id: int, callee_id: int, pos: int) -> None: