注释文件夹下脚本的Debug

csharp 复制代码
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;

public class SimpleDebugLogCommenter : EditorWindow
{
    private string targetFolderPath = "Assets/Scripts";
    private bool includeSubdirectories = true;
    private bool backupFiles = true;
    
    private int processedFilesCount = 0;
    private int commentedLogsCount = 0;
    
    [MenuItem("Tools/Simple Debug Log Commenter")]
    public static void ShowWindow()
    {
        GetWindow<SimpleDebugLogCommenter>("Simple Debug Log Commenter");
    }
    
    private void OnGUI()
    {
        GUILayout.Label("Debug.Log 注释工具 (简单版)", EditorStyles.boldLabel);
        EditorGUILayout.Space();
        
        // 目标文件夹选择
        EditorGUILayout.BeginHorizontal();
        targetFolderPath = EditorGUILayout.TextField("目标文件夹", targetFolderPath);
        if (GUILayout.Button("选择", GUILayout.Width(60)))
        {
            string path = EditorUtility.OpenFolderPanel("选择文件夹", "Assets", "");
            if (!string.IsNullOrEmpty(path) && path.StartsWith(Application.dataPath))
            {
                targetFolderPath = "Assets" + path.Substring(Application.dataPath.Length);
            }
        }
        EditorGUILayout.EndHorizontal();
        
        includeSubdirectories = EditorGUILayout.Toggle("包含子文件夹", includeSubdirectories);
        backupFiles = EditorGUILayout.Toggle("备份原始文件", backupFiles);
        
        EditorGUILayout.Space();
        
        if (processedFilesCount > 0)
        {
            EditorGUILayout.HelpBox(
                $"上次操作: 处理了 {processedFilesCount} 个文件,注释了 {commentedLogsCount} 个 Debug 语句",
                MessageType.Info
            );
        }
        
        EditorGUILayout.Space();
        
        EditorGUI.BeginDisabledGroup(!Directory.Exists(targetFolderPath));
        if (GUILayout.Button("注释 Debug 语句", GUILayout.Height(30)))
        {
            ProcessFiles();
        }
        EditorGUI.EndDisabledGroup();
        
        EditorGUILayout.Space();
        EditorGUILayout.HelpBox(
            "简单版本,使用更可靠的方法处理Debug语句。",
            MessageType.Warning
        );
    }
    
    private void ProcessFiles()
    {
        if (!Directory.Exists(targetFolderPath))
        {
            EditorUtility.DisplayDialog("错误", "目标文件夹不存在!", "确定");
            return;
        }
        
        if (!EditorUtility.DisplayDialog("确认操作", 
            $"将处理 {targetFolderPath} 下所有脚本中的 Debug 语句。\n继续吗?", "继续", "取消"))
        {
            return;
        }
        
        processedFilesCount = 0;
        commentedLogsCount = 0;
        
        SearchOption searchOption = includeSubdirectories ? 
            SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
        
        string[] files = Directory.GetFiles(targetFolderPath, "*.cs", searchOption);
        
        EditorUtility.DisplayProgressBar("正在处理", "扫描文件...", 0);
        
        try
        {
            for (int i = 0; i < files.Length; i++)
            {
                string file = files[i];
                
                float progress = (float)i / files.Length;
                EditorUtility.DisplayProgressBar(
                    "处理文件中...",
                    $"{Path.GetFileName(file)} ({i + 1}/{files.Length})",
                    progress
                );
                
                int commentedCount = ProcessSingleFile(file);
                if (commentedCount > 0)
                {
                    processedFilesCount++;
                    commentedLogsCount += commentedCount;
                }
            }
            
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();
            
            EditorUtility.DisplayDialog("完成", 
                $"处理完成!\n处理文件: {processedFilesCount}\n注释语句: {commentedLogsCount}",
                "确定"
            );
            
            Repaint();
        }
        catch (System.Exception e)
        {
            EditorUtility.ClearProgressBar();
            EditorUtility.DisplayDialog("错误", $"处理过程中发生错误:\n{e.Message}", "确定");
            Debug.LogError($"DebugLogCommenter 错误: {e}");
        }
    }
    
    private int ProcessSingleFile(string filePath)
    {
        if (!File.Exists(filePath))
            return 0;
        
        string originalContent = File.ReadAllText(filePath, Encoding.UTF8);
        
        // 备份文件
        if (backupFiles)
        {
            string backupPath = filePath + ".backup";
            File.WriteAllText(backupPath, originalContent, Encoding.UTF8);
        }
        
        // 处理内容 - 使用简单但可靠的方法
        string processedContent = ProcessContentSimple(originalContent);
        
        // 如果没有变化,不写文件
        if (processedContent == originalContent)
            return 0;
        
        // 统计注释的数量
        int commentedCount = CountDebugStatements(originalContent) - CountDebugStatements(processedContent);
        
        File.WriteAllText(filePath, processedContent, Encoding.UTF8);
        
        return commentedCount;
    }
    
