Перем РасширениеФайлаМодуля;
Перем БылоПрерывание;

Функция СохраняемаяНастройкаФормы(выхНаименование, выхИменаСвойств) Экспорт 
	выхИменаСвойств = "Форма.ИскатьВходящие, Форма.ИскатьИсходящие, Форма.ФильтрПодсистем";
	Возврат Неопределено;
КонецФункции

Процедура ЗагрузитьНастройкуВФорме(НастройкаФормы, ДопПараметры) Экспорт 
	
	ирКлиент.ЗагрузитьНастройкуФормыЛкс(ЭтаФорма, НастройкаФормы); 
	
КонецПроцедуры

Процедура ПриОткрытии()
	ирКлиент.Форма_ПриОткрытииЛкс(ЭтаФорма);
	ирКлиент.СоздатьМенеджерСохраненияНастроекФормыЛкс(ЭтаФорма,,, Новый Структура("ПриОткрытии"));
	//ирКлиент.ДопСвойстваЭлементаФормыЛкс(ЭтаФорма, ЭлементыФормы.ДеревоВызовов).МенеджерПоиска = ирКлиент.СоздатьМенеджерПоискаВТабличномПолеЛкс(Новый Структура("Текст")); // Для отключения раскраски
	ЭтаФорма.ДатаОбновленияКэша = ирОбщий.ДатаОбновленияКэшаМодулейЛкс();
	ДеревоВызовов.Строки.Очистить();
	ПеренестиВКорень(ПараметрСтрокаМетода);
	ТаблицаТипов = ВычислитьТипЗначенияВыражения(мКонтекст);
	Если ТаблицаТипов.Количество() Тогда
		СтрокаОписания = ТаблицаТипов[0].СтрокаОписания; // см. мПлатформа.НоваяТаблицаМетодовМодуля()[0]
		Если Истина
			И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
			И СтрокаОписания.Владелец().Колонки.Найти("ТелоБезВозвратов") <> Неопределено
		Тогда
			ТекущийВызываемыйМетод = ДеревоВызовов.Строки[0].Строки.Найти(СтрокаОписания.Имя, "Метод");
			Если ТекущийВызываемыйМетод <> Неопределено Тогда
				ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока = ТекущийВызываемыйМетод;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

//.
// Параметры:
//    СтрокаМетода - СтрокаТаблицыЗначений - 
Процедура ПеренестиВКорень(Знач СтрокаМетода) Экспорт
	ирОбщий.ОбновитьТекстПослеМаркераЛкс(ЭтаФорма.Заголовок,, СтрокаМетода.Имя, ": "); 
	ДеревоВызовов.Строки.Очистить();
	СтрокаКорня = ДеревоВызовов.Строки.Добавить();
	СтрокаКорня.Метод = СтрокаМетода.Имя;
	СтрокаКорня.Модуль = СтрокаМетода.ИмяМодуля;
	//СтрокаКорня.Позиция = СтрокаМетода.ПозицияОпределения;
	СтрокаКорня.Строки.Добавить();
	ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока = ДеревоВызовов.Строки[0];  
	ОбновитьДанные();
КонецПроцедуры

Процедура ОбновитьДанные() Экспорт
	ЭлементыФормы.ДеревоВызовов.Развернуть(ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока); 
КонецПроцедуры

Процедура ПриЗакрытии()  
	
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	
КонецПроцедуры

Функция ТекстФайлаСтроки(Знач ВыбраннаяСтрока = Неопределено)
	
	Если ВыбраннаяСтрока = Неопределено Тогда
		ВыбраннаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	ФайлМодуля = мПлатформа.ФайлМодуляИзИмениМодуля(ВыбраннаяСтрока.Модуль);
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
	ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
	Возврат ТекстФайла;

КонецФункции

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);

КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт 
	
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);

КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник); 

КонецПроцедуры

