用脚本自动生成代码注释

wen 实用脚本 2

本文目录导读:

用脚本自动生成代码注释

  1. 方案一:Python 通用注释生成器
  2. 方案二:Git 钩子 - 提交时自动添加注释
  3. 方案三:IDE 扩展版(VS Code)
  4. 使用说明
  5. 高级功能建议

我来帮你创建几个自动生成代码注释的脚本方案,覆盖不同语言和使用场景。

Python 通用注释生成器

#!/usr/bin/env python3
"""
自动代码注释生成器
支持 Python, JavaScript, Java, C/C++ 等语言
"""
import os
import re
import ast
from typing import List, Dict, Optional
class CodeCommentGenerator:
    def __init__(self):
        self.language_map = {
            '.py': 'python',
            '.js': 'javascript',
            '.ts': 'typescript',
            '.java': 'java',
            '.c': 'c',
            '.cpp': 'cpp',
            '.h': 'c_header',
            '.hpp': 'cpp_header'
        }
    def detect_language(self, file_path: str) -> str:
        """检测文件语言类型"""
        ext = os.path.splitext(file_path)[1].lower()
        return self.language_map.get(ext, 'unknown')
    def generate_python_docstring(self, source: str) -> str:
        """为 Python 代码生成 docstring"""
        try:
            tree = ast.parse(source)
            lines = source.split('\n')
            new_lines = []
            for node in ast.walk(tree):
                if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
                    # 获取函数的行号
                    start_line = node.lineno - 1
                    # 检查是否已有 docstring
                    if (node.body and 
                        isinstance(node.body[0], ast.Expr) and 
                        isinstance(node.body[0].value, ast.Str)):
                        continue
                    # 生成 docstring
                    doc = self._generate_python_doc(node)
                    indent = ' ' * (node.col_offset + 4)
                    # 在函数定义后插入 docstring
                    insertion_line = start_line
                    while insertion_line < len(lines):
                        if lines[insertion_line].strip().endswith(':'):
                            break
                        insertion_line += 1
                    if insertion_line < len(lines):
                        doc_lines = [f"{indent}{line}" for line in doc.split('\n')]
                        new_lines.extend(lines[:insertion_line + 1])
                        new_lines.extend(doc_lines)
                        new_lines.extend(lines[insertion_line + 1:])
                        lines = new_lines
                        new_lines = []
            return '\n'.join(lines)
        except Exception as e:
            print(f"Error parsing Python: {e}")
            return source
    def _generate_python_doc(self, node) -> str:
        """生成 Python docstring 内容"""
        if isinstance(node, ast.FunctionDef):
            params = [arg.arg for arg in node.args.args if arg.arg != 'self']
            returns = self._get_return_type(node)
            doc = '"""\n'
            doc += f"    {node.name} 函数\n\n"
            doc += "    功能描述:\n    [在此描述函数功能]\n\n"
            if params:
                doc += "    参数:\n"
                for param in params:
                    doc += f"        {param}: [参数类型] - [参数描述]\n"
                doc += "\n"
            if returns:
                doc += f"    返回:\n        [返回值类型] - [返回值描述]\n"
            doc += '    """'
            return doc
        elif isinstance(node, ast.ClassDef):
            doc = '"""\n'
            doc += f"    {node.name} 类\n\n"
            doc += "    功能描述:\n    [在此描述类功能]\n\n"
            doc += "    属性:\n"
            for item in node.body:
                if isinstance(item, ast.FunctionDef) and item.name == '__init__':
                    for arg in item.args.args[1:]:
                        doc += f"        {arg.arg}: [属性描述]\n"
            doc += '\n    """'
            return doc
        return '"""\n    [在此添加文档]\n    """'
    def _get_return_type(self, node) -> Optional[str]:
        """获取函数返回类型"""
        if node.returns:
            return ast.dump(node.returns)
        return None
    def generate_js_comment(self, source: str) -> str:
        """为 JavaScript/TypeScript 生成 JSDoc 注释"""
        # 匹配函数声明
        pattern = r'(function\s+\w+\s*\([^)]*\)|const\s+\w+\s*=\s*\([^)]*\)\s*=>|class\s+\w+)'
        lines = source.split('\n')
        new_lines = []
        for i, line in enumerate(lines):
            match = re.match(r'^(\s*)(function\s+\w+\s*\([^)]*\)|const\s+\w+\s*=\s*\([^)]*\)\s*=>|class\s+\w+)', line)
            if match:
                indent = match.group(1)
                declaration = match.group(2)
                # 检查是否已有注释
                if i > 0 and '/**' in lines[i-1]:
                    new_lines.append(line)
                    continue
                # 生成 JSDoc 注释
                comment_lines = self._generate_js_doc(declaration, indent)
                new_lines.extend(comment_lines)
                new_lines.append(line)
            else:
                new_lines.append(line)
        return '\n'.join(new_lines)
    def _generate_js_doc(self, declaration: str, indent: str) -> List[str]:
        """生成 JavaScript JSDoc 注释"""
        comments = []
        comments.append(f"{indent}/**")
        comments.append(f"{indent} * [功能描述]")
        # 提取参数
        params = re.findall(r'\(\s*([^)]*)\)', declaration)
        if params and params[0].strip():
            params_list = [p.split(':')[0].strip() for p in params[0].split(',')]
            comments.append(f"{indent} *")
            for param in params_list:
                if param and param != ')':
                    comments.append(f"{indent} * @param {{{param}}} - [参数描述]")
        comments.append(f"{indent} * @returns [返回值描述]")
        comments.append(f"{indent} */")
        return comments
    def generate_c_comment(self, source: str) -> str:
        """为 C/C++ 生成 Doxygen 注释"""
        # 匹配函数定义
        pattern = r'^(\w[\w\s\*]*?)\s+(\w+)\s*\(([^)]*)\)\s*\{'
        lines = source.split('\n')
        new_lines = []
        for i, line in enumerate(lines):
            match = re.match(r'^(\s*)([\w\*]+\s+\w+\s*\([^)]*\))\s*\{?', line)
            if match and i > 0 and '/**' not in lines[i-1]:
                indent = match.group(1)
                func_signature = match.group(2)
                # 生成 Doxygen 注释
                comments = self._generate_c_doc(func_signature, indent)
                new_lines.extend(comments)
                new_lines.append(line)
            else:
                new_lines.append(line)
        return '\n'.join(new_lines)
    def _generate_c_doc(self, signature: str, indent: str) -> List[str]:
        """生成 C/C++ Doxygen 注释"""
        comments = []
        comments.append(f"{indent}/**")
        comments.append(f"{indent} * @brief [函数功能简述]")
        comments.append(f"{indent} * [详细描述]")
        comments.append(f"{indent} *")
        # 提取参数
        params = re.findall(r'\(([^)]*)\)', signature)
        if params and params[0].strip():
            for param in params[0].split(','):
                if param.strip():
                    parts = param.strip().split()
                    if len(parts) >= 2:
                        type_name = ' '.join(parts[:-1])
                        param_name = parts[-1]
                        comments.append(f"{indent} * @param {param_name} [参数描述]")
        comments.append(f"{indent} * @return [返回值描述]")
        comments.append(f"{indent} */")
        return comments
    def process_file(self, file_path: str) -> bool:
        """处理单个文件"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                source = f.read()
            lang = self.detect_language(file_path)
            result = source
            if lang == 'python':
                result = self.generate_python_docstring(source)
            elif lang in ['javascript', 'typescript']:
                result = self.generate_js_comment(source)
            elif lang in ['c', 'cpp', 'c_header', 'cpp_header']:
                result = self.generate_c_comment(source)
            else:
                print(f"不支持的文件类型: {file_path}")
                return False
            if result != source:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(result)
                print(f"已更新注释: {file_path}")
                return True
            print(f"无需更新或无法处理: {file_path}")
            return False
        except Exception as e:
            print(f"处理文件失败 {file_path}: {e}")
            return False
    def process_directory(self, directory: str, extensions: Optional[List[str]] = None):
        """处理目录下所有文件"""
        if extensions is None:
            extensions = ['.py', '.js', '.ts', '.java', '.c', '.cpp']
        processed = 0
        failed = 0
        for root, dirs, files in os.walk(directory):
            for filename in files:
                ext = os.path.splitext(filename)[1].lower()
                if ext in extensions:
                    file_path = os.path.join(root, filename)
                    try:
                        if self.process_file(file_path):
                            processed += 1
                    except Exception as e:
                        print(f"处理失败: {file_path} - {e}")
                        failed += 1
        print(f"\n处理完成!成功: {processed} 个文件, 失败: {failed} 个文件")
# 命令行接口
def main():
    import argparse
    parser = argparse.ArgumentParser(description='自动代码注释生成器')
    parser.add_argument('path', help='文件或目录路径')
    parser.add_argument('--type', choices=['python', 'js', 'c'], 
                       help='强制指定语言类型')
    parser.add_argument('--extensions', nargs='+', default=None,
                       help='处理的文件扩展名列表')
    args = parser.parse_args()
    generator = CodeCommentGenerator()
    if os.path.isfile(args.path):
        generator.process_file(args.path)
    elif os.path.isdir(args.path):
        generator.process_directory(args.path, args.extensions)
    else:
        print("路径不存在!")
if __name__ == "__main__":
    main()

Git 钩子 - 提交时自动添加注释

#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 开始自动生成代码注释..."
# 获取暂存的文件
staged_files=$(git diff --cached --name-only --diff-filter=ACM)
echo "检测到待处理文件:"
for file in $staged_files; do
    echo "  📄 $file"
done
# 调用 Python 脚本处理注释
if [ -n "$staged_files" ]; then
    for file in $staged_files; do
        case "$file" in
            *.py|*.js|*.ts|*.java)
                python3 -m auto_comments "$file"
                git add "$file"
                echo "  ✅ 已更新注释: $file"
                ;;
        esac
    done
fi
echo "✨ 注释生成完成!"
exit 0

IDE 扩展版(VS Code)

// comment-generator-extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
    console.log('自动注释生成器已激活');
    // 注册命令:生成单个函数注释
    let generateComment = vscode.commands.registerCommand(
        'comment-generator.generateFunctionComment',
        async () => {
            const editor = vscode.window.activeTextEditor;
            if (!editor) return;
            const document = editor.document;
            const position = editor.selection.active;
            const line = document.lineAt(position.line);
            const languageId = document.languageId;
            let comment = '';
            // 根据语言生成不同风格的注释
            switch (languageId) {
                case 'python':
                    comment = generatePythonDoc();
                    break;
                case 'javascript':
                case 'typescript':
                    comment = generateJSComment();
                    break;
                case 'c':
                case 'cpp':
                    comment = generateCComment();
                    break;
                default:
                    vscode.window.showErrorMessage('不支持的语言类型');
                    return;
            }
            // 插入注释
            await editor.edit(editBuilder => {
                editBuilder.insert(line.range.start, comment);
            });
            vscode.window.showInformationMessage('注释已生成!');
        }
    );
    // 注册命令:批量生成整个文件注释
    let generateFileComments = vscode.commands.registerCommand(
        'comment-generator.generateFileComments',
        async () => {
            const editor = vscode.window.activeTextEditor;
            if (!editor) return;
            const document = editor.document;
            const text = document.getText();
            // 这里调用后端 API 或本地脚本处理整个文件
            vscode.window.showInformationMessage('正在处理整个文件...');
        }
    );
    context.subscriptions.push(generateComment, generateFileComments);
}
function generatePythonDoc(): string {
    return `"""
