| import ast, astor, javalang, re, yaml, black, isort | |
| from .utils import run_cmd | |
| class RefactorEngine: | |
| def __init__(self, rules_path='config/refactor_rules.yaml'): | |
| with open(rules_path) as f: self.rules=yaml.safe_load(f) | |
| def format_python(self,code): | |
| try: return isort.code(black.format_str(code,mode=black.FileMode())) | |
| except: return code | |
| def remove_unused_imports_python(self,code): | |
| try: | |
| t=ast.parse(code);im=[n for n in t.body if isinstance(n,(ast.Import,ast.ImportFrom))] | |
| used={n.id for n in ast.walk(t) if isinstance(n,ast.Name)} | |
| keep=[i for i in im if any((a.asname or a.name.split('.')[0]) in used for a in i.names)] | |
| t.body=keep+[n for n in t.body if n not in im];return astor.to_source(t) | |
| except: return code | |
| def inline_simple_functions_python(self,code): | |
| try: | |
| t=ast.parse(code);funcs={} | |
| for n in t.body: | |
| if isinstance(n,ast.FunctionDef) and len(n.body)==1 and isinstance(n.body[0],ast.Return): | |
| funcs[n.name]=astor.to_source(n.body[0].value).strip() | |
| out=code | |
| for f,b in funcs.items(): out=re.sub(rf'\b{f}\(\)',b,out) | |
| return out | |
| except: return code | |
| def refactor_python(self,code): | |
| r=self.rules.get('python',{}); | |
| if r.get('remove_unused_imports'): code=self.remove_unused_imports_python(code) | |
| if r.get('inline_simple_functions'): code=self.inline_simple_functions_python(code) | |
| if r.get('format'): code=self.format_python(code) | |
| return code | |
| def convert_java_for_each(self,code): | |
| return re.sub(r'for \(int (\w+)=0; \1 < (\w+).size\(\); \1\+\+\)', r'for (var x : \2)', code) | |
| def refactor_java(self,code): | |
| r=self.rules.get('java',{}) | |
| if r.get('convert_for_each'): code=self.convert_java_for_each(code) | |
| return code | |
| def refactor_javascript(self,code): | |
| r=self.rules.get('javascript',{}) | |
| if r.get('convert_var_to_let'): code=code.replace('var ','let ') | |
| return code | |
| def refactor(self,code,lang): | |
| lang=lang.lower() | |
| if lang=='python': return self.refactor_python(code) | |
| if lang=='java': return self.refactor_java(code) | |
| if lang in ('js','javascript'): return self.refactor_javascript(code) | |
| return code | |