@@ -515,6 +515,7 @@ def replace_function_definitions_for_language(
515515 original_source = original_source_code ,
516516 module_abspath = module_abspath ,
517517 language = language ,
518+ target_function_names = function_names ,
518519 )
519520
520521 # If we have function_to_optimize with line info and this is the main file, use it for precise replacement
@@ -621,27 +622,142 @@ def _extract_function_from_code(
621622 return None
622623
623624
625+ def _add_java_class_members (
626+ optimized_code : str , original_source : str , target_function_names : list [str ] | None = None
627+ ) -> str :
628+ """Add new Java class members (static fields and helper methods) from optimized code.
629+
630+ Parses both the optimized and original code to find:
631+ - New static fields in the optimized code that don't exist in the original
632+ - New helper methods in the optimized code that don't exist in the original
633+
634+ These are added to the original class at appropriate positions.
635+ Target functions (being replaced) are NOT added as new helpers.
636+
637+ Args:
638+ optimized_code: The optimized code that may contain new class members.
639+ original_source: The original source code.
640+ target_function_names: List of function names being optimized (to exclude from helpers).
641+
642+ Returns:
643+ Original source with new class members added.
644+
645+ """
646+ target_names = set (target_function_names or [])
647+ try :
648+ from codeflash .languages .java .parser import get_java_analyzer
649+
650+ analyzer = get_java_analyzer ()
651+
652+ # Find classes in both sources
653+ original_classes = analyzer .find_classes (original_source )
654+ optimized_classes = analyzer .find_classes (optimized_code )
655+
656+ if not original_classes or not optimized_classes :
657+ return original_source
658+
659+ # Match by class name (handle single class per file - most common case)
660+ # Use the first class as the target
661+ original_class = original_classes [0 ]
662+ optimized_class = None
663+ for cls in optimized_classes :
664+ if cls .name == original_class .name :
665+ optimized_class = cls
666+ break
667+
668+ if not optimized_class :
669+ # Try to use first class from optimized if names don't match
670+ optimized_class = optimized_classes [0 ]
671+
672+ class_name = original_class .name
673+
674+ # Find existing fields and methods in original
675+ existing_fields = analyzer .find_fields (original_source , class_name )
676+ existing_methods = analyzer .find_methods (original_source )
677+ existing_field_names = {f .name for f in existing_fields }
678+ existing_method_names = {m .name for m in existing_methods if m .class_name == class_name }
679+
680+ # Find fields and methods in optimized code
681+ optimized_fields = analyzer .find_fields (optimized_code , class_name )
682+ optimized_methods = analyzer .find_methods (optimized_code )
683+
684+ # Find new fields (fields in optimized that don't exist in original)
685+ new_fields = []
686+ for field in optimized_fields :
687+ if field .name not in existing_field_names :
688+ if field .source_text :
689+ new_fields .append (field .source_text )
690+
691+ # Find new helper methods (methods in optimized that don't exist in original)
692+ new_methods = []
693+ for method in optimized_methods :
694+ # Exclude target functions (they'll be replaced, not added as new helpers)
695+ if (
696+ method .class_name == class_name
697+ and method .name not in existing_method_names
698+ and method .name not in target_names
699+ ):
700+ # Extract method source including Javadoc
701+ lines = optimized_code .splitlines (keepends = True )
702+ start = (method .javadoc_start_line or method .start_line ) - 1
703+ end = method .end_line
704+ method_source = "" .join (lines [start :end ])
705+ new_methods .append (method_source )
706+
707+ if not new_fields and not new_methods :
708+ return original_source
709+
710+ logger .debug (
711+ f"Adding { len (new_fields )} new fields and { len (new_methods )} helper methods to class { class_name } "
712+ )
713+
714+ # Import the insertion function from replacement module
715+ from codeflash .languages .java .replacement import _insert_class_members
716+
717+ result = _insert_class_members (
718+ original_source , class_name , new_fields , new_methods , analyzer
719+ )
720+
721+ return result
722+
723+ except Exception as e :
724+ logger .debug (f"Error adding Java class members: { e } " )
725+ return original_source
726+
727+
624728def _add_global_declarations_for_language (
625- optimized_code : str , original_source : str , module_abspath : Path , language : Language
729+ optimized_code : str ,
730+ original_source : str ,
731+ module_abspath : Path ,
732+ language : Language ,
733+ target_function_names : list [str ] | None = None ,
626734) -> str :
627735 """Add new global declarations from optimized code to original source.
628736
629- Finds module-level declarations (const, let, var, class, type, interface, enum)
737+ For JavaScript/TypeScript: Finds module-level declarations (const, let, var, class, type, interface, enum)
630738 in the optimized code that don't exist in the original source and adds them.
631739
740+ For Java: Finds new static fields and helper methods in the optimized code that don't exist
741+ in the original source and adds them to the appropriate class.
742+
632743 Args:
633744 optimized_code: The optimized code that may contain new declarations.
634745 original_source: The original source code.
635746 module_abspath: Path to the module file (for parser selection).
636747 language: The language of the code.
748+ target_function_names: List of function names being optimized (to exclude from Java helpers).
637749
638750 Returns:
639- Original source with new declarations added after imports .
751+ Original source with new declarations added.
640752
641753 """
642754 from codeflash .languages .base import Language
643755
644- # Only process JavaScript/TypeScript
756+ # Handle Java class-level members
757+ if language == Language .JAVA :
758+ return _add_java_class_members (optimized_code , original_source , target_function_names )
759+
760+ # Only process JavaScript/TypeScript for module-level declarations
645761 if language not in (Language .JAVASCRIPT , Language .TYPESCRIPT ):
646762 return original_source
647763
0 commit comments