class OpenCodeAI { constructor() { this.supportedLanguages = [ 'javascript', 'python', 'java', 'cpp', 'c', 'csharp', 'go', 'rust', 'php', 'typescript', 'html', 'css' ]; } // 分析代码质量 async analyzeCode(code, language) { const analysis = { language: this.detectLanguage(code, language), issues: [], suggestions: [], metrics: this.calculateMetrics(code) }; // 基本语法检查 analysis.issues = this.checkSyntax(code, analysis.language); // 生成改进建议 analysis.suggestions = this.generateSuggestions(code, analysis.language); return analysis; } // 检测编程语言 detectLanguage(code, hintedLanguage) { if (hintedLanguage && this.supportedLanguages.includes(hintedLanguage)) { return hintedLanguage; } // 简单的语言检测 if (code.includes('def ') && code.includes(':')) return 'python'; if (code.includes('function ') || code.includes('const ')) return 'javascript'; if (code.includes('public class ')) return 'java'; if (code.includes('#include')) return 'cpp'; if (code.includes(' { // 检查未闭合的括号 if (line.includes('{') || line.includes('(') || line.includes('[')) { const openBrackets = (line.match(/[({[]/g) || []).length; const closeBrackets = (line.match(/[)}\]]/g) || []).length; if (openBrackets !== closeBrackets) { issues.push({ line: index + 1, type: 'syntax', message: '可能存在未闭合的括号', severity: 'warning' }); } } // 检查过长的行 if (line.length > 120) { issues.push({ line: index + 1, type: 'style', message: '行长度过长 (>120字符)', severity: 'info' }); } }); // 语言特定检查 switch (language) { case 'javascript': issues.push(...this.checkJavaScript(code)); break; case 'python': issues.push(...this.checkPython(code)); break; case 'java': issues.push(...this.checkJava(code)); break; } return issues; } // JavaScript 特定检查 checkJavaScript(code) { const issues = []; // 检查var关键字 if (code.includes('var ')) { issues.push({ line: null, type: 'style', message: '建议使用 let 或 const 替代 var', severity: 'warning' }); } // 检查分号缺失 const statements = code.split('\n').filter(line => line.trim() && !line.trim().startsWith('//') && !line.trim().startsWith('/*') && !line.includes('{') && !line.includes('}') && !line.endsWith(';') && !line.endsWith(',') && !line.includes('if ') && !line.includes('for ') && !line.includes('while ') && !line.includes('function ') ); if (statements.length > 0) { issues.push({ line: null, type: 'style', message: '可能缺少分号', severity: 'info' }); } return issues; } // Python 特定检查 checkPython(code) { const issues = []; // 检查PEP 8缩进 const lines = code.split('\n'); lines.forEach((line, index) => { const trimmed = line.trim(); if (trimmed && !trimmed.startsWith('#')) { const leadingSpaces = line.length - line.trimStart().length; if (leadingSpaces % 4 !== 0) { issues.push({ line: index + 1, type: 'style', message: '缩进应该使用4个空格', severity: 'warning' }); } } }); return issues; } // Java 特定检查 checkJava(code) { const issues = []; // 检查类名 const classMatch = code.match(/class\s+(\w+)/); if (classMatch && !/^[A-Z]/.test(classMatch[1])) { issues.push({ line: null, type: 'style', message: '类名应该以大写字母开头', severity: 'warning' }); } return issues; } // 生成代码改进建议 generateSuggestions(code, language) { const suggestions = []; // 性能建议 if (code.includes('for (')) { suggestions.push({ type: 'performance', message: '考虑使用更高效的循环方式,如 forEach 或 map', code_example: '// 替代方案\narray.forEach(item => { /* ... */ });' }); } // 可读性建议 if (code.includes('TODO') || code.includes('FIXME')) { suggestions.push({ type: 'maintenance', message: '发现待办事项,建议及时处理' }); } // 安全建议 if (code.includes('eval(')) { suggestions.push({ type: 'security', message: '避免使用 eval(),存在安全风险', severity: 'high' }); } return suggestions; } // 计算代码指标 calculateMetrics(code) { const lines = code.split('\n'); const totalLines = lines.length; const codeLines = lines.filter(line => line.trim() && !line.trim().startsWith('//') && !line.trim().startsWith('#') && !line.trim().startsWith('/*') ).length; return { total_lines: totalLines, code_lines: codeLines, comment_lines: totalLines - codeLines, complexity: this.calculateComplexity(code) }; } // 计算圈复杂度 calculateComplexity(code) { let complexity = 1; // 基础复杂度 const complexityKeywords = ['if', 'else', 'for', 'while', 'switch', 'case', 'catch', '&&', '||']; complexityKeywords.forEach(keyword => { const regex = new RegExp(`\\b${keyword}\\b`, 'g'); const matches = code.match(regex); if (matches) complexity += matches.length; }); return complexity; } // 代码补全 async getCodeCompletion(partialCode, position) { // 简单的代码补全逻辑 const suggestions = []; const line = partialCode.split('\n')[position.line - 1] || ''; const currentWord = line.substring(0, position.character).split(' ').pop(); const language = this.detectLanguage(partialCode); switch (language) { case 'javascript': suggestions.push(...this.getJavaScriptCompletions(currentWord)); break; case 'python': suggestions.push(...this.getPythonCompletions(currentWord)); break; default: suggestions.push(...this.getGenericCompletions(currentWord)); } return suggestions; } getJavaScriptCompletions(currentWord) { const jsKeywords = [ 'function', 'const', 'let', 'var', 'if', 'else', 'for', 'while', 'return', 'class', 'extends', 'import', 'export', 'async', 'await', 'map', 'filter', 'reduce', 'forEach', 'find', 'some', 'every' ]; return jsKeywords .filter(keyword => keyword.startsWith(currentWord)) .map(keyword => ({ text: keyword, type: 'keyword', description: `JavaScript keyword: ${keyword}` })); } getPythonCompletions(currentWord) { const pythonKeywords = [ 'def', 'class', 'if', 'elif', 'else', 'for', 'while', 'return', 'import', 'from', 'as', 'try', 'except', 'with', 'len', 'range', 'list', 'dict', 'set', 'tuple', 'str' ]; return pythonKeywords .filter(keyword => keyword.startsWith(currentWord)) .map(keyword => ({ text: keyword, type: 'keyword', description: `Python keyword: ${keyword}` })); } getGenericCompletions(currentWord) { return [ { text: currentWord, type: 'variable', description: 'Current variable' } ]; } } export default OpenCodeAI;