功能描述:
[在此描述函数功能]
参数:
    [参数名]: [参数类型] - [参数描述]
返回:
    [返回值类型] - [返回值描述]
"""
`;
}
function generateJSComment(): string {
    return `/**
 * [功能描述]
 * 
 * @param {[类型]} [参数名] - [参数描述]
 * @returns {[类型]} [返回值描述]
 */
`;
}
function generateCComment(): string {
    return `/**
 * @brief [函数功能简述]
 * 
 * @param [参数名] [参数描述]
 * @return [返回值描述]
 */
`;
}

使用说明

Python 脚本使用

# 添加执行权限
chmod +x auto_comments.py
# 处理单个文件
python3 auto_comments.py path/to/file.py
# 处理整个目录
python3 auto_comments.py ./src
# 指定扩展名
python3 auto_comments.py ./src --extensions .py .js

Git Hook 配置

# 将脚本放到 .git/hooks/ 目录
chmod +x .git/hooks/pre-commit
# 或者全局配置
git config --global core.hooksPath ~/.githooks

VS Code 扩展

安装到 VS Code:

  1. 将 TypeScript 代码转换为纯 JS 版本
  2. 或使用 yo code 创建扩展项目
  3. 配置快捷键:Ctrl+Shift+P → 打开键盘快捷键设置
// keybindings.json
{
    "key": "ctrl+alt+c",
    "command": "comment-generator.generateFunctionComment"
}

高级功能建议

  1. AI 集成:可集成 ChatGPT 等 AI 服务生成更智能的注释
  2. 配置系统:支持通过 JSON/YAML 配置文件定制注释模板
  3. 多语言支持:扩展支持更多语言(Go、Rust、PHP 等)
  4. 代码分析:结合 AST 分析生成更准确的注释
  5. 批量处理:支持命令行批量处理和 CI/CD 集成

这些脚本可以根据你的具体需求进行定制和扩展!需要我详细解释某个部分或根据你的语言偏好调整吗?

抱歉,评论功能暂时关闭!