Skip to content

Commit d3f3ed6

Browse files
authored
Merge pull request #23 from IBM/symbol-table-call-graph
Symbol table call graph
2 parents c57ffc0 + 0592b8c commit d3f3ed6

File tree

16 files changed

+1615
-111709
lines changed

16 files changed

+1615
-111709
lines changed

cldk/analysis/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
from .program_dependence_graph import ProgramDependenceGraph
44
from .system_dependence_graph import SystemDependenceGraph
55
from .symbol_table import SymbolTable
6+
from .analysis_level import AnalysisLevel
67

7-
__all__ = ["CallGraph", "ProgramDependenceGraph", "SystemDependenceGraph", "SymbolTable"]
8+
__all__ = ["CallGraph", "ProgramDependenceGraph", "SystemDependenceGraph", "SymbolTable", "AnalysisLevel"]

cldk/analysis/analysis_level.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from enum import Enum
2+
3+
4+
class AnalysisLevel(str, Enum):
5+
"""Analysis levels"""
6+
symbol_table = "symbol-table"
7+
call_graph = "call-graph"
8+
program_dependency_graph = "program-dependency-graph"
9+
system_dependency_graph = "system-dependency-graph"

cldk/analysis/java/codeanalyzer/codeanalyzer.py

Lines changed: 284 additions & 32 deletions
Large diffs are not rendered by default.

cldk/analysis/java/java.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Dict, List, Tuple, Set
44
from networkx import DiGraph
55

6-
from cldk.analysis import SymbolTable, CallGraph
6+
from cldk.analysis import SymbolTable, CallGraph, AnalysisLevel
77
from cldk.models.java import JCallable
88
from cldk.models.java import JApplication
99
from cldk.models.java.models import JCompilationUnit, JMethodDetail, JType, JField
@@ -157,7 +157,8 @@ def get_call_graph_json(self) -> str:
157157
raise NotImplementedError("Producing a call graph over a single file is not implemented yet.")
158158
return self.backend.get_call_graph_json()
159159

160-
def get_callers(self, target_class_name: str, target_method_declaration: str):
160+
def get_callers(self, target_class_name: str, target_method_declaration: str,
161+
using_symbol_table: bool = False) -> Dict:
161162
"""
162163
Get all the caller details for a given java method.
163164
@@ -168,7 +169,7 @@ def get_callers(self, target_class_name: str, target_method_declaration: str):
168169
"""
169170
if self.source_code:
170171
raise NotImplementedError("Generating all callers over a single file is not implemented yet.")
171-
return self.backend.get_all_callers(target_class_name, target_method_declaration)
172+
return self.backend.get_all_callers(target_class_name, target_method_declaration, using_symbol_table)
172173

173174
def get_callees(self, source_class_name: str, source_method_declaration: str):
174175
"""
@@ -437,25 +438,50 @@ def get_implemented_interfaces(self, qualified_class_name) -> List[str]:
437438
raise NotImplementedError(f"Support for this functionality has not been implemented yet.")
438439
return self.backend.get_implemented_interfaces(qualified_class_name)
439440

440-
def get_class_call_graph(self, qualified_class_name: str, method_name: str | None = None) -> (List)[Tuple[JMethodDetail, JMethodDetail]]:
441+
def __get_class_call_graph_using_symbol_table(self, qualified_class_name: str, method_signature: str | None = None) -> (List)[Tuple[JMethodDetail, JMethodDetail]]:
442+
"""
443+
A call graph using symbol table for a given class and a given method.
444+
Args:
445+
qualified_class_name:
446+
method_signature:
447+
448+
Returns:
449+
List[Tuple[JMethodDetail, JMethodDetail]]
450+
An edge list of the call graph for the given class and method.
451+
"""
452+
if self.analysis_backend in [AnalysisEngine.CODEQL, AnalysisEngine.TREESITTER]:
453+
raise NotImplementedError(f"Support for this functionality has not been implemented yet.")
454+
return self.backend.get_class_call_graph_using_symbol_table(qualified_class_name, method_signature)
455+
456+
def get_class_call_graph(self, qualified_class_name: str, method_signature: str | None = None,
457+
using_symbol_table: bool = False) -> List[Tuple[JMethodDetail, JMethodDetail]]:
441458
"""
442459
A call graph for a given class and (optionally) a given method.
443460
444461
Parameters
445462
----------
463+
using_symbol_table: bool
464+
Generate call graph using symbol table
446465
qualified_class_name : str
447466
The qualified name of the class.
448467
method_name : str, optional
449-
The name of the method in the class.
468+
The signature of the method in the class.
450469
451470
Returns
452471
-------
453472
List[Tuple[JMethodDetail, JMethodDetail]]
454473
An edge list of the call graph for the given class and method.
474+
475+
Args:
476+
using_symbol_table:
477+
using_symbol_table:
455478
"""
479+
if using_symbol_table:
480+
return self.__get_class_call_graph_using_symbol_table(qualified_class_name=qualified_class_name,
481+
method_signature=method_signature)
456482
if self.analysis_backend in [AnalysisEngine.CODEQL, AnalysisEngine.TREESITTER]:
457483
raise NotImplementedError(f"Support for this functionality has not been implemented yet.")
458-
return self.backend.get_class_call_graph(qualified_class_name, method_name)
484+
return self.backend.get_class_call_graph(qualified_class_name, method_signature)
459485

460486
def get_entry_point_classes(self) -> Dict[str, JType]:
461487
"""

cldk/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def treesitter_parser(self):
114114
else:
115115
raise NotImplementedError(f"Treesitter parser for {self.language} is not implemented yet.")
116116

117-
def tree_sitter_utils(self, source_code: str):
117+
def tree_sitter_utils(self, source_code: str) -> [TreesitterSanitizer| NotImplementedError]:
118118
"""
119119
Parse the project using treesitter.
120120

cldk/models/java/models.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ class JCallSite(BaseModel):
103103
return_type: str = ""
104104
callee_signature: str = ""
105105
is_static_call: bool
106-
is_private: bool
107-
is_public: bool
108-
is_protected: bool
109-
is_unspecified: bool
106+
is_private: bool
107+
is_public: bool
108+
is_protected: bool
109+
is_unspecified: bool
110110
is_constructor_call: bool
111111
start_line: int
112112
start_column: int
@@ -356,6 +356,15 @@ def __hash__(self):
356356
return hash(tuple(self))
357357

358358

359+
class JGraphEdgesST(BaseModel):
360+
source: JMethodDetail
361+
target: JMethodDetail
362+
type: str
363+
weight: str
364+
source_kind: str | None = None
365+
destination_kind: str | None = None
366+
367+
359368
class JGraphEdges(BaseModel):
360369
source: JMethodDetail
361370
target: JMethodDetail

0 commit comments

Comments
 (0)