Процедура КлсКомандаНажатие(Кнопка) Экспорт 
	
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
	
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(Отказ,, Истина) Тогда
		Возврат;
	КонецЕсли;
	ЭтаФорма.ОбработкаОбъект = КопияКомпоненты();
	ПроверитьИнициировать();
КонецПроцедуры

Процедура НайтиВходящие(Знач СтрокаРодителя)
	
	Если ПустаяСтрока(СтрокаРодителя.Модуль) Тогда
		Возврат;
	КонецЕсли;
	ИмяРодногоМодуляБезКонца = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаРодителя.Модуль, "[", "]"));
	АнализаторМодуляРодителя = АнализаторМодуля(СтрокаРодителя);
	СтрокаМетодаРодителя = АнализаторМодуляРодителя.мМодульМетаданных.Методы.Найти(НРег(СтрокаРодителя.Метод), "НИмя");
	ФайлыМодулей = Новый Массив; // Массив из Файл
	ПоискВДинамическомМодуле = Истина
		И АнализаторМодуляРодителя.мМодульМетаданных <> Неопределено
		И АнализаторМодуляРодителя.мМодульМетаданных.Имя = мПлатформа.ИмяДинамическогоМодуля()
		И СтрокаРодителя.Модуль = АнализаторМодуляРодителя.мМодульМетаданных.Имя;
	Если ПоискВДинамическомМодуле Тогда
		ФайлыМодулей.Добавить(Неопределено);
	КонецЕсли; 
	Маска = "";
	Если ТолькоЛокальные Тогда
		Маска = ИмяРодногоМодуляБезКонца + ".";
	КонецЕсли;
	ирОбщий.ДополнитьМассивЛкс(ФайлыМодулей, НайтиФайлы(мПлатформа.ПапкаКэшаМодулей.ПолноеИмя, Маска + "*." + РасширениеФайлаМодуля, Истина)); 
	мПлатформа.ИнициацияОписанияМетодовИСвойств();
	Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ФайлыМодулей.Количество());
	РегВыражениеКэш = Неопределено;
	Если ТолькоЛокальные Тогда
		НачальныйСчетчик = 2;
	Иначе
		НачальныйСчетчик = 1;
	КонецЕсли;
	ШаблонПрямогоВызова = ШаблонПрямогоВызоваСлова(СтрокаРодителя.Метод);
	Если ФильтрПодсистем.Количество() > 0 Тогда
		ОбъектыВыбранныхПодсистем = ирОбщий.ОбъектыПодсистемЛкс(ФильтрПодсистем);
	КонецЕсли;
	ОбъектМД = Неопределено;
	ПриоритетныеФайлы = Новый Массив;    
	РазделительПутиКФайлу = ирОбщий.РазделительПутиКФайлуЛкс();
	Для Каждого Файл Из ФайлыМодулей Цикл
		Если Ложь
			Или Файл = Неопределено
			Или ирОбщий.СтрНайтиЛкс(Файл.ПолноеИмя, РазделительПутиКФайлу + ИмяРодногоМодуляБезКонца + ".",,,, Ложь) > 0 
		Тогда
			ПриоритетныеФайлы.Добавить(Файл);
		КонецЕсли;
	КонецЦикла;
	Для Каждого Файл Из ПриоритетныеФайлы Цикл
		ФайлыМодулей.Удалить(ФайлыМодулей.Найти(Файл));
		ФайлыМодулей.Вставить(0, Файл);
	КонецЦикла;
	ВходящиеВызовыМетода = ВызовыСлова.ВыгрузитьКолонки();
	ВходящиеВызовыМетода.Колонки.ВызывающийМетод.Имя = "Метод";
	ФайлыМодулей = ПриоритетныеФайлы; // Отсекаем внешние ДеревоВызовов
	Для Каждого Файл Из ФайлыМодулей Цикл
		#Если Сервер И Не Сервер Тогда
			Файл = Новый Файл;
		#КонецЕсли
		Если Файл = Неопределено Тогда
			ПолноеИмяФайла = "";
			ИмяМодуля = мПлатформа.ИмяДинамическогоМодуля();
			ТекстовыйДокумент = ПолеТекста;
		Иначе
			ПолноеИмяФайла = Файл.ПолноеИмя;
			ИмяМодуля = СтрЗаменить(ирОбщий.ПоследнийФрагментЛкс(Файл.ПолноеИмя, мПлатформа.ПапкаКэшаМодулей.ПолноеИмя + "\"), "\", " ");
			ИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ИмяМодуля);
			ТекстовыйДокумент = Неопределено;
		КонецЕсли;
		ирОбщий.ОбработатьИндикаторЛкс(Индикатор,, ИмяМодуля);
		Если ТекстовыйДокумент = Неопределено Тогда
			Если ФильтрПодсистем.Количество() > 0 Тогда
				ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПервыеФрагментыЛкс(Файл.ИмяБезРасширения));
				Если ОбъектМД <> Неопределено Тогда
					Если ОбъектыВыбранныхПодсистем[ОбъектМД] = Неопределено тогда
						Продолжить;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			ТекстовыйДокумент = Новый ТекстовыйДокумент;
			ТекстовыйДокумент.Прочитать(ПолноеИмяФайла);
		КонецЕсли;
		ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст();
		Для ЭтапВнутренний = НачальныйСчетчик По 2 Цикл
			Если ЭтапВнутренний = 1 Тогда 
				НайденныеВызовы = мПлатформа.НепрямыеВызовыСловаВМодуле(ИмяМодуля, ТекстовыйДокумент, Файл, ЭтотОбъект, СтрокаРодителя.Метод, Истина);
			ИначеЕсли ЭтапВнутренний = 2 Тогда 
				Если Ложь
					Или (Истина
						//И ИскатьНепрямые 
						И Не ЗначениеЗаполнено(ИмяРодногоМодуляБезКонца))
					Или ирОбщий.СтрНайтиЛкс("." + ИмяМодуля + ".", "." + ИмяРодногоМодуляБезКонца + ".",,,, Ложь) > 0 // TODO переделать на анализ основного объекта формы
				Тогда
					ВхожденияВызова = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонПрямогоВызова,,,,,, Истина, РегВыражениеКэш,, ВхожденияВызова); // Без групп для ускорения
					НайденныеВызовы = ВхожденияВызова;
				Иначе
					Продолжить;
				КонецЕсли;
			КонецЕсли; 
			//
			//Если ЭтапВнутренний = 1 Тогда
			//	Продолжить;
			//КонецЕсли;
			//		ШаблонВнешнегоВызова = шПредИмяПрямое+"(?:"+шИмяСТочками+"\.)?("+ШаблонИскатьСлово+")\s*\((?:(?:"+шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*\)";
			//	ШаблонВнешнегоВызова = ШаблонВнешнегоВызова + "|" + ШаблонЛитерала;
			//ВхожденияВызова = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонВнешнегоВызова,,,,,, Истина, РегВыражениеКэш,, ВхожденияВызова); // Без групп для ускорения
			//НайденныеВызовы = ВхожденияВызова;
			Для Каждого ВхождениеВызова Из НайденныеВызовы Цикл
				Если Истина
					И СтрокаРодителя <> Неопределено
					И СтрокаМетодаРодителя <> Неопределено
					И СтрокаРодителя.Модуль = ИмяМодуля
					И ВхождениеВызова.ПозицияВхождения > СтрокаМетодаРодителя.ПозицияОпределения
					И ВхождениеВызова.ПозицияВхождения < СтрокаМетодаРодителя.ПозицияТела
				Тогда
					Продолжить;
				КонецЕсли;
				Попытка
					ТекстВхождения = ВхождениеВызова.ТекстВхождения;
				Исключение
					ТекстВхождения = Сред(ТекстМодуля, ВхождениеВызова.ПозицияВхождения + 1, ВхождениеВызова.ДлинаВхождения);
				КонецПопытки;
				Если ВхождениеВызова.ПозицияВхождения > 1 Тогда
					ТекстВхождения = Сред(ТекстВхождения, 2);
				КонецЕсли;
				СтрокаВызова = ВходящиеВызовыМетода.Добавить();
				СтрокаВызова.Модуль = ИмяМодуля; 
				СтрокаВызова.Текст = СокрЛ(ТекстВхождения);
				СтрокаВызова.Позиция = ВхождениеВызова.ПозицияВхождения + 1;
				СтрокаВызова.ДлинаВхождения = ВхождениеВызова.ДлинаВхождения - 1;  
				СтрокаВызова.Позиция = СтрокаВызова.Позиция + 1;
				УточнитьСтрокуРезультата(СтрокаВызова);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДеревоВызовов;
	СвернутыеВызовы = ВходящиеВызовыМетода.Скопировать();
	СвернутыеВызовы.Свернуть("Модуль, Метод");
	СвернутыеВызовы.Колонки.Добавить("Места");
	СвернутыеВызовы.Колонки.Добавить("ЧислоВызовов");
	СвернутыеВызовы.Колонки.Добавить("БесконтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("КонтекстныйСерверный");
	Для Каждого СтрокаПары Из СвернутыеВызовы Цикл
		Отбор = Новый Структура;
		Отбор.Вставить("Модуль", СтрокаПары.Модуль);
		Отбор.Вставить("Метод", СтрокаПары.Метод);
		ИменаКолонок = ирОбщий.СтрСоединитьЛкс(ирОбщий.ВыгрузитьСвойствоЛкс(ВызовыТекущегоМетода.Колонки));
		СтрокаПары.Места = ВходящиеВызовыМетода.Скопировать(Отбор, ИменаКолонок);
		СтрокаПары.ЧислоВызовов = СтрокаПары.Места.Количество();
		СтрокаМетода = СтрокаМетодаИзСтрокиДерева(СтрокаПары);
		СтрокаПары.БесконтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
		СтрокаПары.КонтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И Не СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
	КонецЦикла;
	ирОбщий.ЗагрузитьВСтрокиДереваЗначенийЛкс(СвернутыеВызовы, СтрокаРодителя,,,, Истина);
	Для Каждого СтрокаДерева Из СтрокаРодителя.Строки Цикл
		Родитель = СтрокаРодителя;
		Пока Родитель <> Неопределено Цикл
			Если СтрокаДерева.Метод = Родитель.Метод Тогда
				СтрокаДерева.Строки.Очистить();
				Прервать;
			КонецЕсли;
			Родитель = Родитель.Родитель;
		КонецЦикла;
	КонецЦикла; 
	СтрокаРодителя.ВызывающихМетодов = СвернутыеВызовы.Количество();
	
КонецПроцедуры

Процедура НайтиИсходящие(Знач СтрокаРодителя)
	
	Если ПустаяСтрока(СтрокаРодителя.Модуль) Тогда
		Возврат;
	КонецЕсли;
	ИмяРодногоМодуляБезКонца = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаРодителя.Модуль, "[", "]"));
	АнализаторМодуляРодителя = АнализаторМодуля(СтрокаРодителя);
	СтрокаМетодаРодителя = АнализаторМодуляРодителя.мМодульМетаданных.Методы.Найти(НРег(СтрокаРодителя.Метод), "НИмя");
	мПлатформа.ИнициацияОписанияМетодовИСвойств();                                      
	ШаблонПрямогоВызова = ШаблонПрямогоВызоваСлова("((?:" + шИмяСТочками + "\.)?" + мПлатформа.шИмя + ")",, Истина);
	Если ФильтрПодсистем.Количество() > 0 Тогда
		ОбъектыВыбранныхПодсистем = ирОбщий.ОбъектыПодсистемЛкс(ФильтрПодсистем);
	КонецЕсли;
	ОбъектМД = Неопределено;
	ВходящиеВызовыМетода = ВызовыСлова.ВыгрузитьКолонки();
	ВходящиеВызовыМетода.Колонки.ВызывающийМетод.Имя = "Метод";
	Вхождения = ирОбщий.НайтиРегВыражениеЛкс(АнализаторМодуляРодителя.ТелоМетода(СтрокаМетодаРодителя), ШаблонПрямогоВызова);
	АнализаторМодуляРодителя.ЗагрузитьМетодМодуля(СтрокаМетодаРодителя);
	ПозицияТела = АнализаторМодуляРодителя.мПозицияТекстаДляПоискаОпределения;
	Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Вхождения.Количество());
	Для Каждого ВхождениеВызова Из Вхождения Цикл
		ирОбщий.ОбработатьИндикаторЛкс(Индикатор); 
		ВызываемыйМетод = ВхождениеВызова.Группы[0];
		АнализаторМодуляРодителя.ЗагрузитьМетодМодуляПоПозиции(ПозицияТела + ВхождениеВызова.ПозицияВхождения);
		ТаблицаТипов = АнализаторМодуляРодителя.ВычислитьТипЗначенияВыражения(ВызываемыйМетод + "(",,,,,,,,,,,,, ИмяФиктивногоСвойства());
		Если ТаблицаТипов.Количество() > 0 Тогда
			СтрокаМетода = ТаблицаТипов[0].СтрокаОписания; // см. мПлатформа.НоваяТаблицаМетодовМодуля()[0]
			Если Ложь
				Или ТипЗнч(СтрокаМетода) <> Тип("СтрокаТаблицыЗначений") 
				Или СтрокаМетода.Владелец().Колонки.Найти("ИмяМодуля") = Неопределено
			Тогда
				Продолжить;
			КонецЕсли;
		Иначе
			Продолжить;
		КонецЕсли;
		ИмяМодуля = СтрокаМетода.ИмяМодуля;
		Если Истина
			И СтрокаРодителя <> Неопределено
			И СтрокаМетодаРодителя <> Неопределено
			И СтрокаРодителя.Модуль = ИмяМодуля
			И ВхождениеВызова.ПозицияВхождения > СтрокаМетодаРодителя.ПозицияОпределения
			И ВхождениеВызова.ПозицияВхождения < СтрокаМетодаРодителя.ПозицияТела
		Тогда
			Продолжить;
		КонецЕсли;
		ТекстВхождения = ВхождениеВызова.ТекстВхождения;
		Если ВхождениеВызова.ПозицияВхождения > 1 Тогда
			ТекстВхождения = Сред(ТекстВхождения, 2);
		КонецЕсли;
		СтрокаВызова = ВходящиеВызовыМетода.Добавить();
		СтрокаВызова.Модуль = ИмяМодуля;  
		//СтрокаВызова.Текст = СокрЛ(ТекстВхождения);
		СтрокаВызова.Текст = ТекстВхождения;
		СтрокаВызова.Позиция = ПозицияТела + ВхождениеВызова.ПозицияВхождения + 1;
		СтрокаВызова.ДлинаВхождения = ВхождениеВызова.ДлинаВхождения - 1;  
		СтрокаВызова.Позиция = СтрокаВызова.Позиция + 1;
		//УточнитьСтрокуРезультата(СтрокаВызова);
		СтрокаВызова.Метод = СтрокаМетода.Имя;
	КонецЦикла;
	ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДеревоВызовов;
	СвернутыеВызовы = ВходящиеВызовыМетода.Скопировать();
	СвернутыеВызовы.Свернуть("Модуль, Метод");
	СвернутыеВызовы.Колонки.Добавить("Места");
	СвернутыеВызовы.Колонки.Добавить("ЧислоВызовов");
	СвернутыеВызовы.Колонки.Добавить("БесконтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("КонтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("Внешний");
	Для Каждого СтрокаПары Из СвернутыеВызовы Цикл
		Отбор = Новый Структура;
		Отбор.Вставить("Модуль", СтрокаПары.Модуль);
		Отбор.Вставить("Метод", СтрокаПары.Метод);
		ИменаКолонок = ирОбщий.СтрСоединитьЛкс(ирОбщий.ВыгрузитьСвойствоЛкс(ВызовыТекущегоМетода.Колонки));
		СтрокаПары.Места = ВходящиеВызовыМетода.Скопировать(Отбор, ИменаКолонок);
		СтрокаПары.ЧислоВызовов = СтрокаПары.Места.Количество();
		АнализаторМодуля = АнализаторМодуля(СтрокаПары);
		Если Не ЗначениеЗаполнено(СтрокаПары.Метод) Тогда
			Продолжить;
		КонецЕсли;
		СтрокаМетода = СтрокаМетодаИзСтрокиДерева(СтрокаПары);
		СтрокаПары.Внешний = СтрокаМетода.ИмяМодуля <> СтрокаМетодаРодителя.ИмяМодуля;
		СтрокаПары.БесконтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И СтрокаМетода.БезКонтекста  
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
		СтрокаПары.КонтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И Не СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
	КонецЦикла;
	ирОбщий.ЗагрузитьВСтрокиДереваЗначенийЛкс(СвернутыеВызовы, СтрокаРодителя,, Новый Структура("Выход", Истина),, Истина);
	Для Каждого СтрокаДерева Из СтрокаРодителя.Строки Цикл
		Родитель = СтрокаРодителя;
		Пока Родитель <> Неопределено Цикл
			Если СтрокаДерева.Метод = Родитель.Метод Тогда
				СтрокаДерева.Строки.Очистить();
				Прервать;
			КонецЕсли;
			Родитель = Родитель.Родитель;
		КонецЦикла;
	КонецЦикла; 
	СтрокаРодителя.ВызываемыхМетодов = СвернутыеВызовы.Количество();
	
КонецПроцедуры

Процедура ВызовыПриАктивизацииСтроки(Элемент)
	ЭтаФорма.ВызовыТекущегоМетода = Элемент.ТекущаяСтрока.Места;
КонецПроцедуры

Процедура УточнитьСтрокуРезультата(Знач ТекущаяСтрока, Знач Групповое = Истина) Экспорт
	СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если СтрокаДерева.Выход Тогда
		ИмяМодуля = СтрокаДерева.Родитель.Модуль;
	Иначе
		ИмяМодуля = ТекущаяСтрока.Модуль;
	КонецЕсли;
	Если ИмяМодуля = мПлатформа.ИмяДинамическогоМодуля() Тогда
		ЗагрузитьМетодМодуляПоПозиции(ТекущаяСтрока.Позиция);
		ТекущаяСтрока.НомерСтрокиМодуля = НомерСтрокиИзПозиции(ТекущаяСтрока.Позиция);
		Если мМетодМодуля <> Неопределено Тогда
			ТекущаяСтрока.Метод = мМетодМодуля.Имя;
		Иначе
			ТекущаяСтрока.Метод = мПлатформа.ИмяМетодаИнициация();
		КонецЕсли;
		//ТекущаяСтрока.Текст = ПолеТекста.ПолучитьСтроку(ТекущаяСтрока.НомерСтрокиМодуля);
	Иначе
		Если Не Групповое Тогда
			ПолеФрагмента = ЭлементыФормы.ПолеТекстаВхождения;
		КонецЕсли;
		ирКлиент.РазобратьПозициюМодуляВСтрокеТаблицыЛкс(ТекущаяСтрока, ИмяМодуля, ПолеФрагмента,,,,, Истина, "Метод");
	КонецЕсли;
КонецПроцедуры

Процедура ВызовыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	Если ДанныеСтроки.Родитель <> Неопределено Тогда
		Если ДанныеСтроки.Выход Тогда
			Картинка = ирКэш.КартинкаПоИмениЛкс("ирВходящий");
		Иначе
			Картинка = ирКэш.КартинкаПоИмениЛкс("ирВыходящий");
		КонецЕсли;
		ОформлениеСтроки.Ячейки.Выход.ОтображатьТекст = Ложь;
		ОформлениеСтроки.Ячейки.Выход.УстановитьКартинку(Картинка);
	КонецЕсли;
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

Процедура ДействияФормыПерейтиКОпределению(Кнопка = Неопределено)
	ТекущаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ирКлиент.ПоказатьСсылкуНаСтрокуМодуляЛкс(ТекущаяСтрока.Ссылка);
КонецПроцедуры

Процедура ИскатьСловоНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка = Истина)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура НадписьКэшМодулейНажатие(Элемент)
	ПолучитьФорму("ФормаНастройки", ФормаВладелец).Открыть();
