@@ -243,32 +243,40 @@ class JavaMethod():
243243 def __init__ (self ,
244244 root : Node ,
245245 class_interface : 'JavaClassInterface' ,
246- is_constructor : bool = False ):
246+ is_constructor : bool = False ,
247+ is_default_constructor : bool = False ):
247248 self .root = root
248249 self .class_interface = class_interface
249250 self .tree_sitter_lang = self .class_interface .tree_sitter_lang
250251 self .parent_source : Optional [
251252 SourceCodeFile ] = self .class_interface .parent_source
252253 self .is_constructor = is_constructor
254+ self .is_default_constructor = is_default_constructor
255+ self .name : str = ''
253256
254257 # Store method line information
255- self .start_line = self .root .start_point .row + 1
256- self .end_line = self .root .end_point .row + 1
258+ if self .is_default_constructor :
259+ self .start_line = - 1
260+ self .end_line = - 1
261+ self .name = '<init>'
262+ self .public = True
263+ else :
264+ self .start_line = self .root .start_point .row + 1
265+ self .end_line = self .root .end_point .row + 1
266+ self .name = ''
267+ self .public = False
257268
258269 # Other properties
259- self .name : str = ''
260270 self .complexity = 0
261271 self .icount = 0
262272 self .arg_names : list [str ] = []
263273 self .arg_types : list [str ] = []
264274 self .exceptions : list [str ] = []
265275 self .return_type = ''
266- self .sig = ''
267276 self .function_uses = 0
268277 self .function_depth = 0
269278 self .base_callsites : list [tuple [str , int ]] = []
270279 self .detailed_callsites : list [dict [str , str ]] = []
271- self .public = False
272280 self .concrete = True
273281 self .static = False
274282 self .is_entry_method = False
@@ -277,11 +285,12 @@ def __init__(self,
277285 self .stmts : list [Node ] = []
278286 self .var_map : dict [str , str ] = {}
279287
280- # Process method declaration
281- self ._process_declaration ()
288+ if not self .is_default_constructor :
289+ # Process method declaration
290+ self ._process_declaration ()
282291
283- # Process statements
284- self ._process_statements ()
292+ # Process statements
293+ self ._process_statements ()
285294
286295 def post_process_full_qualified_name (self ):
287296 """Post process the full qualified name for types."""
@@ -374,7 +383,6 @@ def _process_statements(self):
374383 for stmt in self .stmts :
375384 self ._process_complexity (stmt )
376385 self ._process_icount (stmt )
377- self ._process_variable_declaration (stmt )
378386
379387 def _process_complexity (self , stmt : Node ):
380388 """Gets complexity measure based on counting branch nodes in a
@@ -443,21 +451,6 @@ def _traverse_node_instr_count(node: Node) -> int:
443451
444452 self .icount += _traverse_node_instr_count (stmt )
445453
446- def _process_variable_declaration (self , stmt : Node ):
447- """Process the local variable declaration."""
448- variable_type = None
449- variable_name = None
450-
451- if stmt .type == 'local_variable_declaration' :
452- variable_type = stmt .child_by_field_name ('type' ).text .decode ()
453- for vars in stmt .children :
454- if vars .type == 'variable_declarator' :
455- variable_name = vars .child_by_field_name (
456- 'name' ).text .decode ()
457-
458- if variable_type and variable_name :
459- self .var_map [variable_name ] = variable_type
460-
461454 def _process_invoke_object (
462455 self , stmt : Node , classes : dict [str , 'JavaClassInterface' ]
463456 ) -> tuple [str , list [tuple [str , int , int ]]]:
@@ -752,6 +745,9 @@ def _process_callsites(
752745 type = ''
753746 callsites = []
754747
748+ if not stmt :
749+ return type , callsites
750+
755751 if stmt .type == 'method_invocation' :
756752 type , invoke_callsites = self ._process_invoke (stmt , classes )
757753 callsites .extend (invoke_callsites )
@@ -769,6 +765,24 @@ def _process_callsites(
769765 type , invoke_callsites = self ._process_callsites (right , classes )
770766 self .var_map [var_name ] = type
771767 callsites .extend (invoke_callsites )
768+ elif stmt .type .endswith ('local_variable_declarattion' ):
769+ for vars in stmt .children :
770+ if vars .type == 'variable_declarator' :
771+ var_name = vars .child_by_field_name ('name' ).text .decode ()
772+ value_node = vars .child_by_field_name ('value' )
773+
774+ type , invoke_callsites = self ._process_callsites (
775+ value_node , classes )
776+ self .var_map [var_name ] = type
777+ callsites .extend (invoke_callsites )
778+ elif stmt .type .endswith ('variable_declarator' ):
779+ var_name = stmt .child_by_field_name ('name' ).text .decode ()
780+ value_node = stmt .child_by_field_name ('value' )
781+
782+ type , invoke_callsites = self ._process_callsites (
783+ value_node , classes )
784+ self .var_map [var_name ] = type
785+ callsites .extend (invoke_callsites )
772786 else :
773787 for child in stmt .children :
774788 callsites .extend (self ._process_callsites (child , classes )[1 ])
@@ -782,6 +796,9 @@ def extract_callsites(self, classes: dict[str, 'JavaClassInterface']):
782796 callsites = []
783797 for stmt in self .stmts :
784798 callsites .extend (self ._process_callsites (stmt , classes )[1 ])
799+ if self .is_constructor :
800+ for stmt in self .class_interface .constructor_callsites :
801+ callsites .extend (self ._process_callsites (stmt , classes )[1 ])
785802 callsites = sorted (set (callsites ), key = lambda x : x [1 ])
786803 self .base_callsites = [(x [0 ], x [2 ]) for x in callsites ]
787804
@@ -819,13 +836,18 @@ def __init__(self,
819836 self .class_fields : dict [str , str ] = {}
820837 self .super_class = 'Object'
821838 self .super_interfaces : list [str ] = []
839+ self .constructor_callsites : list [Node ] = []
822840
823841 # Process the class/interface tree
824842 inner_class_nodes = self ._process_node ()
825843
826844 # Process inner classes
827845 self ._process_inner_classes (inner_class_nodes )
828846
847+ # Add in default constructor if no deinition of constructors
848+ if not self ._has_constructor_defined ():
849+ self .methods .append (JavaMethod (self .root , self , True , True ))
850+
829851 def add_package_to_class_name (self , name : str ) -> Optional [str ]:
830852 """Helper for finding a specific class name."""
831853 if self .name == f'{ self .package } .{ name .rsplit ("." )[- 1 ]} ' :
@@ -918,6 +940,7 @@ def _process_node(self) -> list[Node]:
918940 for fields in body .children :
919941 # Process field_name
920942 if fields .type == 'variable_declarator' :
943+ self .constructor_callsites .append (fields )
921944 field_name = fields .child_by_field_name (
922945 'name' ).text .decode ()
923946
@@ -937,6 +960,14 @@ def _process_inner_classes(self, inner_class_nodes: list[Node]):
937960 JavaClassInterface (node , self .tree_sitter_lang ,
938961 self .parent_source , self ))
939962
963+ def _has_constructor_defined (self ) -> bool :
964+ """Helper method to determine if any constructor is defined."""
965+ for method in self .methods :
966+ if method .is_constructor :
967+ return True
968+
969+ return False
970+
940971 def get_all_methods (self ) -> list [JavaMethod ]:
941972 all_methods = self .methods
942973 for inner_class in self .inner_classes :
0 commit comments