Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions cldk/analysis/java/backend.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -76,8 +76,8 @@ def get_compilation_units(self) -> List[JCompilationUnit]:
"""All compilation units."""

@abstractmethod
def get_java_file(self, qualified_class_name: str) -> str:
"""The file path declaring a class."""
def get_java_file(self, qualified_class_name: str) -> str | None:
"""The file path declaring a class. ``None`` if the class is not found."""

@abstractmethod
def get_java_compilation_unit(self, file_path: str) -> JCompilationUnit:
Expand DownExpand Up@@ -114,8 +114,8 @@ def get_all_classes(self) -> Dict[str, JType]:
"""Every class, keyed by qualified name."""

@abstractmethod
def get_class(self, qualified_class_name: str) -> JType:
"""A single class by qualified name."""
def get_class(self, qualified_class_name: str) -> JType | None:
"""A single class by qualified name. ``None`` if not found."""

@abstractmethod
def get_all_sub_classes(self, qualified_class_name: str) -> Dict[str, JType]:
Expand All@@ -142,12 +142,12 @@ def get_all_methods_in_class(self, qualified_class_name: str) -> Dict[str, JCall
"""The methods of a class."""

@abstractmethod
def get_method(self, qualified_class_name: str, method_signature: str) -> JCallable:
"""A single method of a class."""
def get_method(self, qualified_class_name: str, method_signature: str) -> JCallable | None:
"""A single method of a class. ``None`` if not found."""

@abstractmethod
def get_method_parameters(self, qualified_class_name: str, method_signature: str) -> List[JCallableParameter]:
"""The parameters of a method."""
"""The parameters of a method. Empty list if the method is not found."""

@abstractmethod
def get_all_constructors(self, qualified_class_name: str) -> Dict[str, JCallable]:
Expand DownExpand Up@@ -198,11 +198,11 @@ def get_comment_in_file(self, file_path: str) -> List[JComment]:

@abstractmethod
def get_comments_in_a_class(self, qualified_class_name: str) -> List[JComment]:
"""The comments in a class."""
"""The comments in a class. Returns an empty list if the class is not found."""

@abstractmethod
def get_comments_in_a_method(self, qualified_class_name: str, method_signature: str) -> List[JComment]:
"""The comments in a method."""
"""The comments in a method. Returns an empty list if the method is not found."""

@abstractmethod
def get_all_docstrings(self) -> List[Tuple[str, JComment]]:
Expand Down
35 changes: 23 additions & 12 deletions cldk/analysis/java/codeanalyzer/codeanalyzer.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -458,29 +458,30 @@ def get_all_classes(self) -> Dict[str, JType]:
class_dict.update(v.type_declarations)
return class_dict

def get_class(self, qualified_class_name) -> JType:
def get_class(self, qualified_class_name) -> JType | None:
"""Should return a class given the qualified class name.

Args:
qualified_class_name (str): The qualified name of the class.

Returns:
JType: A class for the given qualified class name.
JType | None: A class for the given qualified class name, or None if not found.
"""
symtab = self.get_symbol_table()
for _, v in symtab.items():
if qualified_class_name in v.type_declarations.keys():
return v.type_declarations.get(qualified_class_name)
return None

def get_method(self, qualified_class_name, method_signature) -> JCallable:
def get_method(self, qualified_class_name, method_signature) -> JCallable | None:
"""Should return a method given the qualified method name.

Args:
qualified_class_name (str): The qualified name of the class.
method_signature (str): The signature of the method.

Returns:
JCallable: A method for the given qualified method name.
JCallable | None: A method for the given qualified method name, or None if not found.
"""
symtab = self.get_symbol_table()
for v in symtab.values():
Expand All@@ -489,6 +490,7 @@ def get_method(self, qualified_class_name, method_signature) -> JCallable:
for cd in ci.callable_declarations.keys():
if cd == method_signature:
return ci.callable_declarations[cd]
return None

def get_method_parameters(self, qualified_class_name, method_signature) -> List[JCallableParameter]:
"""Should return a dictionary of method parameters given the qualified class name and method signature.
Expand All@@ -498,9 +500,11 @@ def get_method_parameters(self, qualified_class_name, method_signature) -> List[
method_signature (str): The signature of the method.

Returns:
Dict[str, str]: A dictionary of method parameters for the given qualified class name and method signature.
List[JCallableParameter]: The method parameters for the given qualified class name and method
signature. Empty list if the method is not found.
"""
return self.get_method(qualified_class_name, method_signature).parameters
method = self.get_method(qualified_class_name, method_signature)
return method.parameters if method is not None else []

def get_parameters_from_callable(self, callable: JCallable) -> List[JCallableParameter]:
"""Should return a dictionary of method parameters given the callable.
Expand All@@ -513,19 +517,20 @@ def get_parameters_from_callable(self, callable: JCallable) -> List[JCallablePar
"""
return callable.parameters

def get_java_file(self, qualified_class_name) -> str:
def get_java_file(self, qualified_class_name) -> str | None:
"""Should return java file name given the qualified class name.

Args:
qualified_class_name (str): The qualified name of the class.

Returns:
str: Java file name containing the given qualified class.
str | None: Java file name containing the given qualified class, or None if not found.
"""
symtab = self.get_symbol_table()
for k, v in symtab.items():
if (qualified_class_name) in v.type_declarations.keys():
return k
return None

def get_compilation_units(self) -> List[JCompilationUnit]:
"""Get all the compilation units in the symbol table.
Expand DownExpand Up@@ -736,9 +741,15 @@ def __raw_call_graph_using_symbol_table_target_method(self, target_class_name: s
if cg is None:
cg = []
target_method_details = self.get_method(qualified_class_name=target_class_name, method_signature=target_method_signature)
if target_method_details is None:
# The target method doesn't exist, so no edges into it can be constructed.
return cg
for class_name in self.get_all_classes():
for method in self.get_all_methods_in_class(qualified_class_name=class_name):
method_details = self.get_method(qualified_class_name=class_name, method_signature=method)
if method_details is None:
# The symbol table momentarily disagreed with itself; skip this entry.
continue
for call_site in method_details.call_sites:
source_method_details = None
source_class = ""
Expand DownExpand Up@@ -1078,10 +1089,10 @@ def get_comments_in_a_method(self, qualified_class_name: str, method_signature:
method_signature (str): Signature of the method.

Returns:
List[str]: List of comments in the method.
List[str]: List of comments in the method. Empty list if the method is not found.
"""
callable = self.get_method(qualified_class_name, method_signature)
return callable.comments
return callable.comments if callable is not None else []

def get_comments_in_a_class(self, qualified_class_name: str) -> List[JComment]:
"""Get all comments in a class.
Expand All@@ -1090,10 +1101,10 @@ def get_comments_in_a_class(self, qualified_class_name: str) -> List[JComment]:
qualified_class_name (str): Qualified name of the class.

Returns:
List[str]: List of comments in the class.
List[str]: List of comments in the class. Empty list if the class is not found.
"""
klass = self.get_class(qualified_class_name)
return klass.comments
return klass.comments if klass is not None else []

def get_comment_in_file(self, file_path: str) -> List[JComment]:
"""Get all comments in a file.
Expand Down
6 changes: 3 additions & 3 deletions cldk/analysis/java/java_analysis.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -610,7 +610,7 @@ def get_classes_by_criteria(
class_dict[application_class] = all_classes[application_class]
return class_dict

def get_class(self, qualified_class_name: str) -> JType:
def get_class(self, qualified_class_name: str) -> JType | None:
"""Return a specific class by its qualified name.

Retrieves detailed information about a single class, including its
Expand All@@ -632,7 +632,7 @@ def get_class(self, qualified_class_name: str) -> JType:

return self.backend.get_class(qualified_class_name)

def get_method(self, qualified_class_name: str, qualified_method_name: str) -> JCallable:
def get_method(self, qualified_class_name: str, qualified_method_name: str) -> JCallable | None:
"""Return a specific method by class and method signature.

Retrieves detailed information about a single method, including its
Expand DownExpand Up@@ -676,7 +676,7 @@ def get_method_parameters(self, qualified_class_name: str, qualified_method_name
"""
return self.backend.get_method_parameters(qualified_class_name, qualified_method_name)

def get_java_file(self, qualified_class_name: str) -> str:
def get_java_file(self, qualified_class_name: str) -> str | None:
"""Return the file path containing a class with the given name.

Given a qualified class name, returns the file path where that class
Expand Down
24 changes: 18 additions & 6 deletions cldk/analysis/java/neo4j/neo4j_backend.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -453,26 +453,30 @@ def get_all_classes(self) -> Dict[str, JType]:
class_dict.update(v.type_declarations)
return class_dict

def get_class(self, qualified_class_name) -> JType:
def get_class(self, qualified_class_name) -> JType | None:
for v in self.get_symbol_table().values():
if qualified_class_name in v.type_declarations.keys():
return v.type_declarations.get(qualified_class_name)
return None

def get_method(self, qualified_class_name, method_signature) -> JCallable:
def get_method(self, qualified_class_name, method_signature) -> JCallable | None:
for v in self.get_symbol_table().values():
if qualified_class_name in v.type_declarations.keys():
ci = v.type_declarations[qualified_class_name]
for cd in ci.callable_declarations.keys():
if cd == method_signature:
return ci.callable_declarations[cd]
return None

def get_method_parameters(self, qualified_class_name, method_signature) -> List[JCallableParameter]:
return self.get_method(qualified_class_name, method_signature).parameters
method = self.get_method(qualified_class_name, method_signature)
return method.parameters if method is not None else []

def get_java_file(self, qualified_class_name) -> str:
def get_java_file(self, qualified_class_name) -> str | None:
for k, v in self.get_symbol_table().items():
if qualified_class_name in v.type_declarations.keys():
return k
return None

def get_all_methods_in_class(self, qualified_class_name) -> Dict[str, JCallable]:
ci = self.get_class(qualified_class_name)
Expand DownExpand Up@@ -563,9 +567,15 @@ def __raw_call_graph_using_symbol_table_target_method(self, target_class_name: s
if cg is None:
cg = []
target_method_details = self.get_method(qualified_class_name=target_class_name, method_signature=target_method_signature)
if target_method_details is None:
# The target method doesn't exist, so no edges into it can be constructed.
return cg
for class_name in self.get_all_classes():
for method in self.get_all_methods_in_class(qualified_class_name=class_name):
method_details = self.get_method(qualified_class_name=class_name, method_signature=method)
if method_details is None:
# The symbol table momentarily disagreed with itself; skip this entry.
continue
for call_site in method_details.call_sites:
source_method_details = None
source_class = ""
Expand DownExpand Up@@ -688,10 +698,12 @@ def get_all_delete_operations(self) -> List[Dict[str, Union[JType, JCallable, Li
return self._crud(CRUDOperationType.DELETE)

def get_comments_in_a_method(self, qualified_class_name: str, method_signature: str) -> List[JComment]:
return self.get_method(qualified_class_name, method_signature).comments
callable = self.get_method(qualified_class_name, method_signature)
return callable.comments if callable is not None else []

def get_comments_in_a_class(self, qualified_class_name: str) -> List[JComment]:
return self.get_class(qualified_class_name).comments
klass = self.get_class(qualified_class_name)
return klass.comments if klass is not None else []

def get_comment_in_file(self, file_path: str) -> List[JComment]:
compilation_unit = self.get_symbol_table().get(file_path, None)
Expand Down
Loading