КонецПроцедуры

Процедура ДействияФормыНайтиВызовыМетода(Кнопка)
	ВыбраннаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если ВыбраннаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ПолеТекстаВызывающее = АнализаторМодуля(ВыбраннаяСтрока);
	ПолеТекстаВызывающее.ОткрытьПоискВызововСлова(ВыбраннаяСтрока.ВызывающийМетод + "(");
КонецПроцедуры

Процедура ФильтрПодсистем_НачалоВыбора(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ФормаВыбора = ирКэш.Получить().ПолучитьФорму("ВыборПодсистемы", Элемент);
	ФормаВыбора.МножественныйВыбор = Истина;
	ФормаВыбора.НачальноеЗначениеВыбора = ФильтрПодсистем;
	ФормаВыбора.РежимВыбора = Истина;
	ФормаВыбора.Открыть();
	
КонецПроцедуры

Процедура ФильтрПодсистем_ПриИзменении(Элемент)

	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	
КонецПроцедуры

Процедура ФильтрПодсистемОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	Элемент.Значение = ВыбранноеЗначение; // Без этого выбор из списка последних использованных не устанавливал значение
	
КонецПроцедуры 

Процедура ФильтрПодсистемНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);

КонецПроцедуры

Процедура ВызовыСловаПередРазворачиванием(Элемент, Строка, Отказ)
	Если Истина   
		И Не БылоПрерывание
		И Строка.Строки.Количество() = 1
		И Строка.Строки[0].Модуль = ""
	Тогда
		//
	Иначе
		Возврат;
	КонецЕсли;
	БылоПрерывание = Истина;
	ПодключитьОбработчикОжидания("ЗавершитьРазвертывание", 0.1, Истина); // Не работает этот способ борьбы с рекурсивным разворачиванием
	Строка.Строки.Очистить();   
	Если Ложь
		Или Не Строка.Выход
		Или ИскатьВходящие И Строка.Родитель = Неопределено
	Тогда
		НайтиВходящие(Строка);
	КонецЕсли;
	Если Ложь
		Или Строка.Выход
		Или ИскатьИсходящие И Строка.Родитель = Неопределено
	Тогда
		НайтиИсходящие(Строка);
	КонецЕсли;  
	Строка.Строки.Сортировать("Выход, Метод, Модуль");
	БылоПрерывание = Ложь;
