import gradio as gr import os from transformers import pipeline import torch import re import ast import traceback # Initialize a more suitable model for code analysis code_analyzer = None def load_analyzer(): global code_analyzer if code_analyzer is None: try: # Using a text generation model that's better for code analysis code_analyzer = pipeline( "text-generation", model="Salesforce/codegen-350M-mono", device=0 if torch.cuda.is_available() else -1 ) except: code_analyzer = "fallback" return code_analyzer def check_python_syntax(code): """Check Python syntax errors""" errors = [] try: ast.parse(code) except SyntaxError as e: errors.append({ 'type': 'Syntax Error', 'line': e.lineno, 'message': e.msg, 'text': e.text.strip() if e.text else '' }) except Exception as e: errors.append({ 'type': 'Parse Error', 'line': None, 'message': str(e), 'text': '' }) return errors def check_common_errors(code, language): """Detect common coding errors""" errors = [] lines = code.split('\n') if language.lower() == 'python': # Check for missing colons for i, line in enumerate(lines, 1): stripped = line.strip() if stripped and not stripped.startswith('#'): if any(stripped.startswith(kw) for kw in ['def ', 'class ', 'if ', 'elif ', 'else', 'for ', 'while ', 'try', 'except', 'finally', 'with ']): if not stripped.endswith(':') and not stripped.endswith('\\'): errors.append({ 'type': 'Missing Colon', 'line': i, 'message': 'Missing colon at end of statement', 'text': stripped }) # Check for missing parentheses for i, line in enumerate(lines, 1): if 'def ' in line or 'for ' in line or 'while ' in line: if '(' not in line or ')' not in line: errors.append({ 'type': 'Missing Parentheses', 'line': i, 'message': 'Missing parentheses in statement', 'text': line.strip() }) # Check for undefined variables (simple check) defined_vars = set() for i, line in enumerate(lines, 1): # Track variable assignments if '=' in line and not line.strip().startswith('#'): parts = line.split('=')[0].strip() if ' ' not in parts or parts.split()[0] in ['for']: var_name = parts.split()[-1].strip('()') defined_vars.add(var_name) # Check for undefined variable usage words = re.findall(r'\b[a-zA-Z_][a-zA-Z0-9_]*\b', line) for word in words: if word not in ['def', 'class', 'if', 'else', 'elif', 'for', 'while', 'in', 'return', 'print', 'len', 'range', 'str', 'int', 'float', 'list', 'dict', 'set', 'tuple']: # Check if it looks like it's being used but not defined if word not in defined_vars and f'{word}(' not in line and f'{word} =' not in line: if re.search(rf'\b{word}\b(?!\s*=)(?!\s*\()', line): errors.append({ 'type': 'Potential Undefined Variable', 'line': i, 'message': f"Variable '{word}' may not be defined", 'text': line.strip() }) return errors def analyze_code_structure(code, language): """Analyze code structure and provide metrics""" lines = code.split('\n') total_lines = len(lines) code_lines = len([l for l in lines if l.strip() and not l.strip().startswith('#') and not l.strip().startswith('//')]) comment_lines = len([l for l in lines if l.strip().startswith('#') or l.strip().startswith('//')]) blank_lines = total_lines - code_lines - comment_lines # Calculate complexity complexity_keywords = ['if', 'else', 'elif', 'for', 'while', 'switch', 'case', 'catch', 'try'] complexity = sum(code.lower().count(keyword) for keyword in complexity_keywords) # Check for functions func_count = len(re.findall(r'\bdef\s+\w+\s*\(', code)) if language.lower() == 'python' else len(re.findall(r'\bfunction\s+\w+\s*\(', code)) return { 'total_lines': total_lines, 'code_lines': code_lines, 'comment_lines': comment_lines, 'blank_lines': blank_lines, 'complexity': complexity, 'functions': func_count } def detect_vulnerabilities(code, language): """Detect common security vulnerabilities""" vulnerabilities = [] patterns = { 'SQL Injection': [r'execute\s*\(.*\+.*\)', r'query\s*\(.*\+.*\)', r'SELECT.*\+.*FROM'], 'Hardcoded Secrets': [r'password\s*=\s*["\'][^"\']+["\']', r'api_key\s*=\s*["\'][^"\']+["\']', r'secret\s*=\s*["\'][^"\']+["\']'], 'Command Injection': [r'os\.system\s*\(', r'subprocess\.call\s*\(', r'eval\s*\(', r'exec\s*\('], 'Path Traversal': [r'\.\./', r'open\s*\(.*\+.*\)'], 'XSS Vulnerability': [r'innerHTML\s*=', r'document\.write\s*\('], } for vuln_type, pattern_list in patterns.items(): for pattern in pattern_list: if re.search(pattern, code, re.IGNORECASE): vulnerabilities.append(vuln_type) break return list(set(vulnerabilities)) def generate_smart_suggestions(code, language, errors): """Generate intelligent code suggestions based on detected issues""" suggestions = [] # Suggestions based on errors if errors: suggestions.append("**Critical Issues Found:**") for error in errors[:5]: # Limit to first 5 errors suggestions.append(f"- Line {error['line']}: {error['type']} - {error['message']}") if error['text']: suggestions.append(f" ```{language.lower()}\n {error['text']}\n ```") # Code quality suggestions metrics = analyze_code_structure(code, language) if metrics['comment_lines'] == 0 and metrics['code_lines'] > 5: suggestions.append("\n**Documentation:**") suggestions.append("- Add comments to explain complex logic") suggestions.append("- Consider adding docstrings to functions") if metrics['complexity'] > 10: suggestions.append("\n**Complexity:**") suggestions.append("- High cyclomatic complexity detected. Consider breaking down complex functions") # Language-specific suggestions if language.lower() == 'python': if 'print(' in code and '+' in code: suggestions.append("\n**String Formatting:**") suggestions.append("- Use f-strings instead of string concatenation: `f'The average is {average}'`") if not re.search(r'if\s+__name__\s*==\s*["\']__main__["\']', code) and metrics['code_lines'] > 10: suggestions.append("\n**Best Practices:**") suggestions.append("- Add `if __name__ == '__main__':` guard for script execution") return "\n".join(suggestions) if suggestions else "Code looks good! Consider adding more comments for better maintainability." def review_code(code, language): """Main code review function""" if not code.strip(): return "⚠️ Please enter some code to review.", "", "" # Check for syntax and common errors all_errors = [] if language.lower() == 'python': syntax_errors = check_python_syntax(code) all_errors.extend(syntax_errors) common_errors = check_common_errors(code, language) all_errors.extend(common_errors) # Analyze code structure metrics = analyze_code_structure(code, language) # Detect vulnerabilities vulnerabilities = detect_vulnerabilities(code, language) # Generate smart suggestions suggestions = generate_smart_suggestions(code, language, all_errors) # Format metrics output quality_score = 100 if metrics['comment_lines'] == 0: quality_score -= 20 if all_errors: quality_score -= len(all_errors) * 10 if metrics['complexity'] > 10: quality_score -= 15 quality_score = max(0, quality_score) metrics_output = f"""## 📊 Code Metrics - **Total Lines:** {metrics['total_lines']} - **Code Lines:** {metrics['code_lines']} - **Comment Lines:** {metrics['comment_lines']} - **Blank Lines:** {metrics['blank_lines']} - **Functions:** {metrics['functions']} - **Cyclomatic Complexity:** {metrics['complexity']} - **Comment Ratio:** {(metrics['comment_lines'] / max(metrics['code_lines'], 1) * 100):.1f}% - **Quality Score:** {quality_score}/100 {'🟢' if quality_score >= 70 else '🟡' if quality_score >= 40 else '🔴'} """ # Format errors and vulnerabilities issues_output = "" if all_errors: issues_output += "## ❌ Errors Detected\n\n" for i, error in enumerate(all_errors[:10], 1): # Show first 10 errors issues_output += f"{i}. **{error['type']}** (Line {error['line']})\n" issues_output += f" - {error['message']}\n" if error['text']: issues_output += f" - Code: `{error['text']}`\n" issues_output += "\n" if vulnerabilities: issues_output += "## 🔒 Security Vulnerabilities\n\n" for vuln in vulnerabilities: issues_output += f"- ⚠️ **{vuln}**\n" issues_output += "\n**Recommendation:** Review and fix these security issues before deployment.\n" if not all_errors and not vulnerabilities: issues_output = "## ✅ No Critical Issues Detected\n\nNo syntax errors or obvious security issues found." # Format suggestions suggestions_output = f"""## 💡 Suggestions for Improvement {suggestions} ### General Best Practices: - Write unit tests for your functions - Use meaningful variable and function names - Keep functions small and focused (Single Responsibility Principle) - Handle exceptions appropriately - Follow {language} PEP 8 style guide (for Python) or equivalent standards """ return metrics_output, issues_output, suggestions_output # Custom CSS custom_css = """ #header { text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 10px; margin-bottom: 20px; color: white; } #header h1 { margin: 0; font-size: 2.5em; font-weight: bold; } #header p { margin: 10px 0 0 0; font-size: 1.1em; opacity: 0.9; } .footer { text-align: center; margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 10px; } .footer a { color: #667eea; text-decoration: none; font-weight: bold; margin: 0 10px; } .footer a:hover { text-decoration: underline; } """ # Create Gradio interface with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo: gr.HTML(""" """) with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 📝 Input Code") language = gr.Dropdown( choices=["Python", "JavaScript", "Java", "C++", "C#", "Go", "Ruby", "PHP", "TypeScript", "Swift"], value="Python", label="Programming Language" ) code_input = gr.Code( label="Paste your code here", language="python", lines=15 ) review_btn = gr.Button("🚀 Review Code", variant="primary", size="lg") gr.Markdown(""" ### 📌 Features: - **Syntax error detection** - **Code quality metrics** - **Security vulnerability scan** - **Smart improvement suggestions** - **Multi-language support** """) with gr.Row(): with gr.Column(): metrics_output = gr.Markdown(label="Code Metrics") with gr.Row(): with gr.Column(): issues_output = gr.Markdown(label="Issues & Security") with gr.Row(): with gr.Column(): suggestions_output = gr.Markdown(label="Suggestions") gr.HTML(""" """) review_btn.click( fn=review_code, inputs=[code_input, language], outputs=[metrics_output, issues_output, suggestions_output] ) language.change( fn=lambda x: gr.Code(language=x.lower()), inputs=[language], outputs=[code_input] ) if __name__ == "__main__": demo.launch()