private void ОбойтиВсеФайлы() { foreach (FileInfo Файл in files) { String ИмяМодуля = Path.GetDirectoryName(Файл.FullName).Substring(3).Replace('\\', '.') + '.' + Файл.Name; Модуль МодульОбъекта = new Модуль(Файл); if (!Модули.ContainsKey(ИмяМодуля)) { Модули.Add(ИмяМодуля, МодульОбъекта); } } Console.WriteLine("Будет проанализировано " + Модули.Count.ToString() + " текстов Модулей"); //foreach (KeyValuePair<String, Модуль> Объект in Модули)НайтиВсеФункцииИПроцедуры(Объект.Value); int КоличествоМодулей = Модули.Count; foreach (KeyValuePair <String, Модуль> Объект in Модули) { Console.WriteLine(Объект.Key); АнализироватьЦиклы(Объект.Value); if (Объект.Value.ЕстьОшибки) { Console.Write((int)(100 - ((float)КоличествоМодулей / (float)Модули.Count) * 100.0f)); Console.WriteLine("% " + Объект.Key); foreach (var T in Объект.Value.ТаблицаАнализа) { Console.WriteLine("строка " + Объект.Value.ПолучитьНомерСтрокиПоИндексу(T.Смещение) + ": \n" + T.ОписаниеПроблемы + "\n"); } } КоличествоМодулей--; } }
private void ПолучитьВсеМодулиИзФайлов() { foreach (FileInfo Файл in files) { String ИмяМодуля = Файл.Name.Replace(".Модуль.txt", "").Replace(".txt", ""); Модуль МодульОбъекта = new Модуль(Файл); if (МодульОбъекта.ЕстьОшибки) { System.Console.Write("x"); } else { System.Console.Write("."); } всегоСтрок += МодульОбъекта.ПолучитьНомерСтрокиПоИндексу(-1); if (!КоманднаяСтрока.isAnalyzeCode) { continue; } if (!Модули.ContainsKey(ИмяМодуля)) { Модули.Add(ИмяМодуля, МодульОбъекта); } } }
public void АнализироватьЦиклы(Модуль МодульОбъекта) { var ПоискФункций = new Regex(@"(Для|Пока|for|while).+(Цикл|do)[\S\s]*?(КонецЦикла|endfor|enddo)", RegexOptions.IgnoreCase | RegexOptions.Multiline); //(Для|Пока).+ нужен иначе выражение находит ....Цикла; код код код для цикл КонецЦикла; // необходимо переработать это выражение т.к если попадаются вложенные циклы то обрабатываются неверно MatchCollection Найдены = ПоискФункций.Matches(МодульОбъекта.Текст); foreach (Match Функция in Найдены) { екурсивныйПоискЗапроса(Функция.Value, МодульОбъекта, Функция.Index, new СвойстваМетодов(), "", 0); } }
/// <summary> /// Метод производит поиск всех всех функции И процедур. /// отмечая их свойства: с запросом и стек вызовов /// </summary> /// <param name="МодульОбъекта">Модуль объекта.</param> private void НайтиВсеФункцииИПроцедуры(Модуль МодульОбъекта) { var ПоискФункций = new Regex(@"^(?!\/\/)[^\.\/]*?(procedur|functio|Процедур|Функци)[enая][\s]*?([А-Яа-яa-z0-9_]*?)[\s]?\(([\S\s]*?)(Конец|End)\1[enыи]", RegexOptions.IgnoreCase | RegexOptions.Multiline); MatchCollection Найдены = ПоискФункций.Matches(МодульОбъекта.Текст); foreach (Match Функция in Найдены) { СвойстваМетодов СвойствоМетода = new СвойстваМетодов(); СвойствоМетода.ЕстьЗапрос = екурсивныйПоискЗапроса(Функция.Groups[3].Value, МодульОбъекта, Функция.Index, СвойствоМетода, Функция.Groups[2].Value, 1); СвойствоМетода.Index = Функция.Index; //МодульОбъекта.ДобавитьМетод(Функция.Groups[2].Value, СвойствоМетода); } }
private bool НайденЗапросРекурсивно(СвойстваМетодов вСвойствоМетода, СвойстваМетодов вызывающийЦиклСвойствоМетода, Модуль МодульОбъекта, int Глубина) { if (вСвойствоМетода.ЕстьЗапрос) { return(true); } // spin.Turn(вСвойствоМетода.ИмяМетода); if (Глубина > 10) { //String КусокКода = "Запутаная рекурсия в " + МодульОбъекта.file.Name + " в " + вызывающийЦиклСвойствоМетода.ИмяМетода + "->...->" + вСвойствоМетода.ИмяМетода + "\nМетод вызывает цепочку методов которые снова вызывают этот же метод, возможно переполнение стека"; //ИнформацияАнализа Анализ = new ИнформацияАнализа(вызывающийЦиклСвойствоМетода.Index, КусокКода, вызывающийЦиклСвойствоМетода.ПолучитьСтекСтрокой()); //МодульОбъекта.ДобавитьПроблему(Анализ); return(false); } foreach (var Метод in вСвойствоМетода.ВызываемыеМетоды) { СвойстваМетодов ВызываемыйСвойствоМетода; if (МодульОбъекта.СловарьМетодов.TryGetValue(Метод.Key, out ВызываемыйСвойствоМетода)) { if (НайденЗапросРекурсивно(ВызываемыйСвойствоМетода, вызывающийЦиклСвойствоМетода, МодульОбъекта, Глубина + 1)) { вСвойствоМетода.ЕстьЗапрос = true; вызывающийЦиклСвойствоМетода.ДобавитьВызов(Метод.Key); return(true); } } } return(false); }
/// <summary> /// Функция производит поиск запросов в вызываемых методах текста /// </summary> /// <param name="Текст">Текст процедуры</param> /// <param name="МодульОбъекта">Весь файл</param> /// <param name="Index">точка входа в процедуру </param> /// <param name="СвойствоМетода">Свойства вызываемых процедур</param> /// <param name="ВызывающийМетод">защита от рекурсий</param> /// <returns>Истина/Ложь</returns> private Boolean екурсивныйПоискЗапроса(String Текст, Модуль МодульОбъекта, int Index, СвойстваМетодов СвойствоМетода, String ВызывающийМетод, int Глубина) { spin.Turn(ВызывающийМетод); String СтекСтрокой = СвойствоМетода.ПолучитьСтекСтрокой(); if (СтекСтрокой.Length > 100) { СтекСтрокой = СтекСтрокой.Substring(0, 100) + "... "; } if (Глубина > 20) { String КусокКода = "Запутаная рекурсия в " + МодульОбъекта.file.Name + " Методе " + ВызывающийМетод + " -> " + СтекСтрокой + "\nМетод вызывает цепочку методов которые снова вызывают этот же метод, возможно переполнение стека"; ИнформацияАнализа Анализ = new ИнформацияАнализа(Index, КусокКода, СтекСтрокой); МодульОбъекта.ДобавитьПроблему(Анализ); СвойствоМетода = new СвойстваМетодов(); Глубина = 1; return(false); } ТелоКода Тело = new ТелоКода(Текст, Index); if (Тело.КоличествоСтрок > 300 && Глубина > 0) { String КусокКода = "Слишком много строк кода в одном методе " + ВызывающийМетод + " -> " + СтекСтрокой + "\n, для повышения массштабируемости и командной поддержки кода, желательно разбить его на несколько методов"; МодульОбъекта.ДобавитьПроблему(new ИнформацияАнализа(Index, КусокКода, СтекСтрокой)); } if (Тело.ЕстьЗапрос()) { СвойствоМетода.ЕстьЗапрос = true; if (Глубина == 0) { МодульОбъекта.ДобавитьПроблему(Тело.ПолучитьАнализ()); } else { return(true); } } if (КоманднаяСтрока.isSearchChainCalls) { var цепочныйВызов = Тело.ВызовыПоЦепочке(); if (цепочныйВызов != null) { МодульОбъекта.ДобавитьПроблему(цепочныйВызов); } } //Ищем другие вызываемые процедуры MatchCollection Найдены = Тело.НайтиВызовы(); foreach (Match Вызов in Найдены) { if (ВызывающийМетод.ToUpper().Contains(Вызов.Groups[1].Value.ToUpper())) { continue; //self call //рекурсия } СвойстваМетодов вСвойствоМетода; if (МодульОбъекта.СловарьМетодов.TryGetValue(Вызов.Groups[1].Value.ToUpper(), out вСвойствоМетода)) { if (НайденЗапросРекурсивно(вСвойствоМетода, СвойствоМетода, МодульОбъекта, 0)) { СтекСтрокой = СвойствоМетода.ПолучитьСтекСтрокой() + "Запрос()"; String КусокКода = (Текст.Length > 20 ? Текст.Substring(0, 20).Trim() : "") + "\n...\n" + СтекСтрокой; ИнформацияАнализа Анализ = new ИнформацияАнализа(Вызов.Groups[1].Index + Index, КусокКода, СтекСтрокой); МодульОбъекта.ДобавитьПроблему(Анализ); СвойствоМетода = new СвойстваМетодов().ДобавитьВызов(ВызывающийМетод); continue; } } } return(false); }
/// <summary> /// Функция производит поиск запросов в вызываемых методах текста /// </summary> /// <param name="Текст">Текст процедуры</param> /// <param name="МодульОбъекта">Весь файл</param> /// <param name="Index">точка входа в процедуру </param> /// <param name="СвойствоМетода">Свойства вызываемых процедур</param> /// <param name="ВызывающийМетод">защита от рекурсий</param> /// <returns>Истина/Ложь</returns> private Boolean екурсивныйПоискЗапроса(String Текст, Модуль МодульОбъекта, int Index, СвойстваМетодов СвойствоМетода, String ВызывающийМетод, int Глубина) { if (Глубина > 20) { String СтекСтрокой = СвойствоМетода.ПолучитьСтекСтрокой(); String КусокКода = "Запутаная рекурсия в " + МодульОбъекта.file.Name + " Методе " + ВызывающийМетод + " -> " + СтекСтрокой + "\nМетод вызывает цепочку методов которые снова вызывают этот же метод, возможно переполнение стека"; ИнформацияАнализа Анализ = new ИнформацияАнализа(Index, КусокКода, СтекСтрокой); МодульОбъекта.ДобавитьПроблему(Анализ); СвойствоМетода = new СвойстваМетодов(); return(false); } ТелоКода Тело = new ТелоКода(Текст, Index); if (Тело.ЕстьЗапрос()) { СвойствоМетода.ЕстьЗапрос = true; if (Глубина == 0) { МодульОбъекта.ДобавитьПроблему(Тело.ПолучитьАнализ()); } else { return(true); } } //Ищем другие вызываемые процедуры MatchCollection Найдены = Тело.НайтиВызовы(); foreach (Match Вызов in Найдены) { if (ВызывающийМетод.ToUpper().Contains(Вызов.Groups[1].Value.ToUpper())) { continue; //self call //рекурсия } var ПоискМетода = new Regex(@"(Процедур|Функци|procedur|functio)[аяne][\s]*?" + ЭкранироватьРег(Вызов.Groups[1].Value) + @"[\s]*?\(([\S\s]*?)(Конец|end)\1[ыиen]", RegexOptions.IgnoreCase | RegexOptions.Multiline); Match Найден = ПоискМетода.Match(МодульОбъекта.Текст); if (!Найден.Success) { continue; } //натравим на эти процедуры эту же функцию СвойствоМетода.ДобавитьВызов(Вызов.Groups[1].Value); if (екурсивныйПоискЗапроса(Найден.Groups[2].Value, МодульОбъекта, Найден.Index, СвойствоМетода, Вызов.Groups[1].Value, Глубина + 1)) { СвойствоМетода.ЕстьЗапрос = true; if (Глубина == 0) { String СтекСтрокой = СвойствоМетода.ПолучитьСтекСтрокой() + "Запрос()"; String КусокКода = (Текст.Length > 20 ? Текст.Substring(0, 20).Trim() : "") + "\n...\n" + СтекСтрокой; ИнформацияАнализа Анализ = new ИнформацияАнализа(Вызов.Groups[1].Index + Index, КусокКода, СтекСтрокой); МодульОбъекта.ДобавитьПроблему(Анализ); СвойствоМетода = new СвойстваМетодов(); continue; } return(true); } else { СвойствоМетода.УдалитьВызов(Вызов.Groups[1].Value); } } return(false); }