КонецПроцедуры

Процедура ЗавершитьРазвертывание()
	БылоПрерывание = Ложь;
КонецПроцедуры

Процедура ВызовыТекущегоМетодаПриАктивизацииСтроки(Элемент)
	#Если Сервер И Не Сервер Тогда
		мПлатформа = Обработки.ирПлатформа.Создать();
	#КонецЕсли
	ЭлементыФормы.ПолеТекстаВхождения.УстановитьТекст("");
	ТекущаяСтрока = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	УточнитьСтрокуРезультата(ТекущаяСтрока, Ложь);
КонецПроцедуры

Процедура ВызовыВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	Если ВыбраннаяСтрока.Выход Тогда
		ирКлиент.ОткрытьМетодМодуляПоОпределениюЛкс(СтрокаМетодаИзСтрокиДерева(ВыбраннаяСтрока));
	Иначе
		ВызовыТекущегоМетодаВыбор();
	КонецЕсли;
	
КонецПроцедуры

Процедура ВызовыТекущегоМетодаВыбор(Элемент = Неопределено, ВыбраннаяСтрока = Неопределено, Колонка = Неопределено, СтандартнаяОбработка = Истина)
	ВыбраннаяСтрока = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяСтрока;
	Если ВыбраннаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Колонка = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяКолонка;
	Если Истина
		И Колонка = ЭлементыФормы.ВызовыТекущегоМетода.Колонки.Ссылка 
		И ирОбщий.СтруктураСсылкиСтрокиМодуляЛкс(ВыбраннаяСтрока.Ссылка) <> Неопределено
	Тогда 
		ДействияФормыПерейтиКОпределению();
	Иначе
		Если Не ирКлиент.ОткрытьСсылкуСтрокиМодуляЛкс(ВыбраннаяСтрока.Ссылка) Тогда 
			Если ВыбраннаяСтрока.Модуль = мПлатформа.ИмяДинамическогоМодуля() Тогда 
				ФормаВладелец.Активизировать();
				ПолеТекстаЛ = ПолеТекста;
			Иначе
				ПолеТекстаЛ = ирКлиент.ОткрытьПолеТекстаМодуляКонфигурацииЛкс(ВыбраннаяСтрока.Модуль).ПолеТекста;
			КонецЕсли;
			ПолеТекстаЛ.УстановитьГраницыВыделения(ВыбраннаяСтрока.Позиция, ВыбраннаяСтрока.Позиция + ВыбраннаяСтрока.ДлинаВхождения,,, Истина);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ИсходящиеПриИзменении(Элемент)
	ОбновитьДанные();
