From 511275032e207bfcb2bca56ba1e9d3f0544a38c5 Mon Sep 17 00:00:00 2001 From: Arthur Chan Date: Wed, 10 Jul 2024 17:57:57 +0100 Subject: [PATCH] JVM: Add constructor informations in the prompt (#429) This PR adds the constructors information of the target method with the use of the new introspector query introduced in #426. **This PR depends on #416 #425 #426 and needed rebase after these three PRs are merged.** --------- Signed-off-by: Arthur Chan --- llm_toolkit/prompt_builder.py | 48 ++++++++++++++++++++++++++-- prompts/template_xml/jvm_problem.txt | 1 + 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/llm_toolkit/prompt_builder.py b/llm_toolkit/prompt_builder.py index 0b17a923f..b0197f0a5 100644 --- a/llm_toolkit/prompt_builder.py +++ b/llm_toolkit/prompt_builder.py @@ -681,8 +681,8 @@ def _format_argument(self, count: int, arg_type: str) -> str: # java.lang.Object argument if 'java.lang.Object' in arg_type: base = self._get_template(self.object_arg_description_template_file) - prefix = 'Argument \#{count} requires an Object instance\n' - argument = '' + prefix + base + '' + prefix = f'Argument #{count} requires an Object instance\n' + argument = f'{prefix}{base}' return argument # Simple arguments @@ -784,6 +784,49 @@ def _format_arguments(self) -> str: return '' + '\n'.join(argument_descriptions) + '' + def _format_constructors(self) -> str: + """Formats a list of functions / constructors to create the object for + invoking the target method.""" + if self.benchmark.is_jvm_static: + return '' + + constructors = [] + ctrs = introspector.query_introspector_matching_function_constructor_type( + self.benchmark.project, self.benchmark.return_type, False) + for ctr in ctrs: + constructor_sig = ctr.get('function_signature') + if constructor_sig: + constructors.append(f'{constructor_sig}') + + if constructors: + ctr_str = '\n'.join(constructors) + return f'{ctr_str}' + + functions = [] + funcs = introspector.query_introspector_matching_function_constructor_type( + self.benchmark.project, self.benchmark.return_type, True) + for func in funcs: + is_static = func.get('is_static', False) + function_sig = func.get('function_signature') + if not function_sig: + continue + if is_static: + functions.append(f'{function_sig}') + else: + function_class = function_sig[1:].split(']')[0] + function_str = f'{function_sig}' + function_str = function_str + ( + 'You MUST create an ' + f'{function_class} object before calling this constructing method.' + '') + function_str = f'{function_str}' + functions.append(function_str) + if functions: + func_str = '\n'.join(functions) + return f'{func_str}' + + return '' + def _format_source_reference(self, signature: str) -> Tuple[str, str]: """Formats the source code reference for this target.""" # Query for source code of the target method @@ -807,6 +850,7 @@ def _format_problem(self, signature: str) -> str: problem = problem.replace('{REQUIREMENTS}', self._format_requirement(signature)) problem = problem.replace('{ARGUMENTS}', self._format_arguments()) + problem = problem.replace('{CONSTRUCTORS}', self._format_constructors()) problem = problem.replace('{EXCEPTIONS}', self._format_exceptions()) self_source, cross_source = self._format_source_reference(signature) diff --git a/prompts/template_xml/jvm_problem.txt b/prompts/template_xml/jvm_problem.txt index 1d4248dab..9389f9825 100644 --- a/prompts/template_xml/jvm_problem.txt +++ b/prompts/template_xml/jvm_problem.txt @@ -2,6 +2,7 @@ Your goal is to write a fuzzing harness for the provided method signature using Jazzer framework from Code Intellengence. It is important that the provided solution compiles and actually calls the function specified by the method signature: {TARGET} {ARGUMENTS} +{CONSTRUCTORS} {EXCEPTIONS} Here is the source code of the target constructor for reference.