|
| 1 | +"""Project generator for the Java language.""" |
| 2 | + |
| 3 | +import re |
| 4 | + |
| 5 | +from .base import BaseLanguageInterface |
| 6 | + |
| 7 | +TEST_FILE_TEMPLATE = """\ |
| 8 | +
|
| 9 | +public class Test {{ |
| 10 | + public static void main(String[] args) {{ |
| 11 | + {params_setup}; |
| 12 | + {result_var_declaration}new Solution().{name}({params_call}); |
| 13 | + System.out.printf("{OUTPUT_RESULT_PREFIX} %s\\n", {result_var}); |
| 14 | + }} |
| 15 | +}} |
| 16 | +""" |
| 17 | + |
| 18 | +FUNCTION_SIGNATURE_PATTERN = re.compile( |
| 19 | + r"public (?P<returnType>[^\s]+) (?P<name>\w+(?:\[\]|\s?\*+)?)\((?P<params>[^)]*)\)\s?{$", |
| 20 | + flags=re.MULTILINE, |
| 21 | +) |
| 22 | + |
| 23 | + |
| 24 | +SOLUTION_REPLACEMENT_PATTERN = re.compile(r"\n }") |
| 25 | +SOLUTION_REPLACEMENT_TEMPLATE = "return {return_value};\n }}" |
| 26 | +SUPPLEMENTAL_FILENAME_PATTERN = re.compile(r"public class (\w+) {") |
| 27 | +UTIL_IMPORT_TEMPLATE = "import java.util.*;\n\n" |
| 28 | + |
| 29 | + |
| 30 | +class JavaLanguageInterface(BaseLanguageInterface): |
| 31 | + """Implementation of the Java language project template interface.""" |
| 32 | + |
| 33 | + function_signature_pattern = FUNCTION_SIGNATURE_PATTERN |
| 34 | + test_command = ["java", "Test"] |
| 35 | + |
| 36 | + @property |
| 37 | + def compile_command(self): |
| 38 | + args = ["javac", "Solution.java", "Test.java"] |
| 39 | + |
| 40 | + supplemental_filename = self.get_supplemental_filename() |
| 41 | + if supplemental_filename is not None: |
| 42 | + args.append(supplemental_filename) |
| 43 | + |
| 44 | + return args |
| 45 | + |
| 46 | + @property |
| 47 | + def default_output(self): |
| 48 | + return self.get_default_value(self.groups["returnType"]) |
| 49 | + |
| 50 | + def get_supplemental_filename(self): |
| 51 | + """Obtains the name of the supplemental file.""" |
| 52 | + code = self.groups["supplemental_code"] |
| 53 | + if not code: |
| 54 | + return None |
| 55 | + return f"{SUPPLEMENTAL_FILENAME_PATTERN.search(code).group(1)}.java" |
| 56 | + |
| 57 | + def get_default_value(self, variable_type: str): |
| 58 | + """Obtains the default value for a given variable type.""" |
| 59 | + return {"boolean": "false", "int": "0", "void": "0"}.get(variable_type, "null") |
| 60 | + |
| 61 | + def prepare_project_files(self, template: str): |
| 62 | + params = self.groups["params"].split(", ") |
| 63 | + self.groups["params_setup"] = ";\n ".join( |
| 64 | + f"{param} = {self.get_default_value(param.split()[0])}" |
| 65 | + for param in self.groups["params"].split(", ") |
| 66 | + ) |
| 67 | + self.groups["params_call"] = ", ".join(param.split()[-1] for param in params) |
| 68 | + |
| 69 | + if self.groups["returnType"] == "void": |
| 70 | + self.groups["result_var_declaration"] = "" |
| 71 | + self.groups["result_var"] = "0" |
| 72 | + formatted_template = template |
| 73 | + else: |
| 74 | + self.groups["result_var_declaration"] = ( |
| 75 | + f"{self.groups['returnType']} result = " |
| 76 | + ) |
| 77 | + self.groups["result_var"] = "result" |
| 78 | + formatted_template = re.sub( |
| 79 | + SOLUTION_REPLACEMENT_PATTERN, |
| 80 | + SOLUTION_REPLACEMENT_TEMPLATE.format(return_value=self.default_output), |
| 81 | + template, |
| 82 | + ) |
| 83 | + |
| 84 | + project_files = { |
| 85 | + "Solution.java": f"{UTIL_IMPORT_TEMPLATE}{formatted_template}\n", |
| 86 | + "Test.java": UTIL_IMPORT_TEMPLATE |
| 87 | + + TEST_FILE_TEMPLATE.format(**self.groups), |
| 88 | + } |
| 89 | + if self.groups["supplemental_code"]: |
| 90 | + filename = self.get_supplemental_filename() |
| 91 | + project_files[filename] = self.groups["supplemental_code"] |
| 92 | + return project_files |
0 commit comments