    private string ProcessContentSimple(string content)
    {
        StringBuilder result = new StringBuilder();
        string[] lines = content.Split('\n');
        
        for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
        {
            string line = lines[lineIndex];
            string processedLine = ProcessLineSimple(line);
            
            // 检查是否有多行Debug语句
            if (ContainsDebugStart(line) && !IsLineCommented(line))
            {
                // 检查括号是否匹配
                int openParenCount = CountChar(line, '(');
                int closeParenCount = CountChar(line, ')');
                
                if (openParenCount > closeParenCount)
                {
                    // 有多行Debug语句,需要特殊处理
                    StringBuilder multiLineStatement = new StringBuilder();
                    multiLineStatement.Append(line);
                    
                    int currentLine = lineIndex;
                    int parenthesesBalance = openParenCount - closeParenCount;
                    
                    while (parenthesesBalance > 0 && currentLine + 1 < lines.Length)
                    {
                        currentLine++;
                        string nextLine = lines[currentLine];
                        multiLineStatement.Append("\n").Append(nextLine);
                        
                        openParenCount = CountChar(nextLine, '(');
                        closeParenCount = CountChar(nextLine, ')');
                        parenthesesBalance += openParenCount - closeParenCount;
                        
                        // 如果这一行有分号且括号平衡,说明语句结束
                        if (parenthesesBalance == 0 && nextLine.Contains(";"))
                        {
                            // 处理这个多行语句
                            string fullStatement = multiLineStatement.ToString();
                            if (!IsAlreadyCommentedInMultiLine(fullStatement))
                            {
                                // 找到第一个Debug的位置
                                int debugIndex = fullStatement.IndexOf("Debug.");
                                if (debugIndex >= 0)
                                {
                                    string beforeDebug = fullStatement.Substring(0, debugIndex);
                                    string debugPart = fullStatement.Substring(debugIndex);
                                    processedLine = beforeDebug + "// " + debugPart;
                                }
                                else
                                {
                                    processedLine = "// " + fullStatement;
                                }
                            }
                            else
                            {
                                processedLine = fullStatement;
                            }
                            
                            lineIndex = currentLine; // 跳过已处理的行
                            break;
                        }
                    }
                }
                else
                {
                    // 单行Debug语句
                    result.Append(processedLine);
                }
            }
            else
            {
                result.Append(processedLine);
            }
            
            if (lineIndex < lines.Length - 1)
            {
                result.Append("\n");
            }
        }
        
        return result.ToString();
    }
    
    private string ProcessLineSimple(string line)
    {
        // 如果行已经被注释,直接返回
        if (IsLineCommented(line))
            return line;
        
        // 检查是否包含Debug语句
        if (!ContainsDebugStatement(line))
            return line;
        
        // 找到Debug的位置
        int debugIndex = FindDebugIndex(line);
        if (debugIndex < 0)
            return line;
        
        // 检查从行开始到Debug位置之间是否有注释符号
        string beforeDebug = line.Substring(0, debugIndex);
        if (beforeDebug.Contains("//") || beforeDebug.Contains("/*"))
            return line;
        
        // 注释这一行(从Debug开始的位置)
        return line.Insert(debugIndex, "// ");
    }
    
    private bool IsLineCommented(string line)
    {
        string trimmedLine = line.Trim();
        return trimmedLine.StartsWith("//") || trimmedLine.StartsWith("/*") || trimmedLine.Contains("*/");
    }
    
    private bool ContainsDebugStatement(string line)
    {
        string lineWithoutStrings = RemoveStringLiterals(line);
        return lineWithoutStrings.Contains("Debug.Log") || 
               lineWithoutStrings.Contains("Debug.LogWarning") || 
               lineWithoutStrings.Contains("Debug.LogError");
    }
    
    private bool ContainsDebugStart(string line)
    {
        string lineWithoutStrings = RemoveStringLiterals(line);
        return lineWithoutStrings.Contains("Debug.Log(") || 
               lineWithoutStrings.Contains("Debug.LogWarning(") || 
               lineWithoutStrings.Contains("Debug.LogError(");
    }
    
    private int FindDebugIndex(string line)
    {
        // 先移除字符串内容,避免在字符串内找到Debug
        string lineWithoutStrings = RemoveStringLiterals(line);
        
        // 查找Debug的位置
        int index = lineWithoutStrings.IndexOf("Debug.Log");
        if (index < 0) index = lineWithoutStrings.IndexOf("Debug.LogWarning");
        if (index < 0) index = lineWithoutStrings.IndexOf("Debug.LogError");
        
        if (index >= 0)
        {
            // 将索引映射回原始行的位置
            // 我们需要找到在原始行中对应的位置
            int originalIndex = MapIndexToOriginalLine(line, lineWithoutStrings, index);
            return originalIndex;
        }
        
        return -1;
    }
    
