/// <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); }