КонецПроцедуры

Процедура ВходящиеПриИзменении(Элемент)
	ОбновитьДанные();
КонецПроцедуры

Процедура ДействияФормыПеренестиВКорень(Кнопка)
	СтрокаМетода = СтрокаМетодаИзСтрокиДерева();
	ПеренестиВКорень(СтрокаМетода);
КонецПроцедуры

Функция СтрокаМетодаИзСтрокиДерева(СтрокаДерева = Неопределено) Экспорт
	Если СтрокаДерева = Неопределено Тогда
		СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	АнализаторМодуля = АнализаторМодуля(СтрокаДерева);
	СтрокаМетода = АнализаторМодуля.мМодульМетаданных.Методы.Найти(НРег(СтрокаДерева.Метод), "НИмя");
	СтрокаМетода.ИмяМодуля = СтрокаДерева.Модуль;
	Возврат СтрокаМетода;
КонецФункции

// TODO перенести в модуль объекта
Функция АнализаторМодуля(Знач СтрокаДерева = Неопределено) Экспорт
	Если СтрокаДерева = Неопределено Тогда
		СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	Если СтрокаДерева.Модуль = мПлатформа.ИмяДинамическогоМодуля() Тогда
		АнализаторМодуля = ЭтотОбъект;
	Иначе
		АнализаторМодуля = мПлатформа.ПолеТекстаМодуля(СтрокаДерева.Модуль);
	КонецЕсли;
	Возврат АнализаторМодуля;
КонецФункции

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирКлсПолеТекстаПрограммы.Форма.ДеревоВызовов");
#Если Сервер И Не Сервер Тогда
	ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
	ПараметрСтрокаМетода = мПлатформа.ПараметрыМетодаМодуля()[0];
#КонецЕсли    
РасширениеФайлаМодуля = "txt";  
ДеревоВызовов.Колонки.Добавить("Места", Новый ОписаниеТипов("ТаблицаЗначений")); 
ИскатьВходящие = Истина;
ИскатьИсходящие = Истина;
ТолькоЛокальные = Истина;
БылоПрерывание = Ложь; 