    private int MapIndexToOriginalLine(string originalLine, string lineWithoutStrings, int indexInStripped)
    {
        // 这个方法将去除字符串后的索引映射回原始行的索引
        int originalIndex = 0;
        int strippedIndex = 0;
        bool inString = false;
        bool escaped = false;
        char stringChar = '\0';
        
        while (originalIndex < originalLine.Length && strippedIndex <= indexInStripped)
        {
            char c = originalLine[originalIndex];
            
            if (escaped)
            {
                escaped = false;
            }
            else if (c == '\\')
            {
                escaped = true;
            }
            else if (!inString && (c == '"' || c == '\''))
            {
                inString = true;
                stringChar = c;
            }
            else if (inString && c == stringChar)
            {
                inString = false;
            }
            
            if (!inString)
            {
                strippedIndex++;
            }
            
            if (strippedIndex > indexInStripped)
            {
                return originalIndex;
            }
            
            originalIndex++;
        }
        
        return originalIndex;
    }
    
    private string RemoveStringLiterals(string line)
    {
        StringBuilder result = new StringBuilder();
        bool inString = false;
        bool escaped = false;
        char stringChar = '\0';
        
        for (int i = 0; i < line.Length; i++)
        {
            char c = line[i];
            
            if (escaped)
            {
                escaped = false;
                if (!inString) result.Append(c);
            }
            else if (c == '\\')
            {
                escaped = true;
                if (!inString) result.Append(c);
            }
            else if (!inString && (c == '"' || c == '\''))
            {
                inString = true;
                stringChar = c;
                // 不添加引号到结果中
            }
            else if (inString && c == stringChar)
            {
                inString = false;
                // 不添加引号到结果中
            }
            else if (!inString)
            {
                result.Append(c);
            }
            // 如果在字符串中,不添加到结果
        }
        
        return result.ToString();
    }
    
    private int CountChar(string text, char charToCount)
    {
        int count = 0;
        bool inString = false;
        bool escaped = false;
        char stringChar = '\0';
        
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            
            if (escaped)
            {
                escaped = false;
                continue;
            }
            
            if (c == '\\')
            {
                escaped = true;
                continue;
            }
            
            if (!inString && (c == '"' || c == '\''))
            {
                inString = true;
                stringChar = c;
            }
            else if (inString && c == stringChar)
            {
                inString = false;
            }
            
            if (!inString && c == charToCount)
            {
                count++;
            }
        }
        
        return count;
    }
    
    private bool IsAlreadyCommentedInMultiLine(string text)
    {
        string[] lines = text.Split('\n');
        foreach (string line in lines)
        {
            string trimmed = line.Trim();
            if (trimmed.StartsWith("//") || trimmed.StartsWith("/*"))
            {
                return true;
            }
        }
        return false;
    }
    
    private int CountDebugStatements(string content)
    {
        int count = 0;
        string[] lines = content.Split('\n');
        
        foreach (string line in lines)
        {
            string lineWithoutStrings = RemoveStringLiterals(line);
            if ((lineWithoutStrings.Contains("Debug.Log(") || 
                 lineWithoutStrings.Contains("Debug.LogWarning(") || 
                 lineWithoutStrings.Contains("Debug.LogError(")) &&
                !IsLineCommented(line))
            {
                count++;
            }
        }
        
        return count;
    }
}
相关推荐
月明长歌3 小时前
【码道初阶】【LeetCode 572】另一棵树的子树:当“递归”遇上“递归”
算法·leetcode·职场和发展
白露与泡影3 小时前
Java关键字解析之final:不可变的本质、设计哲学与并发安全
java·开发语言·安全
Li_7695323 小时前
IDEA 中 maven 图标失踪解决措施
java·maven·intellij-idea
月明长歌3 小时前
【码道初阶】【LeetCode 150】逆波兰表达式求值:为什么栈是它的最佳拍档?
java·数据结构·算法·leetcode·后缀表达式
想用offer打牌3 小时前
一站式了解长轮询,SSE和WebSocket
java·网络·后端·websocket·网络协议·系统架构
C雨后彩虹3 小时前
最大数字问题
java·数据结构·算法·华为·面试
java修仙传3 小时前
力扣hot100:搜索二维矩阵
算法·leetcode·矩阵
梦里不知身是客113 小时前
tomcat作用和功能以及默认端口号
java·tomcat
码界奇点3 小时前
基于SpringBoot与Vue3的多租户中后台管理系统设计与实现
java·spring boot·后端·spring·车载系统·毕业设计·源代码管理