@@ -51,15 +51,14 @@ class JCodeanalyzer:
5151 """
5252
5353 def __init__ (
54- self ,
55- project_dir : Union [str , Path ],
56- source_code : str | None ,
57- analysis_backend_path : Union [str , Path , None ],
58- analysis_json_path : Union [str , Path , None ],
59- analysis_level : str ,
60- use_graalvm_binary : bool ,
61- eager_analysis : bool ,
62- target_files : List [str ] | None
54+ self ,
55+ project_dir : Union [str , Path ],
56+ source_code : str | None ,
57+ analysis_backend_path : Union [str , Path , None ],
58+ analysis_json_path : Union [str , Path , None ],
59+ analysis_level : str ,
60+ use_graalvm_binary : bool ,
61+ eager_analysis : bool ,
6362 ) -> None :
6463 self .project_dir = project_dir
6564 self .source_code = source_code
@@ -68,7 +67,6 @@ def __init__(
6867 self .use_graalvm_binary = use_graalvm_binary
6968 self .eager_analysis = eager_analysis
7069 self .analysis_level = analysis_level
71- self .target_files = target_files
7270 self .application = self ._init_codeanalyzer (
7371 analysis_level = 1 if analysis_level == AnalysisLevel .symbol_table else 2 )
7472 # Attributes related the Java code analysis...
@@ -173,7 +171,7 @@ def _get_codeanalyzer_exec(self) -> List[str]:
173171 resources .files ("cldk.analysis.java.codeanalyzer.bin" ) / "codeanalyzer" ) as codeanalyzer_bin_path :
174172 codeanalyzer_exec = shlex .split (codeanalyzer_bin_path .__str__ ())
175173 else :
176-
174+
177175 if self .analysis_backend_path :
178176 analysis_backend_path = Path (self .analysis_backend_path )
179177 logger .info (f"Using codeanalyzer.jar from { analysis_backend_path } " )
@@ -200,19 +198,11 @@ def _init_codeanalyzer(self, analysis_level=1) -> JApplication:
200198 """
201199
202200 codeanalyzer_exec = self ._get_codeanalyzer_exec ()
203- codeanalyzer_args = ''
201+
204202 if self .analysis_json_path is None :
205203 logger .info ("Reading analysis from the pipe." )
206- # If target file is provided, the input is merged into a single string and passed to codeanalyzer
207- if self .target_files :
208- target_file_options = ' -t ' .join ([s .strip () for s in self .target_files ])
209- codeanalyzer_args = codeanalyzer_exec + shlex .split (
210- f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } -t { target_file_options } "
211- )
212- else :
213- codeanalyzer_args = codeanalyzer_exec + shlex .split (
214- f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } "
215- )
204+ codeanalyzer_args = codeanalyzer_exec + shlex .split (
205+ f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } " )
216206 try :
217207 logger .info (f"Running codeanalyzer: { ' ' .join (codeanalyzer_args )} " )
218208 console_out : CompletedProcess [str ] = subprocess .run (
@@ -226,29 +216,15 @@ def _init_codeanalyzer(self, analysis_level=1) -> JApplication:
226216 raise CodeanalyzerExecutionException (str (e )) from e
227217
228218 else :
229- # Check if the code analyzer needs to be run
230- is_run_code_analyzer = False
231219 analysis_json_path_file = Path (self .analysis_json_path ).joinpath ("analysis.json" )
232- # If target file is provided, the input is merged into a single string and passed to codeanalyzer
233- if self .target_files :
234- target_file_options = ' -t ' .join ([s .strip () for s in self .target_files ])
220+ if not analysis_json_path_file .exists () or self .eager_analysis :
221+ # If the analysis file does not exist, we'll run the analysis. Alternately, if the eager_analysis
222+ # flag is set, we'll run the analysis every time the object is created. This will happen regradless
223+ # of the existence of the analysis file.
224+ # Create the executable command for codeanalyzer.
235225 codeanalyzer_args = codeanalyzer_exec + shlex .split (
236- f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } "
237- f" -o { self .analysis_json_path } -t { target_file_options } "
238- )
239- is_run_code_analyzer = True
240- else :
241- if not analysis_json_path_file .exists () or self .eager_analysis :
242- # If the analysis file does not exist, we'll run the analysis. Alternately, if the eager_analysis
243- # flag is set, we'll run the analysis every time the object is created. This will happen regradless
244- # of the existence of the analysis file.
245- # Create the executable command for codeanalyzer.
246- codeanalyzer_args = codeanalyzer_exec + shlex .split (
247- f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } -o { self .analysis_json_path } "
248- )
249- is_run_code_analyzer = True
250-
251- if is_run_code_analyzer :
226+ f"-i { Path (self .project_dir )} --analysis-level={ analysis_level } -o { self .analysis_json_path } " )
227+
252228 try :
253229 logger .info (f"Running codeanalyzer subprocess with args { codeanalyzer_args } " )
254230 subprocess .run (
@@ -262,6 +238,7 @@ def _init_codeanalyzer(self, analysis_level=1) -> JApplication:
262238
263239 except Exception as e :
264240 raise CodeanalyzerExecutionException (str (e )) from e
241+
265242 with open (analysis_json_path_file ) as f :
266243 data = json .load (f )
267244 return JApplication (** data )
@@ -275,6 +252,7 @@ def _codeanalyzer_single_file(self):
275252 JApplication
276253 The application view of the Java code with the analysis results.
277254 """
255+ # self.source_code: str = re.sub(r"[\r\n\t\f\v]+", lambda x: " " if x.group() in "\t\f\v" else " ", self.source_code)
278256 codeanalyzer_exec = self ._get_codeanalyzer_exec ()
279257 codeanalyzer_args = ["--source-analysis" , self .source_code ]
280258 codeanalyzer_cmd = codeanalyzer_exec + codeanalyzer_args
@@ -430,8 +408,9 @@ def get_all_callers(self, target_class_name: str, target_method_signature: str,
430408 caller_detail_dict = {}
431409 call_graph = None
432410 if using_symbol_table :
433- call_graph = self .__raw_call_graph_using_symbol_table_target_method (target_class_name = target_class_name ,
434- target_method_signature = target_method_signature )
411+ call_graph = self .__call_graph_using_symbol_table (qualified_class_name = target_class_name ,
412+ method_signature = target_method_signature ,
413+ is_target_method = True )
435414 else :
436415 call_graph = self .call_graph
437416 if (target_method_signature , target_class_name ) not in call_graph .nodes ():
@@ -768,7 +747,7 @@ def get_class_call_graph_using_symbol_table(self, qualified_class_name: str,
768747
769748 def __call_graph_using_symbol_table (self ,
770749 qualified_class_name : str ,
771- method_signature : str , is_target_method : bool = False )-> DiGraph :
750+ method_signature : str , is_target_method : bool = False ) -> DiGraph :
772751 """
773752 Generate call graph using symbol table
774753 Args:
@@ -782,10 +761,11 @@ def __call_graph_using_symbol_table(self,
782761 cg = nx .DiGraph ()
783762 sdg = None
784763 if is_target_method :
785- sdg = None
764+ sdg = self .__raw_call_graph_using_symbol_table_target_method (target_class_name = qualified_class_name ,
765+ target_method_signature = method_signature )
786766 else :
787767 sdg = self .__raw_call_graph_using_symbol_table (qualified_class_name = qualified_class_name ,
788- method_signature = method_signature )
768+ method_signature = method_signature )
789769 tsu = JavaSitter ()
790770 edge_list = [
791771 (
@@ -812,8 +792,8 @@ def __call_graph_using_symbol_table(self,
812792 return cg
813793
814794 def __raw_call_graph_using_symbol_table_target_method (self ,
815- target_class_name : str ,
816- target_method_signature : str ,
795+ target_class_name : str ,
796+ target_method_signature : str ,
817797 cg = None ) -> list [JGraphEdgesST ]:
818798 """
819799 Generates call graph using symbol table information given the target method and target class
@@ -832,7 +812,7 @@ def __raw_call_graph_using_symbol_table_target_method(self,
832812 for class_name in self .get_all_classes ():
833813 for method in self .get_all_methods_in_class (qualified_class_name = class_name ):
834814 method_details = self .get_method (qualified_class_name = class_name ,
835- method_signature = method )
815+ method_signature = method )
836816 for call_site in method_details .call_sites :
837817 source_method_details = None
838818 source_class = ''
@@ -856,9 +836,9 @@ def __raw_call_graph_using_symbol_table_target_method(self,
856836 if call_site .receiver_type != "" :
857837 # call to any class
858838 if self .get_class (qualified_class_name = call_site .receiver_type ):
859- if callee_signature == target_method_signature and call_site .receiver_type == target_class_name :
839+ if callee_signature == target_method_signature and call_site .receiver_type == target_class_name :
860840 source_method_details = self .get_method (method_signature = method ,
861- qualified_class_name = class_name )
841+ qualified_class_name = class_name )
862842 source_class = class_name
863843 else :
864844 # check if any method exists with the signature in the class even if the receiver type is blank
0 commit comments