RDT1C/src/DataProcessors/ирКлсПолеТекстаПрограммы/Ext/ObjectModule.bsl
Администратор 56eed46f21 .
2023-10-29 11:43:05 +03:00

11976 lines
878 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирКлиент Экспорт;
Перем ИмяКласса Экспорт;
Перем СсылочнаяФормаКласса Экспорт;
Перем ДопКнопкиКомандныхПанелей Экспорт;
Перем СоответствиеЭУ Экспорт;
Перем мФормаАвтодополнение Экспорт;
Перем мФормаВызовМетода Экспорт;
Перем мФормаКласса;
Перем мРегВыражение Экспорт;
Перем мСлужебнаяФорма Экспорт;
Перем СлужебноеПолеТекстаДолгое Экспорт;
Перем мПолеТекстаВременное Экспорт;
Перем мПарсер;
Перем мШиринаТабуляции;
Перем мПлатформа Экспорт;
Перем мНачальнаяСтрока Экспорт; // снаружи только для чтения
Перем мНачальнаяКолонка Экспорт; // снаружи только для чтения
Перем мКонечнаяСтрока Экспорт; // снаружи только для чтения
Перем мКонечнаяКолонка Экспорт; // снаружи только для чтения
Перем мТекущаяСтрокаНачало Экспорт;
//Перем ОригинальнаяСтрока;
Перем мТекущаяСтрокаКонец;
Перем мНачалоКонтекста;
Перем мНачалоСлова;
Перем мКонецКонтекста;
Перем мОригинальныйТекст Экспорт;
Перем мСтарыйОригинальныйТекст Экспорт;
Перем мТекстБезКомментариевИОпасныхСтрок Экспорт;
Перем мТекстБезТекстовыхЛитералов Экспорт;
Перем мТекстДляПоискаОпределения Экспорт;
Перем мТекстБлока Экспорт;
Перем мПозицияТекстаДляПоискаОпределения Экспорт;
Перем мНачальнаяПозиция0ВложенногоТекста Экспорт;
Перем мРодительскийКонтекст Экспорт;
Перем мКонтекст Экспорт; // Для отладки сделан экспортным
Перем мВызовМетода Экспорт;
Перем мЭтоТекстовыйЛитерал Экспорт;
Перем мЭтоОбъявлениеПсевдонима Экспорт;
Перем мТекущееСлово;
Перем мПозицияВТексте Экспорт;
Перем мПозицияВБлоке Экспорт;
Перем мПредшествующийТекст Экспорт;
Перем мНомерПараметра Экспорт;
Перем мИмяМетодаВызова Экспорт;
Перем мЭтоКонструктор Экспорт;
Перем мФактическиеПараметры Экспорт;
Перем мПервыйФактическийПараметр;
Перем мРазбиратьКонтекст;
Перем мРекурсивныйПуть Экспорт;
Перем мАвтоКонтекстнаяПомощь Экспорт;
Перем мРасширенноеПолучениеМетаданныхADO Экспорт;
Перем мПравилаВычисленияФункций Экспорт;
Перем мПоследнийРежимВызоваСправки;
Перем мИменаОбщихТиповПоИменамКлассовCOM;
Перем мДиалектSQL Экспорт;
Перем мДиалектыSQL Экспорт;
Перем мПараметрыДиалектаSQL Экспорт;
Перем мТерминалыЯзыкаЗапросов Экспорт;
Перем мПрефиксыПараметров Экспорт;
Перем мАнглийский1С;
Перем мМаркерСлужебногоКомментария Экспорт;
Перем мМаркерПорядкаОтладки Экспорт;
Перем мОткрытьСправкуПоПараметру Экспорт; // снаружи только для чтения
Перем мМодульМетаданных Экспорт;
Перем мИмяМодуля Экспорт;
Перем мСтруктурыТиповПодсказкиУдержания;
Перем МассивКомКлассов;
Перем мКонкретныйТипКонтекста;
Перем мСтруктураТипаКонтекста;
Перем мЭтоЛокальныйКонтекстТаблицыСлов Экспорт;
Перем мТолькоСсылочныеИменаТипов;
Перем мСоответствиеТиповСловHTML;
Перем РазрешеноСобытиеПередПоказомАвтодополнения;
Перем АвтоматическаяПодсказкаПоВызовуМетода Экспорт;
Перем АвтоматическаяПодсказкаАвтодополненияHTML Экспорт;
Перем ПоказыватьВсеТипыВСпискеАвтодополненияHTML Экспорт;
Перем ПредпочитатьHTMLРедакторКода Экспорт;
Перем мЭтоАвтоВызов;
Перем МаксСловНаходитьВТекстеПрограммы;
Перем мДоступныеПоляТаблиц;
Перем мМетодМодуля Экспорт;
Перем мНомерПервойСтрокиТелаМетода Экспорт;
Перем мНомерПоследнейСтрокиТелаМетода Экспорт;
Перем мИсторияПереходов;
Перем мФлагиКомпиляции Экспорт;
Перем мКорневаяТаблицаТипов Экспорт;
Перем мОбъектИзКонфигуратора;
Перем мЯзыкПрограммы Экспорт; // Может меняться на вложенный язык в РазобратьТекущийКонтекст()
Перем мПакетЗапросов Экспорт;
Перем мМенеджерВременныхТаблиц Экспорт;
Перем мНаборыСлов Экспорт;
Перем шЧисло;
Перем шЛюбой;
Перем шБуква;
Перем шСтрокаПрограммы Экспорт;
Перем шНачалоСтрокиПрограммы;
Перем шСтрокаЗапроса;
Перем шИндекс;
Перем шСкобки;
Перем шНачалоСкобок;
Перем шИмя;
Перем шИмяСкобки;
Перем шИмяСТочками;
Перем шПараметрЗапроса;
Перем шПредИмя;
Перем шРазделитель;
Перем шНазначениеТипа;
Перем шВыражениеПрограммы Экспорт;
Перем шВыражениеЗапроса;
Перем шВызовМетодаПрограммы;
Перем шВызовМетодаЗапроса;
Перем шИЗ;
Перем шОписаниеТаблицы;
Перем шОписаниеТаблицыСЗахватом;
Перем шПока;
Перем шЕсли;
Перем шВызватьИсключение;
Перем шНачалоТокена;
Перем шКонецТокена;
Перем шКомментарий;
Перем шПрисвоение;
Перем шПростоеВыражениеПрограммы;
Перем шПоискОписанияТаблицы;
Перем шСимволыПрефиксаПараметра;
Перем шПрефиксПараметраНеобяз;
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента - ПолеТекста;
// *пКоманднаяПанель - КоманднаяПанель, *Неопределено - в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура ИнициироватьНеинтерактивно(пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм", пКонфигурация = Неопределено,
Знач пПолеТекстовогоДокумента = Неопределено) Экспорт
Если мСлужебнаяФорма = Неопределено Тогда
СоздатьСлужебноеПоле();
КонецЕсли;
ЭтотОбъект.ЯзыкПрограммы = пЯзыкПрограммы;
мЯзыкПрограммы = пЯзыкПрограммы;
ЭтотОбъект.МетодВыполнения = пМетодВыполнения;
ЭтотОбъект.ТипТекста = пТипТекста;
#Если Клиент Тогда
Если пПолеТекстовогоДокумента = Неопределено Тогда
пПолеТекстовогоДокумента = мПлатформа.НовоеСлужебноеПолеТекста(мСлужебнаяФорма, "1");
КонецЕсли;
ЭтотОбъект.ПолеТекста = ирКлиент.ОболочкаПоляТекстаЛкс(пПолеТекстовогоДокумента);
#Иначе
ЭтотОбъект.ПолеТекста = Новый ТекстовыйДокумент;
#КонецЕсли
УстановитьКонфигурациюМетаданных(пКонфигурация, пКонтекстВыполнения);
мПрефиксыПараметров = мДиалектыSQL.Скопировать(, "ПрефиксПараметра");
мПрефиксыПараметров.Свернуть("ПрефиксПараметра");
мПрефиксыПараметров.ВыгрузитьКолонку(0);
Если ЯзыкПрограммы = 1 Тогда
Если КонтекстВыполнения = Неопределено Тогда
КонтекстВыполнения = Новый Запрос;
КонецЕсли;
ИнициироватьТерминалыЯзыкаЗапросов();
КонецЕсли;
Если МетодВыполнения = "" Тогда
ЭтотОбъект.МетодВыполнения = "ВыполнитьЛокально";
КонецЕсли;
Попытка
ПроверитьПрограммныйКод(, "");
Исключение
ирОбщий.СообщитьСУчетомМодальностиЛкс(ОписаниеОшибки());
ирОбщий.СообщитьСУчетомМодальностиЛкс("Задан неверный контекст выполнения программы. Будет использован общий контекст выполнения");
ЭтотОбъект.КонтекстВыполнения = ЭтотОбъект;
ЭтотОбъект.МетодВыполнения = "ВыполнитьПрограмму";
КонецПопытки;
ДобавитьПравилоВычисленияФункции("Вычислить", "ВычислитьВычислить", "Локальный");
ДобавитьПравилоВычисленияФункции("ПолучитьФорму", "ВычислитьПолучитьФорму", "*");
ДобавитьПравилоВычисленияФункции("ПолучитьФормуСписка", "ВычислитьПолучитьФорму", "*");
ДобавитьПравилоВычисленияФункции("ПолучитьФормуВыбора", "ВычислитьПолучитьФорму", "*");
ДобавитьПравилоВычисленияФункции("ПолучитьОбщуюФорму", "ВычислитьПолучитьФорму", "Локальный");
ДобавитьПравилоВычисленияФункции("ПолучитьФормуЛкс", "ВычислитьПолучитьФорму", "*");
ДобавитьПравилоВычисленияФункции("ПолучитьМакет", "ВычислитьПолучитьМакет", "*");
ДобавитьПравилоВычисленияФункции("ПолучитьОбщийМакет", "ВычислитьПолучитьМакет", "Локальный");
ДобавитьПравилоВычисленияФункции("Область", "ВычислитьПолучитьОбласть", "ТабличныйДокумент");
ДобавитьПравилоВычисленияФункции("ПолучитьОбласть", "ВычислитьПолучитьОбласть", "ТабличныйДокумент");
ДобавитьПравилоВычисленияФункции("РеквизитФормыВЗначение", "ВычислитьРеквизитФормыВЗначение", "*");
ДобавитьПравилоВычисленияФункции("ПрочитатьЗначениеJSON", "ВычислитьПрочитатьЗначениеJSON", "Локальный");
ДобавитьПравилоВычисленияФункции("ПрочитатьXML", "ВычислитьФабрикаXDTOПрочитатьXML", "ФабрикаXDTO");
ДобавитьПравилоВычисленияФункции("ПрочитатьJSON", "ВычислитьФабрикаXDTOПрочитатьJSON", "ФабрикаXDTO");
ДобавитьПравилоВычисленияФункции("Добавить", "ВычислитьКоллекцияДобавить", "*");
ДобавитьПравилоВычисленияФункции("Выгрузить", "ВычислитьРезультатЗапросаВыгрузить", "РезультатЗапроса");
ДобавитьПравилоВычисленияФункции("ОтобратьКоллекциюЛкс", "ВычислитьОтобратьКоллекциюЛкс", "ОбщийМодуль.ирОбщий");
ДобавитьПравилоВычисленияФункции("СоздатьОбъектПоИмениМетаданныхЛкс", "ВычислитьСоздатьОбъектПоИмениМетаданныхЛкс", "ОбщийМодуль.ирОбщий");
// БСП
ДобавитьПравилоВычисленияФункции("ОбщийМодуль", "ВычислитьОбщийМодуль", "ОбщийМодуль.ОбщегоНазначения"); // Добавил чтобы без ограничений на количество динамических вызовов считалось
ДобавитьПравилоВычисленияФункции("ЗначенияРеквизитовОбъекта", "ВычислитьЗначенияРеквизитовОбъектаБСП", "ОбщийМодуль.ОбщегоНазначения");
ДобавитьПравилоВычисленияФункции("СтрокаТаблицыЗначенийВСтруктуру", "ВычислитьСтрокаТаблицыЗначенийВСтруктуруБСП", "ОбщийМодуль.ОбщегоНазначения");
ДобавитьПравилоВычисленияФункции("МакетПечатнойФормы", "ВычислитьМакетПечатнойФормыБСП", "ОбщийМодуль.УправлениеПечатью");
КонецПроцедуры
Процедура СоздатьСлужебноеПоле() Экспорт
мСлужебнаяФорма = мПлатформа.ПолучитьФорму("Служебная");
СлужебноеПолеТекстаДолгое = мПлатформа.НовоеСлужебноеПолеТекста(мСлужебнаяФорма);
КонецПроцедуры
Процедура ИнициироватьТерминалыЯзыкаЗапросов() Экспорт
Если мТерминалыЯзыкаЗапросов = Неопределено Тогда
мТерминалыЯзыкаЗапросов = Новый Соответствие;
мТерминалыЯзыкаЗапросов = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(мПлатформа.ПолучитьМакет("ТерминалыЯзыкаЗапросов"),,,, Истина);
мТерминалыЯзыкаЗапросов.Индексы.Добавить("Ключ");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Русский");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Английский");
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьИнициировать() Экспорт
Если Не ЗначениеЗаполнено(ТипТекста) Тогда
ИнициироватьНеинтерактивно();
КонецЕсли;
КонецПроцедуры
#Если Клиент Тогда
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента - ПолеТекста;
// *пКоманднаяПанель - КоманднаяПанель, *Неопределено - в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура Инициализировать(СтруктураЭкземляров = Неопределено, пФорма, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено, пЯзыкПрограммы = 0, пМетодВыполнения = "",
пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм", пКонфигурация = Неопределено, НеДобавлятьКнопкиЕслиСуществуют = Ложь, Знач пЭтоЧастиныйЗапрос = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПодключитьПерехватКлавиатуры();
СсылочнаяФормаКласса = Ложь;
КоманднаяПанель = пКоманднаяПанель;
УстановитьФормуВладельца(пФорма);
ЭтотОбъект.ЭтоЧастичныйЗапрос = пЭтоЧастиныйЗапрос;
ИнициироватьНеинтерактивно(пЯзыкПрограммы, пМетодВыполнения, пКонтекстВыполнения, пТипТекста, пКонфигурация, пПолеТекстовогоДокумента);
Имя = ПолеТекста.ЭлементФормы.Имя;
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КоманднаяПанель" + Имя, Ложь);
ПолеТекста.ЭлементФормы.КонтекстноеМеню = КоманднаяПанель;
КонецЕсли;
мФормаКласса = мПлатформа.ПолучитьМакетКомпоненты(ЭтотОбъект);// см. Обработка.ирКлсПолеТекстаПрограммы.Форма.ФормаМакет
КнопкиМакета = мФормаКласса.ЭлементыФормы["КоманднаяПанель" + Формат(ЯзыкПрограммы, "ЧН=")].Кнопки;
Если ЯзыкПрограммы = 1 Тогда
КнопкаИсследоватьСхемуЗапроса = КнопкиМакета.Найти("ИсследоватьСхемуЗапроса");
КнопкаФорматировать = КнопкиМакета.Найти("Форматировать");
КнопкаВставитьИзБуфераОбменаВесьТекст = КнопкиМакета.Найти("ВставитьИзБуфераОбменаВесьТекст");
КнопкаКопироватьВБуферОбменаВесьТекст = КнопкиМакета.Найти("КопироватьВБуферОбменаВесьТекст");
КнопкиМакета = ирОбщий.МассивИзКоллекцииЛкс(КнопкиМакета);
Если Не ирКэш.ДоступноСхемаЗапросаЛкс() Или ЭтоЧастичныйЗапрос Тогда
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаИсследоватьСхемуЗапроса));
КонецЕсли;
Если ЭтоЧастичныйЗапрос Тогда
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаФорматировать));
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаВставитьИзБуфераОбменаВесьТекст));
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаКопироватьВБуферОбменаВесьТекст));
КонецЕсли;
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель,,, НеДобавлятьКнопкиЕслиСуществуют);
КнопкиМакета = мФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки;
Если пКоманднаяПанель = Неопределено Тогда
КнопкаУстановитьФокус = КнопкиМакета.Найти("УстановитьФокус");
КнопкиМакета = ирОбщий.МассивИзКоллекцииЛкс(КнопкиМакета);
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаУстановитьФокус));
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель,,, НеДобавлятьКнопкиЕслиСуществуют);
Попытка
ФормаВладелец.ПодключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку", 100);;
ФормаВладелец.ОтключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку");
Исключение
//КоманднаяПанель.Кнопки.Удалить(ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь"));
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь");
Кнопка.Доступность = Ложь;
КонецПопытки;
//ФайлШаблоновТекста = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста");
//Если Ложь
// Или ТипЗнч(ФайлШаблоновТекста) <> Тип("Строка")
// Или ФайлШаблоновТекста = ""
//Тогда
// КнопкаВыполнитьШаблон = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "ВыполнитьШаблон");
// КнопкаВыполнитьШаблон.Доступность = Ложь;
// КнопкаВыполнитьШаблон.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет); // Чтобы освободить сочетание клавиш
//КонецЕсли;
Если СтруктураЭкземляров <> Неопределено Тогда
СтруктураЭкземляров.Вставить(Имя, ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьФормуВладельца(пФорма) Экспорт
ФормаВладелец = пФорма;
КонецПроцедуры
// Освобождает ресурсы занятые экземпляром класса.
// Самое главное - очистить ссылки на формы и объекты БД.
//
// Параметры:
// Нет.
//
Процедура Уничтожить() Экспорт
Для Каждого Реквизит Из Метаданные().Реквизиты Цикл
ЭтотОбъект[Реквизит.Имя] = Неопределено;
КонецЦикла;
Если мФормаВызовМетода <> Неопределено Тогда
ЭтотОбъект.мФормаВызовМетода.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаВызовМетода = Неопределено;
Если ЭтотОбъект.мФормаАвтодополнение <> Неопределено Тогда
ЭтотОбъект.мФормаАвтодополнение.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаАвтодополнение = Неопределено;
ОчиститьТаблицуСловЛокальногоКонтекста();
СохранитьСтатистикуВыбораПодсказки();
КонецПроцедуры
Процедура СохранитьСтатистикуВыбораПодсказки() Экспорт
ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора", мПлатформа.ТаблицаСтатистикиВыбора);
КонецПроцедуры
Процедура ВнешнееСобытиеОбъекта(Источник, Событие, Данные) Экспорт
Если Источник <> "KeyboardHook" Тогда
Возврат;
КонецЕсли;
Если Ложь
Или ФормаВладелец = Неопределено
Или Не ирКлиент.Форма_ВводДоступенЛкс(ФормаВладелец) // Для поля HTML это затратно
Тогда
Возврат;
КонецЕсли;
ирКлиент.Форма_ВнешнееСобытиеЛкс(ФормаВладелец, Источник, Событие, Данные);
//Формат строки данные:
//Первые 5 символов десятичное число в котором закодированы двоичные данные
//биты 0-7 - виртуальный код клавиши (http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx)
//бит 08 - 1 = нажата расширенная клавиша
//бит 09 - 1 = Правый alt
//бит 10 - 1 = Левый alt
//бит 11 - 1 = Правый ctrl
//бит 12 - 1 = Левый ctrl
//бит 13 - 1 = Правый shift
//бит 14 - 1 = Левый shift
//
//6 символ и возможно следующие символы могут быть или не быть (максимальное количество 10)
//Это результат интерпретации клавиши с учетом языковой раскладки. (http://msdn.microsoft.com/en-us/library/ms646320%28v=VS.85%29.aspx)
//
ПолученноеЧисло = Лев(Данные,5);
ПолученноеЧисло = Число(ПолученноеЧисло);
ВиртуальнаяКлавиша = ПолученноеЧисло % 256;
ПолученноеЧисло = ПолученноеЧисло - ВиртуальнаяКлавиша;
РасширеннаяКлавиша = ПолученноеЧисло % 512;
ПолученноеЧисло = ПолученноеЧисло - РасширеннаяКлавиша;
ПравыйАльт = ПолученноеЧисло % 1024;
ПолученноеЧисло = ПолученноеЧисло - ПравыйАльт;
ЛевыйАльт = ПолученноеЧисло % 2048;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйАльт;
ПравыйСонтрол = ПолученноеЧисло % 4096;
ПолученноеЧисло = ПолученноеЧисло - ПравыйСонтрол;
ЛевыйСонтрол = ПолученноеЧисло % 8192;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйСонтрол;
ПравыйШифт = ПолученноеЧисло % 16384;
ПолученноеЧисло = ПолученноеЧисло - ПравыйШифт;
ЛевыйШифт = ПолученноеЧисло;
Если СтрДлина(Данные) > 5 Тогда
Символ = Сред(Данные, 6);
Иначе
Символ = "";
КонецЕсли;
КодыКлавиш = ирКэш.КодыКлавишЛкс();
Если ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы Тогда
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+ALT+Space"]) = 1
Тогда
#Если Сервер И Не Сервер Тогда
ОткрытьАвтодополнение();
#КонецЕсли
ВыполнитьКоманду("ОткрытьАвтодополнение", Данные);
ИначеЕсли Найти(Данные, КодыКлавиш["ALT+F2"]) = 1 Тогда
// Антибаг платформы 8.3.19+ не обновляются пометки закладок
ирКлиент.ОткрытьИЗакрытьПустуюФормуЛкс();
ИначеЕсли Найти(Данные, КодыКлавиш["CTRL+[-]"]) = 1 Тогда
#Если Сервер И Не Сервер Тогда
ВернутьсяИзПерехода();
#КонецЕсли
ВыполнитьКоманду("ВернутьсяИзПерехода", Данные);
ИначеЕсли Ложь
Или Найти(Данные, КодыКлавиш["CTRL"]) = 1 // Мультиметка00452941 Так будет много лишних точек
Или Найти(Данные, КодыКлавиш["CTRL+ALT+P"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+F3"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+F"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+G"]) = 1
Или Найти(Данные, КодыКлавиш["F3"]) = 1
Тогда
// Запоминание срабатывает после системной обработки сочетания!
ЗапомнитьИсточникПерехода();
ИначеЕсли Ложь
Или Найти(Данные, КодыКлавиш["CTRL+C"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+V"]) = 1
Тогда
// Мультиметка00452941 Удаляем избыточные точки истории
УдалитьПоследнийПереходИзИстории();
КонецЕсли;
Если Ложь
Или ЛиДоступноОткрытиеСвободнойФормы()
Или ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеТекстовогоДокумента")
Тогда
// Подсказка по вызову метода
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+SHIFT+Space"]) = 1
Тогда
ВыполнитьКоманду("ПодсказатьПараметр");
КонецЕсли;
ФормаВызовМетода = ФормаВызовМетода();
БылаОткрыта = ФормаВызовМетода.Открыта();
Если Истина
И Не БылаОткрыта
И ЛиДоступноОткрытиеСвободнойФормы()
И (Ложь
Или Символ = "("
Или Символ = ",")
И АвтоматическаяПодсказкаПоВызовуМетода()
Тогда
ВыполнитьКоманду("ПодсказатьПараметрАвто");
КонецЕсли;
Если БылаОткрыта Тогда
ОбновитьПодсказкуПоВызовуМетода();
КонецЕсли;
Если Ложь
Или Найти(Данные, КодыКлавиш["ALT+Up"]) = 1
Или Найти(Данные, КодыКлавиш["ALT+Down"]) = 1
//Или Найти(Данные, КодыКлавиш["CTRL+Up"]) = 1
//Или Найти(Данные, КодыКлавиш["CTRL+Down"]) = 1
Или Найти(Данные, КодыКлавиш["Esc"]) = 1 // Работает только в поле HTML документа. В остальных местах платформа делает полный перехват
Тогда
ФормаВызовМетода.ВнешнееСобытие(Источник, Событие, Данные);
КонецЕсли;
ПриНажатииКлавишиАвтодополнение(Источник, Событие, Данные, Символ);
//_РежимОтладки = Ложь;
//Если _РежимОтладки Тогда // ирОбщий.Пр(_РежимОтладки,1,1)
//Сообщить(Данные);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// Источник - ? -
// Событие - ? -
// Данные - ? -
// КодыКлавиш - Соответствие -
// Символ - Строка -
Процедура ПриНажатииКлавишиАвтодополнение(Источник, Событие, Данные, Символ) Экспорт
Если ТипЗнч(ПолеТекста.ЭлементФормы) <> Тип("ПолеТекстовогоДокумента") Тогда
Возврат;
КонецЕсли;
КодыКлавиш = ирКэш.КодыКлавишЛкс();
ФормаАвтодополнение = ФормаАвтодополнение();
БылаОткрыта = ФормаАвтодополнение.Открыта();
Если БылаОткрыта Тогда
Если Ложь
Или Найти(Данные, КодыКлавиш["Enter"]) = 1
Или Найти(Данные, КодыКлавиш["Up"]) = 1
Или Найти(Данные, КодыКлавиш["Down"]) = 1
Или Найти(Данные, КодыКлавиш["PgUp"]) = 1
Или Найти(Данные, КодыКлавиш["PgDown"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+F1"]) = 1
Тогда
Если ПолеТекста.ФиксированноеВыделениеДвумерное = Неопределено Тогда
ВыделениеДвумерное = ПолеТекста.ВыделениеДвумерное();
ВыделениеДвумерное.НачальнаяКолонка = мНачальнаяКолонка;
ВыделениеДвумерное.НачальнаяСтрока = мНачальнаяСтрока;
ВыделениеДвумерное.КонечнаяКолонка = мКонечнаяКолонка;
ВыделениеДвумерное.КонечнаяСтрока = мКонечнаяСтрока;
ПолеТекста.ФиксированноеВыделениеДвумерное = ВыделениеДвумерное;
КонецЕсли;
ПолеТекста.УстановитьВыделениеДвумерное(ПолеТекста.ФиксированноеВыделениеДвумерное);
// Подстраховка
ПараметрыОбработчика = Новый Структура("ПолеТекста, Текст", ПолеТекста, ПолеТекста.ПолучитьТекст());
ирКлиент.ПодключитьОбработчикОжиданияСПараметрамиЛкс("ирКлиент.АктивироватьЭлементФормыОтложенноЛкс", ПараметрыОбработчика,,, Ложь);
Если Найти(Данные, КодыКлавиш["Enter"]) = 1 Тогда
// Отменим вставленный перенос строки
ВыделениеДвумерное = ПолеТекста.ВыделениеДвумерное();
НоваяСтрока = ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока + 1);
ПолеТекста.УдалитьСтроку(мКонечнаяСтрока + 1);
ПолеТекста.ЗаменитьСтроку(мКонечнаяСтрока, ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока) + Сред(НоваяСтрока, ВыделениеДвумерное.НачальнаяКолонка));
КонецЕсли;
ФормаАвтодополнение.ВнешнееСобытие(Источник, Событие, Данные);
Возврат;
КонецЕсли;
КонецЕсли;
ПолеТекста.ФиксированноеВыделениеДвумерное = Неопределено;
СтарыйКонтекст = мРодительскийКонтекст;
Если Ложь
//Или Найти(Данные, КодыКлавиш["CTRL+Space"]) = 1
Или Найти(Данные, КодыКлавиш["Tab"]) = 1
Или Найти(Данные, КодыКлавиш["Space"]) = 1
Или Найти(Данные, КодыКлавиш["Enter"]) = 1
Тогда
// Чтобы закрылась форма
СтарыйКонтекст = Null;
КонецЕсли;
ПолучитьГраницыВыделения();
ПрочитатьНачалоИКонецТекущейСтроки();
Если Истина
И ЯзыкПрограммы = 0
И Найти(Данные, КодыКлавиш["Enter"]) = 1
И ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока - 1))
И Лев(СокрЛ(ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока)), 1) <> "|"
Тогда
ПолеТекста.ВыделенныйТекст("|");
КонецЕсли;
Если Истина
И ЛиДоступноОткрытиеСвободнойФормы()
И АвтоматическаяПодсказкаАвтодополненияHTML()
Тогда
РазобратьКонтекстСтроки();
Последние2Символа = Прав(мТекущаяСтрокаНачало, 2);
ЛиВнутриКомментария = ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало);
//ПоказатьСписок = МожноПоказатьСписокСлов(Символ, мТекущаяСтрокаНачало, мТекущееСлово);
//Сообщить(Данные);
Если Ложь
Или Истина
И Не БылаОткрыта
И Не (ЯзыкПрограммы = 1 И мЭтоОбъявлениеПсевдонима)
И (Ложь
Или ирОбщий.СтрНачинаетсяСЛкс(Данные, "00") // Без модификаторов
//Или ирОбщий.СтрНачинаетсяСЛкс(Данные, "1") // Зажат шифт, но сюда попадают и нажатия с CTRL
)
И Не ЛиВнутриКомментария
И ирОбщий.НайтиРегВыражениеЛкс(Символ, "[" + шБуква + "]").Количество() > 0
//Или ирОбщий.СтрКончаетсяНаЛкс(мТекущаяСтрокаНачало, "см. ") И ЛиВнутриКомментария И ЯзыкПрограммы = 0 // Только этого условия недостаточно
Или Символ = "&" И Последние2Символа <> "&&" И ЯзыкПрограммы = 1
Или Символ = "~" И Последние2Символа <> "~~" И ЯзыкПрограммы = 0
Или Символ = "#" И Последние2Символа <> "##" И ЯзыкПрограммы = 0
Или Символ = "." И Последние2Символа <> ".."
Или Символ = """" И Последние2Символа <> """""" И ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(мТекущаяСтрокаНачало) И ЯзыкПрограммы = 0
Тогда
ВыполнитьКоманду("ОткрытьАвтодополнение", Данные);
СтарыйКонтекст = мРодительскийКонтекст;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL"]) = 1
Или Найти(Данные, КодыКлавиш["Up"]) = 1
Или Найти(Данные, КодыКлавиш["Down"]) = 1
Или Найти(Данные, КодыКлавиш["PgUp"]) = 1
Или Найти(Данные, КодыКлавиш["PgDown"]) = 1
Тогда
//
ИначеЕсли ФормаАвтодополнение.Открыта() Тогда
РазобратьКонтекстСтроки();
//ПредпоследнееСлово = ""; // TODO
//ПоказатьСписок = МожноПоказатьСписокСлов(Символ, мТекущаяСтрокаНачало, ПредпоследнееСлово);
Если Ложь
Или СтарыйКонтекст <> мРодительскийКонтекст
Или (Истина
И Не ЗначениеЗаполнено(мКонтекст)
И Не мЭтоТекстовыйЛитерал
И Не ирОбщий.ЛиВнутриПрепроцессораЛкс(мТекущаяСтрокаНачало))
Тогда
ФормаАвтодополнение.Закрыть();
Возврат;
КонецЕсли;
БылЗаполненФильтр = ЗначениеЗаполнено(ФормаАвтодополнение.ЭлементыФормы.ПолеОтбораПоПодстроке.Значение);
ФормаАвтодополнение.ТекущееСлово = мНачалоСлова;
ФормаАвтодополнение.ЭлементыФормы.ПолеОтбораПоПодстроке.Значение = мНачалоСлова;
Если Найти(Данные, КодыКлавиш["CTRL+Space"]) = 1 И БылЗаполненФильтр Тогда
ФормаАвтодополнение.ПереброситьВведеннуюСтроку();
КонецЕсли;
ФормаАвтодополнение.ПриИзмененииОтбора();
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьПодсказкуПоВызовуМетода()
ФормаВызовМетода = ФормаВызовМетода();
Если Не ФормаВызовМетода.Открыта() Или Не ФормаВызовМетода.Автообновление Тогда
Возврат;
КонецЕсли;
ФормаВызовМетода.ПараметрПостояннаяСтруктураТипа = Неопределено;
//Если Форма.Открыта() Тогда
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму(, Истина);
//КонецЕсли;
КонецПроцедуры
Функция ЛиМожноЗакрытьФорму() Экспорт
Результат = Истина;
ФормаВызовМетода = ФормаВызовМетода();
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.Закрыть();
Результат = Ложь;
КонецЕсли;
ФормаАвтодополнение = ФормаАвтодополнение();
Если ФормаАвтодополнение.Открыта() Тогда
ФормаАвтодополнение.Закрыть();
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ФормаВызовМетода() Экспорт
Если мФормаВызовМетода = Неопределено Тогда
мФормаВызовМетода = ПолучитьФорму("ВызовМетода", ФормаВладелец);
КонецЕсли;
Возврат мФормаВызовМетода;
КонецФункции
Процедура ОткрытьПрикрепленнуюФормуВызоваМетода(Знач СтруктураТипаКонтекста, Знач ЭтаФорма = Неопределено) Экспорт
ТаблицаВладелец = СтруктураТипаКонтекста.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
ФормаВызовМетода = ПолучитьФорму("ВызовМетода", ЭтаФорма, "Прикрепленное");
Если Не ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.СоединяемоеОкно = Истина;
ФормаВызовМетода.КлючСохраненияПоложенияОкна = ФормаВызовМетода.КлючУникальности;
ФормаВызовМетода.СостояниеОкна = ВариантСостоянияОкна.Прикрепленное;
ФормаВызовМетода.ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ;
КонецЕсли;
ФормаВызовМетода.ПараметрПостояннаяСтруктураТипа = СтруктураТипаКонтекста;
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму();
Иначе
ФормаВызовМетода.Открыть();
КонецЕсли;
КонецПроцедуры
// Получает номер текущей строки в тексте (по конечной границе выделения).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьНомерТекущейСтроки(Начальной = Ложь) Экспорт
Если ПолеТекста <> Неопределено Тогда
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Если Начальной Тогда
Возврат мНачальнаяСтрока;
Иначе
Возврат мКонечнаяСтрока;
КонецЕсли;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьНомерТекущейСтроки()
// Получает текущее объектное выражение (на котором установлен курсор).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Строка - объектное выражение, в котором находится курсов.
//
Функция ТекущееОбъектноеВыражение(НомерСтроки = 0, НомерКолонки = 0, выхЕстьТочкаСправа = Ложь, КончитьОбработкуКоманды = Истина, Знач ЭтоПродолжениеОбработки = Ложь) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Неопределено;
КонецЕсли;
мПлатформа.ИнициацияОписанияМетодовИСвойств();
Если ЭтоПродолжениеОбработки Тогда
ПродолжитьОбработкуКоманды();
Иначе
КончитьОбработкуКоманды();
КонецЕсли;
Если НомерСтроки > ПолеТекста.КоличествоСтрок() Тогда
Возврат Неопределено;
КонецЕсли;
РазобратьТекущийКонтекст(, выхЕстьТочкаСправа,, НомерСтроки, НомерКолонки, Истина);
Если КончитьОбработкуКоманды Тогда
КончитьОбработкуКоманды();
КонецЕсли;
Если мЭтоТекстовыйЛитерал Тогда
мКонтекст = "";
КонецЕсли;
Возврат мКонтекст;
КонецФункции
// Получает текущее контекст параметра.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура -
// "ОбъектноеВыражение"
// "НомерПараметра"
//
Функция ПолучитьТекущийКонтекстПараметра() Экспорт
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,, Истина,,, Истина);
КончитьОбработкуКоманды();
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ОбъектноеВыражение", мВызовМетода);
СтруктураРезультата.Вставить("ПервыйПараметр", мПервыйФактическийПараметр);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
Возврат СтруктураРезультата;
КонецФункции
// Разбирает контекст метода.
//
// Параметры:
// Нет.
//
Функция ТекущийВызовМетода(Знач НомерПараметраДляВыделения = 0) Экспорт
мРегВыражение.Global = Истина;
мКонтекст = "";
//мОригинальныйТекст = ПолеТекста.ПолучитьТекст();
//СлужебноеПолеТекстаДолгое.УстановитьТекст(мОригинальныйТекст);
ПредшествующийТекст = "";
СледующийТекст = "";
НачальнаяПозиция = 1;
МаксЧислоПредшествующихСтрок = 20; // Чтобы снизить вероятность зацикливания при вычислении рег.выражения
Если мКонечнаяСтрока > 1 Тогда
НомерПервойСтроки = Макс(1, мКонечнаяСтрока - МаксЧислоПредшествующихСтрок - 1);
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(НомерПервойСтроки, 1, мКонечнаяСтрока - 1, 333);
ПредшествующийТекст = СлужебноеПолеТекстаДолгое.ВыделенныйТекст;
Если НомерПараметраДляВыделения > 0 Тогда
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(1, 1, НомерПервойСтроки, 1);
НачальнаяПозиция = 1 + СтрДлина(СлужебноеПолеТекстаДолгое.ВыделенныйТекст);
КонецЕсли;
КонецЕсли;
МаксЧислоСтрокАнализировать = 50;
МаксНомерСтроки = Мин(СлужебноеПолеТекстаДолгое.КоличествоСтрок(), мКонечнаяСтрока + МаксЧислоСтрокАнализировать);
Если Истина
И МаксНомерСтроки > 0
И МаксНомерСтроки <= СлужебноеПолеТекстаДолгое.КоличествоСтрок()
Тогда
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
СледующийТекст = СлужебноеПолеТекстаДолгое.ВыделенныйТекст;
КонецЕсли;
ТекстДоКурсора = ПредшествующийТекст + мТекущаяСтрокаНачало; // Так почему то иногда возникало смещение на 1 символ
ТекстПослеКурсора = мТекущаяСтрокаКонец + Символы.ПС + СледующийТекст;
ТекстПослеКурсора = ЗалитьКомментарииИСтроковыеЛитералы(ТекстПослеКурсора); // Защита от больших откатов https://www.hostedredmine.com/issues/967498
Если мЭтоТекстовыйЛитерал Тогда
//ТекстДоКурсора = ТекстДоКурсора + """";
ТекстПослеКурсора = """" + ТекстПослеКурсора;
Если ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(ТекстПослеКурсора) Тогда
ТекстПослеКурсора = ТекстПослеКурсора + """";
КонецЕсли;
КонецЕсли;
Если мЯзыкПрограммы = 0 Тогда
ШаблонПараметра = "(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*";
Иначе
ШаблонПараметра = "(?:" + шВыражениеЗапроса + ")?" + шРазделитель + "*";
КонецЕсли;
мРегВыражение.Global = Ложь;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = "^(?:" + ШаблонПараметра + ",)*" + ШаблонПараметра + "\)";
Результат = мРегВыражение.НайтиВхождения(ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
//КонецВыражения = Лев(ТекстПослеКурсора, Результат[0].Length);
КонецВыражения = Результат[0].Value;
Если мЭтоТекстовыйЛитерал Тогда
КонецВыражения = Сред(КонецВыражения, 2);
КонецЕсли;
КонецЕсли;
мРегВыражение.Global = Ложь;
мРегВыражение.MultiLine = Ложь;
Если мЯзыкПрограммы = 1 Тогда
мРегВыражение.Pattern = шВызовМетодаЗапроса + "$";
Иначе
мРегВыражение.Pattern = шВызовМетодаПрограммы + "$";
КонецЕсли;
Результат = мРегВыражение.НайтиВхождения(ТекстДоКурсора + Лев(КонецВыражения, СтрДлина(КонецВыражения) - 1) + ",");
//Результат = RegExp.НайтиВхождения(Лев(ОригинальныйТекст, СтрДлина(ТекстДоКурсора)+ СтрДлина(КонецВыражения) - 1) + ","); // Отрезаем последний символ зачем то
мФактическиеПараметры = Новый Массив;
Если Результат.Количество() > 0 Тогда
//ПоследнееВхождение = Результат[Результат.Количество() - 1];
ПоследнееВхождение = Результат[0];
//ДлинаТекста = СтрДлина(ОригинальныйТекст);
//Попытка
// СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length));
//Исключение
// СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1)); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
//КонецПопытки;
//СлужебноеПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
мВызовМетода = ПоследнееВхождение.SubMatches(1) + "(";
ТекстПараметров = ПоследнееВхождение.SubMatches(5) + ПоследнееВхождение.SubMatches(14);
НачальнаяПозиция = НачальнаяПозиция + ПоследнееВхождение.FirstIndex + СтрДлина(мВызовМетода);
мЭтоКонструктор = ЗначениеЗаполнено(ПоследнееВхождение.SubMatches(0));
мРегВыражение.Global = Истина;
Если мЯзыкПрограммы = 0 Тогда
ШаблонПараметра = "(" + шВыражениеПрограммы + ")?" ;
Иначе
ШаблонПараметра = "(" + шВыражениеЗапроса + ")?";
КонецЕсли;
мРегВыражение.Pattern = ШаблонПараметра + шРазделитель + "*,";
Результат = мРегВыражение.НайтиВхождения(ТекстПараметров);
ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) + 1 - СтрДлина(КонецВыражения);
Счетчик = 0;
Для Каждого Вхождение Из Результат Цикл
Счетчик = Счетчик + 1;
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= ЛокальнаяПозицияКурсора
И (ПозицияВхождения + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора
Тогда
мНомерПараметра = Счетчик;
КонецЕсли;
ТекстПараметра = СокрЛП(Вхождение.SubMatches(0));
мФактическиеПараметры.Добавить(ТекстПараметра);
Если НомерПараметраДляВыделения = Счетчик Тогда
ПолеТекста.УстановитьГраницыВыделения(НачальнаяПозиция + Вхождение.FirstIndex, НачальнаяПозиция + Вхождение.FirstIndex + СтрДлина(ТекстПараметра));
мНомерПараметра = НомерПараметраДляВыделения;
ЛокальнаяПозицияКурсора = 0;
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.Активизировать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если мФактическиеПараметры.Количество() > 0 Тогда
мПервыйФактическийПараметр = мФактическиеПараметры[0];
КонецЕсли;
мИмяМетодаВызова = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(мВызовМетода), "(");
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ОбъектноеВыражение", мВызовМетода);
СтруктураРезультата.Вставить("ОригинальныйТекст", Лев(ПоследнееВхождение.Value, СтрДлина(ПоследнееВхождение.Value) - 1) + ")");
СтруктураРезультата.Вставить("МассивПараметров", мФактическиеПараметры);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
СтруктураРезультата.Вставить("ЭтоКонструктор", мЭтоКонструктор);
Возврат СтруктураРезультата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
// Разбирает контекст метода.
//
// Параметры:
// Нет.
//
Функция УстановитьТекущийКонтекстМетода(НовыйТекст) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
ВыделенныйТекст(НовыйТекст);
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мНачальнаяСтрока, мНачальнаяКолонка,, ФормаВладелец);
КонецФункции
// Разбирает контекст УК.
//
// Параметры:
// Нет.
//
Функция ПолучитьТекущийКонтекстУК() Экспорт
мПлатформа.ИнициацияОписанияМетодовИСвойств();
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
мРегВыражение.Global = Истина;
ПрочитатьНачалоИКонецТекущейСтроки();
РазобратьКонтекстСтроки();
ИмяСтруктурыПараметров = "";
мОригинальныйТекст = ПолеТекста.ПолучитьТекст();
//СлужебноеПолеТекстаДолгое.УстановитьТекст(мОригинальныйТекст);
мПредшествующийТекст = "";
СледующийТекст = "";
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мПредшествующийТекст = СлужебноеПолеТекстаДолгое.ВыделенныйТекст;
КонецЕсли;
МаксНомерСтроки = Мин(СлужебноеПолеТекстаДолгое.КоличествоСтрок(), мКонечнаяСтрока + 100);
Если Истина
И МаксНомерСтроки > 0
И МаксНомерСтроки <= СлужебноеПолеТекстаДолгое.КоличествоСтрок()
Тогда
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
СледующийТекст = СлужебноеПолеТекстаДолгое.ВыделенныйТекст;
КонецЕсли;
ТекстДоКурсора = мПредшествующийТекст + Символы.ПС + мТекущаяСтрокаНачало;
ТекстПослеКурсора = мТекущаяСтрокаКонец + Символы.ПС + СледующийТекст;
ШаблонУК = "(" + шИмя + ")" + шРазделитель + "*=" + шРазделитель + "*УК\((" + шИмя + ")\)";
мРегВыражение.Global = Ложь;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК;
Результат = мРегВыражение.НайтиВхождения(мТекущаяСтрокаНачало + ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
Смещение = Результат[0].SubMatches(0);
ИмяСтруктурыПараметров = Результат[0].SubMatches(1);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Результат[0].SubMatches(2));
Иначе
Возврат Неопределено;
КонецЕсли;
ШаблонПараметра = шРазделитель + "*" + ИмяСтруктурыПараметров + "\.(" + шИмя + ")" + шРазделитель + "*="
+ шРазделитель + "*(" + шВыражениеПрограммы + ")?" + шРазделитель + "*" + ";";
мРегВыражение.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК + ";" + "((?:" + ШаблонПараметра + шРазделитель + "*" + ")*)";
Результат = мРегВыражение.НайтиВхождения(мТекущаяСтрокаНачало + ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
ПолныйТекстВыражения = Результат[0].Value;
Иначе
Возврат Неопределено;
КонецЕсли;
//RegExp.Global = Ложь;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = ШаблонУК + ";" + "((?:" + ШаблонПараметра + шРазделитель + "*" + ")*)$";
Результат = мРегВыражение.НайтиВхождения(мПредшествующийТекст + ПолныйТекстВыражения);
СтруктураПараметров = Новый Структура;
Если Результат.Количество() > 0 Тогда
ПоследнееВхождение = Результат[Результат.Количество() - 1];
Попытка
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length);
Исключение
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
КонецПопытки;
СлужебноеПолеТекстаДолгое.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
//ИмяСтруктурыПараметров = Результат[0].SubMatches(0);
ТекстПараметров = ПоследнееВхождение.SubMatches(2);
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = ШаблонПараметра;
Результат = мРегВыражение.НайтиВхождения(ТекстПараметров);
//ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) - СтрДлина(ПолныйТекстВыражения);
Счетчик = 0;
Для Каждого Вхождение Из Результат Цикл
Счетчик = Счетчик + 1;
//Если Истина
// И (Вхождение.FirstIndex + 1) <= ЛокальнаяПозицияКурсора
// И (Вхождение.FirstIndex + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора
//Тогда
// мНомерПараметра = Счетчик;
//КонецЕсли;
СтруктураПараметров.Вставить(СокрЛП(Вхождение.SubMatches(0)), СокрЛП(Вхождение.SubMatches(1)));
КонецЦикла;
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ИмяСтруктурыПараметров", ИмяСтруктурыПараметров);
СтруктураРезультата.Вставить("МассивПараметров", МассивПараметров);
СтруктураРезультата.Вставить("ОригинальныйТекст", ПоследнееВхождение.Value);
СтруктураРезультата.Вставить("Смещение", Смещение);
СтруктураРезультата.Вставить("СтруктураПараметров", СтруктураПараметров);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
Возврат СтруктураРезультата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Процедура ПродолжитьОбработкуКоманды() Экспорт
мРазбиратьКонтекст = Ложь;
КонецПроцедуры
// Вызывается в конце обработки команды.
//
// Параметры:
// Нет.
//
Процедура КончитьОбработкуКоманды() Экспорт
мРазбиратьКонтекст = Истина;
КонецПроцедуры
// Находит первое вхождение слова в тексте. Если слово найдено, устанавливается выделение и фокус.
//
// Параметры:
// СтрокаПоиска - -
// СловоЦеликом - Булево, "Переменная" -
// ПолеТекста - -
//
// Возвращаемое значение:
// - Булево - была ли найдена и выделена строка
//
Функция НайтиПоказатьСловоВТексте(СтрокаПоиска, Знач СловоЦеликомИлиШаблон = Истина, ПолеТекста = Неопределено, УстановитьФокус = Ложь, ИскатьСНачала = Ложь, Знач ВТекущемБлоке = Ложь,
Знач ИскатьСНачалаЕслиНеНайдено = Ложь) Экспорт
Если ПолеТекста = Неопределено Тогда
ПолеТекста = ЭтотОбъект.ПолеТекста;
КонецЕсли;
Если СловоЦеликомИлиШаблон = "Переменная" Тогда
СловоЦеликомИлиШаблон = ШаблонШаблонаПоискаСлова();
КонецЕсли;
Если мМетодМодуля <> Неопределено И ВТекущемБлоке Тогда
НачалоОбласти = мМетодМодуля.ПозицияОпределения;
КонецОбласти = мМетодМодуля.ПозицияТела + СтрДлина(мМетодМодуля.Тело);
Иначе
НачалоОбласти = Неопределено;
КонецОбласти = Неопределено;
КонецЕсли;
Если УстановитьФокус Тогда
ЗапомнитьИсточникПерехода();
КонецЕсли;
Результат = ирКлиент.НайтиПоказатьФрагментВПолеТекстаЛкс(ФормаВладелец, ПолеТекста, СтрокаПоиска, СловоЦеликомИлиШаблон, ИскатьСНачала,,, НачалоОбласти, КонецОбласти, ИскатьСНачалаЕслиНеНайдено);
Если УстановитьФокус Тогда
УстановитьФокус();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ШаблонШаблонаПоискаСлова(ЛиМетод = Ложь) Экспорт
Шаблон = шСтрокаПрограммы + "|(?:Новый|New)\s*#Слово#|(^|[^_a-zа-яё0-9"".])(#Слово#)\s*";
Если ЛиМетод Тогда
Возврат Шаблон + "\(";
Иначе
Возврат Шаблон + "($|[^_a-zа-яё0-9\(])";
КонецЕсли;
КонецФункции
// Вставляет в текущую позицию поля текстового документа ссылку на объект БД.
//
// Параметры:
// ЗначенияСвойствНового - Структура - если параметр будет добавлен, то к его строке будут применены эти значения свойств;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ВставитьСсылкуНаОбъектБД(ТабличноеПолеПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ИмяСтруктурыПараметров = "",
ОбновитьКопиюСвойстваВНижнемРегистре = Ложь, НачальноеЗначениеВыбора = Неопределено, РазрешитьВыбор = Истина, ВставитьВТекст = Истина) Экспорт
ТаблицаПараметров = ТабличноеПолеПараметров.Значение;
ТекущееОбъектноеВыражение = ТекущееОбъектноеВыражение();
Если Истина
И РазрешитьВыбор
И НачальноеЗначениеВыбора = Неопределено
И ВставитьВТекст
Тогда
Если Ложь
Или ЯзыкПрограммы = 0
Или Лев(ТекущееОбъектноеВыражение, 1) = "&"
Тогда
ИмяПараметра = ТекущееОбъектноеВыражение;
Если ЯзыкПрограммы = 1 Тогда
ИмяПараметра = Сред(ИмяПараметра, 2);
Иначе
Если Истина
И Не ПустаяСтрока(ИмяСтруктурыПараметров)
И Найти(НРег(ИмяПараметра), НРег(ИмяСтруктурыПараметров) + ".") = 1
Тогда
ИмяПараметра = Сред(ИмяПараметра, СтрДлина(ИмяСтруктурыПараметров) + 2);
КонецЕсли;
КонецЕсли;
СтрокаНайденногоПараметра = ТаблицаПараметров.Найти(ИмяПараметра, ИмяКолонкиИмени);
Если СтрокаНайденногоПараметра <> Неопределено Тогда
Ответ = Вопрос("Использовать тип и значение выделенного в тексте параметра?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ЗначениеПараметра = СтрокаНайденногоПараметра[ИмяКолонкиЗначения];
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПараметра, Ложь) Тогда
НачальноеЗначениеВыбора = ЗначениеПараметра;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ЗначениеЗаполнено(НачальноеЗначениеВыбора) Тогда
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ТипСсылки = ТипЗнч(НачальноеЗначениеВыбора);
Если Не ирОбщий.ЛиТипСсылкиБДЛкс(ТипСсылки, Ложь) Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если РазрешитьВыбор Тогда
ВыделитьТекущееОбъектноеВыражение();
КонецЕсли;
Если ТипСсылки = Неопределено И Не ЗначениеЗаполнено(ТекущееОбъектноеВыражение) Тогда
СтруктураТипаКонтекста = ПолучитьСтруктуруТипаСправаОтРавно();
Если СтруктураТипаКонтекста <> Неопределено Тогда
Если ТипЗнч(СтруктураТипаКонтекста.Метаданные) = Тип("ОбъектМетаданных") Тогда
ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(СтруктураТипаКонтекста.Метаданные.ПолноеИмя()));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если РазрешитьВыбор И ТипСсылки = Неопределено Тогда
ПараметрыВыбораМетаданных = Новый Структура;
ПараметрыВыбораМетаданных.Вставить("ОтображатьСсылочныеОбъекты", Истина);
ПараметрыВыбораМетаданных.Вставить("ОтображатьПеречисления", Истина);
ПараметрыВыбораМетаданных.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
ФормаВыбора = ирКлиент.ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(ФормаВладелец,,, ПараметрыВыбораМетаданных);
Результат = ФормаВыбора.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Результат.ПолноеИмяОбъекта));
КонецЕсли;
Если НачальноеЗначениеВыбора = Неопределено Тогда
НачальноеЗначениеВыбора = Новый (ТипСсылки);
КонецЕсли;
Если РазрешитьВыбор Тогда
ЗначениеПараметра = ирКлиент.ВыбратьСсылкуЛкс(ТипСсылки, НачальноеЗначениеВыбора);
УстановитьФокус();
Иначе
ЗначениеПараметра = НачальноеЗначениеВыбора;
КонецЕсли;
Если ЗначениеПараметра = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если ТабличноеПолеПараметров.ИзменяетДанные Тогда
ФормаВладелец.Модифицированность = Истина;
КонецЕсли;
СтрокаПараметра = ирОбщий.НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени, ИмяКолонкиЗначения, ЗначениеПараметра,, ОбновитьКопиюСвойстваВНижнемРегистре);
Если ВставитьВТекст Тогда
ТекстВставки = СтрокаПараметра[ИмяКолонкиИмени];
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
ТекстВставки = "&" + ТекстВставки;
КонецЕсли;
Если ЯзыкПрограммы = 0 Тогда
Если Не ПустаяСтрока(ИмяСтруктурыПараметров) Тогда
ТекстВставки = ИмяСтруктурыПараметров + "." + ТекстВставки;
КонецЕсли;
КонецЕсли;
ВыделенныйТекст(ТекстВставки);
КонецЕсли;
Возврат СтрокаПараметра;
КонецФункции
// Обрабатывает нажатие на кнопки
//
// Параметры:
// Кнопка - Кнопка.
//
// Возвращаемое значение:
// Булево - результат проверки.
//
Функция Нажатие(Кнопка, ОбновитьКонтекст = Ложь) Экспорт
Перем Результат;
Команда = ирОбщий.ПоследнийФрагментЛкс(Кнопка.Имя, "_");
Если Команда = "АвтоКонтекстнаяПомощь" Тогда
УстановитьАвтоКонтекстнаяПомощь(Не Кнопка.Пометка);
КонецЕсли;
Результат = ВыполнитьКоманду(Команда,, ОбновитьКонтекст);
Возврат Результат;
КонецФункции
Функция ВыполнитьКоманду(Знач Команда, Знач КодКлавиши = "", ОбновитьКонтекст = Истина)
Если ОбновитьКонтекст Тогда
КончитьОбработкуКоманды();
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
КонецЕсли;
Результат = Неопределено;
КнопкиМакета0 = мФормаКласса.ЭлементыФормы.КоманднаяПанель0.Кнопки;
КнопкиМакета1 = мФормаКласса.ЭлементыФормы.КоманднаяПанель1.Кнопки;
КнопкиМакета2 = мФормаКласса.ЭлементыФормы.КоманднаяПанель2.Кнопки;
КнопкиМакетаОбщие = мФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки;
Попытка
мПлатформа.ИнициацияОписанияМетодовИСвойств();
ПолучитьГраницыВыделения();
мОткрытьСправкуПоПараметру = Ложь;
Если Команда = КнопкиМакетаОбщие.ПодменюПолеПрограммы.Кнопки.ОткрытьАвтодополнение.Имя Тогда
ОткрытьАвтодополнение(КодКлавиши, Не ЗначениеЗаполнено(КодКлавиши));
ИначеЕсли Команда = КнопкиМакета0.СписокМетодов.Имя Тогда
ОткрытьСписокМетодов();
ИначеЕсли Команда = КнопкиМакета0.СсылкиНаМетод.Имя Тогда
ОткрытьПоискВызововМетода();
ИначеЕсли Команда = КнопкиМакетаОбщие.ПодменюПолеПрограммы.Кнопки.ЗаменитьТабуляции.Имя Тогда
ЗаменитьТабуляции();
ИначеЕсли Команда = КнопкиМакетаОбщие.ПодменюПолеПрограммы.Кнопки.ВыделитьСлово.Имя Тогда
// В платформе есть аналогичная системная команда, но для HTML редактора нужна.
ВыделитьТекущееСлово();
ИначеЕсли Команда = КнопкиМакета0.ПереименоватьСлово.Имя Тогда
ПереименоватьСлово();
ИначеЕсли Команда = КнопкиМакета0.СписокМетодов.Имя Тогда
//
ИначеЕсли Команда = КнопкиМакета0.ВыделитьМетод.Имя Тогда
ВыделитьМетод();
ИначеЕсли Команда = КнопкиМакетаОбщие.СравнитьТекст.Имя Тогда
ВариантСинтаксиса = Неопределено;
Если ЯзыкПрограммы = 0 Тогда
ВариантСинтаксиса = "ВстроенныйЯзык";
ИначеЕсли ЯзыкПрограммы = 1 Тогда
ВариантСинтаксиса = "ЯзыкЗапросов";
ИначеЕсли ЯзыкПрограммы = 2 Тогда
ВариантСинтаксиса = "ЯзыкКомпоновки";
КонецЕсли;
ирКлиент.ЗапомнитьСодержимоеЭлементаФормыДляСравненияЛкс(ФормаВладелец, ПолеТекста, ВариантСинтаксиса);
ИначеЕсли Команда = КнопкиМакета1.УдалитьПереносы.Имя Тогда
УдалитьПереносы();
ИначеЕсли Команда = КнопкиМакета1.КонструкторЗапросов1С.Имя Тогда
Результат = ВызватьКонструкторЗапросов(Ложь);
ИначеЕсли Команда = КнопкиМакета1.КонструкторЗапросовИР.Имя Тогда
Результат = ВызватьКонструкторЗапросов(Истина);
ИначеЕсли Команда = КнопкиМакета0.КонструкторЗапросов.Имя Тогда
Результат = ВызватьКонструкторЗапросов();
ИначеЕсли Команда = КнопкиМакета1.КонсольЗапросов.Имя Тогда
Результат = РедактироватьВКонсолиЗапросов();
ИначеЕсли Команда = КнопкиМакета0.КонсольКода.Имя Тогда
Результат = РедактироватьВКонсолиКода();
ИначеЕсли Команда = КнопкиМакета1.ВставитьИзБуфераОбменаВесьТекст.Имя Тогда
ирКлиент.УстановитьТекстСОткатомЛкс(ПолеТекста, ирКлиент.ТекстИзБуфераОбменаОСЛкс());
ИначеЕсли Команда = КнопкиМакета1.КопироватьВБуферОбменаВесьТекст.Имя Тогда
ирКлиент.ТекстВБуферОбменаОСЛкс(ПолеТекста.ПолучитьТекст(), ?(ЯзыкПрограммы = 0, "ВстроенныйЯзык", "ЯзыкЗапросов"));
ИначеЕсли Команда = КнопкиМакета1.КопироватьВБуферОбменаТекстВВидеКода.Имя Тогда
КопироватьВБуферОбменаТекстВВидеКода();
ИначеЕсли Команда = КнопкиМакета1.Закомментировать.Имя Тогда
Закомментировать();
ИначеЕсли Команда = КнопкиМакета1.Раскомментировать.Имя Тогда
Раскомментировать();
ИначеЕсли Команда = КнопкиМакета0.РедакторСтроковогоЛитерала.Имя Тогда
Результат = ОткрытьРедакторСтроковогоЛитерала();
ИначеЕсли Команда = КнопкиМакета1.ИсследоватьСхемуЗапроса.Имя Тогда
Если ПроверитьПрограммныйКод() Тогда
СхемаЗапроса = Вычислить("Новый схемаЗапроса");
#Если Сервер И Не Сервер Тогда
СхемаЗапроса = Новый СхемаЗапроса;
#КонецЕсли
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803014 Тогда
СхемаЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
КонецЕсли;
СхемаЗапроса.УстановитьТекстЗапроса(ПолеТекста.ПолучитьТекст());
ирОбщий.ИсследоватьЛкс(СхемаЗапроса);
КонецЕсли;
ИначеЕсли Команда = КнопкиМакетаОбщие.ПерейтиКОпределению.Имя Тогда
ПерейтиКОпределению();
Результат = мТекущееСлово;
ИначеЕсли Команда = КнопкиМакетаОбщие.Проверить.Имя Тогда
ПроверитьПрограммныйКод(Истина);
ИначеЕсли Команда = КнопкиМакетаОбщие.УстановитьФокус.Имя Тогда
УстановитьФокус();
ИначеЕсли Команда = КнопкиМакета1.Форматировать.Имя Тогда
ФорматироватьТекст();
ИначеЕсли Команда = КнопкиМакета0.Выполнить.Имя Тогда
ВыполнитьПрограммныйКод();
ИначеЕсли Команда = КнопкиМакетаОбщие.КонтекстныйСинтаксПомощник.Имя Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьКонтекстнуюСправку(, ФормаВладелец);
//ИначеЕсли Команда = КнопкиМакетаОбщие.СинтаксПомощник.Имя Тогда
// _ОткрытьСправкуПоЯзыкуПрограммы();
ИначеЕсли Команда = КнопкиМакетаОбщие.ПодсказатьПараметр.Имя Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьСправкуПоПараметру();
ИначеЕсли Команда = КнопкиМакетаОбщие.ВернутьсяИзПерехода.Имя Тогда
ВернутьсяИзПерехода();
ИначеЕсли Команда = КнопкиМакета0.КонструкторОписанияТипов.Имя Тогда
КонструкторОписанияТипов();
ИначеЕсли Команда = КнопкиМакетаОбщие.ПодменюПолеПрограммы.Кнопки.Настройка.Имя Тогда
ПолучитьФорму("ФормаНастройки", ФормаВладелец).Открыть();
// Бескнопочные команды
ИначеЕсли Команда = "ПодсказатьПараметрАвто" Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы Тогда
ОткрытьСправкуПоПараметру(, Ложь);
КонецЕсли;
#КонецЕсли
ИначеЕсли Команда = КнопкиМакетаОбщие.ПодменюПолеПрограммы.Кнопки.ВыполнитьШаблон.Имя Тогда
ВыполнитьШаблонТекста();
ИначеЕсли Команда = "НайтиСледующееHTML" Тогда
НайтиСледующееHTML();
ИначеЕсли Команда = "НайтиПредыдущееHTML" Тогда
НайтиПредыдущееHTML();
ИначеЕсли Команда = "ЗаменитьВхожденияHTML" Тогда
ЗаменитьВхожденияHTML();
ИначеЕсли Команда = "СочетанияКлавишHTML" Тогда
СочетанияКлавишHTML();
ИначеЕсли Команда = "КонструкторФорматнойСтроки" Тогда
КонструкторФорматнойСтроки();
КонецЕсли;
Если Ложь
Или Команда = "ВыделитьСлово"
Или Команда = "Форматировать"
Или Команда = "ВыполнитьШаблон"
Или Команда = "ОткрытьАвтодополнение"
Или Команда = "ПодсказатьПараметрАвто"
Или Команда = "ЗаменитьТабуляции"
Или Команда = "УдалитьПереносы"
Или Команда = "ПерейтиКОпределению"
Или Команда = "КонструкторЗапросов1С"
Или Команда = "КонструкторЗапросовИР"
Или Команда = "КонструкторЗапросов"
Или Команда = "РедакторСтроковогоЛитерала"
Тогда
Если Результат <> Ложь Тогда
ВосстановитьГраницыВыделенияПослеКоманды();
КонецЕсли;
КонецЕсли;
Исключение
КончитьОбработкуКоманды();
ВосстановитьФокусВвода();
ВызватьИсключение;
КонецПопытки;
КончитьОбработкуКоманды();
ВосстановитьФокусВвода();
Возврат Результат;
КонецФункции
Процедура ВосстановитьГраницыВыделенияПослеКоманды()
УстановитьГраницыВыделения();
Если мОткрытьСправкуПоПараметру Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
// Антибаг 8.3.19+ https://www.hostedredmine.com/issues/956304
//ОткрытьСправкуПоПараметру(, Ложь);
ФормаПодсказкаПоПараметрам = ФормаВызовМетода();
ФормаПодсказкаПоПараметрам.ПодключитьОбработчикОжидания("ОткрытьОтложенно", 0.1, Истина);
#КонецЕсли
КонецЕсли;
КонецПроцедуры
Процедура ПолучитьГраницыВыделения() Экспорт
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
КонецПроцедуры
Процедура УстановитьГраницыВыделения(Знач НачальнаяСтрокаИлиПозиция = Неопределено, Знач НачальнаяКолонкаИлиКонечнаяПозиция = Неопределено, Знач КонечнаяСтрока = Неопределено, Знач КонечнаяКолонка = Неопределено,
Знач ОшибкаПриВыходеЗаКонец = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если НачальнаяСтрокаИлиПозиция = Неопределено Тогда
НачальнаяСтрокаИлиПозиция = мНачальнаяСтрока;
НачальнаяКолонкаИлиКонечнаяПозиция = мНачальнаяКолонка;
КонечнаяСтрока = мКонечнаяСтрока;
КонечнаяКолонка = мКонечнаяКолонка;
КонецЕсли;
//Структура = ПолеТекста.ВыделениеДвумерное();
//Если Ложь
// // Экономная установка для подавления угасания мигания каретки из-за антибага платформы https://www.hostedredmine.com/issues/936432
// // Но баг платформы ЗаменитьСтроку() вызывает фактическое выделение всего предшествующего текста иногда без возможности получить настоящие границы выделения на 8.3.18 https://www.hostedredmine.com/issues/936821
// Или Структура.НачальнаяСтрока <> мНачальнаяСтрока
// Или Структура.НачальнаяКолонка <> мНачальнаяКолонка
// Или Структура.КонечнаяСтрока <> мКонечнаяСтрока
// Или Структура.КонечнаяКолонка <> мКонечнаяКолонка
//Тогда
ПолеТекста.УстановитьГраницыВыделения(НачальнаяСтрокаИлиПозиция, НачальнаяКолонкаИлиКонечнаяПозиция, КонечнаяСтрока, КонечнаяКолонка,, ФормаВладелец, ОшибкаПриВыходеЗаКонец);
//КонецЕсли;
КонецПроцедуры
Процедура ФорматироватьТекст()
ВыделениеДвумерное = ПолеТекста.ВыделениеДвумерное();
ВыделенныйТекст = ВыделенныйТекст();
ТолькоВыделенныйТекст = СтрДлина(ВыделенныйТекст) > 1;
Если ТолькоВыделенныйТекст Тогда
ТекстЗапроса = ВыделенныйТекст;
Иначе
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Попытка
Если ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
НовыйТекст = КонструкторЗапроса.СобратьПолныйТекст(, Истина);
Если Не ТолькоВыделенныйТекст Тогда
ВыделитьВесьТекст();
КонецЕсли;
ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(НовыйТекст);
КонецЕсли;
ПолеТекста.УстановитьВыделениеДвумерное(ВыделениеДвумерное);
ПолучитьГраницыВыделения();
Исключение
Сообщить(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
КонецПроцедуры
Функция ВыделенныйТекст(Знач НовыйТекст = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Результат = ПолеТекста.ВыделенныйТекст(НовыйТекст);
Если НовыйТекст <> Неопределено Тогда
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьВТекстЗапросаОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата, ИменаПолей = Неопределено) Экспорт
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Если КонструкторЗапроса.ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
КонструкторЗапроса.ЗагрузитьПоследнийЗапрос();
КонструкторЗапроса.ДобавитьОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата,, ИменаПолей);
ВыделитьВесьТекст();
ВыделенныйТекст(КонструкторЗапроса.СобратьПолныйТекст(, Истина));
КонструкторЗапроса.ЗагрузитьПараметрыВОбъект();
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
КонецПроцедуры
Процедура ВыделитьВесьТекст(ПолеТекста = Неопределено) Экспорт
Если ПолеТекста = Неопределено Тогда
ПолеТекста = ЭтотОбъект.ПолеТекста;
КонецЕсли;
КоличествоСтрок = ПолеТекста.КоличествоСтрок();
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.УстановитьГраницыВыделения(1, 1, Макс(1, КоличествоСтрок), СтрДлина(ПолеТекста.ПолучитьСтроку(КоличествоСтрок) + 1),, ФормаВладелец);
КонецПроцедуры
Процедура ПослеУстановкиВыделенногоМногострочногоТекста()
Перем НачСтрока, НачКолонка, КонСтрока, КонКолонка;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ФормаВладелец = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеТекстовогоДокумента") Тогда
// Антибаг платформы https://partners.v8.1c.ru/forum/topic/1860281 , http://www.hostedredmine.com/issues/840411
ПолеТекста.ПолучитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка);
ПолеТекста.УстановитьГраницыВыделения(1, 1, 1, 1);
ПолеТекста.ЭлементФормы.ВыделенныйТекст = "";
ПолеТекста.УстановитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка,, ФормаВладелец);
УстановитьПризнакМодифицированностиФормы();
КонецЕсли;
КонецПроцедуры
// Устанавливает фокус на связанное поле текста программы
Процедура УстановитьФокус(Знач Мягко = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ФормаВладелец = Неопределено Тогда
Возврат;
КонецЕсли;
ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ФормаВладелец.ТекущийЭлемент, ПолеТекста.ЭлементФормы); // Условно меняем для ускорения
Если Не Мягко Тогда
ВосстановитьФокусВвода();
КонецЕсли;
КонецПроцедуры
// https://www.hostedredmine.com/issues/931798 и куча похожих
Процедура ВосстановитьФокусВвода()
Если Истина
И ФормаВладелец <> Неопределено
И ТипЗнч(ФормаВладелец.ТекущийЭлемент) = Тип("ПолеHTMLДокумента")
Тогда
// https://github.com/salexdv/bsl_console/issues/122
//ПолеТекста.РедакторHTML().focus();
//ПолеТекста.РедакторHTML().editor.focus();
ирКлиент.УстановитьФокусВводаФормеЛкс();
КонецЕсли;
КонецПроцедуры
Процедура АвтоОбновитьСправку() Экспорт
Если Ложь
Или Не ирКлиент.Форма_ВводДоступенЛкс(ФормаВладелец)
Или ФормаВладелец.ТекущийЭлемент <> ПолеТекста.ЭлементФормы
Тогда
Возврат;
КонецЕсли;
Если мПоследнийРежимВызоваСправки = Неопределено Тогда
Возврат;
КонецЕсли;
мЭтоАвтоВызов = Истина;
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, мПоследнийРежимВызоваСправки);
Нажатие(Кнопка);
ФормаВладелец.Активизировать();
мЭтоАвтоВызов = Ложь;
КонецПроцедуры
Функция ПолучитьВыделенныйИлиВесьТекст() Экспорт
НовыйТекстЗапроса = ВыделенныйТекст();
Если ПустаяСтрока(НовыйТекстЗапроса) Тогда
НовыйТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Возврат НовыйТекстЗапроса;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура КопироватьВБуферОбменаТекстВВидеКода() Экспорт
ПрограммныйКод = ПолучитьВыделенныйИлиВесьТекст();
ЛиВыделенВесьТекст = ПрограммныйКод = ПолеТекста.ПолучитьТекст();
Если Прав(ПрограммныйКод, 1) <> Символы.ПС Тогда
ПрограммныйКод = ПрограммныйКод + Символы.ПС;
КонецЕсли;
ПрограммныйКод = ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(ПрограммныйКод);
Если ЛиВыделенВесьТекст Тогда
ИменованныеЗапросы = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ПрограммныйКод);
ПрограммныйКод = ПрограммныйКод + ";" + Символы.ПС;
Для Каждого КлючИЗначение Из ИменованныеЗапросы Цикл
ПрограммныйКод = ПрограммныйКод + "Индекс_" + КлючИЗначение.Ключ + " = " + XMLСтрока(КлючИЗначение.Значение) + ";" + Символы.ПС;
КонецЦикла;
Иначе
ПрограммныйКод = "|" + ирОбщий.УдалитьВнешниеСкобкиВыраженияЛкс(ПрограммныйКод, """", Символы.ПС + "|""");
КонецЕсли;
ирКлиент.ТекстВБуферОбменаОСЛкс(ПрограммныйКод);
КонецПроцедуры
Процедура Закомментировать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Новый ТекстовыйДокумент;
#КонецЕсли
ПерваяСтрока = мНачальнаяСтрока;
ПерваяКолонка = мНачальнаяКолонка;
ПоследняяСтрока = мКонечнаяСтрока;
ПоследняяКолонка = мКонечнаяКолонка;
КоличествоСтрок = ирОбщий.СтрЧислоСтрокЛкс(ПолеТекста.ПолучитьТекст());
ВыделенныйФрагмент = "";
ДлинаПоследнейСтроки = 0;
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока - 1;
КонецЕсли;
Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда
ПоследняяКолонка = Макс(1, СтрДлина(ПолеТекста.ПолучитьСтроку(ПерваяСтрока)));
ПоследняяСтрока = ПерваяСтрока;
КонецЕсли;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Фрагмент = ПолеТекста.ПолучитьСтроку(НомерСтроки);
Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
Если НомерСтроки = ПерваяСтрока Тогда
ВыделенныйФрагмент = ВыделенныйФрагмент + "//" + Фрагмент;
Иначе
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + "//" +Фрагмент;
КонецЕсли;
Если НомерСтроки = ПоследняяСтрока Тогда
ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменитьФрагментТекстаВПоле(ПолеТекста, ВыделенныйФрагмент, ДлинаПоследнейСтроки, ПерваяСтрока, ПоследняяСтрока, ПоследняяКолонка);
КонецПроцедуры
Процедура Раскомментировать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПерваяСтрока = мНачальнаяСтрока;
ПерваяКолонка = мНачальнаяКолонка;
ПоследняяСтрока = мКонечнаяСтрока;
ПоследняяКолонка = мКонечнаяКолонка;
КоличествоСтрок = ирОбщий.СтрЧислоСтрокЛкс(ПолеТекста.ПолучитьТекст());
ВыделенныйФрагмент = "";
ДлинаПоследнейСтроки = ПоследняяКолонка;
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока - 1;
КонецЕсли;
Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда
ПоследняяКолонка = СтрДлина(ПолеТекста.ПолучитьСтроку(ПерваяСтрока));
ПоследняяСтрока = ПерваяСтрока;
КонецЕсли;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Фрагмент = ПолеТекста.ПолучитьСтроку(НомерСтроки);
Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
Если Лев(СокрЛ(Фрагмент), 2) = "//" Тогда
Позиция = Найти(Фрагмент, "//");
Фрагмент = Лев(Фрагмент, Позиция - 1) + Сред(Фрагмент, Позиция + 2);
КонецЕсли;
Если НомерСтроки = ПерваяСтрока Тогда
ВыделенныйФрагмент = ВыделенныйФрагмент + Фрагмент;
Иначе
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + Фрагмент;
КонецЕсли;
Если НомерСтроки = ПоследняяСтрока Тогда
ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменитьФрагментТекстаВПоле(ПолеТекста, ВыделенныйФрагмент, ДлинаПоследнейСтроки, ПерваяСтрока, ПоследняяСтрока, ПоследняяКолонка);
КонецПроцедуры
Процедура УдалитьЛевыеТабуляции(ЧислоШагов = 1) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
КоличествоСтрок = ирОбщий.СтрЧислоСтрокЛкс(ПолеТекста.ПолучитьТекст());
ПерваяСтрока = 1;
ПерваяКолонка = 1;
ПоследняяСтрока = КоличествоСтрок;
ПоследняяКолонка = 50;
ВыделенныйФрагмент = "";
ДлинаПоследнейСтроки = ПоследняяКолонка;
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока - 1;
КонецЕсли;
Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда
ПоследняяКолонка = СтрДлина(ПолеТекста.ПолучитьСтроку(ПерваяСтрока));
ПоследняяСтрока = ПерваяСтрока;
КонецЕсли;
Маркер = Символы.Таб;
УдаляемыйФрагмент = "";
Для Счетчик = 1 По ЧислоШагов Цикл
УдаляемыйФрагмент = УдаляемыйФрагмент + Маркер;
КонецЦикла;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Фрагмент = ПолеТекста.ПолучитьСтроку(НомерСтроки);
Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
Если ирОбщий.СтрНачинаетсяСЛкс(Фрагмент, УдаляемыйФрагмент) Тогда
Фрагмент = Сред(Фрагмент, СтрДлина(УдаляемыйФрагмент) + 1);
КонецЕсли;
Если НомерСтроки = ПерваяСтрока Тогда
ВыделенныйФрагмент = ВыделенныйФрагмент + Фрагмент;
Иначе
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + Фрагмент;
КонецЕсли;
Если НомерСтроки = ПоследняяСтрока Тогда
ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + СтрДлина(УдаляемыйФрагмент) + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменитьФрагментТекстаВПоле(ПолеТекста, ВыделенныйФрагмент, ДлинаПоследнейСтроки, ПерваяСтрока, ПоследняяСтрока, ПоследняяКолонка);
КонецПроцедуры
Процедура ЗаменитьФрагментТекстаВПоле(Знач ПолеТекста, Знач ВыделенныйФрагмент, Знач ДлинаПоследнейСтроки, Знач ПерваяСтрока, Знач ПоследняяСтрока, Знач ПоследняяКолонка)
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока + 1;
ДлинаПоследнейСтроки = 1;
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки);
ЧислоПереносовСтрокНачальное = СтрЧислоСтрок(ВыделенныйТекст() + "й") - 1;
Если ЧислоПереносовСтрокНачальное > ПоследняяСтрока - ПерваяСтрока Тогда
// https://www.hostedredmine.com/issues/925662
Для Счетчик = 1 По Мин(2, ДлинаПоследнейСтроки - 1) Цикл
ДлинаПоследнейСтрокиБезПереноса = ДлинаПоследнейСтроки - Счетчик;
ПолеТекста.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтрокиБезПереноса);
Если СтрЧислоСтрок(ВыделенныйТекст() + "й") - 1 < ЧислоПереносовСтрокНачальное Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ВыделенныйТекст(ВыделенныйФрагмент);
ПолеТекста.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки,, ФормаВладелец);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
Процедура ПрочитатьНачалоИКонецТекущейСтроки(Знач ОригинальнаяСтрока = "", Знач НомерПозиции = 0) Экспорт
СброситьРезультатРазбораПозицииВТексте();
Если Не ЗначениеЗаполнено(ОригинальнаяСтрока) Тогда
//ОригинальнаяСтрока = СокрП(ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока));
ОригинальнаяСтрока = ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока);
КонецЕсли;
Если НомерПозиции = 0 Тогда
НомерПозиции = мКонечнаяКолонка;
КонецЕсли;
Для Счетчик = 0 По НомерПозиции - СтрДлина(ОригинальнаяСтрока) - 2 Цикл
ОригинальнаяСтрока = ОригинальнаяСтрока + " ";
КонецЦикла;
мТекущаяСтрокаНачало = Лев(ОригинальнаяСтрока, НомерПозиции - 1);
мТекущаяСтрокаКонец = Сред(ОригинальнаяСтрока, НомерПозиции);
мЭтоТекстовыйЛитерал = ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(мТекущаяСтрокаНачало);
КонецПроцедуры
Процедура РазобратьКонтекстСтроки(Знач ЛиСправаОтРавенства = Ложь, выхЕстьТочкаСправа = Ложь, Знач КакВызовМетода = Ложь) Экспорт
мЭтоОбъявлениеПсевдонима = Ложь;
мВызовМетода = "";
Если Ложь
Или КакВызовМетода = Истина
Или КакВызовМетода = Неопределено И мЭтоТекстовыйЛитерал
Тогда
ТекущийВызовМетода();
КонецЕсли;
мРегВыражение.Global = Ложь;
// Начало контекста
СтрокаШаблона = шПредИмя + "(";
Если Ложь
Или мЯзыкПрограммы = 1
Или мЯзыкПрограммы = 2
Тогда
СтрокаШаблона = "(?:" + шРазделитель + "+(КАК|AS|(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?))" + шРазделитель + "*)?" + СтрокаШаблона + шПрефиксПараметраНеобяз + "(?:" + шИмя + ")?";
Иначе
СтрокаШаблона = "()" + СтрокаШаблона + шПрефиксПараметраНеобяз + "(?:" + шИмя + ")?";
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + шСкобки + "?" + "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)?";
Если ЛиСправаОтРавенства Тогда
СтрокаШаблона = СтрокаШаблона + шРазделитель + "*=" + шРазделитель + "*";
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + "$";
мРегВыражение.Pattern = СтрокаШаблона;
Результат = мРегВыражение.НайтиВхождения(мТекущаяСтрокаНачало);
Если Результат.Количество() > 0 Тогда
ПервоеВхождение = Результат[0];
мНачалоКонтекста = "" + ПервоеВхождение.SubMatches(1);
мЭтоОбъявлениеПсевдонима = ПервоеВхождение.SubMatches(0) <> Неопределено И Найти(мНачалоКонтекста, ".") = 0;
КонецЕсли;
// Конец контекста
мРегВыражение.Global = Ложь;
Если Не ЛиСправаОтРавенства Тогда
мРегВыражение.Pattern = "([" + шБуква + "\d]*\(?)(\.)?";
Результат = мРегВыражение.НайтиВхождения(мТекущаяСтрокаКонец);
Если Результат.Количество() > 0 Тогда
мКонецКонтекста = Результат[0].SubMatches(0);
выхЕстьТочкаСправа = Результат[0].SubMatches(1) <> Неопределено;
КонецЕсли;
КонецЕсли;
СтрокаШаблона = шПрефиксПараметраНеобяз + "(?:" + шИмя + ")?";
СтрокаШаблона = "(?:((?:" + шИмяСкобки + "?" + "(?:(?:\." + шИмяСкобки + "?)|" + шИндекс + ")*))\.)?(" + СтрокаШаблона + ")?$";
// Родительский контекст по позиции курсора
мРегВыражение.Pattern = СтрокаШаблона;
Результат = мРегВыражение.НайтиВхождения(мНачалоКонтекста);
Если Результат.Количество() > 0 Тогда
ПервоеВхождение = Результат[0];
Если ПервоеВхождение.SubMatches(0) <> Неопределено Тогда
мРодительскийКонтекст = ПервоеВхождение.SubMatches(0);
КонецЕсли;
Если ПервоеВхождение.SubMatches(4) <> Неопределено Тогда
мНачалоСлова = ПервоеВхождение.SubMatches(4);
КонецЕсли;
КонецЕсли;
мТекущееСлово = мНачалоСлова + ирОбщий.ПервыйФрагментЛкс(мКонецКонтекста);
мКонтекст = мНачалоКонтекста + мКонецКонтекста;
КонецПроцедуры
// Замена операторов внешнего перехода https://partners.v8.1c.ru/forum/t/1849050/m/1849050
Функция ЗаменитьОператорыВнешнегоПерехода(Знач Текст = Неопределено, выхТипыВнешнихПереходов, выхЗаглушкаВозврата = "", выхИмяПараметраТипаВыхода = "") Экспорт
Перем ИмяМетода;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
УникальнаяСтрока = "1092383289";
Если Не ЗначениеЗаполнено(выхЗаглушкаВозврата) Тогда
выхЗаглушкаВозврата = "Возврат" + УникальнаяСтрока + "=0";
КонецЕсли;
Если Не ЗначениеЗаполнено(выхИмяПараметраТипаВыхода) Тогда
выхИмяПараметраТипаВыхода = "ТипВыхода";
КонецЕсли;
Если Текст <> Неопределено Тогда
ПолеТекста.УстановитьТекст(Текст);
КонецЕсли;
Если выхТипыВнешнихПереходов = Неопределено Тогда
выхТипыВнешнихПереходов = Новый Структура;
КонецЕсли;
СтартоваяСтрока = 0;
Пока Истина Цикл
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если Найти(ОписаниеОшибки, "Оператор Прервать") > 0 Тогда
ИмяОператора = "Прервать";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Продолжить") > 0 Тогда
ИмяОператора = "Продолжить";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Возврат") > 0 Тогда
ИмяОператора = "Возврат";
//ИначеЕсли Найти(ОписаниеОшибки, "Оператор Перейти") > 0 Тогда
// ИмяОператора = "Перейти"; // TODO
Иначе
Прервать;
КонецЕсли;
КоординатыОшибки = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
выхТипыВнешнихПереходов.Вставить(ИмяОператора);
// Выделяем вхождение имени оператора в ПолеТекста
ПолеТекста.УстановитьГраницыВыделения(1, 1, КоординатыОшибки.НомерСтроки, КоординатыОшибки.НомерКолонки);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СокрП(ВыделенныйТекст()));
КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
ДлинаПоследнейСтроки = СтрДлина(ТекстовыйДокумент.ПолучитьСтроку(КоличествоСтрок) + 1);
ПолеТекста.УстановитьГраницыВыделения(Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки - СтрДлина(ИмяОператора), Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки);
ВыделенныйТекст(выхИмяПараметраТипаВыхода + " = """ + ИмяОператора + """; " + выхЗаглушкаВозврата);
Если ИмяОператора = "Возврат" Тогда
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
КоординатыОшибкиПосле = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
Если КоординатыОшибкиПосле.НомерСтроки = КоординатыОшибки.НомерСтроки Тогда
ВыделенныйТекст("=");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Текст = ПолеТекста.ПолучитьТекст();
Возврат Текст;
КонецФункции
Функция КоординатыОшибки(Знач ИнформацияОбОшибке, Знач СтартоваяСтрока = 0) Экспорт
КоординатыОшибки = Новый Структура("НомерСтроки, НомерКолонки");
мРегВыражение.Pattern = "{[^\(]*\(([^\)]+)\)}";
ТекстКоординат = мРегВыражение.НайтиВхождения(ИнформацияОбОшибке.Описание)[0].SubMatches(0);
Фрагменты = ирОбщий.СтрРазделитьЛкс(ТекстКоординат, ",", Истина);
КоординатыОшибки.НомерСтроки = Число(Фрагменты[0]) + СтартоваяСтрока;
КоординатыОшибки.НомерКолонки = Число(Фрагменты[1]);
Возврат КоординатыОшибки;
КонецФункции
Процедура ВыделитьТекущееСлово() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(мНачалоКонтекста);
Если Не ПустаяСтрока(мРодительскийКонтекст) Тогда
мНачальнаяКолонка = мНачальнаяКолонка + СтрДлина(мРодительскийКонтекст) + 1;
КонецЕсли;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(мКонецКонтекста);
Если Прав(мКонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
КонецПроцедуры
Функция ПереименоватьСлово() Экспорт
Форма = ПолучитьФорму("ПереименоватьСлово");
РезультатФормы = Форма.ОткрытьМодально();
Возврат РезультатФормы;
КонецФункции
Функция ВыделитьМетод(Знач Параметры = Неопределено, Знач ИмяВременногоМодуля = "") Экспорт
Перем НачСтрока, НачКолонка, КонСтрока, КонКолонка;
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
мПлатформа.ИнициацияОписанияМетодовИСвойств();
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,, Истина);
АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс();
#Если Сервер И Не Сервер Тогда
АнализаторКода = Обработки.ирКлсПолеТекстаПрограммы.Создать();
ПараметрыВходаАлгоритма = Новый Структура;
#КонецЕсли
АнализаторКода.ИнициироватьНеинтерактивно();
АнализаторКода.мФлагиКомпиляции = мФлагиКомпиляции;
АнализаторКода.ЭтоМодуль = Истина;
НомераПервойСтрокиТела = 1;
АнализаторКода.УстановитьТекст(ТелоАктивногоМетода(НомераПервойСтрокиТела));
//НевидимоеПолеТекста.мМодульМетаданных = мМодульМетаданных;
СмещениеНомеровСтрок = НомераПервойСтрокиТела - 1;
Если Не ЗначениеЗаполнено(ВыделенныйТекст()) Тогда
УстановитьГраницыВыделения(мНомерПервойСтрокиТелаМетода, 1, мНомерПоследнейСтрокиТелаМетода + 1, 1);
КонецЕсли;
Если Параметры = Неопределено Тогда
Параметры = ЭтотОбъект.Параметры;
КонецЕсли;
ПолеТекста.ПолучитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка);
Если КонСтрока - СмещениеНомеровСтрок < 1 Или НачСтрока - СмещениеНомеровСтрок < 1 Тогда
Возврат Ложь;
КонецЕсли;
АнализаторКода.ПолеТекста.УстановитьГраницыВыделения(НачСтрока - СмещениеНомеровСтрок, НачКолонка, КонСтрока - СмещениеНомеровСтрок, КонКолонка);
ТекстНовогоМетода = АнализаторКода.ПолеТекста.ВыделенныйТекст();
Если Не ЗначениеЗаполнено(ТекстНовогоМетода) Тогда
Возврат Ложь;
КонецЕсли;
ОчиститьСообщения();
ТекстСмещения = ирОбщий.ПервыеНепечатныеСимволыПервойНепустойСтрокиЛкс(ТекстНовогоМетода);
//ФормаВладелец.Модифицированность = Истина;
АнализаторКода.ПолеТекста.УстановитьГраницыВыделения(1, 1, НачСтрока - СмещениеНомеровСтрок, НачКолонка);
ТекстДо = АнализаторКода.ПолеТекста.ВыделенныйТекст();
АнализаторКода.ПолеТекста.УстановитьГраницыВыделения(КонСтрока - СмещениеНомеровСтрок, КонКолонка, Макс(1, АнализаторКода.ПолеТекста.КоличествоСтрок()), 300);
ТекстПосле = АнализаторКода.ПолеТекста.ВыделенныйТекст();
АнализаторКода.ПолеТекста.УстановитьГраницыВыделения(НачСтрока - СмещениеНомеровСтрок, НачКолонка, КонСтрока - СмещениеНомеровСтрок, КонКолонка);
ФормаНовогоМетода = АнализаторКода.ПолучитьФорму("ВыделениеМетода", ФормаВладелец);
ЛиКорректныйФрагмент = Истина;
ЗаглушкаВозврата = "";
ИмяПараметраТипаВыхода = "";
ИмяПеременнойЗаглушки = "Пустышка845234571";
ТекстДо = АнализаторКода.ЗаменитьОператорыВнешнегоПерехода(ТекстДо, , ЗаглушкаВозврата, ИмяПараметраТипаВыхода);
ТекстПосле = АнализаторКода.ЗаменитьОператорыВнешнегоПерехода(ТекстПосле, , ЗаглушкаВозврата, ИмяПараметраТипаВыхода);
СтруктураПараметровКода = Новый Структура;
МетаОбщиеМодули = Метаданные.ОбщиеМодули;
ТипыВнешнихПереходов = Новый Структура;
ТекстНовогоМетода = АнализаторКода.ЗаменитьОператорыВнешнегоПерехода(ТекстНовогоМетода, ТипыВнешнихПереходов, ЗаглушкаВозврата, ИмяПараметраТипаВыхода);
Если ТипыВнешнихПереходов.Количество() > 0 Тогда
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Добавить();
СтрокаПараметра.Имя = ИмяПараметраТипаВыхода;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаПараметра);
СтрокаПараметра.Вход = Ложь;
СтрокаПараметра.Выход = Истина;
СтрокаПараметра.ТипЗначения = "Строка";
СтрокаПараметра.Комментарий = "Служебный параметр для перехода после вызова метода";
КонецЕсли;
ПараметрыИзАлгоритма(ТекстДо + ТекстНовогоМетода + ТекстПосле, АнализаторКода, ЛиКорректныйФрагмент,, Истина);
Если Не ЛиКорректныйФрагмент Тогда
Возврат "Ошибка";
КонецЕсли;
// Добавим переменные, которые не определены в выделенном фрагменте текста, как входные параметры
ПараметрыВходаАлгоритма = ПараметрыИзАлгоритма(ТекстНовогоМетода, АнализаторКода, ЛиКорректныйФрагмент,,, Ложь);
ЗаглушкаТекстаМетода = "";
ЭтоВыражение = Не ЛиКорректныйФрагмент Или мНомерПараметра > 0;
Если Не ЛиКорректныйФрагмент Тогда
// Выделено выражение
ЗаглушкаТекстаМетода = "0";
ПараметрыВходаАлгоритма = ПараметрыИзАлгоритма("ми7ва7в9вц3ая = " + ТекстНовогоМетода, АнализаторКода, ЛиКорректныйФрагмент);
Если Не ЛиКорректныйФрагмент Тогда
Возврат "Ошибка";
КонецЕсли;
КонецЕсли;
АнализаторКода.УстановитьТекст(ТекстДо);
ФормаНовогоМетода.ТекстСмещения = ТекстСмещения;
Для Каждого КлючИЗначение Из ПараметрыВходаАлгоритма Цикл
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Добавить();
СтрокаПараметра.Имя = КлючИЗначение.Ключ;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаПараметра);
СтрокаПараметра.Вход = Истина;
// TODO сделать более универсальное экранирование конструктора "Новый <ИмяПеременной>"
Пока АнализаторКода.НайтиПоказатьСловоВТексте("Новый " + КлючИЗначение.Ключ) Цикл
АнализаторКода.ПолеТекста.ВыделенныйТекст(ИмяПеременнойЗаглушки);
КонецЦикла;
Пока АнализаторКода.НайтиПоказатьСловоВТексте(КлючИЗначение.Ключ) Цикл
АнализаторКода.ПолеТекста.ВыделенныйТекст(ИмяПеременнойЗаглушки);
КонецЦикла;
КонецЦикла;
ТекстДоПереименованный = АнализаторКода.ПолеТекста.ПолучитьТекст();
// Добавим внутренние переменные, чтобы пользователь мог включить их передачу на выход
АнализаторКода.УстановитьТекст(ТекстНовогоМетода);
АнализаторКода.РазобратьТекущийКонтекст();
АнализаторКода.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина,,, Истина);
СтрокиЛокальныхПеременных = АнализаторКода.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический"));
Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл
Если мФлагиКомпиляции.Сервер И МетаОбщиеМодули.Найти(СтрокаПеременной.НСлово) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Если ирОбщий.СтрокиРавныЛкс(СтрокаПеременной.НСлово, ирОбщий.ПервыйФрагментЛкс(ЗаглушкаВозврата, "=", Ложь)) Тогда
Продолжить;
КонецЕсли;
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Найти(СтрокаПеременной.НСлово, "НИмя");
Если СтрокаПараметра = Неопределено Тогда
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Добавить();
СтрокаПараметра.Имя = СтрокаПеременной.Слово;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаПараметра);
КонецЕсли;
КонецЦикла;
// Добавим переменные, которые не определены начиная с первой выделеной строки и до конца текста, как свозные параметры
ПараметрыСквозныеАлгоритма = ПараметрыИзАлгоритма(ТекстДоПереименованный + ТекстНовогоМетода + ТекстПосле, АнализаторКода, ЛиКорректныйФрагмент,
ИмяПеременнойЗаглушки);
Если Не ЛиКорректныйФрагмент Тогда
Возврат "Ошибка";
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПараметрыСквозныеАлгоритма = Новый Структура;
#КонецЕсли
Для Каждого КлючИЗначение Из ПараметрыСквозныеАлгоритма Цикл
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Найти(НРег(КлючИЗначение.Ключ), "НИмя");
Если СтрокаПараметра = Неопределено Тогда
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Добавить();
СтрокаПараметра.Имя = КлючИЗначение.Ключ;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаПараметра);
КонецЕсли;
СтрокаПараметра.Вход = Истина;
СтрокаПараметра.Выход = Истина;
КонецЦикла;
// Добавим переменные, которые не определены в следующем тексте, как параметры выхода
ПараметрыВыходаАлгоритма = ПараметрыИзАлгоритма(ТекстДоПереименованный + ЗаглушкаТекстаМетода + ТекстПосле, АнализаторКода,, ИмяПеременнойЗаглушки);
#Если Сервер И Не Сервер Тогда
ПараметрыВыходаАлгоритма = Новый Структура;
#КонецЕсли
ТаблицаЛокальногоКонтекста = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипаМодуля(),,,,,, "Свойство", мФлагиКомпиляции,,,,, Истина);
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаЛокальногоКонтекста, "Слово");
ИмяРезультатаВыражения = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаЛокальногоКонтекста, "Результат", "Слово");
Если ЭтоВыражение Тогда
ПараметрыВыходаАлгоритма.Вставить(ИмяРезультатаВыражения);
КонецЕсли;
Для Каждого КлючИЗначение Из ПараметрыВыходаАлгоритма Цикл
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Найти(НРег(КлючИЗначение.Ключ), "НИмя");
Если СтрокаПараметра = Неопределено Тогда
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Добавить();
СтрокаПараметра.Имя = КлючИЗначение.Ключ;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаПараметра);
КонецЕсли;
СтрокаПараметра.Выход = Истина;
КонецЦикла;
// Удалим переменные, которые не определены в оригнальном тексте
ПараметрыВыходаЛожные = ПараметрыИзАлгоритма(ТекстДо + ТекстНовогоМетода + ТекстПосле, АнализаторКода,,,, Ложь);
#Если Сервер И Не Сервер Тогда
ПараметрыВыходаЛожные = Новый Структура;
#КонецЕсли
Для Каждого КлючИЗначение Из ПараметрыВыходаЛожные Цикл
Если ПараметрыВходаАлгоритма.Свойство(КлючИЗначение.Ключ) Тогда
Продолжить;
КонецЕсли;
СтрокаПараметра = ФормаНовогоМетода.ТаблицаПараметров.Найти(НРег(КлючИЗначение.Ключ), "НИмя");
Если СтрокаПараметра <> Неопределено Тогда
ФормаНовогоМетода.ТаблицаПараметров.Удалить(СтрокаПараметра);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаПараметра Из ФормаНовогоМетода.ТаблицаПараметров Цикл
СтрокаПараметра.Обязательный = СтрокаПараметра.Вход;
СтрокаПараметра.Позиция = 200;
// Параметры исходного метода
ПараметрМетода = Неопределено;
ПараметрыМетодаМодуля = мПлатформа.ПараметрыМетодаМодуля(мМетодМодуля);
Если ПараметрыМетодаМодуля <> Неопределено Тогда
ПараметрМетода = ПараметрыМетодаМодуля.Найти(НРег(СтрокаПараметра.Имя), "НИмя");
Если ПараметрМетода <> Неопределено Тогда
СтрокаПараметра.Комментарий = ПараметрМетода.Описание;
СтрокаПараметра.Позиция = ПараметрыМетодаМодуля.Индекс(ПараметрМетода);
СтрокаПараметра.ТипЗначения = ПараметрМетода.ТипЗначения;
Если ЗначениеЗаполнено(ПараметрМетода.Значение) Тогда
СтрокаПараметра.Значение = Вычислить(ПараметрМетода.Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПараметрМетода = Неопределено Тогда
СтрокаПараметра.СвойствоМодуля = ТаблицаЛокальногоКонтекста.Найти(НРег(СтрокаПараметра.НИмя), "НСлово") <> Неопределено;
Если СтрокаПараметра.СвойствоМодуля Тогда
СтрокаПараметра.Вход = Ложь;
СтрокаПараметра.Выход = Ложь;
КонецЕсли;
// Динамический локальный контекст (например консоль кода)
СтрокаЭтогоАлгоритмаПараметры = Параметры.Найти(НРег(СтрокаПараметра.Имя), "НИмя");
Если Истина
И СтрокаЭтогоАлгоритмаПараметры <> Неопределено
И (Ложь
Или мМетодМодуля = Неопределено
Или СтрокаЭтогоАлгоритмаПараметры.Модуль)
Тогда
СтрокаПараметра.Комментарий = СтрокаЭтогоАлгоритмаПараметры.Комментарий;
СтрокаПараметра.Позиция = СтрокаЭтогоАлгоритмаПараметры.Позиция + 100;
СтрокаПараметра.ТипЗначения = СтрокаЭтогоАлгоритмаПараметры.ИмяТипаЗначения;
СтрокаПараметра.СвойствоМодуля = СтрокаЭтогоАлгоритмаПараметры.Модуль;
ТипЗначения = ТипЗнч(СтрокаЭтогоАлгоритмаПараметры.Значение);
Если Ложь
Или ТипЗначения = Тип("Строка") И СтрДлина(СтрокаЭтогоАлгоритмаПараметры.Значение) < 100
Или ТипЗначения = Тип("Число")
Или ТипЗначения = Тип("Булево")
Или ТипЗначения = Тип("Неопределено")
Или ТипЗначения = Тип("Null")
Тогда
СтрокаПараметра.Значение = СтрокаЭтогоАлгоритмаПараметры.Значение;
КонецЕсли;
Если СтрокаПараметра.Значение <> Неопределено Тогда
СтрокаПараметра.Обязательный = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И Не ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения)
И (Ложь
Или СтрокаПараметра.Вход
Или СтрокаПараметра.Выход
Или ФормаНовогоМетода.ТаблицаПараметров.Количество() < 10)
Тогда
// Очень долго при большом числе параметров
ТаблицаТипов = ВычислитьТипЗначенияВыражения(СтрокаПараметра.Имя, ТекстДо + ТекстНовогоМетода);
СтрокаПараметра.ТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаТипов);
КонецЕсли;
КонецЦикла;
//ЗаменаЗаглушки = Символы.ПС + ТекстСмещения + "Возврат";
Если ЭтоВыражение Тогда
ТекстНовогоМетода = Символы.Таб + ИмяРезультатаВыражения + " = " + ТекстНовогоМетода + "
|;";
ИначеЕсли СтрЧислоСтрок(СокрЛП(ТекстНовогоМетода)) = 1 Тогда
Присвоения = ирОбщий.НайтиРегВыражениеЛкс(ТекстНовогоМетода, "^\s*(" + шИмя + ")\s*=");
Если Присвоения.Количество() > 0 Тогда
ИмяНовогоМетода = Присвоения[0].Подгруппы[0];
КонецЕсли;
КонецЕсли;
ЗаменаЗаглушкиВозврата = "Возврат";
ТекстНовогоМетода = СтрЗаменить(ТекстНовогоМетода, ЗаглушкаВозврата + "=", ЗаменаЗаглушкиВозврата);
ЗаменаЗаглушкиВозврата = ЗаменаЗаглушкиВозврата + " Неопределено";
ТекстНовогоМетода = СтрЗаменить(ТекстНовогоМетода, ЗаглушкаВозврата, ЗаменаЗаглушкиВозврата);
Если мМетодМодуля <> Неопределено Тогда
Если Не ЗначениеЗаполнено(ИмяНовогоМетода) Тогда
ИмяНовогоМетода = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(мМодульМетаданных.Методы, мМетодМодуля.Имя);
КонецЕсли;
ФормаНовогоМетода.ЛиАсинх = мМетодМодуля.ЛиАсинх;
ФормаНовогоМетода.ДирективаКомлиляции = Сред(мМетодМодуля.Аннотация, 2);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяНовогоМетода) Тогда
ИмяНовогоМетода = ИмяВременногоМодуля;
КонецЕсли;
ФормаНовогоМетода.Имя = ИмяНовогоМетода;
ФормаНовогоМетода.ЭлементыФормы.ПолеТела.УстановитьТекст(ТекстНовогоМетода);
ФормаНовогоМетода.РежимВыбора = Истина;
ФормаНовогоМетода.ТекстДо = ТекстДо;
ФормаНовогоМетода.ЭтоВыражение = ЭтоВыражение;
ФормаНовогоМетода.ИмяПараметраТипаВыхода = ИмяПараметраТипаВыхода;
ФормаНовогоМетода.ТипыВнешнихПереходов = ТипыВнешнихПереходов;
РезультатФормы = ФормаНовогоМетода.ОткрытьМодально();
Если РезультатФормы = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если Ложь
Или ФормаВладелец <> Неопределено И ФормаВладелец.ТолькоПросмотр
Или ПолеТекста.ТолькоПросмотр()
Тогда
ирКлиент.ОткрытьТекстЛкс(ФормаНовогоМетода.ПолноеОпределение, "Метод " + ФормаНовогоМетода.Имя, "ВстроенныйЯзык");
ирОбщий.СообщитьЛкс("Поле текста недоступно для изменения.");
Возврат Ложь;
КонецЕсли;
СтруктураВыделения = ПолеТекста.ВыделениеДвумерное();
Если мМетодМодуля <> Неопределено Тогда
ПолеТекста.ВставитьСтроку(мНомерПоследнейСтрокиТелаМетода + 2, Символы.ПС + ФормаНовогоМетода.ПолноеОпределение);
КонецЕсли;
ПолеТекста.УстановитьВыделениеДвумерное(СтруктураВыделения);
ПолучитьГраницыВыделения();
ВыделенныйТекст(ФормаНовогоМетода.ТекстВставки);
Если мМетодМодуля = Неопределено Тогда
ПолеТекста.ВставитьСтроку(мНомерПервойСтрокиТелаМетода, Символы.ПС + ФормаНовогоМетода.ПолноеОпределение);
КонецЕсли;
Если ФормаВладелец = Неопределено Тогда
Возврат ФормаНовогоМетода.ПолноеОпределение;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция СтруктураТипаМодуля()
СтруктураТипаМодуля = мМодульМетаданных.СтруктураТипа;
Если СтруктураТипаМодуля = Неопределено Тогда
СтруктураТипаМодуля = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип("ОбщийМодуль"));
КонецЕсли;
Возврат СтруктураТипаМодуля;
КонецФункции
Функция ЗаменитьВозвратыНаПерейтиВТекстеМетода(Знач Текст = Неопределено, Знач ИмяПеременнойРезультата = "Результат", Знач ДобавлятьПереносыСтрок = Ложь, Знач ИмяМетки = "Конец", Знач ВставитьМетку = Ложь) Экспорт
Если Текст = Неопределено Тогда
Текст = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Результат = мПлатформа.ЗаменитьВозвратыНаПерейтиВТекстеМетода(Текст, ИмяПеременнойРезультата, ДобавлятьПереносыСтрок, ИмяМетки, ВставитьМетку);
Возврат Результат;
КонецФункции
Функция ПараметрыИзАлгоритма(Знач ТекстДляПроверки, Знач НевидимоеПолеПрограммы, выхКорректныйФрагмент = Истина, Знач ИгнорироватьПеременную = "", Знач ПоказыватьСтрокуОшибки = Ложь, Знач ВыводитьОшибку = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
НевидимоеПолеПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураПараметровКода = Новый Структура;
МетаОбщиеМодули = Метаданные.ОбщиеМодули;
мСмещениеНомеровСтрок = 0;
ТекстДляПроверки = мПлатформа.ЗаменитьВозвратыНаПерейтиВТекстеМетода(ТекстДляПроверки,,, "КонецСлужебный", Истина);
НевидимоеПолеПрограммы.УстановитьТекст(ТекстДляПроверки);
Пока Истина Цикл
ИнформацияОбОшибке = НевидимоеПолеПрограммы.ПроверитьТекстИВернутьОшибку(, мСмещениеНомеровСтрок, , , Истина);
НеопределенныйМетод = мПлатформа.ИмяНеопределенногоМетодаИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если НеопределенныйМетод <> Неопределено Тогда
КоординатыОшибки = НевидимоеПолеПрограммы.КоординатыОшибки(ИнформацияОбОшибке, мСмещениеНомеровСтрок);
НачальнаяКолонка = КоординатыОшибки.НомерКолонки;
НевидимоеПолеПрограммы.ПолеТекста.УстановитьГраницыВыделения(КоординатыОшибки.НомерСтроки, НачальнаяКолонка, КоординатыОшибки.НомерСтроки, НачальнаяКолонка);
НевидимоеПолеПрограммы.ПолеТекста.ВыделенныйТекст("ирОбщий.");
Продолжить;
КонецЕсли;
НеопределеннаяПеременная = мПлатформа.ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда
выхКорректныйФрагмент = ИнформацияОбОшибке = Неопределено;
Если Не выхКорректныйФрагмент И ВыводитьОшибку Тогда
// Сообщим ошибку
Если ПоказыватьСтрокуОшибки Тогда
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
КонецЕсли;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, мСмещениеНомеровСтрок,,,, ИнформацияОбОшибке);
Иначе
НевидимоеПолеПрограммы.ПроверитьПрограммныйКод();
КонецЕсли;
КонецЕсли;
Прервать;
КонецЕсли;
Если мФлагиКомпиляции.Сервер И МетаОбщиеМодули.Найти(НеопределеннаяПеременная) <> Неопределено Тогда
//
Иначе
Если Ложь
Или Не ЗначениеЗаполнено(ИгнорироватьПеременную)
Или Не ирОбщий.СтрокиРавныЛкс(ИгнорироватьПеременную, НеопределеннаяПеременная)
Тогда
СтруктураПараметровКода.Вставить(НеопределеннаяПеременная);
КонецЕсли;
КонецЕсли;
НевидимоеПолеПрограммы.ПолеТекста.ВставитьСтроку(1, НеопределеннаяПеременная + "=0;");
мСмещениеНомеровСтрок = мСмещениеНомеровСтрок + 1;
КонецЦикла;
Возврат СтруктураПараметровКода;
КонецФункции
Процедура ВыделитьТекущееОбъектноеВыражение() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(мНачалоКонтекста);
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(мКонецКонтекста);
Если Прав(мКонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
КонецПроцедуры
// Получает путь к описанию заданного контекста.
//
// Параметры:
// ПутьКСлову - Строка;
// *СтрокаОписания - СтрокаТаблицыЗначений - возвращаемая строка описания;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
Функция НайтиПоказатьСправкуПоСлову(Знач ПутьКСлову, ВключатьПутьКОписаниюТипаЗначения = Ложь, выхФормаВыбора = Неопределено, РазрешитьАнализИмениТипа = Истина,
ВладелецФормы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТаблицаТиповКонтекста = ВычислитьТипЗначенияВыражения(ПутьКСлову, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, РазрешитьАнализИмениТипа, мЭтоКонструктор);
Если ТаблицаТиповКонтекста.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
СтруктураТипаКонтекста = ТаблицаТиповКонтекста[0];
Результат = НайтиПоказатьСправкуПоСтруктуреТипа(ПутьКСлову, СтруктураТипаКонтекста, ВключатьПутьКОписаниюТипаЗначения, выхФормаВыбора, ВладелецФормы, ТаблицаТиповКонтекста);
Возврат Результат;
КонецФункции
Функция НайтиПоказатьСправкуПоСтруктуреТипа(Знач ПутьКСлову, Знач СтруктураТипа, ВключатьПутьКОписаниюТипаЗначения = Ложь, выхФормаВыбора = Неопределено, ВладелецФормы = Неопределено,
Знач ТаблицаТиповКонтекста = Неопределено) Экспорт
Если Истина
И ТипЗнч(СтруктураТипа.СтрокаОписания) <> Тип("СтрокаТаблицыЗначений")
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("COMОбъект")
Тогда
Если мНомерПараметра > 0 Тогда
Возврат Неопределено;
КонецЕсли;
МетаданныеСлова = СтруктураТипа.Метаданные;
ИмяТипа = мПлатформа.ПолноеИмяТипаCOMОбъекта(МетаданныеСлова);
Попытка
Пустышка = МетаданныеСлова.Path_;
Исключение
Пустышка = Неопределено;
КонецПопытки;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову, ".", Ложь);
Если Прав(ПутьКСлову, 1) = "(" Тогда
Слово = СтрЗаменить(Слово, "(", "");
КонецЕсли;
Если Пустышка <> Неопределено Тогда
// WMI
ИмяКлассаWMI = МетаданныеСлова.Path_.Class;
Если ЗначениеЗаполнено(Слово) Тогда
ОписаниеСлова = ирОбщий.ДокументацияСвойстваWMIЛкс(ИмяКлассаWMI, Слово);
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ОписаниеСлова);
ТекстовыйДокумент.Показать(ИмяКласса + "." + Слово);
КонецЕсли;
КонецЕсли;
Иначе
ЗапуститьПриложение("http://google.com/search?q=" + ирОбщий.ПервыйФрагментЛкс(ИмяТипа, " ") + "+" + Слово);
КонецЕсли;
Иначе
Если ВладелецФормы <> Неопределено И СтруктураТипа.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипа.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
ФормаВызовМетода = ФормаВызовМетода();
ФормаВызовМетода.ПараметрПостояннаяСтруктураТипа = СтруктураТипа;
БылаОткрыта = ФормаВызовМетода.Открыта();
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаВызовМетода, Ложь);
ФормаВызовМетода.Автообновление = Ложь;
Если Не БылаОткрыта Тогда
ирКлиент.Форма_АктивироватьОткрытьЛкс(ФормаВладелец);
КонецЕсли;
Иначе
ФормаВызовМетода.ОткрытьМодально();
КонецЕсли;
Возврат ФормаВызовМетода;
КонецЕсли;
КонецЕсли;
Если СтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
ВключатьПутьКОписаниюТипаЗначения = Истина;
КонецЕсли;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову);
// Возможные роли слова без учета вычисленного контекста
ТаблицаСтруктурВозможныхТиповКонтекста = ирКлиент.НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Слово, ЯзыкПрограммы);
Если ТаблицаТиповКонтекста = Неопределено Тогда
ТаблицаТиповКонтекста = Новый Массив;
ТаблицаТиповКонтекста.Добавить(СтруктураТипа);
КонецЕсли;
СтруктураЦикла = Новый Соответствие;
СтруктураЦикла.Вставить("1.Предсказанные:", ТаблицаТиповКонтекста);
СтруктураЦикла.Вставить("2.Возможные:", ТаблицаСтруктурВозможныхТиповКонтекста);
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ВладелецФормы = Неопределено Тогда
ВладелецФормы = ФормаВладелец;
КонецЕсли;
мПлатформа.ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения, ВладелецФормы, Слово, мНомерПараметра,, выхФормаВыбора, мФактическиеПараметры.Количество());
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Открывает контекстную справку по текущему слову или его типу.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Функция ОткрытьКонтекстнуюСправку(ПутьКСлову = "", ВладелецФормы = Неопределено) Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
// Возврат;
//КонецЕсли;
//КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,,,,, Истина);
РазрешитьАнализИмениТипа = Не ЗначениеЗаполнено(ПутьКСлову);
Если РазрешитьАнализИмениТипа Тогда
ПутьКСлову = мТекущееСлово;
КонецЕсли;
Если мРодительскийКонтекст <> "" Тогда
ПутьКСлову = мРодительскийКонтекст + "." + ПутьКСлову;
КонецЕсли;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,,, РазрешитьАнализИмениТипа, ВладелецФормы);
КонецФункции
Процедура _ОткрытьСправкуПоЯзыкуПрограммы() Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
// Возврат;
//КонецЕсли;
Если ЯзыкПрограммы = 0 Тогда
Книга = "shcntx_ru";
ИначеЕсли ЯзыкПрограммы = 1 Тогда
Книга = "shquery_ru";
ИначеЕсли ЯзыкПрограммы = 2 Тогда
Книга = "dcsui_ru";
КонецЕсли;
ФормаСправка = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , ФормаВладелец);
ФормаСправка.ТекущаяСтраницаУстановлена = Истина;
ФормаСправка.ОткрытьАдрес("//" + Книга);
КонецПроцедуры
// Открывает контекстную справку по текущему параметру метода.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Процедура ОткрытьСправкуПоПараметру(ПутьКСлову = "", ОткрыватьСинтаксПомощник = Истина) Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
// Возврат;
//КонецЕсли;
РазобратьТекущийКонтекст(,, Истина,,, Истина);
Если ПутьКСлову = "" Тогда
ПутьКСлову = мВызовМетода;
КонецЕсли;
// Если раскомментировать, то при вызове через мОткрытьСправкуПоПараметру не будет открываться окно
//Если Не ЗначениеЗаполнено(ПутьКСлову) Тогда
// Возврат;
//КонецЕсли;
Если ОткрыватьСинтаксПомощник И ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ФормаСинтаксПомощникаДо = Неопределено;
ФормаСинтаксПомощникаПосле = Неопределено;
Если Не ЛиДоступноОткрытиеСвободнойФормы() Тогда
ФормаСинтаксПомощникаДо = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
КонецЕсли;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,, ФормаСинтаксПомощникаПосле);
КонецЕсли;
ФормаПодсказкаПоПараметрам = ФормаВызовМетода();
ФормаПодсказкаПоПараметрам.ПараметрПостояннаяСтруктураТипа = Неопределено;
Если Не ФормаПодсказкаПоПараметрам.Открыта() И ЗначениеЗаполнено(мИмяМетодаВызова) Тогда
ФормаПодсказкаПоПараметрам.ЗапомнитьПозициюКаретки();
КонецЕсли;
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
Если Ложь
Или ОткрыватьСинтаксПомощник
Или Не ФормаПодсказкаПоПараметрам.Открыта()
Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаПодсказкаПоПараметрам);
КонецЕсли;
Иначе
Если Истина
И Не мЭтоАвтоВызов
И ФормаСинтаксПомощникаДо <> Неопределено
И ФормаСинтаксПомощникаДо.Открыта() = ФормаСинтаксПомощникаПосле.Открыта()
Тогда
ФормаПодсказкаПоПараметрам.ОткрытьМодально();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьПодсказкуПоВызовуМетодаПассивно(Знач ФормаПодсказкаПоПараметрам, Знач Автообновление = Истина)
ФормаПодсказкаПоПараметрам.Автообновление = Автообновление;
ФормаПодсказкаПоПараметрам.Открыть();
ФормаПодсказкаПоПараметрам.Обновить(); // Нужно для ускорения срабатывания установки позиции окна и для 8.2, т.к. там форма форкус получает после завершения ПриОткрытии и только после этого сработает установка позиции окна
//ирКлиент.УстановитьФокусВводаФормеЛкс(); Не помогает восстановить мигание каретки
КонецПроцедуры
Функция УдалитьКомментарии(Текст) Экспорт
мРегВыражение.Global = Истина;
мРегВыражение.Multiline = Ложь;
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
// Не проверено
мРегВыражение.Pattern = "(?:(?://[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
ИначеЕсли ЯзыкПрограммы = 0 Тогда
шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n])*""?";
шОднострочнаяСтрокаПрограммыСЧерты = "\n\s*\|(?:(?:"""")|[^""\n])*""?";
мРегВыражение.Pattern = "//[^\n]*|" + "(" + "#[^\n]*" + ")|(" + шОднострочнаяСтрокаПрограммыСКавычки + ")|(" + шОднострочнаяСтрокаПрограммыСЧерты + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
КонецЕсли;
Результат = мРегВыражение.Заменить(Текст, ШаблонЗамены);
Возврат Результат;
КонецФункции
// Меняет RegExp!
Функция ЭтоРусскийВариантТекстаЗапроса(Текст) Экспорт
ТекстБезКомментариев = СокрЛП(ЗалитьКомментарииИСтроковыеЛитералы(Текст));
мРегВыражение.Pattern = "[А-ЯЁ]";
ЭтоРусскийЯзык = мРегВыражение.Проверить(Лев(ТекстБезКомментариев, 1));
Возврат ЭтоРусскийЯзык;
КонецФункции
// Добавляет/заменяет/удаляет оператор ПОМЕСТИТЬ в запросе.
// Это неточный метод, основанный на regexp.
//
// Параметры:
// ТекстЗапроса - Строка;
// *ИмяВременнойТаблицы - Строка - если пустое, то оператор удаляется.
//
// Возвращаемое значение:
// Строка - исправленный текст запроса.
//
Функция ИзменитьОператорПоместитьЗапроса(ТекстЗапроса, ИмяВременнойТаблицы = "") Экспорт
ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса); // Меняет RegExp!
мРегВыражение.Global = Истина;
ШаблонПОМЕСТИТЬИЗ = "(" + шСтрокаЗапроса + ")|(?:(" + шРазделитель + ")+(" + "(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?)" + шРазделитель + "+" + шИмя + шРазделитель + "+)"
+ "|((?:ИЗ|FROM|ГДЕ|WHERE|СГРУППИРОВАТЬ|GROUP|УПОРЯДОЧИТЬ|ORDER|ИМЕЮЩИЕ|HAVING|ОБЪЕДИНИТЬ|UNION)" + шРазделитель + "+))|(.|\r|\n)";
мРегВыражение.Pattern = ШаблонПОМЕСТИТЬИЗ;
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Если ЭтоРусскийЯзык Тогда
ТерминПоместить = "ПОМЕСТИТЬ";
Иначе
ТерминПоместить = "INTO";
КонецЕсли;
Результат = мРегВыражение.НайтиВхождения(ТекстЗапроса);
Текст = "";
ПредложениеДобавлено = Ложь;
Для Каждого Match Из Результат Цикл
Если Ложь
Или ПредложениеДобавлено
Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(0))
Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(4))
Тогда
Текст = Текст + Match.Value;
Иначе
Текст = Текст + "
|" + ТерминПоместить + "
| " + ИмяВременнойТаблицы;
Если Match.SubMatches(3) <> 0 Тогда // Видимо здесь ошибка
Текст = Текст + Символы.ПС + Match.SubMatches(3);
КонецЕсли;
ПредложениеДобавлено = Истина;
КонецЕсли;
КонецЦикла;
Если Не ПредложениеДобавлено Тогда
Текст = Текст + "
|" + ТерминПоместить + "
| " + ИмяВременнойТаблицы;
КонецЕсли;
Иначе
Текст = мРегВыражение.Заменить(ТекстЗапроса, "$1$2$4$5");
КонецЕсли;
Возврат Текст;
КонецФункции
Функция ШаблонЗапросаДопускаетВстройкуВРодительскийЗапрос(Текст) Экспорт
мРегВыражение.Global = Ложь;
мРегВыражение.Pattern = шРазделитель + "*(?:ВЫБРАТЬ|SELECT)(?:" + шРазделитель + "+)\*(?:" + шРазделитель + "+)(?:ИЗ|FROM)(?:" + шРазделитель + "+(?:КАК|AS)?(?:" + шРазделитель + "+" + шИмя + "))" + шРазделитель + "*";
Результат = мРегВыражение.Проверить(Текст);
Возврат Результат;
КонецФункции
Функция ПолучитьКомментарийИзТокеновЯзыкаЗапросов(Токен1, Токен2 = Неопределено, выхИмяЗапросаИзКомментария = "", выхИмяЧастиОбъединенияИзКомментария = "") Экспорт
Массив = Новый Массив();
Если Токен1 <> Неопределено И Токен1.Name = "Comment" Тогда
Массив.Добавить(Токен1);
КонецЕсли;
Если Токен2 <> Неопределено И Токен2.Name = "Comment" Тогда
Массив.Добавить(Токен2);
КонецЕсли;
ТекстКомментария = "";
Для Каждого Токен Из Массив Цикл
ТекстТокена = ПолучитьТекстИзТокена(Токен);
РазобратьКомментарий(ТекстКомментария, выхИмяЗапросаИзКомментария, выхИмяЧастиОбъединенияИзКомментария);
КонецЦикла;
Возврат ТекстКомментария;
КонецФункции
Процедура РазобратьКомментарий(ТекстКомментария, выхИмяЗапросаИзКомментария = Неопределено, выхИмяЧастиОбъединенияИзКомментария = Неопределено, выхПорядокОтладки = Неопределено) Экспорт
ЧистыйКомментарий = "";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКомментария);
Для Счетчик = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
Если ПустаяСтрока(СтрокаТекста) Тогда
Продолжить;
КонецЕсли;
//Если Счетчик = 1 Тогда
Если Найти(СтрокаТекста, мПараметрыДиалектаSQL.СтрочныйКомментарий) = 1 Тогда
СтрокаТекста = Сред(СтрокаТекста, СтрДлина(мПараметрыДиалектаSQL.СтрочныйКомментарий) + 1);
КонецЕсли;
Если Найти(СтрокаТекста, мМаркерСлужебногоКомментария) = 1 Тогда
Продолжить;
КонецЕсли;
Если Найти(СтрокаТекста, мПлатформа.мМаркерИмениЗапросаПакета) = 1 Тогда
ИмяЗапросаИзКомментария = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаТекста, мПлатформа.мМаркерИмениЗапросаПакета, " ");
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапросаИзКомментария) Тогда
выхИмяЗапросаИзКомментария = ИмяЗапросаИзКомментария;
КонецЕсли;
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
Если Найти(СтрокаТекста, мПлатформа.мМаркерИмениЧастиОбъединения) = 1 Тогда
ИмяЧастиОбъединенияИзКомментария = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаТекста, мПлатформа.мМаркерИмениЧастиОбъединения, " ");
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЧастиОбъединенияИзКомментария) Тогда
выхИмяЧастиОбъединенияИзКомментария = ИмяЧастиОбъединенияИзКомментария;
КонецЕсли;
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
СтрокаТекста = СокрЛ(СтрокаТекста);
Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаТекста, мМаркерПорядкаОтладки) = 1 Тогда
выхПорядокОтладки = Сред(СтрокаТекста, СтрДлина(мМаркерПорядкаОтладки) + 1);
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
//КонецЕсли;
Если ЧистыйКомментарий <> "" Тогда
ЧистыйКомментарий = ЧистыйКомментарий + Символы.ПС;
КонецЕсли;
ЧистыйКомментарий = ЧистыйКомментарий + СтрокаТекста;
КонецЦикла;
ТекстКомментария = ЧистыйКомментарий;
КонецПроцедуры
// Разбирает текущий контекст по составляющим.
//
// Параметры:
// ЛиСправаОтРавенства - -
// выхЕстьТочкаСправа - -
// КакВызовМетода - Булево, Неопределено - если равен Неопределено, то трактуется как Истина в случае если внутри строкового литерала
// НомерСтроки - Число - если не передано, то считывается из ПолеТекста
// НомерКолонки - Число - если не передано, то считывается из ПолеТекста
// ПереходитьВоВложенныйКонтекст - -
// ПозицияВТексте - Число - передается для ускорения, т.е. дополнительно к переданным или установленным НомерСтроки/мКонечнаяСтроки И НомерКолонки/мКонечнаяКолонка
//
Процедура РазобратьТекущийКонтекст(Знач ЛиСправаОтРавенства = Ложь, выхЕстьТочкаСправа = Ложь, Знач КакВызовМетода = Неопределено, Знач НомерСтроки = 0, Знач НомерКолонки = 0,
Знач ПереходитьВоВложенныйКонтекст = Ложь, Знач ПозицияВТексте = 0) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
СлужебноеПолеТекстаДолгое = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
мОригинальныйТекст = ПолеТекста.ПолучитьТекст();
ОригинальныйТекстИзменен = мСтарыйОригинальныйТекст <> мОригинальныйТекст;
Если Не мРазбиратьКонтекст И Не ОригинальныйТекстИзменен Тогда
Возврат;
КонецЕсли;
мПлатформа.ИнициацияОписанияМетодовИСвойств();
Если Не ЗначениеЗаполнено(НомерСтроки) Тогда
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Иначе
мНачальнаяСтрока = НомерСтроки;
мКонечнаяСтрока = НомерСтроки;
мНачальнаяКолонка = НомерКолонки;
мКонечнаяКолонка = НомерКолонки;
КонецЕсли;
ПрочитатьНачалоИКонецТекущейСтроки();
мПозицияТекстаДляПоискаОпределения = 0;
мПредшествующийТекст = "";
мТекстДляПоискаОпределения = "";
мТекстБлока = "";
мТекстБезТекстовыхЛитералов = "";
мМетодМодуля = Неопределено;
мПакетЗапросов = НовыйПакетЗапросов();
мНомерПервойСтрокиОпределенияМетода = 1;
мНомерПервойСтрокиТелаМетода = 1;
мНомерПоследнейСтрокиТелаМетода = Неопределено;
ТекстПакетаЗапросов = мОригинальныйТекст;
мЯзыкПрограммы = ЯзыкПрограммы;
мНачальнаяПозиция0ВложенногоТекста = 0;
НомерПервойСтрокиБлока = 1;
Если ОригинальныйТекстИзменен Тогда
СлужебноеПолеТекстаДолгое.УстановитьТекст(мОригинальныйТекст);
КонецЕсли;
Если ЗначениеЗаполнено(ПозицияВТексте) Тогда
мПозицияВТексте = ПозицияВТексте;
Иначе
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока, мКонечнаяКолонка);
мПозицияВТексте = СтрДлина(СлужебноеПолеТекстаДолгое.ВыделенныйТекст) + 1; // Долго 2мс TODO написать свой расчет позиции
КонецЕсли;
Если Истина
И ПереходитьВоВложенныйКонтекст
И (Ложь
Или ирОбщий.ЛиВнутриНепервойСтрокиТекстовогоЛитералаЛкс(мТекущаяСтрокаНачало) // Первую строку литерала игнорируем для ускорения
Или Найти(мТекущаяСтрокаНачало, ".Текст = ""ВЫБРАТЬ") > 0 И ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(мТекущаяСтрокаНачало))
Тогда
мМенеджерВременныхТаблиц = Неопределено;
ВыражениеЛитерала = "";
ТекстЛитерала = ВыделитьТекстовыйЛитерал(СлужебноеПолеТекстаДолгое, мНачальнаяПозиция0ВложенногоТекста,, Ложь, ВыражениеЛитерала);
Если ирОбщий.ЛиТекстЯзыкаЗапросовЛкс(ТекстЛитерала) Тогда
СлужебноеПолеТекстаДолгое.ПолучитьГраницыВыделения(НомерПервойСтрокиБлока, 0, 0, 0);
НачальнаяПозицияПредТекста = мНачальнаяПозиция0ВложенногоТекста - 100;
ТекстДоЛитерала = Сред(мОригинальныйТекст, НачальнаяПозицияПредТекста, Мин(0, НачальнаяПозицияПредТекста) + 100); // не более 100 символов перед литералом
мРегВыражение.Global = Ложь;
мРегВыражение.Pattern = шПредИмя + "(" + шИмяСТочками + ")\.Текст\s*=\s*$";
Вхождения = мРегВыражение.НайтиВхождения(ТекстДоЛитерала);
Если Вхождения.Количество() > 0 Тогда
ПеременнаяЗапроса = Вхождения[0].Submatches(0);
КопияАнализатора = КопияКомпоненты();
КопияАнализатора.РазобратьТекущийКонтекст(,,,,, Ложь, мНачальнаяПозиция0ВложенногоТекста);
ТаблицаТиповЗапроса = КопияАнализатора.ВычислитьТипЗначенияВыражения(ПеременнаяЗапроса); // Меняет границы выделения в нашем СлужебноеПолеТекстаДолгое!
Если Истина
И ТаблицаТиповЗапроса.Количество() > 0
И ТипЗнч(ТаблицаТиповЗапроса[0].ДержательМетаданных) = Тип("Структура")
Тогда
мМенеджерВременныхТаблиц = ТаблицаТиповЗапроса[0].ДержательМетаданных;
мПакетЗапросов.Параметры = ТаблицаТиповЗапроса[0].Метаданные.Параметры;
КонецЕсли;
мПакетЗапросов.КоординатыТекста = КопияАнализатора.НовыеКоординатыВыражения(ВыражениеЛитерала, мНачальнаяПозиция0ВложенногоТекста);
КонецЕсли;
Если мМенеджерВременныхТаблиц = Неопределено Тогда
мМенеджерВременныхТаблиц = НовыйМенеджерВременныхТаблиц();
мМенеджерВременныхТаблиц.ПакетыЗапросов.Добавить(мПакетЗапросов);
КонецЕсли;
ТекстПакетаЗапросов = ВыражениеЛитерала;
мЭтоТекстовыйЛитерал = Ложь;
мЯзыкПрограммы = 1;
КонецЕсли;
КонецЕсли;
РазобратьКонтекстСтроки(ЛиСправаОтРавенства, выхЕстьТочкаСправа, КакВызовМетода);
ЧислоСтрокВБлоке = 0;
Если ЯзыкПрограммы = 0 И ОригинальныйТекстИзменен Тогда
ОбновитьМодульМетаданных(мОригинальныйТекст);
КонецЕсли;
Если мЯзыкПрограммы = 0 Тогда
ЗагрузитьМетодМодуляПоПозиции(мПозицияВТексте); // устанавливает мМетодМодуля
ЧислоСтрокВБлоке = ирОбщий.СтрЧислоСтрокЛкс(мТекстБлока);
мНомерПервойСтрокиТелаМетода = СтрЧислоСтрок(Лев(мОригинальныйТекст, мПозицияТекстаДляПоискаОпределения) + "й");
мНомерПоследнейСтрокиТелаМетода = мНомерПервойСтрокиТелаМетода + ЧислоСтрокВБлоке - 1;
НомерТекущейСтрокиВБлоке = мКонечнаяСтрока - мНомерПервойСтрокиТелаМетода + 1;
Иначе
мПакетЗапросов.ПозицииЗапросов = Новый Массив;
мПакетЗапросов.ТекстыЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаЗапросов, мПозицияВТексте, мПакетЗапросов.ПозицииЗапросов);
Для ИндексЗапроса = 0 По мПакетЗапросов.ТекстыЗапросов.ВГраница() Цикл
мТекстБлока = мПакетЗапросов.ТекстыЗапросов[ИндексЗапроса];
мПозицияТекстаДляПоискаОпределения = мПакетЗапросов.ПозицииЗапросов[ИндексЗапроса];
ЧислоСтрокВБлоке = ирОбщий.СтрЧислоСтрокЛкс(мТекстБлока) - 1;
НомерПервойСтрокиБлока = НомерПервойСтрокиБлока + ЧислоСтрокВБлоке;
Если НомерПервойСтрокиБлока >= мНачальнаяСтрока Тогда
Прервать;
КонецЕсли;
КонецЦикла;
мПозицияТекстаДляПоискаОпределения = мНачальнаяПозиция0ВложенногоТекста + мПозицияТекстаДляПоискаОпределения;
НомерТекущейСтрокиВБлоке = мКонечнаяСтрока - (НомерПервойСтрокиБлока - ЧислоСтрокВБлоке) + 1;
КонецЕсли;
мТекстДляПоискаОпределения = мТекстБлока;
Если НомерТекущейСтрокиВБлоке > 1 Тогда
мПолеТекстаВременное.УстановитьТекст(мТекстБлока);
мПолеТекстаВременное.УстановитьГраницыВыделения(1, 1, НомерТекущейСтрокиВБлоке - 1, 333);
мПредшествующийТекст = мПолеТекстаВременное.ВыделенныйТекст;
Иначе
мПредшествующийТекст = "";
КонецЕсли;
Если мЯзыкПрограммы = 0 Тогда
мТекстДляПоискаОпределения = мПредшествующийТекст;
КонецЕсли;
мПредшествующийТекст = мПредшествующийТекст + Лев(мТекущаяСтрокаНачало, СтрДлина(мТекущаяСтрокаНачало) - СтрДлина(мНачалоКонтекста));
//мПозицияВТексте = мПозицияТекстаДляПоискаОпределения + СтрДлина(мПредшествующийТекст + мНачалоКонтекста);
мПозицияВБлоке = мПозицияВТексте - мПозицияТекстаДляПоискаОпределения - 1;
мПредшествующийТекст = Прав(мПредшествующийТекст, 500); // Обрезка для ускорения
мСтарыйОригинальныйТекст = мОригинальныйТекст;
Если мМодульМетаданных <> Неопределено Тогда
мМодульМетаданных.ТекущийМетод = мМетодМодуля;
КонецЕсли;
ПродолжитьОбработкуКоманды();
КонецПроцедуры
// Функция - Новый пакет запросов
//
// Параметры:
// Текст - -
// КоординатыТекста - см. НовыеКоординатыВыражения -
//
// Возвращаемое значение:
// -
Функция НовыйПакетЗапросов(Знач Текст = Неопределено, Знач КоординатыТекста = Неопределено) Экспорт
Результат = Новый Структура("Тип, ТекстыЗапросов, Структура, ПозицииЗапросов, Параметры");
Результат.Вставить("Тип", "ПакетЗапросов");
Результат.Вставить("Текст", Текст);
Результат.Вставить("КоординатыТекста", КоординатыТекста);
Результат.Вставить("Параметры", Новый Структура);
// документация
//Результат.Вставить("ТекстыЗапросов", Новый Массив);
//Результат.Вставить("ПозицииЗапросов", Новый Массив);
//Результат.Вставить("Структура", Новый СписокЗначений);
//Результат.Вставить("КоординатыТекста", НовыеКоординатыВыражения());
Возврат Результат;
КонецФункции
// Функция - Загрузить метод модуля по позиции
//
// Параметры:
// ПозицияВТексте - Число - начиная с 1
//
// Возвращаемое значение:
// Булево - загружен ли другой метод
//
Функция ЗагрузитьМетодМодуляПоПозиции(Знач ПозицияВТексте1) Экспорт
НовыйМетодМодуля = Неопределено;
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаМетода Из мМодульМетаданных.Методы Цикл
Если Истина
И СтрокаМетода.ПозицияСОписанием <> Неопределено
И СтрокаМетода.ПозицияСОписанием <= ПозицияВТексте1
И СтрокаМетода.ПозицияСОписанием + СтрокаМетода.ДлинаСОписанием >= ПозицияВТексте1
Тогда
НовыйМетодМодуля = СтрокаМетода;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаМетода Из мМодульМетаданных.Методы Цикл   Если Истина   И СтрокаМетода.ПозицияСОписанием <> Неопределено   И СтрокаМетода.ПозицияСОписанием <= ПозицияВТексте1   И СтрокаМетода.ПозицияСОписанием + СтрокаМетода.ДлинаСОписанием >= ПозицияВТексте1   Тогда   НовыйМетодМодуля = СтрокаМетода;   Прервать;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
Результат = ЗагрузитьМетодМодуля(НовыйМетодМодуля);
Возврат Результат;
КонецФункции
Функция ЗагрузитьМетодМодуля(Знач НовыйМетодМодуля) Экспорт
Если НовыйМетодМодуля = мМетодМодуля И НовыйМетодМодуля <> Неопределено Тогда
Возврат Ложь;
КонецЕсли;
мМетодМодуля = НовыйМетодМодуля;
Если мМетодМодуля <> Неопределено Тогда
мФлагиКомпиляции = ирОбщий.СкопироватьКоллекциюЛкс(мМодульМетаданных.ФлагиКомпиляции);
мФлагиКомпиляции.Сервер = мМетодМодуля.Сервер И мФлагиКомпиляции.Сервер;
мФлагиКомпиляции.КлиентУправляемоеПриложение = мМетодМодуля.Клиент И мФлагиКомпиляции.КлиентУправляемоеПриложение;
мФлагиКомпиляции.КлиентОбычноеПриложение = мМетодМодуля.Клиент И мФлагиКомпиляции.КлиентОбычноеПриложение;
мФлагиКомпиляции.БезКонтекста = мМетодМодуля.БезКонтекста;
мТекстБлока = мМетодМодуля.Тело;
мПозицияТекстаДляПоискаОпределения = мМетодМодуля.ПозицияТела;
Иначе
мТекстБлока = мМодульМетаданных.Программа;
мПозицияТекстаДляПоискаОпределения = мМодульМетаданных.ПозицияПрограммы - 1;
КонецЕсли;
Возврат Истина;
КонецФункции
// Сначала нужно разобрать контекст
Функция ТелоАктивногоМетода(выхНомераПервойСтрокиТела = 1) Экспорт
выхНомераПервойСтрокиТела = мНомерПервойСтрокиТелаМетода;
Если мМетодМодуля <> Неопределено Тогда
Возврат мМетодМодуля.Тело;
ИначеЕсли мМодульМетаданных <> Неопределено Тогда
Возврат мМодульМетаданных.Программа;
Иначе
Возврат мОригинальныйТекст;
КонецЕсли;
КонецФункции
// Сначала нужно разобрать контекст
Функция ОпределениеАктивногоМетодаСОписанием(СмещениеНомераМетода = 0) Экспорт
Если мМетодМодуля <> Неопределено Тогда
Если СмещениеНомераМетода = 0 Тогда
Результат = ТекстМетодаСОписанием(мМетодМодуля);
Иначе
СледующийМетодМодуля = мМодульМетаданных.Методы[мМодульМетаданных.Методы.Индекс(мМетодМодуля) + СмещениеНомераМетода];
Результат = ТекстМетодаСОписанием(СледующийМетодМодуля);
КонецЕсли;
Иначе
Результат = мОригинальныйТекст;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// МетодМодуля - ?, ? -
// Возвращаемое значение:
// Строка -
Функция ТекстМетодаСОписанием(МетодМодуля) Экспорт
Результат = Сред(мОригинальныйТекст, МетодМодуля.ПозицияСОписанием, МетодМодуля.ДлинаСОписанием);
Возврат Результат;
КонецФункции
// Сначала нужно разобрать контекст
Функция ОпределениеМетодаБезОписания(МетодМодуля = Неопределено) Экспорт
Если МетодМодуля = Неопределено Тогда
МетодМодуля = мМетодМодуля;
КонецЕсли;
Если мМетодМодуля <> Неопределено Тогда
Результат = Сред(мОригинальныйТекст, мМетодМодуля.ПозицияОпределения, мМетодМодуля.ДлинаОпределения);
Результат = ирОбщий.ЗаменитьРегВыражениеЛкс(Результат, "^\n*", "", Ложь);
Возврат Результат;
Иначе
Возврат мОригинальныйТекст;
КонецЕсли;
КонецФункции
// Выполняет программу на внутреннем языке.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Булево - безошибочность выполнения кода.
//
Функция ВыполнитьПрограммныйКод(Знач ЛиСинтаксическийКонтроль = Ложь, выхИнформацияОбОшибке = Неопределено, Знач ТекстДляВыполнения = "") Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Не ЗначениеЗаполнено(ТекстДляВыполнения) Тогда
ТекстДляВыполнения = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Попытка
мПлатформа.ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения, ТекстДляВыполнения, ЛиСинтаксическийКонтроль);
Возврат Истина;
Исключение
выхИнформацияОбОшибке = ИнформацияОбОшибке();
Если Не ЛиСинтаксическийКонтроль Тогда
// Баг платформы. Зависает приложение, если пытаемся установить выделение на невидимой странице.
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста,,,,, выхИнформацияОбОшибке);
КонецЕсли;
Возврат Ложь;
КонецПопытки;
КонецФункции
Функция ЗаполнитьДоступныеТаблицыWQL() Экспорт
////Если мДоступныеТаблицыПолучены Тогда
//// Возврат Неопределено;
////КонецЕсли;
////ЭтотОбъект.мДоступныеТаблицыПолучены = Истина;
//ДоступныеТаблицы.Очистить();
ОчиститьДоступныеНеВременныеТаблицы();
Если Конфигурация = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Состояние("Подготовка метаданных...");
wbemFlagUseAmendedQualifiers = 131072; //&H20000
КоллекцияКлассов = Конфигурация.SubclassesOf(, wbemFlagUseAmendedQualifiers);
ВидимостьКолонкиСхема = Ложь;
ВидимостьКолонкиОписание = Ложь;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКлассов.Count, "Получаем метаданные");
Для Каждого ЭлементКоллекции Из КоллекцияКлассов Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
СтрокаТаблицы = ДоступныеТаблицы.Добавить();
СтрокаТаблицы.Имя = ЭлементКоллекции.Path_.Class;
//СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;
//СтрокаТаблицы.Тип = СтрокаТЗ.TABLE_TYPE;
СтрокаТаблицы.Описание = ирОбщий.ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции);
ПолноИмя = СтрокаТаблицы.Имя;
Если ЗначениеЗаполнено(СтрокаТаблицы.Схема) Тогда
ПолноИмя = СтрокаТаблицы.Схема + "." + ПолноИмя;
КонецЕсли;
СтрокаТаблицы.ПолноеИмя = ПолноИмя;
СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя);
ВидимостьКолонкиСхема = ВидимостьКолонкиСхема Или ЗначениеЗаполнено(СтрокаТаблицы.Схема);
ВидимостьКолонкиОписание = ВидимостьКолонкиСхема Или ЗначениеЗаполнено(СтрокаТаблицы.Описание);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Возврат Неопределено;
КонецФункции
Функция ЗаполнитьДоступныеТаблицыADO() Экспорт
////Если мДоступныеТаблицыПолучены Тогда
//// Возврат Неопределено;
////КонецЕсли;
////мДоступныеТаблицыПолучены = Истина;
//ДоступныеТаблицы.Очистить();
ОчиститьДоступныеНеВременныеТаблицы();
Если Ложь
Или Конфигурация = Неопределено
Или Конфигурация.State = 0
Тогда
Возврат Неопределено;
КонецЕсли;
Состояние("Подготовка метаданных...");
Если Не мРасширенноеПолучениеМетаданныхADO Тогда
Фильтры = Новый Массив();
Фильтры.Добавить(); // TABLE_CATALOG
Фильтры.Добавить(); // TABLE_SCHEMA
Фильтры.Добавить(); // TABLE_NAME
Если Не мРасширенноеПолучениеМетаданныхADO Тогда
Фильтры.Добавить("TABLE"); // TABLE_TYPE
КонецЕсли;
Фильтры = Новый COMSafeArray(Фильтры, "VT_VARIANT");
ОписаниеТаблицRecordSet = Конфигурация.OpenSchema(20, Фильтры); //adSchemaTables // Может выполняться долго (oracle)
Иначе
ОписаниеТаблицRecordSet = Конфигурация.OpenSchema(20); //adSchemaTables // Может выполняться долго (oracle)
КонецЕсли;
ОписаниеТаблицТЗ = ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(ОписаниеТаблицRecordSet);
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаТЗ Из ОписаниеТаблицТЗ Цикл
ТипТаблицы = СтрокаТЗ.TABLE_TYPE;
Если Истина
И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "table")
И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "view")
Тогда
Продолжить;
КонецЕсли;
СтрокаТаблицы = ДоступныеТаблицы.Добавить();
СтрокаТаблицы.Имя = СтрокаТЗ.TABLE_NAME;
СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;
СтрокаТаблицы.Тип = ТипТаблицы;
СтрокаТаблицы.Описание = СтрокаТЗ.DESCRIPTION;
ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);
СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;
СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого СтрокаТЗ Из ОписаниеТаблицТЗ Цикл   ТипТаблицы = СтрокаТЗ.TABLE_TYPE;   Если Истина   И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "table")   И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "view")   Тогда   Продолжить;   КонецЕсли;   СтрокаТаблицы = ДоступныеТаблицы.Добавить();   СтрокаТаблицы.Имя = СтрокаТЗ.TABLE_NAME;   СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;   СтрокаТаблицы.Тип = ТипТаблицы;   СтрокаТаблицы.Описание = СтрокаТЗ.DESCRIPTION;   ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);   СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;   СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);   КонецЦикла;  
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция ПолучитьИмяТаблицыADO(Знач ИмяИсходное)
Если Лев(ИмяИсходное, 1) <> "[" Тогда
ИмяИсходное = "[" + ИмяИсходное + "]";
КонецЕсли;
Возврат ИмяИсходное;
КонецФункции
Процедура ОбновитьВычисляемыеДоступныеВременныеТаблицы() Экспорт
ОчиститьДоступныеВременныеТаблицы();
Если мМенеджерВременныхТаблиц <> Неопределено Тогда
Для Каждого ПакетЗапросов Из мМенеджерВременныхТаблиц.ПакетыЗапросов Цикл // см. НовыйПакетЗапросов()
ПодготовитьПакетЗапросов(ПакетЗапросов);
Для Каждого ЭлементСписка Из ПакетЗапросов.Структура Цикл
Если ЗначениеЗаполнено(ЭлементСписка.Представление) Тогда
НайтиДобавитьДоступнуюВременнуюТаблицу(ЭлементСписка.Представление);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из ПакетЗапросов.Параметры Цикл
Если ТипЗнч(КлючИЗначение.Значение) = Тип("ТаблицаЗначений") Тогда
НайтиДобавитьДоступнуюВременнуюТаблицу("&" + КлючИЗначение.Ключ);
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
КонтекстВыполнения.Параметры.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция НайтиДобавитьДоступнуюВременнуюТаблицу(Знач ЛюбоеИмяТаблицы, ПородившийЗапрос = Неопределено, выхБылиДобавления = Ложь, ИсточникДанных1С = Неопределено) Экспорт
ПолноеИмяТаблицы = ПолноеИмяДоступнойТаблицы(ЛюбоеИмяТаблицы);
КраткоеИмяТаблицы = КраткоеИмяВременнойТаблицы(ЛюбоеИмяТаблицы);
Если Лев(ЛюбоеИмяТаблицы, 1) = "&" Тогда
Тип = "Параметр";
КраткоеИмяТаблицы = Сред(КраткоеИмяТаблицы, 2);
Иначе
Тип = "ВременнаяТаблица";
КонецЕсли;
ПолноеИмяТаблицы = ПолноеИмяВременнойТаблицы(ПолноеИмяТаблицы, ИсточникДанных1С);
СтрокаДоступнойТаблицы = ДоступныеТаблицы.Найти(НРег(ПолноеИмяТаблицы), "НПолноеИмя");
Если СтрокаДоступнойТаблицы = Неопределено Тогда
СтрокаДоступнойТаблицы = ДоступныеТаблицы.Добавить();
СтрокаДоступнойТаблицы.Имя = КраткоеИмяТаблицы;
СтрокаДоступнойТаблицы.ПолноеИмя = ПолноеИмяТаблицы;
СтрокаДоступнойТаблицы.Схема = ИсточникДанных1С;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаДоступнойТаблицы, "ПолноеИмя");
СтрокаДоступнойТаблицы.Тип = Тип;
СтрокаДоступнойТаблицы.ЕстьДоступ = Истина;
выхБылиДобавления = Истина;
КонецЕсли;
Если ПородившийЗапрос <> Неопределено Тогда
Для Каждого СтараяСтрока Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("ПородившийЗапрос", ПородившийЗапрос)) Цикл
Если СтараяСтрока = СтрокаДоступнойТаблицы Тогда
Продолжить;
КонецЕсли;
ДоступныеТаблицы.Удалить(СтараяСтрока);
КонецЦикла;
СтрокаДоступнойТаблицы.ПородившийЗапрос = ПородившийЗапрос;
КонецЕсли;
Возврат СтрокаДоступнойТаблицы;
КонецФункции
Функция ПолноеИмяДоступнойТаблицы(Знач ИмяДоступнойТаблицы, ИмяСхемы = Неопределено) Экспорт
Если Истина
И Найти(ИмяДоступнойТаблицы, ".") = 0
И мПараметрыДиалектаSQL.Диалект <> "1С"
И мПараметрыДиалектаSQL.Диалект <> "WQL"
Тогда
ИмяДоступнойТаблицы = ПолучитьИмяТаблицыADO(ИмяДоступнойТаблицы);
Если ИмяСхемы = Неопределено И ДоступныеТаблицы.Количество() > 0 Тогда
ИмяСхемы = ДоступныеТаблицы[0].Схема;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяСхемы) Тогда
ИмяДоступнойТаблицы = ИмяСхемы + "." + ИмяДоступнойТаблицы;
КонецЕсли;
КонецЕсли;
Возврат ИмяДоступнойТаблицы;
КонецФункции
Функция ДоступнаяТаблицаПоИмениВыбранной(Знач ПолноеИмя) Экспорт
ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(ПолноеИмя);
СтрокаДоступнойТаблицы = ДоступныеТаблицы.Найти(НРег(ПолноеИмяДоступнойТаблицы), "НПолноеИмя");
Возврат СтрокаДоступнойТаблицы;
КонецФункции
Функция ЭтоПараметрПериодичность1С(Знач СтрокаПараметраТаблицы, Знач ДиалектSQL = "") Экспорт
Если ДиалектSQL = "" Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
Результат = Истина
И Найти(НРег(СтрокаПараметраТаблицы.Имя), "периодичность") = 1
И ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С");
Возврат Результат;
КонецФункции
Функция ПоляДоступнойТаблицы(Знач СтрокаДоступнойТаблицы, Знач ПараметрыТаблицы = Неопределено, Знач ДиалектSQL = "", Знач ПородившийЗапрос = Неопределено) Экспорт
Если ДиалектSQL = "" Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
ПолноеИмяТаблицы = СтрокаДоступнойТаблицы.ПолноеИмя;
ИспользоватьКэширование = Истина
И СтрокаДоступнойТаблицы.Тип <> "ВременнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "Параметр"
И ТипЗнч(Конфигурация) <> Тип("ОбъектМетаданныхКонфигурация");
Если ИспользоватьКэширование Тогда
ТаблицаПолей = мДоступныеПоляТаблиц[ПолноеИмяТаблицы];
Если ТаблицаПолей <> Неопределено Тогда
Возврат ТаблицаПолей;
КонецЕсли;
КонецЕсли;
ТаблицаПолей = Новый ТаблицаЗначений;
ТаблицаПолей.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
ТаблицаПолей.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
ТаблицаПолей.Колонки.Добавить("Метаданные");
Если СтрокаДоступнойТаблицы.Тип = "ВременнаяТаблица" Тогда
КолонкиРезультата = Новый Массив();
Если мМенеджерВременныхТаблиц <> Неопределено Тогда
Построитель = НайтиЗапросВременнойТаблицы(ПолноеИмяТаблицы);
Если Построитель <> Неопределено Тогда
КолонкиРезультата = мПлатформа.ПустаяТаблицаЗначенийИзПостроителя(Построитель).Колонки;
КонецЕсли;
ИначеЕсли ПородившийЗапрос <> Неопределено Тогда
//КолонкиРезультата = ПородившийЗапрос.ЧастиОбъединения[0].ВыбранныеПоля;
КолонкиРезультата = ПородившийЗапрос.ПоляОбъединения;
Иначе
ТекстЗапроса = "SELECT * FROM " + ПолноеИмяТаблицы + " WHERE 1=0";
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ВременныйЗапрос.Текст = ТекстЗапроса;
РезультатВременногоЗапроса = Неопределено;
Попытка
РезультатВременногоЗапроса = ВременныйЗапрос.Выполнить();
Исключение
КонецПопытки;
Если РезультатВременногоЗапроса <> Неопределено Тогда
КолонкиРезультата = РезультатВременногоЗапроса.Выгрузить();
КолонкиРезультата = ирОбщий.ТаблицаСКолонкамиБезТипаNullЛкс(КолонкиРезультата, Ложь);
КолонкиРезультата = КолонкиРезультата.Колонки;
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "WQL") Тогда
//
Иначе // ADO
Попытка
РезультатВременногоЗапроса = Конфигурация.Execute(ТекстЗапроса);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если РезультатВременногоЗапроса <> Неопределено Тогда
РезультатТаблица = Новый ТаблицаЗначений;
ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатВременногоЗапроса, Истина);
КолонкиРезультата = РезультатТаблица.Колонки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Для Каждого ВыбранноеПоле Из КолонкиРезультата Цикл
Если ВыбранноеПоле.Имя = "" Тогда
ВызватьИсключение "Не определены имена полей таблицы """ + ПолноеИмяТаблицы + """";
КонецЕсли;
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ВыбранноеПоле.Имя;
СтрокаПоля.ТипЗначения = ВыбранноеПоле.ТипЗначения;
КонецЦикла;
ИначеЕсли СтрокаДоступнойТаблицы.Тип = "Параметр" Тогда
КолонкиРезультата = Новый Массив();
ТаблицаПараметр = Неопределено;
Если Истина
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
И КонтекстВыполнения.Параметры.Свойство(СтрокаДоступнойТаблицы.Имя, ТаблицаПараметр)
Тогда
КолонкиРезультата = ТаблицаПараметр.Колонки;
КонецЕсли;
Для Каждого ВыбранноеПоле Из КолонкиРезультата Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ВыбранноеПоле.Имя;
СтрокаПоля.ТипЗначения = ВыбранноеПоле.ТипЗначения;
КонецЦикла;
ИначеЕсли ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ИндексПараметраПериодичность = Неопределено;
ОпределениеПараметраПериодичность = "";
Если ПараметрыТаблицы <> Неопределено Тогда
Для ИндексПараметра = 0 По ПараметрыТаблицы.Количество() - 1 Цикл
СтрокаПараметраТаблицы = ПараметрыТаблицы[ИндексПараметра];
Если ЭтоПараметрПериодичность1С(СтрокаПараметраТаблицы) Тогда
ИндексПараметраПериодичность = ИндексПараметра;
ОпределениеПараметраПериодичность = СтрокаПараметраТаблицы.Определение;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы,, ИндексПараметраПериодичность, ОпределениеПараметраПериодичность, Ложь);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
#КонецЕсли
Если ПоляТаблицыБД <> Неопределено Тогда
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
//Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
// Продолжить;
//КонецЕсли;
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ПолеТаблицыБД.Имя;
СтрокаПоля.ТипЗначения = ПолеТаблицыБД.ТипЗначения;
СтрокаПоля.Метаданные = ПолеТаблицыБД.Метаданные;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл         СтрокаПоля = ТаблицаПолей.Добавить();   СтрокаПоля.Имя = ПолеТаблицыБД.Имя;   СтрокаПоля.ТипЗначения = ПолеТаблицыБД.ТипЗначения;   СтрокаПоля.Метаданные = ПолеТаблицыБД.Метаданные;   КонецЦикла;  
КонецЕсли;
ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ТаблицаПолей, СтрокаДоступнойТаблицы, Истина);
КонецЕсли;
Иначе
СтрокаДоступнойТаблицы = ДоступнаяТаблицаПоИмениВыбранной(ПолноеИмяТаблицы);
Если ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "WQL") Тогда
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписаниеКласса = Конфигурация.Get(СтрокаДоступнойТаблицы.Имя, wbemFlagUseAmendedQualifiers);
ТаблицаКласса = Новый ТаблицаЗначений;
МассивКоллекцийСвойств = Новый Массив();
МассивКоллекцийСвойств.Добавить(ОписаниеКласса.Properties_);
//Если СобиратьСистемныеСвойстваWMI Тогда
// МассивКоллекцийСвойств.Добавить(ОписаниеКласса.SystemProperties_);
//КонецЕсли;
Для Каждого КоллекцияСвойств Из МассивКоллекцийСвойств Цикл
Для Каждого Свойство Из КоллекцияСвойств Цикл
ИмяТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство);
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа,,,, Новый КвалификаторыСтроки(1024)); // Доделать распознавание типов
Исключение
ОписаниеТипов = Новый ОписаниеТипов();
КонецПопытки;
ПредставлениеСвойства = ирОбщий.ПолучитьОписаниеЭлементаWMIЛкс(Свойство, "DisplayName");
ТаблицаКласса.Колонки.Добавить(, ОписаниеТипов, ПредставлениеСвойства);
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = Свойство.Name;
СтрокаПоля.ТипЗначения = ОписаниеТипов;
//СтрокаПоля.Описание = ПредставлениеСвойства;
КонецЦикла;
КонецЦикла;
Иначе // ADO
Фильтры = Новый Массив();
Фильтры.Добавить(); //TABLE_CATALOG
Если ЗначениеЗаполнено(СтрокаДоступнойТаблицы.Схема) Тогда //TABLE_SCHEMA
Фильтры.Добавить(СтрокаДоступнойТаблицы.Схема);
Иначе
Фильтры.Добавить(Неопределено);
КонецЕсли;
Фильтры.Добавить(СтрокаДоступнойТаблицы.Имя); // TABLE_NAME
Фильтры = Новый COMSafeArray(Фильтры, "VT_VARIANT");
Состояние("Запрашиваем поля " + ПолноеИмяТаблицы + "...");
ОписаниеПолейRecordSet = Конфигурация.OpenSchema(4, Фильтры); //adSchemaColumns
ADOUtils = мПлатформа.ПолучитьADOUtils();
Если ADOUtils <> Неопределено Тогда
ОписаниеПолейТЗ = ADOUtils.ADORecordsetToValueTable(ОписаниеПолейRecordSet);
Для Каждого СтрокаТЗ Из ОписаниеПолейТЗ Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = СтрокаТЗ.COLUMN_NAME;
ЧисловаяРазрядность = СтрокаТЗ.NUMERIC_SCALE;
ДлинаТипа = СтрокаТЗ.CHARACTER_MAXIMUM_LENGTH;
ЧисловаяТочность = СтрокаТЗ.NUMERIC_PRECISION;
НомерТипа = СтрокаТЗ.DATA_TYPE;
FieldADO = ирОбщий.FieldADOЛкс(СтрокаПоля.Имя, НомерТипа, ДлинаТипа, ЧисловаяТочность, ЧисловаяРазрядность);
СтрокаПоля.ТипЗначения = ирОбщий.FieldADO_ПолучитьТип1CЛкс(FieldADO, Истина);
КонецЦикла;
Иначе
Пока Не ОписаниеПолейRecordSet.EOF() Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ОписаниеПолейRecordSet.Fields("COLUMN_NAME").Value;
ЧисловаяРазрядность = ОписаниеПолейRecordSet.Fields("NUMERIC_SCALE").Value;
ДлинаТипа = ОписаниеПолейRecordSet.Fields("CHARACTER_MAXIMUM_LENGTH").Value;
ЧисловаяТочность = ОписаниеПолейRecordSet.Fields("NUMERIC_PRECISION").Value;
НомерТипа = ОписаниеПолейRecordSet.Fields("DATA_TYPE").Value;
FieldADO = ирОбщий.FieldADOЛкс(СтрокаПоля.Имя, НомерТипа, ДлинаТипа, ЧисловаяТочность, ЧисловаяРазрядность);
СтрокаПоля.ТипЗначения = ирОбщий.FieldADO_ПолучитьТип1CЛкс(FieldADO, Истина);
ОписаниеПолейRecordSet.MoveNext();
КонецЦикла;
КонецЕсли;
КонецЕсли;
Состояние();
КонецЕсли;
Если ИспользоватьКэширование Тогда
мДоступныеПоляТаблиц[ПолноеИмяТаблицы] = ТаблицаПолей;
КонецЕсли;
Возврат ТаблицаПолей;
КонецФункции
Функция ПолноеИмяВременнойТаблицы(Знач КраткоеИмяТаблицы, Знач ИсточникДанных1С = Неопределено) Экспорт
Результат = КраткоеИмяТаблицы;
Если Истина
И Найти(КраткоеИмяТаблицы, ".") = 0
И мПараметрыДиалектаSQL.Диалект = "1С"
И ЗначениеЗаполнено(ИсточникДанных1С)
И ИсточникДанных1С <> "<Локальный>"
Тогда
Результат = "ВнешнийИсточникДанных." + ИсточникДанных1С + ".ВременнаяТаблица." + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КраткоеИмяВременнойТаблицы(ЛюбоеИмяТаблицы) Экспорт
Результат = ЛюбоеИмяТаблицы;
Если Истина
И мПараметрыДиалектаSQL.Диалект = "1С"
И Найти(Результат, ".") > 0
Тогда
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОчиститьДоступныеВременныеТаблицы(ТаблицаДоступныхТаблиц = Неопределено) Экспорт
Если ТаблицаДоступныхТаблиц = Неопределено Тогда
ТаблицаДоступныхТаблиц = ДоступныеТаблицы;
КонецЕсли;
ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюВКолонкеЛкс(ТаблицаДоступныхТаблиц, "Тип", "ВременнаяТаблица");
КонецПроцедуры
Процедура ОчиститьДоступныеНеВременныеТаблицы() Экспорт
ДоступныеВременныеТаблицы = ДоступныеТаблицы.Выгрузить(Новый Структура("Тип", "ВременнаяТаблица"));
ДоступныеТаблицы.Очистить();
ДоступныеТаблицы.Загрузить(ДоступныеВременныеТаблицы);
КонецПроцедуры
Функция ПрефиксПараметра() Экспорт
Возврат мПараметрыДиалектаSQL.ПрефиксПараметра;
КонецФункции
// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
// Нет.
//
Функция ВызватьКонструкторЗапросов(Знач ИспользуемСобственныйКонструктор = Неопределено) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст запроса не может быть изменен. Открыть конструктор без возможности применения изменений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ИспользуемСобственныйКонструктор = Ложь
КонецЕсли;
ПредпочитаюСобственныйКонструкторЗапроса = Ложь;
Если ИспользуемСобственныйКонструктор = Неопределено Тогда
ПредпочитаюСобственныйКонструкторЗапроса = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса");
Если ПредпочитаюСобственныйКонструкторЗапроса = Неопределено Тогда
Ответ = Вопрос("Подсистема имеет собственный конструктор запроса. Приоритет его использования задается в настройках компоненты ""Контекстная подсказка"".
|Хотите установить приоритет его использования?", РежимДиалогаВопрос.ДаНет);
ПредпочитаюСобственныйКонструкторЗапроса = Ответ = КодВозвратаДиалога.Да;
ирОбщий.СохранитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса", ПредпочитаюСобственныйКонструкторЗапроса);
КонецЕсли;
КонецЕсли;
ИспользуемСобственныйКонструктор = Ложь
Или ИспользуемСобственныйКонструктор = Истина
Или мДиалектSQL <> "1С"
Или ПредпочитаюСобственныйКонструкторЗапроса;
Если ИспользуемСобственныйКонструктор Тогда
Если ЯзыкПрограммы = 1 Тогда
КопияКомпоненты = ЭтотОбъект;
Иначе
КопияКомпоненты = КопияКомпоненты(); // чтобы не испортилось содержимое СлужебноеПолеТекстаДолгое этой компоненты
КопияКомпоненты.СоздатьСлужебноеПоле();
КопияКомпоненты.ОбновитьВычисляемыеДоступныеВременныеТаблицы();
КонецЕсли;
КонструкторЗапроса = КопияКомпоненты.ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.Конфигурация = Конфигурация;
Иначе
КонструкторЗапроса = Новый КонструкторЗапроса;
КонецЕсли;
//ОбрамитьСобранныйТекстСкобками = Ложь;
Если ЯзыкПрограммы = 1 Тогда
Если СтрДлина(СокрЛП(ВыделенныйТекст())) < 6 И Не ЭтоЧастичныйЗапрос Тогда
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
НачальнаяСтрокаЗапроса = 0;
НачальнаяКолонкаЗапроса = 0;
Иначе
ТекстЗапроса = ВыделенныйТекст();
//Если Не ЗначениеЗаполнено(ТекстЗапроса) И ЭтоЧастичныйЗапрос Тогда
// ТекстЗапроса = "ВЫБРАТЬ 1";
// ОбрамитьСобранныйТекстСкобками = Истина;
//КонецЕсли;
НачальнаяСтрокаЗапроса = мНачальнаяСтрока - 1;
НачальнаяКолонкаЗапроса = мНачальнаяКолонка - 1;
КонецЕсли;
КонструкторЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
//КонструкторЗапроса.АвтодобавлениеПредставлений = Истина;
МассивВременныхТаблиц = Новый Массив;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
Если Истина
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
И Не ИспользуемСобственныйКонструктор
Тогда
СтарыйТекстЗапроса = ТекстЗапроса;
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстЗапроса);
Попытка
ТекстЗапроса = мПлатформа.ЗамаскироватьВременныеТаблицы(КонтекстВыполнения, ТекстЗапроса, МассивВременныхТаблиц);
Исключение
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, , , Истина,, ИнформацияОбОшибке());
Возврат Ложь;
КонецПопытки;
НоваяИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстЗапроса);
Если Истина
И НоваяИнформацияОбОшибке <> Неопределено
И ИнформацияОбОшибке = Неопределено
И Найти(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(НоваяИнформацияОбОшибке), "Ожидается псевдоним запроса") > 0
Тогда
// Сюда попадаем, когда у временной таблицы нет псевдонима
ирОбщий.СообщитьСУчетомМодальностиЛкс("В запросе присутствуют временные таблицы без псевдонимов. "
+ "Для максимальной функциональности рекомендуется задать каждой временной таблице псевдоним",, СтатусСообщения.Внимание);
МассивВременныхТаблиц = Новый Массив;
ТекстЗапроса = СтарыйТекстЗапроса;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
// Мультиметка77248851
РазобратьТекущийКонтекст();
ТекстПоля = ПолеТекста.ПолучитьТекст();
мРегВыражение.Global = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = шСтрокаПрограммы;
Результат = мРегВыражение.НайтиВхождения(ТекстПоля);
Успех = Ложь;
Для Каждого Вхождение Из Результат Цикл
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= мПозицияВТексте
И (ПозицияВхождения + Вхождение.Length) >= мПозицияВТексте
Тогда
ПолеТекста.УстановитьГраницыВыделения(ПозицияВхождения + 1, ПозицияВхождения + 1 + Вхождение.Length);
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
ПолеТекста.ПолучитьГраницыВыделения(НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, , );
НачальнаяСтрокаЗапроса = НачальнаяСтрокаЗапроса - 1;
НачальнаяКолонкаЗапроса = НачальнаяСтрокаЗапроса - 1;
Если Успех Тогда
ТекстЗапроса = ВыделенныйТекст();
Если Прав(ТекстЗапроса, 1) <> """" Тогда
ТекстЗапроса = ТекстЗапроса + """";
КонецЕсли;
ТекстЗапроса = Вычислить(ТекстЗапроса);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "|", "");
Иначе
ТекстЗапроса = "";
КонецЕсли;
КонецЕсли;
Если ИспользуемСобственныйКонструктор Тогда
Парсер = мПлатформа.мПолучитьПарсер("ГрамматикаЯзыкаЗапросов");
Если Парсер = Неопределено Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Компонента анализа текста запроса не подключена");
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
Если ИспользуемСобственныйКонструктор Тогда
РезультатРазбора = ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса,, мДиалектSQL,, НачальнаяСтрокаЗапроса);
Если Не РезультатРазбора Тогда
Возврат Ложь;
КонецЕсли;
Иначе
СтруктуруРезультатаПакетногоЗапроса = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ТекстЗапроса);
Если СтруктуруРезультатаПакетногоЗапроса.Количество() > 0 Тогда
Ответ = Вопрос("В комментариях обнаружены имена запросов. Стандартный конструктор запросов их удалит. Продолжить?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Попытка
КонструкторЗапроса.Текст = ТекстЗапроса;
Исключение
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, Истина,, ИнформацияОбОшибке());
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Иначе
Если ИспользуемСобственныйКонструктор Тогда
//КонструкторЗапроса.УстановитьДиалектSQL(мДиалектSQL);
КонструкторЗапроса.УстановитьДанные();
КонецЕсли;
КонецЕсли;
РезультатФормы = КонструкторЗапроса.ОткрытьМодально();
Если РезультатФормы = Истина Тогда
Если Не РежимТолькоПросмотр Тогда
НовыйТекстЗапроса = КонструкторЗапроса.Текст;
Если Истина
И ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация")
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
Тогда
//RegExp.Global = Истина;
//RegExp.MultiLine = Ложь;
//RegExp.IgnoreCase = Истина;
//// Допустим 1 уровень скобок.
//шОдинарныеСкобки = "\([^\)\(]*?\)";
//шИмяВременнойТаблицы = "";
//Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл
// шИмяВременнойТаблицы = шИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица;
//КонецЦикла;
//шИмяВременнойТаблицы = Сред(шИмяВременнойТаблицы, 2);
//RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шОдинарныеСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + шИмяВременнойТаблицы + ")""\)";
//НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "$1");
НовыйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(НовыйТекстЗапроса, МассивВременныхТаблиц);
КонецЕсли;
Если ЯзыкПрограммы = 1 Тогда
Если Не ЭтоЧастичныйЗапрос И НачальнаяСтрокаЗапроса = 0 Тогда
ВыделитьВесьТекст();
КонецЕсли;
//Если ОбрамитьСобранныйТекстСкобками Тогда
// НовыйТекстЗапроса = "(" + НовыйТекстЗапроса + ")";
//КонецЕсли;
Если ИспользуемСобственныйКонструктор Тогда
ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(НовыйТекстЗапроса, КонструкторЗапроса.мНомерТекущейСтрокиВСобранномТексте);
Иначе
ВыделенныйТекст(НовыйТекстЗапроса);
КонецЕсли;
ПослеУстановкиВыделенногоМногострочногоТекста();
Иначе
НовыйТекстЗапроса = ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(НовыйТекстЗапроса);
ЧислоСтрокЗамены = СтрЧислоСтрок(НовыйТекстЗапроса);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(НовыйТекстЗапроса);
СдвинутыйТекст = ТекстовыйДокумент.ПолучитьСтроку(1);
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", мШиринаТабуляции);
ТекстНачальнойСтроки = ПолеТекста.ПолучитьСтроку(мНачальнаяСтрока);
ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / мШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % мШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
Для Счетчик = 2 По ЧислоСтрокЗамены Цикл
ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
КонецЦикла;
ВыделенныйТекст(СдвинутыйТекст);
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция РедактироватьВКонсолиЗапросов() Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст запроса не может быть изменен. Открыть консоль без возможности применения изменений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Текст = ПолеТекста.ПолучитьТекст();
ВыделениеДвумерное = ПолеТекста.ВыделениеДвумерное();
Если Истина
И мПлатформа.РедактироватьЗапрос(Текст,,,,, ВыделениеДвумерное)
И Не РежимТолькоПросмотр
Тогда
ВыделитьВесьТекст();
ВыделенныйТекст(Текст);
ПолеТекста.УстановитьВыделениеДвумерное(ВыделениеДвумерное);
ПослеУстановкиВыделенногоМногострочногоТекста();
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция РедактироватьВКонсолиКода() Экспорт
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст запроса не может быть изменен. Открыть консоль без возможности применения изменений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ФормаКонсоли = ирКлиент.ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма", , , Новый УникальныйИдентификатор);
ФормаКонсоли.мРежимРедактора = Истина;
ФормаКонсоли.ПараметрТекст = ПолеТекста.ПолучитьТекст();
Если Истина
И ФормаКонсоли.ОткрытьМодально() <> Неопределено
И Не РежимТолькоПросмотр
Тогда
ВыделитьВесьТекст();
ВыделенныйТекст(ФормаКонсоли.РезультатФормы.Текст);
ПослеУстановкиВыделенногоМногострочногоТекста();
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Процедура ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(Знач НовыйТекстЗапроса, Знач НомерТекущейСтрокиВСобранномТексте = 0)
ПолучитьНомерТекущейСтроки();
ВыделенныйТекст(НовыйТекстЗапроса);
мНачальнаяСтрока = мНачальнаяСтрока + НомерТекущейСтрокиВСобранномТексте;
мНачальнаяКолонка = 1;
мКонечнаяСтрока = мНачальнаяСтрока;
мКонечнаяКолонка = мНачальнаяКолонка;
КонецПроцедуры
Процедура ПоказатьТекущиеКоординаты(ПолеТекста, СтартоваяСтрокаДляОтображенияОшибок = 0)
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ФормаВладелец = Неопределено Тогда
Возврат;
КонецЕсли;
// Антибаг платформы 8.1 . Терялся фокус
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ПолеТекста.ПоказатьОшибку(мПарсер.CurrentLineNumber() + СтартоваяСтрокаДляОтображенияОшибок, мПарсер.CurrentColumnNumber(), ФормаВладелец);
КонецПроцедуры
Функция ПолучитьКоординатыВТекстеЗапроса(ПолеТекста, СтартоваяСтрокаДляОтображенияОшибок = 0)
НомерСтроки = СтартоваяСтрокаДляОтображенияОшибок + мПарсер.CurrentLineNumber();
Результат = "";
Если ПолеТекста <> Неопределено Тогда
Результат = Результат + ирОбщий.ПредставлениеИзИдентификатораЛкс(ПолеТекста.ЭлементФормы.Имя) + ": ";
КонецЕсли;
Результат = Результат + "Строка " + НомерСтроки + ": {(" + НомерСтроки + "," + мПарсер.CurrentColumnNumber() + ")}: ";
Возврат Результат;
КонецФункции
Функция ПолучитьСтрокуОжидаемыхТокенов()
СтрокаОжидаемыхТокенов = "";
Для й = 0 по мПарсер.TokenCount() - 1 Цикл
Токен = мПарсер.Tokens(й);
СтрокаОжидаемыхТокенов = СтрокаОжидаемыхТокенов + ", " + Токен.Text;
КонецЦикла;
Возврат Сред(СтрокаОжидаемыхТокенов, 3);
КонецФункции // ПолучитьСтрокуОжидаемыхТокенов()
Функция _ПолучитьГраничныйТерминалПравила(Данные, ИндексГраницы = 0, ЗахватыватьКрайниеКомментарии = Ложь) Экспорт
КоличествоТокенов = Данные.TokenCount;
Для Сч1 = 1 По КоличествоТокенов Цикл
Если ИндексГраницы = 1 Тогда
УзелКандидат = Данные.Tokens(КоличествоТокенов - Сч1);
Иначе
УзелКандидат = Данные.Tokens(Сч1 - 1);
КонецЕсли;
Если ТипЗнч(УзелКандидат.Data) = Тип("Строка") Тогда
Если ЗахватыватьКрайниеКомментарии И ИндексГраницы = 1 И УзелКандидат.EndNoise <> Неопределено Тогда
Возврат УзелКандидат.EndNoise;
ИначеЕсли ЗахватыватьКрайниеКомментарии И ИндексГраницы = 0 И УзелКандидат.BeginNoise <> Неопределено Тогда
Возврат УзелКандидат.BeginNoise;
Иначе
Возврат УзелКандидат;
КонецЕсли;
ИначеЕсли ТипЗнч(УзелКандидат.Data) = Тип("COMОбъект") Тогда
Если УзелКандидат.Data.TokenCount > 0 Тогда
УзелСнизу = _ПолучитьГраничныйТерминалПравила(УзелКандидат.Data, ИндексГраницы, ЗахватыватьКрайниеКомментарии);
Если УзелСнизу <> Неопределено Тогда
Возврат УзелСнизу;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ПолучитьТекстИзТокена(Токен, выхНачальнаяСтрока = 0, выхНачальнаяКолонка = 0, выхКонечнаяСтрока = 0, выхКонечнаяКолонка = 0, Знач СлужебноеПолеТекста = Неопределено) Экспорт
Если Токен = Неопределено Тогда
Возврат "";
КонецЕсли;
НачальныйТокен = Токен.GetBorderToken(0);
Если НачальныйТокен = Неопределено Тогда
Возврат "";
КонецЕсли;
выхНачальнаяКолонка = НачальныйТокен.ColumnNumber;
выхНачальнаяСтрока = НачальныйТокен.LineNumber;
КонечныйТокен = Токен.GetBorderToken(1);
Если КонечныйТокен = Неопределено Тогда
Возврат "";
КонецЕсли;
выхКонечнаяКолонка = КонечныйТокен.ColumnNumber + СтрДлина(КонечныйТокен.Data);
выхКонечнаяСтрока = КонечныйТокен.LineNumber + СтрЧислоСтрок(КонечныйТокен.Data) - 1;
Если СлужебноеПолеТекста = Неопределено Тогда
СлужебноеПолеТекста = СлужебноеПолеТекстаДолгое;
КонецЕсли;
СлужебноеПолеТекста.УстановитьГраницыВыделения(выхНачальнаяСтрока, выхНачальнаяКолонка, выхКонечнаяСтрока, выхКонечнаяКолонка);
ТекстОпределения = СлужебноеПолеТекста.ВыделенныйТекст;
ТекстОпределения = СокрЛП(ТекстОпределения);
Возврат ТекстОпределения;
КонецФункции
Функция _ПолучитьТекстИзДанныхТокена(ДанныеТокена, выхНачальнаяСтрока = 0, выхНачальнаяКолонка = 0, выхКонечнаяСтрока = 0, выхКонечнаяКолонка = 0) Экспорт
НачальныйТокен = _ПолучитьГраничныйТерминалПравила(ДанныеТокена, 0);
Если НачальныйТокен = Неопределено Тогда
Возврат "";
КонецЕсли;
выхНачальнаяКолонка = НачальныйТокен.ColumnNumber;
выхНачальнаяСтрока = НачальныйТокен.LineNumber;
КонечныйТокен = _ПолучитьГраничныйТерминалПравила(ДанныеТокена, 1);
Если КонечныйТокен = Неопределено Тогда
Возврат "";
КонецЕсли;
выхКонечнаяКолонка = КонечныйТокен.ColumnNumber + СтрДлина(КонечныйТокен.Data);
выхКонечнаяСтрока = КонечныйТокен.LineNumber + СтрЧислоСтрок(КонечныйТокен.Data) - 1;
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(выхНачальнаяСтрока, выхНачальнаяКолонка, выхКонечнаяСтрока, выхКонечнаяКолонка);
ТекстОпределения = СлужебноеПолеТекстаДолгое.ВыделенныйТекст;
ТекстОпределения = СокрЛП(ТекстОпределения);
Возврат ТекстОпределения;
КонецФункции
Функция ЗагрузитьТекстВКонструктор(ТекстЗапроса = Неопределено, Знач КонструкторЗапроса = Неопределено, Знач СокращенноеДерево = Ложь, ДиалектSQL = Неопределено,
ИменованныеПараметры = Неопределено, СтартоваяСтрокаДляОтображенияОшибок = 0) Экспорт
Если ТекстЗапроса = Неопределено Тогда
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Если КонструкторЗапроса <> Неопределено Тогда
КонструкторЗапроса.УстановитьДиалектSQL(ДиалектSQL, ИменованныеПараметры);
КонецЕсли;
ТаблицаКомментариев = Неопределено;
БылиПотери = Неопределено;
НачальныйТокен = РазобратьТекстЗапроса(ТекстЗапроса, СокращенноеДерево,,, Истина, ТаблицаКомментариев, БылиПотери, СтартоваяСтрокаДляОтображенияОшибок);
Если Истина
И НачальныйТокен <> Неопределено
И КонструкторЗапроса <> Неопределено
Тогда
КонструкторЗапроса.СлужебноеПолеТекстаДолгое.УстановитьТекст(ТекстЗапроса);
Если ДиалектSQL = Неопределено Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
КонструкторЗапроса.ЗапросыПакета.Очистить();
КонструкторЗапроса.УстановитьДанные(НачальныйТокен, ТаблицаКомментариев, БылиПотери,, ПолучитьНомерТекущейСтроки());
КонецЕсли;
Возврат НачальныйТокен <> Неопределено;
КонецФункции
// Возвращает начальный токен (Структура) построенной структуры запроса.
//
// Параметры:
// ТекстЗапроса - -
// СокращенноеДерево - -
// ОбновлятьСостояние - -
// пПолеТекста - ОбработкаОбъект.ирПолеТекста, Неопределено, Null - при Неопределено будет использоваться связанное поле, при Null поле не будет использоваться
// СообщатьОПропущенныхТерминалах - -
// выхТаблицаКомментариев - -
// выхБылиПотери - -
// СтартоваяСтрокаДляОтображенияОшибок - -
//
// Возвращаемое значение:
// -
//
Функция РазобратьТекстЗапроса(ТекстЗапроса, СокращенноеДерево = Ложь, ОбновлятьСостояние = Истина, Знач пПолеТекста = Неопределено, СообщатьОПропущенныхТерминалах = Ложь, выхТаблицаКомментариев = Неопределено,
выхБылиПотери = Неопределено, СтартоваяСтрокаДляОтображенияОшибок = 0, Знач ПоказыватьОшибки = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПарсер = мПлатформа.мПолучитьПарсер("ГрамматикаЯзыкаЗапросов");
Если мПарсер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если пПолеТекста = Null Тогда
пПолеТекста = Неопределено;
ИначеЕсли пПолеТекста = Неопределено Тогда
пПолеТекста = ПолеТекста;
Иначе
пПолеТекста = ирКлиент.ОболочкаПоляТекстаЛкс(пПолеТекста);
КонецЕсли;
Если ОбновлятьСостояние Тогда
ирОбщий.СостояниеЛкс("Синтаксический разбор...");
КонецЕсли;
выхТаблицаКомментариев = Новый ТаблицаЗначений;
выхТаблицаКомментариев.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число"));
выхТаблицаКомментариев.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка"));
выхТаблицаКомментариев.Колонки.Добавить("ЭтоРасширение", Новый ОписаниеТипов("Булево"));
gpMsgTokenRead = 1;
gpMsgReduction = 2;
gpMsgAccept = 3;
gpMsgNotLoadedError = 4;
gpMsgLexicalError = 5;
gpMsgSyntaxError = 6;
gpMsgCommentError = 7;
gpMsgInternalError = 8;
gpMsgCommentBlockRead = 9;
gpMsgCommentLineRead = 10;
мПарсер.OpenTextString(ТекстЗапроса + Символы.ПС);
Закончили = Ложь;
//ПоследниеТокены = Новый Массив();
ПоследнееПравилоНеКомментарий = Неопределено;
TrimReductions = СокращенноеДерево;
мПарсер.TrimReductions = СокращенноеДерево; // Была Истина
Пока Не Закончили Цикл
ОбработкаПрерыванияПользователя();
Ответ = мПарсер.Parse();
Если Истина
И СокращенноеДерево
И TrimReductions <> Истина
Тогда
мПарсер.TrimReductions = Истина;
TrimReductions = Истина;
КонецЕсли;
Если Ложь
Или Ответ = gpMsgLexicalError
Или (Истина // Хотя Builder в этом случае диагностирует лексическую ошибку, этот парсер почему то бесконечно выдает статус 7
И Ответ = 7
И мПарсер.CurrentReduction = Неопределено)
Тогда
мПарсер.PopInputToken();
Закончили = Истина;
Если ПоказыватьОшибки Тогда
КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Лексическая ошибка!",, СтатусСообщения.Важное);
Если пПолеТекста <> Неопределено Тогда
ПоказатьТекущиеКоординаты(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
КонецЕсли;
КонецЕсли;
ИначеЕсли Ответ = gpMsgSyntaxError Тогда
ТекущийТокен = мПарсер.CurrentToken();
Если Истина
И ТекущийТокен.Kind = 1
И (Ложь
Или ТекущийТокен.Name = "MultiCommentLine"
//Или ТекущийТокен.Name = "ExtensionBlock"
Или ТекущийТокен.Name = "CommentBlock")
Тогда
Если СообщатьОПропущенныхТерминалах Тогда
КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Проигнорирован комментарий """
+ СокрЛП(ТекущийТокен.Data) + """"
//+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов()
, , СтатусСообщения.Внимание);
КонецЕсли;
мПарсер.PopInputToken();
Иначе
Закончили = Истина;
Если ПоказыватьОшибки Тогда
КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
ТекстОшибки = КоординатыВТекстеЗапроса + "Синтаксическая ошибка """
+ ТекущийТокен.Data + """"
+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов();
ирОбщий.СообщитьСУчетомМодальностиЛкс(ТекстОшибки,, СтатусСообщения.Важное);
Если пПолеТекста <> Неопределено Тогда
ПоказатьТекущиеКоординаты(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ответ = gpMsgReduction Тогда
Если СокращенноеДерево Тогда
//ИмяПравила = мПарсер.CurrentReduction.ParentRule.RuleNonterminal.Name;
ИмяПравила = мПарсер.CurrentRuleName();
Если Ложь // Есть сомнения, что это работает как задумано
Или ИмяПравила = "Table"
Или ИмяПравила = "TableName"
Тогда
мПарсер.TrimReductions = Ложь;
TrimReductions = Ложь;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ответ = gpMsgAccept Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgCommentError Тогда
ИначеЕсли Ответ = gpMsgTokenRead Тогда
Если мПарсер.IsCurrentTokenComment() Тогда
// Храним 2 последних токена
ТекущийТокен = мПарсер.CurrentToken();
ПрочитатьКомментарий(выхТаблицаКомментариев, ТекущийТокен, пПолеТекста, СообщатьОПропущенныхТерминалах, СтартоваяСтрокаДляОтображенияОшибок);
КонецЕсли;
ИначеЕсли Ответ = gpMsgInternalError Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgNotLoadedError Тогда
Закончили = Истина;
КонецЕсли;
КонецЦикла;
Если ОбновлятьСостояние Тогда
ирОбщий.СостояниеЛкс("");
КонецЕсли;
Если Ответ = gpMsgAccept Тогда
НачальныйТокен = Новый Структура("Data, LineNumber, ColumnNumber, Name, Kind", мПарсер.CurrentReduction, 0, 0, "", 0);
Возврат НачальныйТокен;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Процедура ПрочитатьКомментарий(Знач выхТаблицаКомментариев, Знач ТекущийТокен, Знач пПолеТекста, Знач СообщатьОПропущенныхТерминалах, Знач СтартоваяСтрокаДляОтображенияОшибок)
ТекстКомментария = СокрЛП(ТекущийТокен.Data);
МаркерХАРАКТЕРИСТИКИ = "ХАРАКТЕРИСТИКИ";
ЭтоРасширение = Ложь;
Если Лев(ТекстКомментария, 1) = "{" Тогда
ТекстКомментария = Сред(ТекстКомментария, 2, СтрДлина(ТекстКомментария) - 2);
ЭтоРасширение = мПараметрыДиалектаSQL.Это1С;
ИначеЕсли Лев(ТекстКомментария, 2) = "//" Тогда
ТекстКомментария = Сред(ТекстКомментария, 3);
ИначеЕсли Лев(ТекстКомментария, 2) = "/*" Тогда
ТекстКомментария = Сред(ТекстКомментария, 3, СтрДлина(ТекстКомментария) - 4);
КонецЕсли;
Если ЭтоРасширение И Лев(ТекстКомментария, СтрДлина(МаркерХАРАКТЕРИСТИКИ)) = МаркерХАРАКТЕРИСТИКИ Тогда
выхБылиПотери = Истина;
Если СообщатьОПропущенныхТерминалах Тогда
КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Проигнорирован комментарий """
+ СокрЛП(ТекущийТокен.Data) + """"
//+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов()
, , СтатусСообщения.Внимание);
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ТекстКомментария) Тогда
СтрокаРасширения = выхТаблицаКомментариев.Добавить();
СтрокаРасширения.ЭтоРасширение = ЭтоРасширение;
СтрокаРасширения.Позиция = ПолучитьОтносительнуюПозициюТокена(ТекущийТокен);
СтрокаРасширения.Текст = ТекстКомментария; // Убираем крайние фигурные скобки
КонецЕсли;
КонецПроцедуры
Функция ПолучитьОтносительнуюПозициюТокена(Токен) Экспорт
Результат = Токен.LineNumber * 1000 + Токен.ColumnNumber;
Возврат Результат;
КонецФункции
// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Возвращаемое значение:
// Булево - признак изменения текста
//
Функция ОткрытьРедакторСтроковогоЛитерала() Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Ложь;
КонецЕсли;
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец <> Неопределено И ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст не может быть изменен. Открыть редактор без возможности сохранения измений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РазобратьТекущийКонтекст(,,,,, Истина);
ФормаРедактора = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор);
ПараметрГраницыВыделения = ПолеТекста.ВыделениеДвумерное();
ФормаРедактора.ПараметрГраницыВыделения = ПараметрГраницыВыделения;
ТекстСтроковогоЛитерала = ВыделитьТекстовыйЛитерал();
ГраницыЛитерала = ПолеТекста.ВыделениеДвумерное();
ПараметрГраницыВыделения.НачальнаяСтрока = ПараметрГраницыВыделения.НачальнаяСтрока - ГраницыЛитерала.НачальнаяСтрока + 1;
ПараметрГраницыВыделения.КонечнаяСтрока = ПараметрГраницыВыделения.КонечнаяСтрока - ГраницыЛитерала.НачальнаяСтрока + 1;
ФормаРедактора.НачальноеЗначениеВыбора = ТекстСтроковогоЛитерала;
ФормаРедактора.мМенеджерВременныхТаблиц = мМенеджерВременныхТаблиц;
ТекстИзменен = Ложь;
Если ФормаРедактора.ОткрытьМодально() <> Неопределено Тогда
Если Не РежимТолькоПросмотр Тогда
НовыйТекстЗапроса = ФормаРедактора.Текст;
Если НовыйТекстЗапроса = ТекстСтроковогоЛитерала Тогда
// Для TuboConf
Иначе
НовыйТекстЗапроса = ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(НовыйТекстЗапроса);
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", мШиринаТабуляции);
ТекстНачальнойСтроки = ПолеТекста.ПолучитьСтроку(мНачальнаяСтрока);
ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / мШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % мШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
ВыделенныйТекст(СтрЗаменить(НовыйТекстЗапроса, Символы.ПС, Символы.ПС + НачалоНовойСтроки));
ГраницыВыделенияНовые = ФормаРедактора.ПолеТекста().ВыделениеДвумерное();
мНачальнаяСтрока = ГраницыВыделенияНовые.НачальнаяСтрока + ГраницыЛитерала.НачальнаяСтрока - 1;
мКонечнаяСтрока = ГраницыВыделенияНовые.КонечнаяСтрока + ГраницыЛитерала.НачальнаяСтрока - 1;
мНачальнаяКолонка = ГраницыВыделенияНовые.НачальнаяКолонка;
мКонечнаяКолонка = ГраницыВыделенияНовые.КонечнаяКолонка;
ТекстИзменен = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
УстановитьГраницыВыделения();
Возврат ТекстИзменен;
КонецФункции
Функция ВыделитьТекстовыйЛитерал(Знач ПолеТекстаЛ = Неопределено, выхНачальнаяПозиция0 = 0, выхКонечнаяПозиция0 = 0, Знач РазбиратьКонтекст = Истина, выхВыражение = "") Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если РазбиратьКонтекст Тогда
РазобратьТекущийКонтекст();
КонецЕсли;
Если ПолеТекстаЛ = Неопределено Тогда
ПолеТекстаЛ = ПолеТекста;
Иначе
ПолеТекстаЛ = ирКлиент.ОболочкаПоляТекстаЛкс(ПолеТекстаЛ);
КонецЕсли;
// Мультиметка77248851
ТекстПоля = ПолеТекстаЛ.ПолучитьТекст();
мРегВыражение.Global = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = шСтрокаПрограммы;
Результат = мРегВыражение.НайтиВхождения(ТекстПоля);
Успех = Ложь;
Для Каждого Вхождение Из Результат Цикл
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= мПозицияВТексте
И (ПозицияВхождения + Вхождение.Length) >= мПозицияВТексте
Тогда
ПолеТекстаЛ.УстановитьГраницыВыделения(ПозицияВхождения + 1, ПозицияВхождения + 1 + Вхождение.Length,, ФормаВладелец);
Успех = Истина;
выхНачальнаяПозиция0 = ПозицияВхождения;
выхКонечнаяПозиция0 = ПозицияВхождения + Вхождение.Length;
Прервать;
КонецЕсли;
КонецЦикла;
Если Успех Тогда
выхВыражение = ПолеТекстаЛ.ВыделенныйТекст();
ТекстСтроковогоЛитерала = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(выхВыражение);
Иначе
ТекстСтроковогоЛитерала = Неопределено;
КонецЕсли;
Возврат ТекстСтроковогоЛитерала;
КонецФункции
// Осуществляет переход к определению контекста.
//
// Параметры:
// Нет.
//
Функция ПерейтиКОпределению(НомерСтроки = 0, НомерКолонки = 0, РазрешитьДиалоги = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Неопределено;
КонецЕсли;
РазобратьТекущийКонтекст(,,, НомерСтроки, НомерКолонки, Истина);
Если ПустаяСтрока(мКонтекст) Тогда
Возврат Неопределено;
КонецЕсли;
ПоследнееВхождение = Неопределено;
ПоследнееОпределение = Неопределено;
НайтиОпределениеСлова(мКонтекст, ПоследнееОпределение, ПоследнееВхождение);
Если ПоследнееВхождение <> Неопределено Тогда
ЗапомнитьИсточникПерехода();
Если ирОбщий.СтрКончаетсяНаЛкс(мКонтекст, "(") И мЯзыкПрограммы = 0 Тогда
НачальнаяПозицияОпределения = 0;
Иначе
НачальнаяПозицияОпределения = мПозицияТекстаДляПоискаОпределения;
КонецЕсли;
НачальнаяПозицияОпределения = НачальнаяПозицияОпределения + ПоследнееВхождение.FirstIndex + Найти(ПоследнееВхождение.Value, ПоследнееОпределение);
КонечнаяПозицияОпределения = НачальнаяПозицияОпределения + СтрДлина(ПоследнееОпределение);
ВыделитьДиапазонОдномерныйДляПользователя(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
Результат = Истина;
ИначеЕсли мЯзыкПрограммы = 0 Тогда
ТаблицаТипов = Неопределено;
Результат = Новый СписокЗначений;
Если Ложь
Или мЭтоТекстовыйЛитерал
Или ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало)
Тогда
Если РазрешитьДиалоги Тогда
Если Ложь
Или Найти(мКонтекст + ".", ".Форма.") > 0
Или ирОбщий.СтрНачинаетсяСЛкс(мКонтекст, "ОбщаяФорма.") > 0
Тогда
ЧастиИмени = ЧастиПолногоИмениЭлементаФормы(мКонтекст);
Форма = ирКлиент.ПассивнаяФормаПоИмениЛкс(ЧастиИмени.ИмяФормы);
Если Форма <> Неопределено Тогда
Форма.Открыть();
ирКлиент.НачатьОтслеживаниеФормыЛкс(Форма);
Если ЧастиИмени.ИмяФормы <> мКонтекст Тогда
СтруктураТипа = ВычислитьСвойствоФормыПоПолномуИмени(мКонтекст);
Если СтруктураТипа <> Неопределено Тогда
Попытка
Форма.ТекущийЭлемент = Форма.Элементы[СтруктураТипа.Метаданные.Имя];
Исключение
КонецПопытки;
Попытка
Форма.ТекущийЭлемент = Форма.ЭлементыФормы[СтруктураТипа.Метаданные.Имя];
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Найти(мКонтекст, ".Реквизит.") > 0
Или Найти(мКонтекст, ".Измерение.") > 0
Или Найти(мКонтекст, ".Ресурс.") > 0
Тогда
ОписаниеТаблицы = ирОбщий.ОписаниеТаблицыБДЛкс(ирОбщий.ПервыеФрагментыЛкс(мКонтекст));
Если ОписаниеТаблицы <> Неопределено Тогда
Форма = ирКлиент.ОткрытьКолонкуБДЛкс(ирОбщий.ПервыеФрагментыЛкс(мКонтекст), ирОбщий.ПоследнийФрагментЛкс(мКонтекст));
Если Форма <> Неопределено Тогда
Форма.Открыть();
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КорневоеСловоБД = "БД.";
Если ирОбщий.СтрНачинаетсяСЛкс(мКонтекст, КорневоеСловоБД) Тогда
ИмяКолонки = Сред(мКонтекст, СтрДлина(КорневоеСловоБД) + 1);
Форма = ирКлиент.ОткрытьКолонкуБДЛкс(ИмяКолонки);
Если Форма <> Неопределено Тогда
Форма.Открыть();
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ирОбщий.ЛиИмяПеременнойЛкс(мКонтекст) Тогда
МетодМодуля = мПлатформа.СтрокаМетодаМодуляПоИмени(мМодульМетаданных, мКонтекст);
Если МетодМодуля <> Неопределено Тогда
ПерейтиКОпределениюЛокальногоМетода(МетодМодуля);
Возврат Истина;
КонецЕсли;
КонецЕсли;
Если Истина
И СтрЧислоВхождений(мКонтекст, ".") = 1
И Найти(мКонтекст, "(") = 0
И Метаданные.ОбщиеМодули.Найти(ирОбщий.ПервыйФрагментЛкс(мКонтекст)) <> Неопределено
Тогда
Фрагменты = ирОбщий.СтрРазделитьЛкс(мКонтекст);
ИмяМодуля = "ОбщийМодуль." + Фрагменты[0];
Если Истина
И мМодульМетаданных <> Неопределено
И ирОбщий.СтрНачинаетсяСЛкс(мИмяМодуля, "ОбщийМодуль." + Фрагменты[0])
Тогда
МетодМодуля = мПлатформа.СтрокаМетодаМодуляПоИмени(мМодульМетаданных, Фрагменты[1]);
Если МетодМодуля <> Неопределено Тогда
ПерейтиКОпределениюЛокальногоМетода(МетодМодуля);
Возврат Истина;
КонецЕсли;
КонецЕсли;
АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс();
АнализаторКода.ИнициироватьНеинтерактивно();
ТаблицаТипов = АнализаторКода.ВычислитьТипЗначенияВыражения(мКонтекст + "(");
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов = Неопределено Тогда
ПараметрыМетода = мПлатформа.ПараметрыМетодаМодуля(мМетодМодуля);
Если ПараметрыМетода <> Неопределено Тогда
СтрокаПараметра = ПараметрыМетода.Найти(НРег(мКонтекст), "НИмя");
Если СтрокаПараметра <> Неопределено Тогда
ПерейтиКОпределениюЛокальногоМетода(мМетодМодуля, СтрокаПараметра.Имя);
Возврат Истина;
КонецЕсли;
КонецЕсли;
СтрокаПеременной = мМодульМетаданных.Переменные.Найти(НРег(мКонтекст), "НИмя");
Если СтрокаПеременной <> Неопределено Тогда
ПолеТекста.УстановитьГраницыВыделения(СтрокаПеременной.ПозицияСОписанием, СтрокаПеременной.ПозицияСОписанием,,,, ФормаВладелец);
ВыделитьДиапазонОдномерныйДляПользователя(СтрокаПеременной.ПозицияСОписанием, СтрокаПеременной.ПозицияСОписанием + СтрДлина("Перем " + СтрокаПеременной.Имя));
Возврат Истина;
КонецЕсли;
//ТаблицаТипов = ВычислитьТипЗначенияВыражения(мКонтекст, мТекстДляПоискаОпределения, мПредшествующийТекст, Истина); // Так для ПолучитьФорму("Справочник.Мо<>й") будет вычислять форму
ТаблицаТипов = ВычислитьТипЗначенияВыражения(мКонтекст, мТекстДляПоискаОпределения, мПредшествующийТекст, Ложь);
Если Истина
И Прав(мКонтекст, 1) <> "("
И (Ложь
Или мЭтоТекстовыйЛитерал
Или ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало))
И (Ложь
Или ТаблицаТипов.Количество() = 0
Или (Истина
И ТаблицаТипов[0].Детальность = 0
И ТаблицаТипов[0].СтрокаОписания = Неопределено))
Тогда
ТаблицаТипов = ВычислитьТипЗначенияВыражения(мКонтекст + "(", мТекстДляПоискаОпределения, мПредшествующийТекст, Ложь);
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов <> Неопределено Тогда
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
ДобавитьПереходыИзСтруктурыТипаВСписокВыбора(СтруктураТипа, Результат);
КонецЦикла;
КонецЕсли;
ИменаМД = ирОбщий.ИменаМетаданныхИзОписанияТиповЛкс(мКонтекст);
Для Каждого ЭлементСписка Из ИменаМД Цикл
ДобавитьТипДанныхВСписокПереходов(Результат, ЭлементСписка.Значение);
КонецЦикла;
Результат.СортироватьПоПредставлению();
Если РазрешитьДиалоги Тогда
ВыбратьПереход(Результат);
ИначеЕсли Результат.Количество() = 0 Тогда
Результат.Добавить(мКонтекст);
КонецЕсли;
ИначеЕсли мЯзыкПрограммы = 1 Тогда
ОписаниеТаблицыБД = ирОбщий.ОписаниеТаблицыБДЛкс(мКонтекст);
Если ОписаниеТаблицыБД <> Неопределено Тогда
ирКлиент.ОткрытьОбъектМетаданныхЛкс(ОписаниеТаблицыБД.ПолноеИмяМД);
Результат = ОписаниеТаблицыБД.ПолноеИмяМД;
Иначе
ТаблицаТиповКонтекста = ВычислитьТипЗначенияВыражения(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаКонтекста = ТаблицаТиповКонтекста[0];
ИмяТаблицы = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
ОписаниеТаблицыБД = ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы);
Если ОписаниеТаблицыБД <> Неопределено Тогда
Если ОписаниеТаблицыБД.Тип = "ВиртуальнаяТаблица" Тогда
ИмяТаблицы = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ИмяТаблицы);
КонецЕсли;
ФормаКолонки = ирКлиент.ОткрытьКолонкуБДЛкс(ИмяТаблицы, мТекущееСлово);
Результат = ИмяТаблицы + "." + ФормаКолонки.РолиПоля + "." + мТекущееСлово;
Если Не РазрешитьДиалоги Тогда
ФормаКолонки.Закрыть();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// МетодМодуля - ? -
Процедура ПерейтиКОпределениюЛокальногоМетода(МетодМодуля, Знач ИмяПараметра = "", Знач СмещениеСтрокиМетода = 0) Экспорт
РазобратьТекущийКонтекст(,,,,,, МетодМодуля.ПозицияТела);
Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда
мКонтекст = МетодМодуля.Имя + "(";
Если ПерейтиКОпределению() Тогда
Если ЗначениеЗаполнено(СмещениеСтрокиМетода) Тогда
ВыделитьСтрокуВПолеТекста(мНомерПервойСтрокиТелаМетода + СмещениеСтрокиМетода - 1);
КонецЕсли;
КонецЕсли;
Иначе
Если ЛиВЗаголовкеМетода(МетодМодуля) Тогда
НачалоОбласти = МетодМодуля.ПозицияСОписанием;
КонецОбласти = МетодМодуля.ПозицияОпределения;
ШаблонПоиска = "(" + мПлатформа.шПустоеНачалоСтроки + "//\s+)(#Слово#)(\s+-)";
Иначе
НачалоОбласти = МетодМодуля.ПозицияОпределения;
КонецОбласти = МетодМодуля.ПозицияТела;
ШаблонПоиска = "([\(,]\s*(?:Знач\s+)?)(#Слово#)(\s*[\),=])";
КонецЕсли;
ЗапомнитьИсточникПерехода();
Успех = ирКлиент.НайтиПоказатьФрагментВПолеТекстаЛкс(ФормаВладелец, ПолеТекста, ИмяПараметра, ШаблонПоиска, Истина,,, НачалоОбласти, КонецОбласти);
Если Успех Тогда
УстановитьФокус();
КонецЕсли;
ПолучитьГраницыВыделения();
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// МетодМодуля - ? -
// Возвращаемое значение:
// ? -
Функция ЛиВЗаголовкеМетода(МетодМодуля = Неопределено) Экспорт
Если МетодМодуля = Неопределено Тогда
МетодМодуля = мМетодМодуля;
КонецЕсли;
Результат = Истина
И МетодМодуля <> Неопределено
И мПозицияВТексте < МетодМодуля.ПозицияТела
И мПозицияВТексте > МетодМодуля.ПозицияОпределения;
Возврат Результат;
КонецФункции
Процедура ВыделитьДиапазонОдномерныйДляПользователя(Знач НачальнаяПозицияОпределения, Знач КонечнаяПозицияОпределения)
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
СлужебноеПолеТекстаДолгое.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка); // Там текст без комментариев и опасных строковых литералов
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец); // Для ТуброКонфа
КонецПроцедуры
Процедура ОткрытьОпределениеСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоОбщийТип = Ложь, Знач ИмяПараметраМетода = "") Экспорт
СписокВыбора = ДобавитьПереходыИзСтруктурыТипаВСписокВыбора(СтруктураТипа);
ВыбратьПереход(СписокВыбора, ЭтоОбщийТип, ИмяПараметраМетода);
КонецПроцедуры
//.
// Параметры:
// СписокВыбора - Булево, СписокЗначений -
// ЭтоОбщийТип - Булево -
// ИмяПараметраМетода - Строка -
Процедура ВыбратьПереход(Знач СписокВыбора, Знач ЭтоОбщийТип = Ложь, Знач ИмяПараметраМетода = "") Экспорт
Если СписокВыбора.Количество() = 0 Тогда
Возврат;
ИначеЕсли СписокВыбора.Количество() > 1 Тогда
РезультатВыбора = ирКлиент.ВыбратьЭлементСпискаЗначенийЛкс(СписокВыбора,,, "Выберите переход",, Истина);
Если РезультатВыбора = Неопределено Тогда
Возврат;
КонецЕсли;
Иначе
РезультатВыбора = СписокВыбора[0];
КонецЕсли;
СтруктураСсылки = Неопределено;
Если ТипЗнч(РезультатВыбора.Значение) = Тип("Строка") Тогда
СтруктураСсылки = ирОбщий.СтруктураСсылкиСтрокиМодуляЛкс(РезультатВыбора.Значение);
КонецЕсли;
Если СтруктураСсылки <> Неопределено Тогда
ПерейтиПоСсылкеСтрокиМодуля(РезультатВыбора.Значение, Ложь);
ИначеЕсли ирОбщий.ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора.Значение) Тогда
ирКлиент.ОткрытьЗначениеЛкс(РезультатВыбора.Значение);
//ирКлиент.ОткрытьСсылкуВРедактореОбъектаБДЛкс(РезультатВыбора.Значение);
ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(РезультатВыбора.Представление, "Метод ") Тогда
ирКлиент.ОткрытьМетодМодуляПоОпределениюЛкс(РезультатВыбора.Значение,, ИмяПараметраМетода, ЭтотОбъект);
ИначеЕсли ирОбщий.МножественноеИмяМДЛкс(ирОбщий.ПервыйФрагментЛкс(РезультатВыбора.Значение,, Ложь)) <> Неопределено Тогда
Если ирОбщий.СтрНачинаетсяСЛкс(РезультатВыбора.Представление, "Картинка") Тогда
ирКлиент.ОткрытьЗначениеЛкс(БиблиотекаКартинок[ирОбщий.ПоследнийФрагментЛкс(РезультатВыбора.Значение)]);
ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(РезультатВыбора.Представление, "Форма") Тогда
ирКлиент.ПассивнаяФормаПоИмениЛкс(РезультатВыбора.Значение).Открыть();
Иначе
ирКлиент.ОткрытьОбъектМетаданныхЛкс(РезультатВыбора.Значение);
КонецЕсли;
//ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(РезультатВыбора.Представление, "Справка") Тогда
// СтруктураТипа = РезультатВыбора.Значение;
// Если ЭтоОбщийТип Тогда
// ПутьКСлову = СтруктураТипа.ИмяОбщегоТипа;
// Иначе
// ПутьКСлову = мКонтекст;
// КонецЕсли;
// НайтиПоказатьСправкуПоСтруктуреТипа(ПутьКСлову, СтруктураТипа);
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// СсылкаСтрокиМодуля - Строка -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция ПерейтиПоСсылкеСтрокиМодуля(Знач СсылкаСтрокиМодуля, Знач ТолькоЛокально = Истина) Экспорт
Если ТипЗнч(СсылкаСтрокиМодуля) = Тип("Строка") Тогда
СтруктураСсылки = ирОбщий.СтруктураСсылкиСтрокиМодуляЛкс(СсылкаСтрокиМодуля);
КонецЕсли;
Если СтруктураСсылки = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если СтруктураСсылки.Модуль = мМодульМетаданных.Имя Тогда
Если ЗначениеЗаполнено(СтруктураСсылки.Метод) Тогда
СтрокаМетода = мПлатформа.СтрокаМетодаМодуляПоИмени(мМодульМетаданных, СтруктураСсылки.Метод);
ПозицияБлока = СтрокаМетода.ПозицияТела;
Если ПозицияБлока = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Иначе
ПозицияБлока = мМодульМетаданных.ПозицияПрограммы;
КонецЕсли;
НомерСтроки = ирОбщий.СтрЧислоСтрокЛкс(Лев(мОригинальныйТекст, ПозицияБлока)) + СтруктураСсылки.СмещениеСтрокиМетода - 1;
ВыделитьСтрокуВПолеТекста(НомерСтроки, СтруктураСсылки.НомерКолонки);
Возврат Истина;
ИначеЕсли Не ТолькоЛокально Тогда
Если ЗначениеЗаполнено(СтруктураСсылки.Метод) Тогда
Модуль = мПлатформа.МодульМетаданныхИзКэша(СтруктураСсылки.Модуль);
СтрокаМетода = мПлатформа.СтрокаМетодаМодуляПоИмени(Модуль, СтруктураСсылки.Метод);
ирКлиент.ОткрытьМетодМодуляПоОпределениюЛкс(СтрокаМетода,,,, СтруктураСсылки.СмещениеСтрокиМетода);
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
//.
// Параметры:
// НомерСтроки - Число -
Процедура ВыделитьСтрокуВПолеТекста(Знач НомерСтроки, Знач НомерКолонки = 1) Экспорт
УстановитьГраницыВыделения(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки + 1);
ПолучитьГраницыВыделения();
КонецПроцедуры
Функция ДобавитьПереходыИзСтруктурыТипаВСписокВыбора(Знач СтруктураТипа, Знач СписокВыбора = Неопределено)
Если СписокВыбора = Неопределено Тогда
СписокВыбора = Новый СписокЗначений;
КонецЕсли;
Если Истина
И ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Структура")
И (Ложь
Или СтруктураТипа.ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц")
Или СтруктураТипа.ДержательМетаданных.Тип = "ПакетЗапросов")
Тогда
Если СтруктураТипа.ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц") Тогда
МенеджерВременныхТаблиц = СтруктураТипа.ДержательМетаданных; // см. НовыйМенеджерВременныхТаблиц()
ПакетЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов[МенеджерВременныхТаблиц.ПакетыЗапросов.ВГраница()];
Иначе
// Колонка результата запроса
ПакетЗапросов = СтруктураТипа.ДержательМетаданных; // см. НовыйПакетЗапросов()
КонецЕсли;
КоординатыТекстаЗапроса = ПакетЗапросов.КоординатыТекста;
АнализаторКода = КопияКомпоненты();
АнализаторКода.мЯзыкПрограммы = 1;
АнализаторКода.мМодульМетаданных = КоординатыТекстаЗапроса.Модуль;
АнализаторКода.ЗагрузитьМетодМодуля(КоординатыТекстаЗапроса.Метод);
НачальнаяПозицияПоиска = КоординатыТекстаЗапроса.Позиция0ВБлоке + 1;
АнализаторКода.мТекстДляПоискаОпределения = Сред(АнализаторКода.мТекстБлока, НачальнаяПозицияПоиска, КоординатыТекстаЗапроса.ДлинаТекста);
Если ПакетЗапросов.Свойство("ИндексВПакете") Тогда
ИндексВПакете = ПакетЗапросов.ИндексВПакете;
ПозицииЗапросов = Новый Массив;
ТекстыЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(АнализаторКода.мТекстДляПоискаОпределения,, ПозицииЗапросов);
НачальнаяПозицияПоиска = НачальнаяПозицияПоиска + ПозицииЗапросов[ИндексВПакете];
АнализаторКода.мТекстДляПоискаОпределения = Сред(АнализаторКода.мТекстБлока, НачальнаяПозицияПоиска, СтрДлина(ТекстыЗапросов[ИндексВПакете]));
КонецЕсли;
ПоследнееВхождение = Неопределено;
АнализаторКода.НайтиОпределениеСлова(мТекущееСлово,, ПоследнееВхождение);
Если ПоследнееВхождение <> Неопределено Тогда
ЗапомнитьИсточникПерехода();
ПозицияВМетоде = -1 + НачальнаяПозицияПоиска + ПоследнееВхождение.FirstIndex + ирОбщий.СтрНайтиЛкс(ПоследнееВхождение.Value, мТекущееСлово, Истина,,, Ложь);
мПолеТекстаВременное.УстановитьТекст(АнализаторКода.мТекстБлока);
мПолеТекстаВременное.УстановитьГраницыВыделения(ПозицияВМетоде, ПозицияВМетоде);
НомерСтрокиМетода = 0;
НомерКолонкиМетода = 0;
мПолеТекстаВременное.ПолучитьГраницыВыделения(НомерСтрокиМетода, НомерКолонкиМетода, НомерСтрокиМетода, НомерКолонкиМетода);
Если КоординатыТекстаЗапроса.Метод <> Неопределено Тогда
ИмяМетода = КоординатыТекстаЗапроса.Метод.Имя;
Иначе
//ИмяМетода = "<Инициация>";
ИмяМетода = "";
КонецЕсли;
КлючПерехода = ирОбщий.СсылкаСтрокиМодуляЛкс(КоординатыТекстаЗапроса.Модуль.Имя,, ИмяМетода, НомерСтрокиМетода,, НомерКолонкиМетода);
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
СписокВыбора.Добавить(КлючПерехода, "Запрос",, ирКэш.КартинкаПоИмениЛкс("ирЗапрос"));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураТипа.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипа.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
СтрокаМетода = СтруктураТипа.СтрокаОписания; // см. мМетодМодуля
Если СтрокаМетода.Имя = "<>" Тогда
ВиртуальныйМетод = СтрокаМетода.Владелец().Добавить();
ЗаполнитьЗначенияСвойств(ВиртуальныйМетод, СтрокаМетода);
ВиртуальныйМетод.Имя = ирОбщий.ПервыйФрагментЛкс(мТекущееСлово, "(");
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ВиртуальныйМетод);
СтрокаМетода = ВиртуальныйМетод;
КонецЕсли;
КлючПерехода = ирОбщий.СсылкаСтрокиМодуляЛкс(СтрокаМетода.ИмяМодуля,, СтрокаМетода.Имя);
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
Если Истина
И Найти(мРодительскийКонтекст, "(") = 0
И Не ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало)
И Не ирОбщий.ЛиВнутриТекстовогоЛитералаЛкс(мТекущаяСтрокаНачало)
И Не ирОбщий.ЛиВнутриПрепроцессораЛкс(мТекущаяСтрокаНачало)
И (Ложь
Или Метаданные.ОбщиеМодули.Найти(мРодительскийКонтекст) <> Неопределено
Или ирОбщий.ЕдинственноеИмяМДЛкс(ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст)) <> Неопределено)
Тогда
СписокВыбора.Добавить(КлючПерехода, "Метод прямой",, ирКэш.КартинкаПоИмениЛкс("ирМетодыМодуля"));
Иначе
СписокВыбора.Добавить(КлючПерехода, "Метод непрямой",, ирКэш.КартинкаПоИмениЛкс("ирМетодыМодуля"));
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("Значение") <> Неопределено
И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(СтруктураТипа.СтрокаОписания.Значение)
И ЗначениеЗаполнено(СтруктураТипа.СтрокаОписания.Значение)
Тогда
КлючПерехода = СтруктураТипа.СтрокаОписания.Значение;
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
СписокВыбора.Добавить(КлючПерехода, "Объект БД",, ирКэш.КартинкаПоИмениЛкс("ирСсылка"));
КонецЕсли;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("ТипЗначения") <> Неопределено
И СтруктураТипа.СтрокаОписания.ТипЗначения = "Картинка"
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
КлючПерехода = СтруктураТипа.Метаданные.ПолноеИмя();
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
СписокВыбора.Добавить(КлючПерехода, "Картинка " + СтруктураТипа.Метаданные.Имя,, ирКэш.КартинкаПоИмениЛкс("ирКартинка"));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Форма")
Или ТипЗнч(СтруктураТипа.ДержательМетаданных) = ирОбщий.ТипУправляемаяФормаЛкс()
Тогда
КлючПерехода = ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.ДержательМетаданных);
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
СписокВыбора.Добавить(КлючПерехода, "Форма",, ирКэш.КартинкаПоИмениЛкс("ирФорма"));
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
ДобавитьТипДанныхВСписокПереходов(СписокВыбора, СтруктураТипа.Метаданные.ПолноеИмя());
КонецЕсли;
//СписокВыбора.Добавить(СтруктураТипа, "Справка",, ирКэш.КартинкаПоИмениЛкс("ирСинтаксПомощник")); // Могут появляться дубли
Возврат СписокВыбора;
КонецФункции
//.
// Параметры:
// СписокВыбора - Булево, СписокЗначений -
// КлючПерехода - Неопределено -
Процедура ДобавитьТипДанныхВСписокПереходов(Знач СписокВыбора, Знач КлючПерехода) Экспорт
Если СписокВыбора.НайтиПоЗначению(КлючПерехода) = Неопределено Тогда
СписокВыбора.Добавить(КлючПерехода, "Тип " + КлючПерехода,, ирКэш.КартинкаПоИмениЛкс("ирМетаданные"));
КонецЕсли;
КонецПроцедуры
// Перед вызовом можно установить свойство мНачальнаяСтрока например через ПолучитьГраницыВыделения()
Функция СсылкаСтрокиМодуля(Знач НомерСтроки = 0) Экспорт
ИмяМетода = "";
Если Не ЗначениеЗаполнено(НомерСтроки) Тогда
НомерСтроки = мНачальнаяСтрока;
КонецЕсли;
Если мМетодМодуля <> Неопределено Тогда
ИмяМетода = мМетодМодуля.Имя;
СмещениеСтрокиМетода = мНачальнаяСтрока - НомерСтрокиИзПозиции(мМетодМодуля.ПозицияОпределения);
КонецЕсли;
Результат = ирОбщий.СсылкаСтрокиМодуляЛкс(мИмяМодуля, мНачальнаяСтрока, ИмяМетода, СмещениеСтрокиМетода, ПолеТекста.ПолучитьСтроку(мНачальнаяСтрока));
Возврат Результат;
КонецФункции
//.
// Параметры:
// Позиция - Число - начиная с 1
// Возвращаемое значение:
// Число -
Функция НомерСтрокиИзПозиции(Позиция) Экспорт
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(Позиция, Позиция);
НомерСтроки = ирКлиент.ОболочкаПоляТекстаЛкс(СлужебноеПолеТекстаДолгое).ВыделениеДвумерное().КонечнаяСтрока;
Возврат НомерСтроки;
КонецФункции
// Ищем в мТекстДляПоискаОпределения
Функция НайтиОпределениеСлова(Слово, ПоследнееОпределение = Неопределено, ПоследнееВхождение = Неопределено) Экспорт
ПоследнееОпределение = Неопределено;
Если мЯзыкПрограммы = 1 Тогда
ФрагментыСлова = ирОбщий.СтрРазделитьЛкс(Слово);
Если ФрагментыСлова.Количество() < 3 Тогда
ПсевдонимТаблицыИлиПоля = ФрагментыСлова[0];
мРегВыражение.Global = Ложь;
//мТекстДляПоискаОпределения = СтрЗаменить(мТекстДляПоискаОпределения, Символы.ПС + "|", Символы.ПС + " ");
Если Лев(мТекстДляПоискаОпределения, 1) = """" Тогда
мТекстДляПоискаОпределения = " " + Сред(мТекстДляПоискаОпределения, 2);
КонецЕсли;
Если Прав(мТекстДляПоискаОпределения, 1) = """" Тогда
мТекстДляПоискаОпределения = Лев(мТекстДляПоискаОпределения, СтрДлина(мТекстДляПоискаОпределения) - 1) + " ";
КонецЕсли;
мРегВыражение.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ПсевдонимТаблицыИлиПоля));
ЛиНайденоИмяДоступнойТаблицы = Ложь;
РезультатТекста = мРегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
Если РезультатТекста.Количество() = 0 Тогда
// Теперь ищем определение поля
мРегВыражение.Pattern = "(ъъъ)?(ъъъ)?(ъъъ)?(" + шВыражениеЗапроса + ")?\s(?:КАК|AS)\s*" + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ПсевдонимТаблицыИлиПоля);
РезультатТекста = мРегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
Если РезультатТекста.Количество() = 0 Тогда
ПоследнееВхождение = Неопределено;
ПоследнееОпределение = ПсевдонимТаблицыИлиПоля;
ЛиНайденоИмяДоступнойТаблицы = Истина;
КонецЕсли;
КонецЕсли;
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[0];
ПоследнееОпределение = ПоследнееВхождение.SubMatches(3);
КонецЕсли;
ПакетЗапросов = Неопределено; // см. НовыйПакетЗапросов()
ИндексЗапроса = Неопределено;
НайтиЗапросВременнойТаблицы(ПоследнееОпределение,, ПакетЗапросов, ИндексЗапроса);
Если ИндексЗапроса <> Неопределено Тогда
Если ФрагментыСлова.Количество() = 2 Тогда
Если Ложь
Или ЯзыкПрограммы = 1
Или ПакетЗапросов.КоординатыТекста.Модуль = мМодульМетаданных
Тогда
ЗагрузитьЗапросПакетаПоИндексу(ПакетЗапросов, ИндексЗапроса);
Возврат НайтиОпределениеСлова(ФрагментыСлова[1], ПоследнееОпределение, ПоследнееВхождение);
КонецЕсли;
Иначе
Если ПоследнееВхождение <> Неопределено Тогда
лНачальнаяСтрока = 0;
лНачальнаяКолонка = 0;
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
НачальнаяПозицияВхождения = мПозицияТекстаДляПоискаОпределения + ПоследнееВхождение.FirstIndex + 1;
СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(НачальнаяПозицияВхождения, НачальнаяПозицияВхождения + СтрДлина(ПоследнееОпределение));
СлужебноеПолеТекстаДолгое.ПолучитьГраницыВыделения(лНачальнаяСтрока, лНачальнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
ЛиНайденоИмяДоступнойТаблицы = Истина
И лНачальнаяСтрока = мНачальнаяСтрока И лНачальнаяКолонка <= мНачальнаяКолонка
И лКонечнаяСтрока = мКонечнаяСтрока И лКонечнаяКолонка >= мКонечнаяКолонка;
КонецЕсли;
Если Истина
И ЛиНайденоИмяДоступнойТаблицы
И (Ложь
Или ЯзыкПрограммы = 1
Или ПакетЗапросов.КоординатыТекста.Модуль = мМодульМетаданных)
Тогда
ЗагрузитьЗапросПакетаПоИндексу(ПакетЗапросов, ИндексЗапроса);
мРегВыражение.Global = Ложь;
ШаблонСозданияТаблицы = "(?:" + шРазделитель + "|\|)+" + "(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?)" + шРазделитель + "+(#Идентификатор#)" + шРазделитель;
мРегВыражение.Pattern = СтрЗаменить(ШаблонСозданияТаблицы, "#Идентификатор#", ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ПоследнееОпределение));
РезультатТекста = мРегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееОпределение = РезультатТекста[0].SubMatches(0);
ПоследнееВхождение = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирОболочкаРегВхождение");
ЗаполнитьЗначенияСвойств(ПоследнееВхождение, РезультатТекста[0],, "SubMatches"); // Создаем неполноценный объект ради изменения свойства FirstIndex
//ПоследнееВхождение.FirstIndex = ПоследнееВхождение.FirstIndex - мПозицияТекстаДляПоискаОпределения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ФрагментыСлова.Количество() = 2 Или ПоследнееВхождение = Неопределено Тогда
ПоследнееВхождение = Неопределено;
ПоследнееОпределение = Неопределено;
КонецЕсли;
КонецЕсли;
Иначе
МаркерЗначение = "ЗНАЧЕНИЕ(";
Если Прав(мПредшествующийТекст, СтрДлина(МаркерЗначение)) = МаркерЗначение Тогда
мРегВыражение.Global = Ложь;
мРегВыражение.Pattern = шИмя;
Если мРегВыражение.Проверить(Слово) Тогда
Попытка
ПредопределенноеЗначение = ПредопределенноеЗначение(Слово);
Исключение
ПредопределенноеЗначение = Неопределено;
КонецПопытки;
Если ПредопределенноеЗначение <> Неопределено Тогда
ОткрытьЗначение(ПредопределенноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
мРегВыражение.Global = Истина;
ЭкранированноеСлово = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ирОбщий.ПервыйФрагментЛкс(Слово, "("));
Если ирОбщий.СтрКончаетсяНаЛкс(Слово, "(") Тогда
// Ищем определение метода в тексте модуля
мРегВыражение.Pattern = ирОбщий.СтрЗаменитьЛкс(мПлатформа.ШаблоныДляАнализаВстроенногоЯзыка().ОписаниеМетодаЧистое, шИмя, ЭкранированноеСлово);
РезультатТекста = мРегВыражение.НайтиВхождения(мОригинальныйТекст);
ИначеЕсли Лев(Слово, 1) = "~" Тогда
мРегВыражение.Pattern = мПлатформа.шПустоеНачалоСтроки + "(" + Слово + ":)";
РезультатТекста = мРегВыражение.НайтиВхождения(мТекстБлока);
Иначе
ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмяСкобки + "?" + шИндекс + "?" + "(\." + шИмяСкобки + "?" + шИндекс + "?)*))";
мРегВыражение.Pattern = шПредИмя + ЭкранированноеСлово + "(" + шПрисвоение + "|" + ШаблонКоллекции + ")";
РезультатТекста = мРегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
КонецЕсли;
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[РезультатТекста.Количество() - 1];
ПоследнееОпределение = ПоследнееВхождение.SubMatches(0);
//Если ПоследнееВхождение.SubMatches(1) <> Неопределено Тогда
// // Это присвоение
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(1);
//Иначе
// // Это обход коллекции
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(20);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПоследнееОпределение;
КонецФункции
// .
// Параметры:
// ИмяТаблицы - -
// ПакетЗапросов - см. НовыйПакетЗапросов() -
//
// Возвращаемое значение:
// Число -
//
Функция НайтиИндексЗапросаСозданияВременнойТаблицы(Знач ИмяТаблицы, Знач ПакетЗапросов = Неопределено) Экспорт
Если ПакетЗапросов = Неопределено Тогда
ПакетЗапросов = мПакетЗапросов;
КонецЕсли;
Если ПакетЗапросов = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПодготовитьПакетЗапросов(ПакетЗапросов);
СтруктураПакета = ПакетЗапросов.Структура;
ИндексЗапроса = СтруктураПакета.НайтиПоЗначению(НРег(ИмяТаблицы));
Если ИндексЗапроса <> Неопределено Тогда
ИндексЗапроса = СтруктураПакета.Индекс(ИндексЗапроса);
КонецЕсли;
Возврат ИндексЗапроса;
КонецФункции
//.
// Параметры:
// ПакетЗапросов - , Структура -
Процедура ПодготовитьПакетЗапросов(Знач ПакетЗапросов) Экспорт
Если ПакетЗапросов.Структура = Неопределено Тогда
Если ПакетЗапросов.ТекстыЗапросов = Неопределено Тогда
ПакетЗапросов.ТекстыЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ПакетЗапросов.Текст,, ПакетЗапросов.ПозицииЗапросов);
КонецЕсли;
ПакетЗапросов.Структура = мПлатформа.СоздаваемыеВременныеТаблицыПакетаЗапросов(ПакетЗапросов.ТекстыЗапросов);
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// ИндексЗапроса - Число, Неопределено -
Процедура ЗагрузитьЗапросПакетаПоИндексу(Знач ПакетЗапросов, Знач ИндексЗапроса) Экспорт
мТекстБлока = ПакетЗапросов.ТекстыЗапросов[ИндексЗапроса];
мТекстДляПоискаОпределения = мТекстБлока;
мПозицияТекстаДляПоискаОпределения = ПакетЗапросов.ПозицииЗапросов[ИндексЗапроса];
Если ПакетЗапросов.КоординатыТекста <> Неопределено Тогда
мПозицияТекстаДляПоискаОпределения = мПозицияТекстаДляПоискаОпределения + ПакетЗапросов.КоординатыТекста.Метод.ПозицияТела + ПакетЗапросов.КоординатыТекста.Позиция0ВБлоке;
КонецЕсли;
КонецПроцедуры
// Вычисляет массив структур типа дочернего контекста.
//
// Параметры:
// РодительскиеСтрутурыТипа - см. мПлатформа.НоваяТаблицаТипов - родительских структур типа;
// ТекущееСлово - Строка - дочернеее слово;
// ТипСлова - Строка - тип слова;
// *ТекущийИндекс - Строка, *Неопределено - выражение в квадратных скобках;
// *ТекущиеАргументы - Строка, *"" - аргументы метода;
// *ПредшествующийТекст - Строка, *"" - текст для поиска определения таблицы в режиме языка запросов.
//
// Возвращаемое значение:
// МассивСтрутурТипа - Массив - дочерних структур типа.
//
Функция ВычислитьТипДочернегоЭлемента(Знач РодительскиеСтрутурыТипа, Знач ТекущееСлово, Знач ТипСлова, Знач ТекущийИндекс = Неопределено, Знач ТекущиеАргументы = "", Знач ПредшествующийТекст = "",
Знач ПолныйАнализСоставаТипов = Истина, выхЛиПеременнаяМодуля = Ложь, Знач ПозицияВМетоде = 0, ТаблицаТипов = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если мРекурсивныйПуть = Неопределено Тогда
ИнициироватьРекурсивныйПуть();
КонецЕсли;
Если ТекущийИндекс <> Неопределено Тогда
Если РодительскиеСтрутурыТипа[0].ИмяОбщегоТипа = "Массив[РезультатЗапроса]" Тогда
КопияКомпоненты = КопияКомпоненты();
КопияКомпоненты.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(, Ложь,,,, ТекущееСлово,, Истина);
ПеременныеВыражения = Новый Структура;
Для Каждого СтрокаСлова Из КопияКомпоненты.ТаблицаСлов Цикл
ЗначениеПеременной = Неопределено;
ТаблицаСтруктурТипа = ВычислитьТипЗначенияВыражения(СтрокаСлова.Слово, ПредшествующийТекст, ПредшествующийТекст,,,, Ложь,,, Истина,, ПозицияВМетоде);
Если ТаблицаСтруктурТипа.Количество() > 0 Тогда
ЗначениеПеременной = ТаблицаСтруктурТипа[0].Метаданные;
Если ТипЗнч(ЗначениеПеременной) = Тип("ПостроительЗапроса") Тогда
ЗначениеПеременной = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ЗначениеПеременной.Текст);
КонецЕсли;
КонецЕсли;
ПеременныеВыражения.Вставить(СтрокаСлова.Слово, ЗначениеПеременной);
КонецЦикла;
Алгоритм = ирОбщий.СтрСоединитьЛкс(ирОбщий.ВыгрузитьСвойствоЛкс(ПеременныеВыражения),,,, "%1=_АлгоритмОбъект.%1;" + Символы.ПС)
+ "Результат = " + ТекущееСлово;
ТекущееСлово = "";
ЗначениеВыражения = Неопределено;
Попытка
ЗначениеВыражения = ирОбщий.ВыполнитьАлгоритм(Алгоритм, ПеременныеВыражения);
ТекущееСлово = XMLСтрока(ЗначениеВыражения);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
ТаблицаСвойствТипа = мПлатформа.НоваяТаблицаСвойствТипа(); // Ускорение
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = мПлатформа.НоваяТаблицаТипов();
КонецЕсли;
СчетчикТипов = 0;
ПараметрыИсходящегоВызова = Неопределено;
Для Каждого РодительскаяСтруктураТипа Из РодительскиеСтрутурыТипа Цикл
СчетчикТипов = СчетчикТипов + 1;
Если Истина
И Не ПолныйАнализСоставаТипов
И СчетчикТипов > 50
Тогда
Прервать;
КонецЕсли;
Если РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
Продолжить;
КонецЕсли;
ВиртуальнаяТаблица = Неопределено;
МетаданныеРодителя = РодительскаяСтруктураТипа.Метаданные;
ЭтоЛокальныйКонтекст = РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Локальный";
Если Истина
И ЗначениеЗаполнено(ТекущийИндекс)
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВременныеТаблицыЗапроса"
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Структура")
Тогда
ИмяВременнойТаблицы = ВычислитьЗначениеВыражения(ТекущееСлово,,,, ПозицияВМетоде);
ПостроительЗапроса = НайтиЗапросВременнойТаблицы(ИмяВременнойТаблицы, РодительскаяСтруктураТипа.Метаданные);
Если ПостроительЗапроса <> Неопределено Тогда
СтруктраТипа = мПлатформа.НоваяСтруктураТипа("ВременнаяТаблицаЗапроса");
СтруктраТипа.Метаданные = ПостроительЗапроса;
СтруктраТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктраТипа);
Прервать;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТекущийИндекс) Тогда
Если Истина
И ЭтоЛокальныйКонтекст
И ТипСлова = "Свойство"
Тогда
ПараметрыМетода = мПлатформа.ПараметрыМетодаМодуля(мМетодМодуля);
Если ПараметрыМетода <> Неопределено Тогда
СтрокаПараметраМетода = ПараметрыМетода.Найти(НРег(ТекущееСлово), "НИмя");
Если СтрокаПараметраМетода <> Неопределено Тогда
ТаблицаТиповИсточник = Неопределено;
Если Истина
И мМетодМодуля.КлючевыеПараметры <> Неопределено
И мМетодМодуля.КлючевыеПараметры.Свойство(ТекущееСлово, ТаблицаТиповИсточник)
Тогда
Если ТаблицаТиповИсточник <> Неопределено Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИсточник);
Прервать;
КонецЕсли;
КонецЕсли;
Если СтрокаПараметраМетода.ТаблицаТипов = Неопределено Тогда
ВычислитьТипПараметраМетода(ПараметрыМетода, мРекурсивныйПуть.ВходящиеВызовы, СтрокаПараметраМетода, ТаблицаТипов);
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтрокаПараметраМетода.ТаблицаТипов);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если мЯзыкПрограммы = 1 Тогда
ВиртуальнаяТаблица = Новый Структура("Выражение, НомерСтроки");
ВиртуальнаяТаблица.Выражение = "." + ТекущееСлово;
Если ЗначениеЗаполнено(ТекущиеАргументы) Тогда
//ВиртуальнаяТаблица.Выражение = ВиртуальнаяТаблица.Выражение + "." + ТекущиеАргументы; // Кажется это было сделано умышленно
ВиртуальнаяТаблица.Выражение = ВиртуальнаяТаблица.Выражение + ТекущиеАргументы; // https://www.hostedredmine.com/issues/958394
КонецЕсли;
ВиртуальнаяТаблица.НомерСтроки = СтрЧислоСтрок(ПредшествующийТекст);
Если ЭтоЛокальныйКонтекст Тогда
Если Лев(ТекущееСлово, 1) = "&" Тогда
ТаблицаТиповТаблицыПареметра = Неопределено;
Если Истина
И мПакетЗапросов.Свойство("Параметры")
И мПакетЗапросов.Параметры.Свойство(Сред(ТекущееСлово, 2), ТаблицаТиповТаблицыПареметра)
Тогда
СтруктраТипа = мПлатформа.НоваяСтруктураТипа("ВременнаяТаблица");
СтруктраТипа.Метаданные = ТаблицаТиповТаблицыПареметра[0].Метаданные;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктраТипа);
Прервать;
КонецЕсли;
Иначе
ПостроительЗапроса = НайтиЗапросВременнойТаблицы(ТекущееСлово, РодительскаяСтруктураТипа.ДержательМетаданных);
Если ПостроительЗапроса <> Неопределено Тогда
СтруктраТипа = мПлатформа.НоваяСтруктураТипа("ВременнаяТаблица");
СтруктраТипа.Метаданные = ПостроительЗапроса;
СтруктраТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктраТипа);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТекущийИндекс) Тогда
ТаблицаСвойствТипа.Очистить();
мПлатформа.СловаКонтекстаПредопределенные(РодительскаяСтруктураТипа, ТекущееСлово, ТипСлова, ВиртуальнаяТаблица, мЯзыкПрограммы, Конфигурация,, мФлагиКомпиляции, ТаблицаСвойствТипа, ЭтоЛокальныйКонтекст);
Если ТаблицаСвойствТипа.Количество() > 0 Тогда
МаксКоличествоВариантов = 5;
КоличествоВариантов = 0;
Для Каждого СтрокаСлова Из ТаблицаСвойствТипа Цикл
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтрокаСлова.ТаблицаТипов);
КоличествоВариантов = КоличествоВариантов + 1;
Если КоличествоВариантов >= МаксКоличествоВариантов Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "БлокировкаДанных"
И ТипСлова = "Метод"
И ТекущееСлово = "Добавить"
Тогда
ТаблицаТипов.ЗаполнитьЗначения(ирОбщий.ТекстМеждуМаркерамиЛкс(ТекущиеАргументы, """", """"), "Метаданные");
КонецЕсли;
ИначеЕсли Истина
И ЗначениеЗаполнено(РодительскаяСтруктураТипа.ТипЯзыка)
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Строка"
Тогда
ЗаполнитьЗначенияСвойств(ТаблицаТипов.Добавить(), РодительскаяСтруктураТипа);
Продолжить;
КонецЕсли;
Если ТипСлова = "Метод" Тогда
// Ищем правило вычисления
ПравилоВычисленияФункции = НайтиПравилоВычисленияФункции(ТекущееСлово, РодительскаяСтруктураТипа);
Если ПравилоВычисленияФункции <> Неопределено Тогда
Если ПараметрыИсходящегоВызова = Неопределено Тогда
ПараметрыИсходящегоВызова = РазобратьФактическиеПараметрыВызова(ТекущиеАргументы);
КонецЕсли;
//Попытка
мРекурсивныйПуть.ДобавлятьКлючевыеПараметры = Истина;
ТаблицаТиповВычисленная = Вычислить(ПравилоВычисленияФункции.Правило + "(РодительскаяСтруктураТипа, ПараметрыИсходящегоВызова, ТекущееСлово, ПредшествующийТекст, ПозицияВМетоде, ТаблицаТипов)"); // см. мПлатформа.НоваяТаблицаТипов()
мРекурсивныйПуть.ДобавлятьКлючевыеПараметры = Ложь;
Если ТаблицаТиповВычисленная <> Неопределено Тогда
Если ТаблицаТипов <> ТаблицаТиповВычисленная Тогда
ТаблицаТиповВычисленная.ЗаполнитьЗначения(ТаблицаТипов[0].СтрокаОписания, "СтрокаОписания");
ТаблицаТипов.Очистить();
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповВычисленная);
КонецЕсли;
Прервать;
КонецЕсли;
//Исключение КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ТаблицаСвойствТипа.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если ЭтоЛокальныйКонтекст И мМодульМетаданных <> Неопределено Тогда
СтруктураКлюча = Новый Структура("НИмя", Нрег(ТекущееСлово));
НайденныеСтроки = ТаблицаЛокальногоКонтекста(ТипСлова).НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
// Это локальный метод или свойство модуля
СтрокаСлова = НайденныеСтроки[0];
Если мЯзыкПрограммы <> 1 Тогда
ПолеТекстаПрограммыВызова = КопияКомпоненты();
Если ТипСлова = "Метод" Тогда
мПлатформа.ПодготовитьТипРезультатаМетода(СтрокаСлова, мМодульМетаданных,, ПолеТекстаПрограммыВызова);
Иначе
выхЛиПеременнаяМодуля = Истина;
мПлатформа.ПодготовитьТипЗначенияПеременнойМодуля(СтрокаСлова, мМодульМетаданных, ПолеТекстаПрограммыВызова);
КонецЕсли;
КонецЕсли;
ТаблицаТиповСловаМодуля = мПлатформа.ТаблицаТиповСловаМодуля(СтрокаСлова, мМодульМетаданных);
Если Истина
И ЗначениеЗаполнено(ТекущиеАргументы)
И ТипСлова = "Метод"
Тогда
ТаблицаТиповМетода = ВычислитьТипФункцииСФактПараметрами(СтрокаСлова, ТекущиеАргументы, ПредшествующийТекст, ПолныйАнализСоставаТипов, ПараметрыИсходящегоВызова, ПолеТекстаПрограммыВызова);
Если ТаблицаТиповМетода <> Неопределено Тогда
ТаблицаТиповСловаМодуля = ТаблицаТиповМетода;
КонецЕсли;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповСловаМодуля);
Прервать;
КонецЕсли;
КонецЕсли;
ТаблицаСвойствТипа.Очистить();
мПлатформа.СловаКонтекстаМетаданные(РодительскаяСтруктураТипа,
ТекущееСлово, ТипСлова, ВиртуальнаяТаблица, мЯзыкПрограммы, ТекущийИндекс,,, мФлагиКомпиляции, МодульМетаданныхКонтекста(РодительскаяСтруктураТипа), ТаблицаСвойствТипа,, ЭтоЛокальныйКонтекст);
Если ТаблицаСвойствТипа.Количество() > 0 Тогда
Для Каждого СтрокаСлова Из ТаблицаСвойствТипа Цикл
Если Истина
И СтрокаСлова.ТаблицаТипов <> Неопределено
И (Ложь
Или Найти(СтрокаСлова.Слово, "<") = 0
Или ТаблицаТипов.Количество() = 0
Или Найти(ТаблицаТипов[0].ИмяОбщегоТипа, "<") > 0)
Тогда
ТаблицаТиповИсточник = СтрокаСлова.ТаблицаТипов;
Если ТаблицаТиповИсточник.Количество() > 0 Тогда
СтрокаОписания = ТаблицаТиповИсточник[0].СтрокаОписания;
Если Истина
И ЗначениеЗаполнено(ТекущиеАргументы)
И ТипСлова = "Метод"
И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") <> Неопределено
Тогда
ТаблицаТиповМетода = ВычислитьТипФункцииСФактПараметрами(СтрокаОписания, ТекущиеАргументы, ПредшествующийТекст, ПолныйАнализСоставаТипов, ПараметрыИсходящегоВызова);
Если ТаблицаТиповМетода <> Неопределено Тогда
ТаблицаТиповИсточник = ТаблицаТиповМетода;
КонецЕсли;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИсточник);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// ТекущееСлово - Строка -
// МенеджерВременныхТаблиц - см. НовыйМенеджерВременныхТаблиц() -
// ПакетЗапросовТекущий - Структура -
// Возвращаемое значение:
// ПостроительЗапроса, Неопределено -
Функция НайтиЗапросВременнойТаблицы(Знач ТекущееСлово, Знач МенеджерВременныхТаблиц = Неопределено, выхПакетЗапросовТекущий = Неопределено, выхИндексЗапроса = Неопределено) Экспорт
Если ТипЗнч(МенеджерВременныхТаблиц) <> Тип("Структура") Тогда
МенеджерВременныхТаблиц = мМенеджерВременныхТаблиц;
КонецЕсли;
ПостроительЗапроса = Неопределено;
Если МенеджерВременныхТаблиц = Неопределено Тогда
выхПакетЗапросовТекущий = мПакетЗапросов;
выхИндексЗапроса = НайтиИндексЗапросаСозданияВременнойТаблицы(ТекущееСлово, выхПакетЗапросовТекущий);
Иначе
Если выхИндексЗапроса = Неопределено И ТипЗнч(МенеджерВременныхТаблиц) = Тип("Структура") Тогда
ПакетыЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов;
Для Индекс = 1 - ПакетыЗапросов.Количество() По 0 Цикл // Обратный обход
ПакетЗапросовЦикл = ПакетыЗапросов[-Индекс];
выхИндексЗапроса = НайтиИндексЗапросаСозданияВременнойТаблицы(ТекущееСлово, ПакетЗапросовЦикл);
Если выхИндексЗапроса <> Неопределено Тогда
выхПакетЗапросовТекущий = ПакетЗапросовЦикл;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если выхИндексЗапроса <> Неопределено Тогда
ПостроительЗапроса = мПлатформа.ПостроительПакетаЗапросовДоИндекса(выхПакетЗапросовТекущий.ТекстыЗапросов, выхИндексЗапроса);
Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 Тогда
ПостроительЗапроса = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ПостроительЗапроса;
КонецФункции
//.
// Параметры:
// ПараметрыМетода - ТаблицаЗначений -
// ПройденныеВызовы - Строка -
// СтрокаПараметраМетода - Неопределено, СтрокаТаблицыЗначений -
// ТаблицаТипов - ТаблицаЗначений -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция ВычислитьТипПараметраМетода(Знач ПараметрыМетода, Знач ПройденныеВызовы, Знач СтрокаПараметраМетода, Знач ТаблицаТипов)
СтрокаПараметраМетода.ТаблицаТипов = ТаблицаТипов;
Если мМодульМетаданных.СтруктураТипа <> Неопределено Тогда
// События формы
ФормаМодуля = мМодульМетаданных.СтруктураТипа.Метаданные;
Если Истина
И ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".Форма.Модуль")
И (Ложь
Или ТипЗнч(ФормаМодуля) = Тип("Структура")
Или ТипЗнч(ФормаМодуля) = Тип("Форма")
Или ТипЗнч(ФормаМодуля) = ирОбщий.ТипУправляемаяФормаЛкс())
Тогда
ВсеОбработчикиСобытий = ирОбщий.ВсеОбработчикиСобытийФормаЛкс(ФормаМодуля, Истина);
СтрокаОбработчика = ВсеОбработчикиСобытий.Найти(НРег(мМетодМодуля.Имя), "НОбработчик");
Если СтрокаОбработчика <> Неопределено Тогда
ЭлементФормы = Неопределено;
ПараметрыСобытия = мПлатформа.ПараметрыМетодаПлатформы(СтрокаОбработчика.СтрокаОписания);
Если ЗначениеЗаполнено(СтрокаОбработчика.Имя) Тогда
СтрокаПараметраЭлемент = ПараметрыСобытия.Вставить(0);
СтрокаПараметраЭлемент.Слово = "Элемент";
Если ТипЗнч(ФормаМодуля) = Тип("Форма") Тогда
Попытка
ЭлементФормы = Вычислить("ФормаМодуля.ЭлементыФормы." + СтрокаОбработчика.Имя);
Исключение
КонецПопытки;
Иначе
// Нельзя использовать Найти(), т.к. возможен имитатор формы
Попытка
ЭлементФормы = ФормаМодуля.Элементы[СтрокаОбработчика.Имя];
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
ЗаполнитьОписанияПараметровИзСобытия(СтрокаОбработчика.СтрокаОписания, ПараметрыСобытия);
Если ЭлементФормы <> Неопределено Тогда
Если ирОбщий.СтрокиРавныЛкс(СтрокаПараметраМетода.Имя, "Элемент") Тогда
Если ТипЗнч(ЭлементФормы) = Тип("Структура") Тогда
СтрукутраТипаЭлемента = мПлатформа.СтруктураТипаИзКонкретногоТипа(ЭлементФормы.Тип);
СтрукутраТипаЭлемента.Метаданные = ЭлементФормы;
Иначе
СтрукутраТипаЭлемента = мПлатформа.СтруктураТипаИзЗначения(ЭлементФормы);
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтрукутраТипаЭлемента);
Возврат ТаблицаТипов;
ИначеЕсли Истина
И ПараметрыМетода[0].Имя = "Элемент"
И (Ложь
Или СтрокаПараметраМетода.Имя = "ВыбраннаяСтрока"
Или СтрокаПараметраМетода.Имя = "ДанныеСтроки")
И ТипЗнч(ФормаМодуля) = Тип("Форма")
Тогда
ТаблицаДочернихСлов = мПлатформа.СловаКонтекстаПредопределенные(мПлатформа.СтруктураТипаИзЗначения(ЭлементФормы), "ТекущиеДанные", "Свойство");
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаДочернихСлов[0].ТаблицаТипов);
Возврат ТаблицаТипов;
ИначеЕсли Истина
И ПараметрыМетода[0].Имя = "Элемент"
И ТипЗнч(ФормаМодуля) = Тип("Форма")
Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип(СтрокаПараметраМетода.ТипЗначения),, Новый Структура("Метаданные", ЭлементФормы)));
Возврат ТаблицаТипов;
КонецЕсли;
Иначе
Если СтрокаПараметраМетода.Имя = "ТекущийОбъект" Тогда
КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаФормыЛкс(ФормаМодуля);
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(КлючОсновногоОбъекта);
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, "Ссылка.", "Объект.");
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Подсказка по параметрам обработчиков методов Http-сервисов
Если Истина
И ирОбщий.СтрНачинаетсяСЛкс(мМодульМетаданных.Имя, "HTTPСервис.")
И ПараметрыМетода.Индекс(СтрокаПараметраМетода) = 0
Тогда
ОбъектМД = мМодульМетаданных.СтруктураТипа.Метаданные;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.HTTPСервисы.task1;
#КонецЕсли
Для Каждого Шаблон Из ОбъектМД.ШаблоныURL Цикл
Если ирОбщий.НайтиЭлементКоллекцииЛкс(Шаблон.Методы, "Обработчик", мМетодМодуля.Имя) <> Неопределено Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип("HTTPЗапрос")));
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Подсказка по параметрам обработчиков модуля команды
Если Истина
И ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульКоманды")
И мМетодМодуля.Имя = "ОбработкаКоманды"
Тогда
Если ПараметрыМетода.Индекс(СтрокаПараметраМетода) = 0 Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мМодульМетаданных.СтруктураТипа.Метаданные.ТипПараметраКоманды);
КонецЕсли;
СобытияМодуля = ирКэш.СобытияПоИмениОбщегоТипаЛкс("Модуль команды");
ЗаполнитьОписанияПараметровИзСобытия(СобытияМодуля[0]);
КонецЕсли;
// Подсказка по параметрам обработчиков с фиксированными именами
Если Ложь
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульКоманды")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульМенеджера")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульОбъекта")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульНабораЗаписей")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульМенеджераЗначения")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульУправляемогоПриложения")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульОбычногоПриложения")
Или ирОбщий.СтрКончаетсяНаЛкс(мМодульМетаданных.Имя, ".МодульСеанса")
Тогда
СобытияМодуля = ирКэш.СобытияПоИмениОбщегоТипаЛкс(мМодульМетаданных.СтруктураТипа.ИмяОбщегоТипа);
СтрокаСобытия = ирОбщий.НайтиЭлементКоллекцииЛкс(СобытияМодуля, "НСлово", НРег(мМетодМодуля.Имя));
Если СтрокаСобытия <> Неопределено Тогда
ЗаполнитьОписанияПараметровИзСобытия(СтрокаСобытия);
Если Истина
И СтрокаСобытия.Слово = "ОбработкаПолученияДанныхВыбора"
И СтрокаПараметраМетода.Имя = "Параметры"
Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа("Структура");
СтруктураТипа.Метаданные = Новый Структура("СтрокаПоиска, Отбор, ВыборГруппИЭлементов, СпособПоискаСтроки, ПолнотекстовыйПоиск, РежимПолученияДанныхВыбора");
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Подсказка по параметру "Источник" обработчиков подписок на события
Если Истина
И СтрокаПараметраМетода.Имя = "Источник"
И ирОбщий.СтрНачинаетсяСЛкс(мМодульМетаданных.Имя, "ОбщийМодуль.")
Тогда
ИмяМодуля = мМодульМетаданных.СтруктураТипа.Метаданные.Имя;
Для Каждого ПодпискаНаСобытие Из Метаданные.ПодпискиНаСобытия Цикл
Если ирОбщий.СтрокиРавныЛкс(ПодпискаНаСобытие.Обработчик, ИмяМодуля + "." + мМетодМодуля.Имя) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ПодпискаНаСобытие.Источник);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаПараметраМетода.ТипЗначения) Тогда
// Тип из комментария
ТаблицаТиповНазначенных = ТаблицаТиповИзТекста(СтрокаПараметраМетода.ТипЗначения, СтрокаПараметраМетода.Описание);
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповНазначенных);
Если ЛиДетальностьТиповДостаточна(ТаблицаТипов, 4) Тогда
Возврат ТаблицаТипов;
КонецЕсли;
КонецЕсли;
// Анализ локальных вызовов
ПолеТекстаПрограммыВызова = Неопределено;
МинДетальность = 3;
МаксЧислоВызовов = 3;
СчетчикВызовов = 0;
ДетальностьТиповДостаточна = Ложь;
ИндексПараметра = ПараметрыМетода.Индекс(СтрокаПараметраМетода);
ВхожденияВызова = ПройденныеВызовы[мМетодМодуля.НИмя];
Если ВхожденияВызова = Неопределено Тогда
ШаблонПараметра = "(" + шВыражениеПрограммы + ")?" + шРазделитель + "*(?:$|,|\))";
ВхожденияВызова = ирОбщий.НайтиРегВыражениеЛкс(мОригинальныйТекст, ШаблонВызоваМетода(мМетодМодуля.Имя),,,,,, Истина, мРегВыражение); // Передаем РегВыражение для ускорения
#Если Сервер И Не Сервер Тогда
ВхожденияВызова = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
ПройденныеВызовы[мМетодМодуля.НИмя] = ВхожденияВызова;
КонецЕсли;
Для Каждого ВхождениеВызова Из ВхожденияВызова Цикл
Если Истина
И ВхождениеВызова.ПозицияВхождения > мМетодМодуля.ПозицияОпределения
И ВхождениеВызова.ПозицияВхождения < мМетодМодуля.ПозицияТела
Тогда
// В области заголовка определения текущего метода
Продолжить;
КонецЕсли;
ПараметрыВходящегоВызова = Сред(ВхождениеВызова.ТекстВхождения, Найти(ВхождениеВызова.ТекстВхождения, "(") + 1);
Если ИндексПараметра > СтрЧислоВхождений(ПараметрыВходящегоВызова, ",") Тогда
Продолжить;
КонецЕсли;
ВхожденияПараметров = ирОбщий.НайтиРегВыражениеЛкс(ПараметрыВходящегоВызова, ШаблонПараметра,,,,,, Истина, мРегВыражение,, ВхожденияПараметров); // Передаем РегВыражение для ускорения
#Если Сервер И Не Сервер Тогда
ВхожденияПараметров = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
Если ВхожденияПараметров.Количество() > ИндексПараметра Тогда
ВхождениеПараметра = ВхожденияПараметров[ИндексПараметра];
ФактическийПараметр = СокрЛП(ирОбщий.СтрокаБезКонцаЛкс(ВхождениеПараметра.ТекстВхождения));
Если ЛиБесполезноеПрисвоениеПеременной(ФактическийПараметр) Тогда
Если ЗначениеЗаполнено(ФактическийПараметр) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.НоваяСтруктураТипа(ФактическийПараметр));
КонецЕсли;
Продолжить;
ИначеЕсли ЛиБулевыйЛитерал(ФактическийПараметр) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.НоваяСтруктураТипа("Булево"));
Иначе
Если ПолеТекстаПрограммыВызова = Неопределено Тогда
ПолеТекстаПрограммыВызова = КопияКомпоненты();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекстаПрограммыВызова = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
НачальнаяПозицияБлока = ПолеТекстаПрограммыВызова.ЗагрузитьМетодМодуляПоПозицииИРазобратьКонтекст(Истина, ВхождениеВызова.ПозицияВхождения);
Если ПолеТекстаПрограммыВызова.мМетодМодуля = Неопределено Тогда
ИмяВызывающегоМетода = "<Инициация>";
Иначе
ИмяВызывающегоМетода = ПолеТекстаПрограммыВызова.мМетодМодуля.Имя;
КонецЕсли;
КлючВызова = ИмяВызывающегоМетода + "-" + мМетодМодуля.Имя;
Если ПройденныеВызовы[КлючВызова] = Неопределено Тогда
ПройденныеВызовы[КлючВызова] = 1; // Таким образом мы не более одного вызова из каждого метода проверяем
ТаблицаТиповИсточник = ПолеТекстаПрограммыВызова.ВычислитьТипЗначенияВыражения(ФактическийПараметр,,,,,, Ложь,,,,, ВхождениеВызова.ПозицияВхождения - 1 - НачальнаяПозицияБлока);
Если ЛиДетальностьТиповДостаточна(ТаблицаТиповИсточник, 1) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИсточник);
Если ЛиДетальностьТиповДостаточна(ТаблицаТиповИсточник, МинДетальность) Тогда
ДетальностьТиповДостаточна = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
СчетчикВызовов = СчетчикВызовов + 1;
Если МаксЧислоВызовов = СчетчикВызовов Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Истина
И (Ложь
Или мРекурсивныйПуть.ДобавлятьКлючевыеПараметры
Или Не ДетальностьТиповДостаточна // Надо отключить проверку детальности для ирОбщий.НайтиЭлементКоллекцииЛкс
)
И мРекурсивныйПуть.ВычислениеРезультатаМетода = мМетодМодуля.Имя
Тогда
ПравилоВычисленияФункции = НайтиПравилоВычисленияФункции(мМетодМодуля.Имя, мМодульМетаданных.СтруктураТипа);
Если ПравилоВычисленияФункции = Неопределено Тогда
КлючевыеПараметры = мМетодМодуля.КлючевыеПараметры;
Если КлючевыеПараметры = Неопределено Тогда
КлючевыеПараметры = Новый Структура;
мМетодМодуля.КлючевыеПараметры = КлючевыеПараметры;
КонецЕсли;
КлючевыеПараметры.Вставить(СтрокаПараметраМетода.Имя);
КонецЕсли;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// ТаблицаТипов - ТаблицаЗначений -
// МинДетальность - Число -
// Возвращаемое значение:
// Булево -
Функция ЛиДетальностьТиповДостаточна(ТаблицаТипов, Знач МинДетальность = 3, выхЛучшийТип = Неопределено) Экспорт
Если ТаблицаТипов.Количество() > 0 Тогда
Счетчик = 1;
Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход
СтрокаТипа = ТаблицаТипов[-Индекс];
Если Ложь
Или СтрокаТипа.ИмяОбщегоТипа = "Строка"
Или СтрокаТипа.ИмяОбщегоТипа = "Число"
//Или СтрокаТипа.ИмяОбщегоТипа = "Булево"
Или СтрокаТипа.Детальность >= МинДетальность
Тогда
выхЛучшийТип = СтрокаТипа;
Возврат Истина;
КонецЕсли;
Если Счетчик = 3 Тогда
// Проверяем не больше 3-х, т.к. бесполезных типов обычно очень мало указывают в описании, например Неопределено, Null
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
КонецЕсли;
Возврат Ложь;
КонецФункции
//.
// Параметры:
// МетодМодуля - см. мМодульМетаданных.Методы.Добавить() -
// ТекущиеАргументы - Строка -
// ПредшествующийТекст - Строка, Строка -
// ПолныйАнализСоставаТипов - Булево -
// ПараметрыИсходящегоВызова - Массив -
Функция ВычислитьТипФункцииСФактПараметрами(Знач МетодМодуля, Знач ТекущиеАргументы, Знач ПредшествующийТекст, Знач ПолныйАнализСоставаТипов, Знач ПараметрыИсходящегоВызова,
Знач ПолеТекстаПрограммыВызова = Неопределено)
Если МетодМодуля.КлючевыеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СчетчикиВызовов = мРекурсивныйПуть.СчетчикиВызовов;
КлючСчетчика = МетодМодуля.ИмяМодуля + "." + МетодМодуля.Имя;
СчетчикВызовов = СчетчикиВызовов[КлючСчетчика];
Если СчетчикВызовов = Неопределено Тогда
СчетчикВызовов = 0;
КонецЕсли;
Если СчетчикВызовов > 0 Тогда
// Для ускорения
Возврат Неопределено;
КонецЕсли;
СчетчикВызовов = СчетчикВызовов + 1;
СчетчикиВызовов[КлючСчетчика] = СчетчикВызовов;
Если ПолеТекстаПрограммыВызова = Неопределено Тогда
ПолеТекстаПрограммыВызова = КопияКомпоненты();
КонецЕсли;
Если ПараметрыИсходящегоВызова = Неопределено Тогда
ПараметрыИсходящегоВызова = РазобратьФактическиеПараметрыВызова(ТекущиеАргументы);
КонецЕсли;
ПараметрыМетода = мПлатформа.ПараметрыМетодаМодуля(МетодМодуля);
ФактическиеПараметры = Новый Структура;
Для Каждого КлючИЗначение Из МетодМодуля.КлючевыеПараметры Цикл
Если КлючИЗначение.Значение <> Неопределено Тогда
// Защита от рекурсии. Вроде бы СчетчикВызовов это уже делает
Возврат Неопределено;
КонецЕсли;
СтрокаПараметра = ПараметрыМетода.Найти(НРег(КлючИЗначение.Ключ), "НИмя");
ИндексПараметра = ПараметрыМетода.Индекс(СтрокаПараметра);
Если ПараметрыИсходящегоВызова.ВГраница() < ИндексПараметра Тогда
ВыражениеПараметра = "";
Иначе
ВыражениеПараметра = ПараметрыИсходящегоВызова[ИндексПараметра];
КонецЕсли;
Если Не ЗначениеЗаполнено(ВыражениеПараметра) Тогда
Продолжить;
КонецЕсли;
ТаблицаТиповПараметра = ВычислитьТипЗначенияВыражения(ВыражениеПараметра, ПредшествующийТекст,,,, ПолныйАнализСоставаТипов, Ложь,,, Истина);
Если Не ЛиДетальностьТиповДостаточна(ТаблицаТиповПараметра, 1) Тогда
Продолжить;
КонецЕсли;
ФактическиеПараметры.Вставить(КлючИЗначение.Ключ, ТаблицаТиповПараметра);
КонецЦикла;
Если ФактическиеПараметры.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
МетодМодуля.КлючевыеПараметры = ФактическиеПараметры;
ТаблицаТиповИсточник = мПлатформа.ПодготовитьТипРезультатаМетода(МетодМодуля, МетодМодуля.ИмяМодуля,, ПолеТекстаПрограммыВызова, Истина);
Возврат ТаблицаТиповИсточник;
КонецФункции
//.
// Параметры:
// ТекущиеАргументы - ? -
// Возвращаемое значение:
// Массив -
Функция РазобратьФактическиеПараметрыВызова(ТекущиеАргументы) Экспорт
мРегВыражение.Global = Истина;
Если мЯзыкПрограммы = 0 Тогда
мРегВыражение.Pattern = "(" + шВыражениеПрограммы + ")?" + шРазделитель + "*,";
Иначе
мРегВыражение.Pattern = "(" + шВыражениеЗапроса + ")?" + шРазделитель + "*,";
КонецЕсли;
Результат = мРегВыражение.НайтиВхождения(Нрег(Сред(ТекущиеАргументы, 2, СтрДлина(ТекущиеАргументы) - 2) + ","));
МассивПараметров = Новый Массив;
Для Каждого Вхождение Из Результат Цикл
МассивПараметров.Добавить(СокрЛП(Вхождение.SubMatches(0)));
КонецЦикла;
Возврат МассивПараметров;
КонецФункции
//.
// Параметры:
// СтрокаСобытия - ? -
// ПараметрыСобытия - ? -
Процедура ЗаполнитьОписанияПараметровИзСобытия(СтрокаСобытия, Знач ПараметрыСобытия = Неопределено) Экспорт
Если Истина
И мМетодМодуля.Параметры.Количество() > 0
и Не ЗначениеЗаполнено(мМетодМодуля.Параметры[0].ТипЗначения)
Тогда
Если ПараметрыСобытия = Неопределено Тогда
ПараметрыСобытия = мПлатформа.ПараметрыМетодаПлатформы(СтрокаСобытия);
КонецЕсли;
мМетодМодуля.Описание = СтрокаСобытия.Описание;
// TODO перенести в мПлатформа.ПараметрыМетодаМодуля()
ИндексПараметра = 0;
Для Каждого СтрокаПараметра Из ПараметрыСобытия Цикл
СтрокаПараметраЦикл = мМетодМодуля.Параметры[ИндексПараметра];
СтрокаПараметраЦикл.ТипЗначения = СтрокаПараметра.ТипЗначения;
СтрокаПараметраЦикл.Описание = СтрокаПараметра.Описание;
ИндексПараметра = ИндексПараметра + 1;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ШаблонВызоваМетода(Знач ИмяВызова) Экспорт
Если Лев(ИмяВызова, 1) = "." Тогда
Начало = "(?:" + шИмяСТочками + ")?";
Иначе
// Начало = "(?:[^" + мПлатформа.шБуква + "\d\.\s]|^|[^\.\s]\s+)" // Более строгий, но медленный
Начало = "(?:[^" + шБуква + "\d\.]|^)";
КонецЕсли;
ШаблонВызова = Начало + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ИмяВызова) + "\s*\(((?:(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*(?=[,\)])|,)*)\)";
Возврат ШаблонВызова;
КонецФункции
Функция МодульМетаданныхКонтекста(Знач РодительскаяСтрутураТипа)
Если РодительскаяСтрутураТипа.ИмяОбщегоТипа = "Локальный" Тогда
МодульМетаданных = мМодульМетаданных;
Иначе
МодульМетаданных = Неопределено;
КонецЕсли;
Возврат МодульМетаданных;
КонецФункции
// Определяет тип значения слова в режиме внутреннего языка.
//
// Параметры:
// Выражение - Строка -
// ТекстДляПоискаОпределения - Строка - где ищем определение;
// ПредшествующийТекст - -
// РазрешитьАнализИмениТипа - -
// ЭтоВызовКонструктора - -
// ПолныйАнализСоставаТипов - -
// ЛиКорневойВызов - -
// ГлобальныйПоискВМодуле - -
// БезВычисленияРодителя - -
// ВычислитьЗначение - -
// Позиция0ВМетодеОт - -
// Позиция0ВМетодеДо - -
// ДопКлючКэша - - если Неопределено и ЛиКорневойВызов то кэш выражений отключается
//
// Возвращаемое значение:
// см. мПлатформа.НоваяТаблицаТипов -
Функция ВычислитьТипЗначенияВыражения(Знач Выражение = "", Знач ТекстДляПоискаОпределения = "", Знач ПредшествующийТекст = "", Знач РазрешитьАнализИмениТипа = Ложь,
Знач ЭтоВызовКонструктора = Ложь, ПолныйАнализСоставаТипов = Истина, Знач ЛиКорневойВызов = Истина, Знач ГлобальныйПоискВМодуле = Ложь, Знач БезВычисленияРодителя = Ложь, Знач ВычислитьЗначение = Ложь,
Знач Позиция0ВМетодеОт = 0, Знач Позиция0ВМетодеДо = 0, Знач ДопКлючКэша = "", Знач ДляСвойства = "") Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Если ЛиКорневойВызов Или мРекурсивныйПуть = Неопределено Тогда
ИнициироватьРекурсивныйПуть(Выражение, ДопКлючКэша);
КонецЕсли;
Если ГлобальныйПоискВМодуле Тогда
ТекстДляПоискаОпределения = ПолеТекста.ПолучитьТекст();
СтарыйМетод = мМетодМодуля;
Иначе
Если Не ЗначениеЗаполнено(ТекстДляПоискаОпределения) Тогда
ТекстДляПоискаОпределения = ДиапазонТекстаДляПоиска(мТекстБлока, Позиция0ВМетодеОт, Позиция0ВМетодеДо);
КонецЕсли;
Если Не ЗначениеЗаполнено(Позиция0ВМетодеДо) Тогда
Позиция0ВМетодеДо = СтрДлина(ТекстДляПоискаОпределения);
КонецЕсли;
Если Не ЗначениеЗаполнено(ПредшествующийТекст) Тогда
ПредшествующийТекст = ТекстДляПоискаОпределения;
КонецЕсли;
КонецЕсли;
ТаблицаТипов = мПлатформа.НоваяТаблицаТипов();
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
//Если ЗначениеЗаполнено(Конфигурация) Тогда
СтруктураТипа.Метаданные = Конфигурация;
//Иначе
// СтруктураТипа.Метаданные = мПлатформа.мМетаданные;
//КонецЕсли;
Если РазрешитьАнализИмениТипа Тогда
Если мЯзыкПрограммы = 1 Тогда
мТолькоСсылочныеИменаТипов = Истина;
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = шПредИмя + "(?:ССЫЛКА|REFS)" + шРазделитель + "+$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
//RegExp.Pattern = шПредИмя + "(?:ВЫРАЗИТЬ|CAST)" + шРазделитель + "*\(" + шВыражениеЗапроса + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+$"; // Привязка к концу вызывала катастрофическое шагание назад
мРегВыражение.Pattern = шПредИмя + "(?:ВЫРАЗИТЬ|CAST)" + шРазделитель + "*\(" + шВыражениеЗапроса + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+"; // 08.02.2023
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст, Истина);
Если Истина
И Вхождения.Количество() > 0
И ПустаяСтрока(Сред(ПредшествующийТекст, Вхождения[0].FirstIndex + Вхождения[0].Length)) // 08.02.2023
Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
мТолькоСсылочныеИменаТипов = Ложь;
КонецЕсли;
мРегВыражение.Pattern = шПредИмя + "(?:ТИП|TYPE)" + шРазделитель + "*\(" + шРазделитель + "*$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
мТолькоСсылочныеИменаТипов = Ложь;
КонецЕсли;
мРегВыражение.Pattern = шПредИмя + "(?:ЗНАЧЕНИЕ|VALUE)" + шРазделитель + "*\(" + шРазделитель + "*$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе";
КонецЕсли;
Иначе
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "+$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
мРегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*\(" + шРазделитель + "*""$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
// Активная следующая строка блокирует недокументированные возможности.
//СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
мРегВыражение.Pattern = шПредИмя + "Тип" + шРазделитель + "*\(" + шРазделитель + "*""$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
мРегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*ОписаниеТипов\(" + шРазделитель + "*""[^""]*$";
Вхождения = мРегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Вхождения.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
КонецЕсли;
Если Ложь
Или СтруктураТипа.ТипЯзыка = "ИмяТипа"
Или СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе"
Тогда
СтруктураТипа.ИмяОбщегоТипа = "";
Иначе
Если мЭтоТекстовыйЛитерал Тогда
ИмяОтключенияЛишнихВычислений = "Зукера45";
ТаблицаТипов = ВычислитьТипЗначенияВыражения(мВызовМетода + ИмяОтключенияЛишнихВычислений + ")", ТекстДляПоискаОпределения, ПредшествующийТекст,, мЭтоКонструктор, ПолныйАнализСоставаТипов, Ложь);
Возврат ТаблицаТипов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Выражение = Неопределено
Или Выражение = ""
Тогда
Если СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
СтруктураТипа.ИмяОбщегоТипа = "Локальный"; // Приватные свойства + глобальный контекст
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Если мМодульМетаданных <> Неопределено И мМодульМетаданных.СтруктураТипа <> Неопределено Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мМодульМетаданных.СтруктураТипа);
КонецЕсли;
КонецЕсли;
ИначеЕсли Лев(Выражение, 1) = """" Тогда
СтруктураТипа.ИмяОбщегоТипа = "Строка";
Если ВычислитьЗначение Тогда
СтруктураТипа.Метаданные = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(Выражение);
//Если СтрДлина(СтруктураТипа.Метаданные) > 50 Тогда // Для сбора текстов запроса нужно обязательно возвращать координаты
СтруктураТипа.ДержательМетаданных = НовыеКоординатыВыражения(Выражение, Позиция0ВМетодеДо);
//КонецЕсли;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиЦифраЛкс(Лев(Выражение, 1)) Тогда
СтруктураТипа.ИмяОбщегоТипа = "Число";
Если ВычислитьЗначение Тогда
Попытка
СтруктураТипа.Метаданные = Число(Выражение);
Исключение
КонецПопытки;
КонецЕсли;
Иначе
ВычислениеРазрешено = Истина;
ЛиВиртПрисвоение = Ложь;
ЛиПеременнаяРезультата = Выражение = мПлатформа.ИмяПеременнойВозвращаемогоЗначения();
ТекущееСлово = Выражение;
ТекущийИндекс = Неопределено;
ТекущиеАргументы = Неопределено;
Если мЯзыкПрограммы = 1 И Лев(Выражение, 1) = "&" Тогда
РодительскийКонтекст = "";
ТекущееСлово = Выражение;
Иначе
Если ирОбщий.СтрНачинаетсяСЛкс(Выражение, "Новый ") Тогда
// Для ускорения
ЛиВиртПрисвоение = Истина;
ИначеЕсли Ложь
//Или Выражение = мПлатформа.ИмяПеременнойВозвращаемогоЗначения() // Наверно не даст ускорения
Или Найти(Выражение, ".") = 0 И ирОбщий.ЛиИмяПеременнойЛкс(Выражение)
Тогда
// Для ускорения
ТипСлова = "Свойство";
РодительскийКонтекст = "";
Иначе
КэшРазбораВыражений = мПлатформа.мКэшРазбораВыражений;
Если мПлатформа.мКэшРазбораВыражений = Неопределено Тогда
КэшРазбораВыражений = Новый Соответствие;
мПлатформа.мКэшРазбораВыражений = КэшРазбораВыражений;
КонецЕсли;
КлючКэшаРазбора = НРег(Выражение);
Вхождения = КэшРазбораВыражений[КлючКэшаРазбора];
Если Вхождения = Неопределено Тогда
мРегВыражение.Global = Ложь;
мРегВыражение.Pattern = "(((\.(" + шИмя + "|\?|)" + шСкобки + "?)|" + шИндекс + ")*)" +
"((\.(" + шИмя + "|\?|)" + шНачалоСкобок + "?)|" + шИндекс + ")$"; // Возможно нужно заменить на шИмяНачалоСкобок
Вхождения = мРегВыражение.НайтиВхождения("." + Выражение);
КэшРазбораВыражений[КлючКэшаРазбора] = Вхождения;
КонецЕсли;
Если Вхождения.Количество() > 0 Тогда
ТипСлова = "Свойство";
Вхождение = Вхождения[0];
РодительскийКонтекст = Сред(Вхождение.SubMatches(0), 2);
ТекущееСлово = Вхождение.SubMatches(8);
ТекущийИндекс = Вхождение.SubMatches(10);
ТекущиеАргументы = Вхождение.SubMatches(9);
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
ТекущееСлово = Сред(ТекущийИндекс, 2, СтрДлина(ТекущийИндекс) - 2);
КонецЕсли;
Иначе
ЛиВиртПрисвоение = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если мЯзыкПрограммы = 1 Тогда
ТипСлова = Неопределено;
ИначеЕсли ЗначениеЗаполнено(ТекущееСлово) Тогда
ТипСлова = "Свойство";
Если Истина
И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущиеАргументы)
И Не СтруктураТипа.ТипЯзыка = "ИмяТипа"
Тогда
// Это метод или функция
Если ЭтоВызовКонструктора Тогда
ТипСлова = "Конструктор";
Иначе
ТипСлова = "Метод";
КонецЕсли;
КонецЕсли;
Иначе
ВычислениеРазрешено = Ложь;
КонецЕсли;
Если ВычислениеРазрешено Тогда
// Кэш проверяем в первую очередь!
КлючВыраженияСПозицией = "";
Если мРекурсивныйПуть.ДопКлючКэша <> Неопределено Тогда
Если мМетодМодуля <> Неопределено Тогда
ТипыВыраженийМетода = мМетодМодуля.ТипыВыражений;
Если ТипыВыраженийМетода = Неопределено Тогда
ТипыВыраженийМетода = Новый Соответствие;
мМетодМодуля.ТипыВыражений = ТипыВыраженийМетода;
КонецЕсли;
Иначе
ТипыВыраженийМетода = мРекурсивныйПуть.ТипыВыраженийПрограммы; // TODO перенести в мМодульМетаданных и возможно нужно отключить для глобального поиска
КонецЕсли;
КлючВыраженияСПозицией = мРекурсивныйПуть.ДопКлючКэша + ";"
//+ XMLСтрокаозиция0ВМетодеОт) + ";"
+ XMLСтрокаозиция0ВМетодеДо) + ";" + Лев(Выражение, 200);
ТаблицаТиповКэш = ТипыВыраженийМетода[КлючВыраженияСПозицией];
Если ТаблицаТиповКэш <> Неопределено Тогда
Возврат ТаблицаТиповКэш;
КонецЕсли;
// Защита от рекурсии
//мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
ТипыВыраженийМетода.Вставить(КлючВыраженияСПозицией, ТаблицаТипов);
КонецЕсли;
ТаблицаТиповРодителя = новый Массив;
Если Истина
И Не ЛиВиртПрисвоение
И Не ЛиПеременнаяРезультата
И (Ложь
Или Не БезВычисленияРодителя
Или Найти(Выражение, ".") = 0)
Тогда
Если Истина
И ПустаяСтрока(РодительскийКонтекст)
И мКорневаяТаблицаТипов <> Неопределено
И СтруктураТипа.ТипЯзыка = ""
Тогда
ТаблицаТиповРодителя = мКорневаяТаблицаТипов;
Иначе
ТаблицаТиповРодителя = ВычислитьТипЗначенияВыражения(РодительскийКонтекст, ТекстДляПоискаОпределения, ПредшествующийТекст, РазрешитьАнализИмениТипа,, ПолныйАнализСоставаТипов, Ложь,,,,,
Позиция0ВМетодеДо,, ТекущееСлово);
Если ПустаяСтрока(РодительскийКонтекст) И мКорневаяТаблицаТипов = Неопределено Тогда
мКорневаяТаблицаТипов = ТаблицаТиповРодителя;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТаблицаТиповРодителя.Количество() > 0 Тогда
ЛиПеременнаяМодуля = Ложь;
ВычислитьТипДочернегоЭлемента(ТаблицаТиповРодителя, ТекущееСлово, ТипСлова, ТекущийИндекс, ТекущиеАргументы, ПредшествующийТекст, ПолныйАнализСоставаТипов, ЛиПеременнаяМодуля,
Позиция0ВМетодеДо, ТаблицаТипов);
Если ЛиПеременнаяМодуля Тогда
КлючВыраженияСПозицией = "";
Если Ложь
//Или Не ГлобальныйПоискВМодуле // Закомментировал, чтобы сужение типа через проверку типа работало
Или Не ЛиКорневойВызов
Тогда
Перейти ~Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если мЯзыкПрограммы = 1 Тогда
Если РодительскийКонтекст = "" Тогда
Если ЗначениеЗаполнено(ТекущееСлово) Тогда
мРегВыражение.Global = Ложь;
мРегВыражение.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ТекущееСлово));
РезультатТекста = мРегВыражение.НайтиВхождения(ТекстДляПоискаОпределения);
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[0];
ПозицияВхождения0 = ПоследнееВхождение.FirstIndex;
СледРекурсии = мРекурсивныйПуть.Позиции.Найти(ПозицияВхождения0);
Если СледРекурсии = Неопределено Тогда
мРекурсивныйПуть.Позиции.Добавить(ПозицияВхождения0);
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(3);
Если ПрисвоенныйКонтекст <> Выражение Тогда
МассивСтруктурПрисвоенныхТипов = ВычислитьТипЗначенияВыражения(ПрисвоенныйКонтекст, ТекстДляПоискаОпределения,
Лев(ТекстДляПоискаОпределения, ПозицияВхождения0 - 1),,, ПолныйАнализСоставаТипов, Ложь,,,,, ПозицияВхождения0);
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, МассивСтруктурПрисвоенныхТипов);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ТекущиеАргументы) Тогда
ТекущееСлово = ирОбщий.УдалитьВнешниеСкобкиВыраженияЛкс(ТекущиеАргументы);
Если ирОбщий.СтрНачинаетсяСЛкс(ТекущееСлово, "Выразить(") Тогда
ТекущиеАргументы = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекущееСлово, "(", ")", Ложь, Истина);
ТекущееСлово = "ВЫРАЗИТЬ";
мРегВыражение.Pattern = шРазделитель + "(?:КАК|AS)" + шРазделитель + "+(" + шИмяСТочками + ")";
Вхождения = мРегВыражение.НайтиВхождения(ТекущиеАргументы);
Если Вхождения.Количество() > 0 Тогда
ИмяТипаВыражения = Вхождения[Вхождения.Количество() - 1].Submatches(0);
Если Найти(ИмяТипаВыражения, ".") > 0 Тогда
ИмяТипаВыражения = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ИмяТипаВыражения);
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип(ИмяТипаВыражения));
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, ирОбщий.ПеревестиСтроку("Ссылка") + ".", ".");
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ТекущееСлово) И ТипСлова = "Свойство" Тогда
Если ТаблицаТиповРодителя.Количество() > 0 Тогда
МетаданныеРодителя = ТаблицаТиповРодителя[0].Метаданные;
Иначе
МетаданныеРодителя = Неопределено;
КонецЕсли;
Если Истина
И МетаданныеРодителя <> Неопределено
И ТаблицаТипов.Количество() = 1
И (Ложь
Или ТаблицаТипов[0].ИмяОбщегоТипа = "ОбщийМодуль"
//Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыКоллекция")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктураСКоллекцией"))
Тогда
// Считаем что тип уже достаточно точно вычислен. Отсекаем малополезное обогащение типов
Иначе
// Обогощаем присвоенными типами
ПроверятьТипЧерезЕсли = Ложь;
Если ЛиВиртПрисвоение Тогда
ИмяВиртПеременной = "ВиртВыражение294";
мРегВыражение.Pattern = ШаблонНазначенияТипаВыражению(ИмяВиртПеременной, ПроверятьТипЧерезЕсли);
ТекстДляПоискаОпределения = ИмяВиртПеременной + "=" + Выражение;
Вхождения = мРегВыражение.НайтиВхождения(ТекстДляПоискаОпределения);
Выражение = ИмяВиртПеременной;
Иначе
ШаблонПоиска = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(Выражение);
Если Истина
И ГлобальныйПоискВМодуле
И мМодульМетаданных <> Неопределено
И мМодульМетаданных.СтруктураТипа <> Неопределено
Тогда
Если мМодульМетаданных.СтруктураТипа.ИмяОбщегоТипа = "Форма" Тогда
ИмяСамоСвойствоКонтекста = "ЭтаФорма";
ИначеЕсли мМодульМетаданных.СтруктураТипа.ИмяОбщегоТипа = "ФормаКлиентскогоПриложения" Тогда
ИмяСамоСвойствоКонтекста = "(?:ЭтаФорма|ЭтотОбъект)";
Иначе
ИмяСамоСвойствоКонтекста = "ЭтотОбъект";
КонецЕсли;
ШаблонПоиска = "(?:" + ИмяСамоСвойствоКонтекста + "\.)?" + ШаблонПоиска;
КонецЕсли;
ПроверятьТипЧерезЕсли = Истина
И Не ГлобальныйПоискВМодуле
И Найти(Выражение, "(") = 0
И Не ЛиПеременнаяРезультата;
ШаблонПоиска = ШаблонНазначенияТипаВыражению(ШаблонПоиска, ПроверятьТипЧерезЕсли);
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле, ТекстДляПоискаОпределения);
КонецЕсли;
ЛиТипЧерезЕслиНазначен = Ложь;
Если Вхождения.Количество() > 0 Тогда
//СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураЕдинственногоТипа = Неопределено;
ИндексВхождения = Вхождения.Количество();
ЧислоПроверенныхВариантов = 0;
ЛиУстановкаЗначения = Ложь;
Пока ИндексВхождения > 0 Цикл
ИндексВхождения = ИндексВхождения - 1;
ПоследнееВхождение = Вхождения[ИндексВхождения];
Если Не ЛиВиртПрисвоение И ЛиВхождениеВЗапрешенномДиапазоне(ПоследнееВхождение, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Продолжить;
КонецЕсли;
ПозицияВхождения0 = ПоследнееВхождение.FirstIndex;
НачальнаяПозицияБлока = ЗагрузитьМетодМодуляПоПозицииИРазобратьКонтекст(ГлобальныйПоискВМодуле, ПозицияВхождения0);
ПозицияВхождения0 = ПозицияВхождения0 - 1 - НачальнаяПозицияБлока;
ПрисвоенныйТип = ПоследнееВхождение.SubMatches(23);
Если Истина
И ПрисвоенныйТип <> Неопределено
И Найти(ПрисвоенныйТип, "=") = 0
И Найти(ПрисвоенныйТип, ";") = 0
И Найти(ПрисвоенныйТип, """") = 0
Тогда
// Назначение типа в комментарии
ТекстДоВхождения = Сред(ТекстДляПоискаОпределения, НачальнаяПозицияБлока, ПозицияВхождения0); // МультиМетка8294218
ТаблицаТиповИзКомментария = ТаблицаТиповИзТекста(ирОбщий.ПервыйФрагментЛкс(ПрисвоенныйТип, "-"),, ТекстДоВхождения);
Если ТаблицаТиповИзКомментария.Количество() > 0 Тогда
//ТекстПослеВхождения = Сред(ТекстДляПоискаОпределения, ПозицияВхождения0, Позиция0ВМетодеДо - ПозицияВхождения0);
Если Истина
И ИндексВхождения = Вхождения.Количество() - 1
//И МожноПрименитьПрисвоениеТипаИзЕсли() // TODO Сделать проверку отсутствия далее открытого "Иначе", т.е. без "Если"
Тогда
СтруктураЕдинственногоТипа = ТаблицаТиповИзКомментария[0];
ДобавитьЕдинственныйТип(ТаблицаТипов, СтруктураЕдинственногоТипа);
Иначе
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИзКомментария);
КонецЕсли;
Если ЛиДетальностьТиповДостаточна(ТаблицаТипов, 4) Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭтоПрисвоение = Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(2));
Если ЭтоПрисвоение Тогда
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(3);
Если ЛиБесполезноеПрисвоениеПеременной(ПрисвоенныйКонтекст) Тогда
Если ЗначениеЗаполнено(ПрисвоенныйКонтекст) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.НоваяСтруктураТипа(ПрисвоенныйКонтекст));
КонецЕсли;
Продолжить;
КонецЕсли;
Если ирОбщий.СтрокиРавныЛкс(Выражение, ПрисвоенныйКонтекст) Тогда
// TODO описать когда такое случается
Продолжить;
КонецЕсли;
КонецЕсли;
Если ПроверятьТипЧерезЕсли Тогда
ПрисвоенныйТипЕсли = ПоследнееВхождение.SubMatches(24);
Если ПрисвоенныйТипЕсли <> Неопределено Тогда
Если Не ЛиТипЧерезЕслиНазначен Тогда
ПрименитьТип = МожноПрименитьПрисвоениеТипаИзЕсли(ТекстДляПоискаОпределения, Позиция0ВМетодеДо, ПоследнееВхождение, ПозицияВхождения0);
Если ПрименитьТип Тогда
Тип = Неопределено;
Если Найти(ПрисвоенныйТипЕсли, """") > 0 Тогда
ИмяТипа = ирОбщий.ТекстМеждуМаркерамиЛкс(ПрисвоенныйТипЕсли, """", """");
Попытка
Тип = Тип(ИмяТипа);
Исключение
КонецПопытки;
//Иначе
// Тип = ВычислитьЗначениеВыражения(ПрисвоенныйТипЕсли, ПредшествующийТекст,,, ПозицияВхождения0);
КонецЕсли;
Если ТипЗнч(Тип) = Тип("Тип") Тогда
СтруктураЕдинственногоТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип);
ДобавитьЕдинственныйТип(ТаблицаТипов, СтруктураЕдинственногоТипа);
КонецЕсли;
ЛиТипЧерезЕслиНазначен = Истина;
КонецЕсли;
КонецЕсли;
Продолжить;
КонецЕсли;
КонецЕсли;
ЛиУстановкаЗначения = Истина;
ЧислоПроверенныхВариантов = ЧислоПроверенныхВариантов + 1;
Если ЭтоПрисвоение Тогда
Если ЛиБулевыйЛитерал(ПрисвоенныйКонтекст) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.НоваяСтруктураТипа("Булево"));
Продолжить;
КонецЕсли;
СловоНовый = НРег(ПоследнееВхождение.SubMatches(4));
Если СловоНовый = Нрег("Новый") Или СловоНовый = Нрег("New") Тогда
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(5)) Тогда
ИмяТипа = ПоследнееВхождение.SubMatches(5);
ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(6)) Тогда
ИмяТипа = ПоследнееВхождение.SubMatches(6);
ИмяТипа = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ИмяТипа);
Иначе
ИмяТипа = Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяТипа) Тогда
Попытка
ТипНового = Тип(ИмяТипа);
Исключение
ТипНового = Неопределено;
СтруктураТипа.ИмяОбщегоТипа = ИмяТипа;
КонецПопытки;
Если Истина
И ТипНового = Тип("COMОбъект")
И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(6))
Тогда
ПолноеИмяОсновногоКлассаCOM = ПоследнееВхождение.SubMatches(6);
СтруктураКОМТипа = мИменаОбщихТиповПоИменамКлассовCOM[ПолноеИмяОсновногоКлассаCOM];
Если СтруктураКОМТипа = Неопределено Тогда
СтруктураКОМТипа = Новый Структура;
МетаданныеСлова = мПлатформа.ПолучитьОбразецCOMОбъектаолноеИмяОсновногоКлассаCOM); // При этом может открыться форма Automation-сервера например RegexBuddy так делает
Если МетаданныеСлова = Неопределено Тогда
ИмяОсновногоКлассаCOM = ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
ИмяОбщегоТипа = ИмяОсновногоКлассаCOM + " {" + ПолноеИмяОсновногоКлассаCOM + "}";
Иначе
ИмяОбщегоТипа = мПлатформа.ПолноеИмяТипаCOMОбъекта(МетаданныеСлова);
Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Тогда
ИмяОсновногоКлассаCOM = ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
ИмяОбщегоТипа = ИмяОсновногоКлассаCOM + " {" + ПолноеИмяОсновногоКлассаCOM + "}";
КонецЕсли;
СтруктураКОМТипа.Вставить("Метаданные", МетаданныеСлова);
КонецЕсли;
СтруктураКОМТипа.Вставить("ИмяОбщегоТипа", ИмяОбщегоТипа);
мИменаОбщихТиповПоИменамКлассовCOM[ПолноеИмяОсновногоКлассаCOM] = СтруктураКОМТипа;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтруктураКОМТипа);
ИначеЕсли ТипНового <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ТипНового, мЯзыкПрограммы);
Если Ложь
Или ТипНового = Тип("Запрос")
Или ТипНового = Тип("ПостроительЗапроса")
Тогда
ПервыйФактПараметр = ПоследнееВхождение.SubMatches(6);
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервыйФактПараметр) Тогда
ТекстПакета = ПервыйФактПараметр;
СтруктураТипа.ДержательМетаданных = НовыеКоординатыВыражения(ТекстПакета, ПоследнееВхождение.FirstIndex + Найти(ПоследнееВхождение.Value, """"));
ТекстПакета = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ТекстПакета);
СтруктураТипа.Метаданные = ПостроительЗапросаИзТекстаДляТипа(ТекстПакета);
КонецЕсли;
ИначеЕсли ТипНового = Тип("МенеджерВременныхТаблиц") Тогда
Если Истина
И ТаблицаТиповРодителя[0].ИмяОбщегоТипа = "Запрос"
И ТипЗнч(ТаблицаТиповРодителя[0].ДержательМетаданных) = Тип("Структура")
И ТаблицаТиповРодителя[0].ДержательМетаданных.Активен
И ирОбщий.СтрокиРавныЛкс(ТекущееСлово, "МенеджерВременныхТаблиц")
Тогда
// Опасно
Иначе
СтруктураТипа.Метаданные = НовыйМенеджерВременныхТаблиц(Истина);
СтруктураТипа.ДержательМетаданных = НовыеКоординатыВыражения(ПрисвоенныйКонтекст, ПоследнееВхождение.FirstIndex);
КонецЕсли;
ИначеЕсли ТипНового = Тип("ОписаниеТипов") Тогда
ПервыйФактПараметр = ПоследнееВхождение.SubMatches(6);
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервыйФактПараметр) Тогда
ИменаТипов = ВычислитьЗначениеВыражения(ПервыйФактПараметр,,, Позиция0ВМетодеОт, ПоследнееВхождение.FirstIndex);
Если ЗначениеЗаполнено(ИменаТипов) Тогда
Попытка
СтруктураТипа.Метаданные = Новый ОписаниеТипов(ИменаТипов);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипНового = Тип("Структура")
Или ТипНового = Тип("ФиксированнаяСтруктура")
Тогда
// TODO добавить разбор шИмяСточками
ПервыйФактПараметр = ПоследнееВхождение.SubMatches(6);
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервыйФактПараметр) Тогда
ИменаСвойств = ВычислитьЗначениеВыражения(ПервыйФактПараметр,,, Позиция0ВМетодеОт, ПоследнееВхождение.FirstIndex);
Если ЗначениеЗаполнено(ИменаСвойств) Тогда
Попытка
СтруктураТипа.Метаданные = Новый Структура(ИменаСвойств);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Иначе //Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(8)) Тогда ;
ПредСлово = ПоследнееВхождение.SubMatches(0);
Если Ложь
Или ПредСлово = "И"
Или ПредСлово = "Если"
Или ПредСлово = "ИначеЕсли"
Тогда
ЛиУстановкаЗначения = Ложь;
Если ПроверятьТипЧерезЕсли Тогда
ПрименитьТип = МожноПрименитьПрисвоениеТипаИзЕсли(ТекстДляПоискаОпределения, Позиция0ВМетодеДо, ПоследнееВхождение, ПозицияВхождения0);
Иначе
ПрименитьТип = Ложь;
КонецЕсли;
Иначе
ПрименитьТип = Истина;
КонецЕсли;
Если ПрименитьТип Тогда
Если ВычислитьЗначение И Лев(ПрисвоенныйКонтекст, 1) = """" Тогда
СмещениеПозиции = Найти(ПоследнееВхождение.Value, Лев(ПрисвоенныйКонтекст, 10));
Иначе
// Для ускороения
СмещениеПозиции = 0;
КонецЕсли;
МассивСтруктурПрисвоенныхТипов = ВычислитьТипЗначенияВыражения(ПрисвоенныйКонтекст,,,,, ПолныйАнализСоставаТипов, Ложь,,, ВычислитьЗначение,, ПозицияВхождения0 + СмещениеПозиции);
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, МассивСтруктурПрисвоенныхТипов);
КонецЕсли;
КонецЕсли;
Иначе
// Это обход коллекции
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(17);
ТаблицаТиповКоллекции = ВычислитьТипЗначенияВыражения(ПрисвоенныйКонтекст,,,,, ПолныйАнализСоставаТипов, Ложь,,,,, ПозицияВхождения0);
Для Каждого СтруктураТипаЭлемента Из ТаблицаТиповКоллекции Цикл
Если ЗначениеЗаполнено(СтруктураТипаЭлемента.ИмяОбщегоТипа) Тогда
ЛиУстановкаЗначения = Истина;
МассивСтруктурПрисвоенныхТипов = мПлатформа.СловаКонтекстаМетаданные(СтруктураТипаЭлемента, "[0]",,, мЯзыкПрограммы, "0",,, мФлагиКомпиляции)[0].ТаблицаТипов;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, МассивСтруктурПрисвоенныхТипов);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Ложь
Или ЧислоПроверенныхВариантов >= 3 // Проверяем не более 3-х назначений типа для ускорения
Или Истина
//И Не ГлобальныйПоискВМодуле // Отключил, т.к. очень долго обходить все присвоения в большом модуле
И ЛиДетальностьТиповДостаточна(ТаблицаТипов, 4) // если делать меньше 3, то будет давать артефакты частичное обновление модуля, т.к. там не очищаем колонку ТипЗначения
Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если ЛиУстановкаЗначения Тогда
Позиция0ВМетодеОт = ПозицияВхождения0;
КонецЕсли;
//Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
// ТаблицаСтруктурРодителей = ТаблицаТипов;
// ТаблицаТипов = мПлатформа.НоваяТаблицаТипов();
//КонецЕсли;
Если ТаблицаТипов.Количество() > 0 Тогда
Если СтруктураЕдинственногоТипа <> Неопределено И ТаблицаТипов.Количество() > 1 Тогда
ДобавитьЕдинственныйТип(ТаблицаТипов, СтруктураЕдинственногоТипа);
КонецЕсли;
СтруктураТипа = ТаблицаТипов[0];
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ТипСлова = "Свойство"
И Не СтруктураТипа.Конструктор
Тогда
Если ЛиПеременнаяРезультата Тогда
ЛиВиртПрисвоение = Истина;
КонецЕсли;
Если Ложь
Или ЗначениеЗаполнено(Позиция0ВМетодеОт)
Или ЗначениеЗаполнено(Позиция0ВМетодеДо)
Тогда
ТекстДляПоискаОпределения = ДиапазонТекстаДляПоиска(ТекстДляПоискаОпределения, Позиция0ВМетодеОт, Позиция0ВМетодеДо);
КонецЕсли;
Для Каждого СтруктураТипаЦикл Из ТаблицаТипов Цикл
Если Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Структура"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ФиксированнаяСтруктура"
Тогда
СобратьТипыСвойствСтруктуры(Выражение, СтруктураТипаЦикл.Метаданные, ГлобальныйПоискВМодуле, ЛиВиртПрисвоение, Позиция0ВМетодеОт, Позиция0ВМетодеДо);
мПлатформа.ОбновитьДетальностьСтруктурыТипа(СтруктураТипаЦикл);
КонецЕсли;
Если ЛиВиртПрисвоение Тогда
Продолжить;
КонецЕсли;
Если Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Массив"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ФиксированныйМассив"
Тогда
ШаблонПоиска = шПредИмя + Выражение + "\s*\.\s*Добавить\s*\(\s*(.*?)\s*\)";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле);
ИменаТиповЭлементов = Новый СписокЗначений;
МаксЭлементов = 3;
Счетчик = 1;
Для Каждого ВхождениеСвойства Из Вхождения Цикл
Если Счетчик > МаксЭлементов Тогда
Прервать;
КонецЕсли;
Если ЛиВхождениеВЗапрешенномДиапазоне(ВхождениеСвойства, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, ВхождениеСвойства);
ТаблицаТиповЭлементов = ВычислитьТипЗначенияВыражения(ВхождениеСвойства.SubMatches(0),,,,
ЭтоВызовКонструктора, ПолныйАнализСоставаТипов, Ложь, ГлобальныйПоискВМодуле,,,, ВхождениеСвойства.FirstIndex);
Для Каждого СтруктураТипаЭлемента Из ТаблицаТиповЭлементов Цикл
ИмяТипаЭлемента = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаЭлемента);
Если ИмяТипаЭлемента <> "?" И ИменаТиповЭлементов.НайтиПоЗначению(ИмяТипаЭлемента) = Неопределено Тогда
ИменаТиповЭлементов.Добавить(ИмяТипаЭлемента);
КонецЕсли;
Если СтруктураТипаЭлемента.Детальность > 3 Тогда
СтруктураТипаЦикл.Метаданные = СтруктураТипаЭлемента.Метаданные;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ИменаТиповЭлементов.Количество() > 0 Тогда
ИменаТиповЭлементов.СортироватьПоЗначению();
СтруктураТипаЦикл.ИмяОбщегоТипа = СтруктураТипаЦикл.ИмяОбщегоТипа + "[" + ирОбщий.СтрСоединитьЛкс(ИменаТиповЭлементов.ВыгрузитьЗначения()) + "]";
КонецЕсли;
мПлатформа.ОбновитьДетальностьСтруктурыТипа(СтруктураТипаЦикл);
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ТаблицаЗначений"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ДеревоЗначений"
Тогда
МетаданныеТаблицы = СтруктураТипаЦикл.Метаданные;
Если Истина
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ДеревоЗначений")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ТаблицаЗначений")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("Структура")
Тогда
МетаданныеТаблицы = Новый ТаблицаЗначений;
КонецЕсли;
ШаблонПоиска = шПредИмя + Выражение + "\s*\.\s*Колонки\s*.\s*(?:Добавить\s*\(\s*|Вставить\s*\((?:" + шИмя + "|\d+),\s*)"
+ "(" + шСтрокаПрограммы + "|" + шИмяСТочками + ")\s*(?:,\s*" + шПростоеВыражениеПрограммы + "|,|\))";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле);
Для Каждого ВхождениеСвойства Из Вхождения Цикл
Если ЛиВхождениеВЗапрешенномДиапазоне(ВхождениеСвойства, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Прервать;
КонецЕсли;
ПрисвоенноеВыражение = ВхождениеСвойства.SubMatches(0);
Если Лев(ПрисвоенноеВыражение, 1) = """" Тогда
ТекстовоеЗначение = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ПрисвоенноеВыражение);
Иначе
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, ВхождениеСвойства);
ТекстовоеЗначение = ВычислитьЗначениеВыражения(ПрисвоенноеВыражение,,, Позиция0ВМетодеОт, ВхождениеСвойства.FirstIndex);
КонецЕсли;
Если ЗначениеЗаполнено(ТекстовоеЗначение) Тогда
ОписаниеТипов = ВычислитьЗначениеВыражения(ВхождениеСвойства.SubMatches(1),,, Позиция0ВМетодеОт, ВхождениеСвойства.FirstIndex);
Если Не ЗначениеЗаполнено(ОписаниеТипов) Тогда
ОписаниеТипов = Неопределено;
КонецЕсли;
Попытка
МетаданныеТаблицы.Колонки.Добавить(ТекстовоеЗначение, ОписаниеТипов);
Исключение
Если ОписаниеТипов = Неопределено Тогда
ТаблицаТиповКолонки = Неопределено;
Иначе
ТаблицаТиповКолонки = мПлатформа.ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
КонецЕсли;
Попытка
МетаданныеТаблицы.Вставить(ТекстовоеЗначение, ТаблицаТиповКолонки);
Исключение
Пустышка = 0;
КонецПопытки;
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если Истина
И ТипЗнч(МетаданныеТаблицы) = Тип("ТаблицаЗначений")
И МетаданныеТаблицы.Колонки.Количество() > 0
Тогда
СтруктураТипаЦикл.Метаданные = МетаданныеТаблицы;
КонецЕсли;
мПлатформа.ОбновитьДетальностьСтруктурыТипа(СтруктураТипаЦикл);
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Запрос"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительЗапроса"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительОтчета"
Тогда
Если ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ПостроительЗапроса") Тогда
СтруктураТипаЦикл.Метаданные = Новый ПостроительЗапроса;;
КонецЕсли;
Если ТипЗнч(СтруктураТипаЦикл.ДержательМетаданных) <> Тип("Структура") Тогда
СтруктураТипаЦикл.ДержательМетаданных = НовыйМенеджерВременныхТаблиц();
КонецЕсли;
ПостроительЗапроса = СтруктураТипаЦикл.Метаданные;
МенеджерВременныхТаблиц = СтруктураТипаЦикл.ДержательМетаданных;
Если СтруктураТипаЦикл.ИмяОбщегоТипа = "Запрос" Тогда
ЛиНовыйКэшаВыражений = ирОбщий.СтрокиРавныЛкс(ДляСвойства, "МенеджерВременныхТаблиц");
ТаблицаТиповМенеджера = ВычислитьТипЗначенияВыражения(Выражение + ".МенеджерВременныхТаблиц",,,,,, ЛиНовыйКэшаВыражений, ГлобальныйПоискВМодуле,, Истина, Позиция0ВМетодеОт,
Позиция0ВМетодеДо, "МенеджерВременныхТаблиц");
ЛучшийТип = Неопределено; // см. мПлатформа.НоваяСтруктураТипа()
Если ЛиДетальностьТиповДостаточна(ТаблицаТиповМенеджера, 2, ЛучшийТип) Тогда
Если ТипЗнч(ЛучшийТип.Метаданные) = Тип("Структура") Тогда
МенеджерВременныхТаблиц = ЛучшийТип.Метаданные;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ПозицияПоискаТекстаДо = Позиция0ВМетодеДо;
ПозицияПоискаТекстаОт = Позиция0ВМетодеОт; // TODO сдвинуть вперед до позиции найденной установки менеджера
НачальныйИндекс = МенеджерВременныхТаблиц.ПакетыЗапросов.Количество();
ТекстВЭтомБлокеУстановлен = Ложь;
Пока Истина Цикл
КоординатыТекста = Новый Структура; // см. НовыеКоординатыВыражения()
ТекстПакета = ВычислитьЗначениеВыражения(Выражение + ".Текст", ТекстДляПоискаОпределения, ГлобальныйПоискВМодуле, ПозицияПоискаТекстаОт, ПозицияПоискаТекстаДо, КоординатыТекста);
Если ЗначениеЗаполнено(ТекстПакета) Тогда
ПакетЗапросов = НовыйПакетЗапросов(КоординатыТекста.Выражение, КоординатыТекста);
МенеджерВременныхТаблиц.ПакетыЗапросов.Вставить(НачальныйИндекс, ПакетЗапросов);
Если Не ТекстВЭтомБлокеУстановлен Тогда
ПостроительЗапросаИзТекстаДляТипа(ТекстПакета, ПостроительЗапроса);
ирОбщий.СкопироватьКоллекциюЛкс(СобратьТипыСвойствСтруктуры(Выражение + ".Параметры",,,, ПозицияПоискаТекстаОт, ПозицияПоискаТекстаДо), ПостроительЗапроса.Параметры);
ИмяКолонкиФлагаВнутриТаблицы = мПлатформа.ИмяКолонкиФлагаВнутриТаблицы();
Для Каждого КлючИЗначение Из ПостроительЗапроса.Параметры Цикл
ЗначениеПараметра = КлючИЗначение.Значение;
Если Истина
И ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений")
И ЗначениеПараметра.Колонки.Найти(ИмяКолонкиФлагаВнутриТаблицы) <> Неопределено
Тогда
Если ЗначениеПараметра.Количество() > 0 Тогда
ЗначениеПараметра = ЗначениеПараметра[0].Метаданные;
Иначе
ЗначениеПараметра = Неопределено;
КонецЕсли;
КонецЕсли;
ПакетЗапросов.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеПараметра);
КонецЦикла;
ТекстВЭтомБлокеУстановлен = Истина;
КонецЕсли;
КонецЕсли;
Если ТекстПакета = Неопределено Или Не МенеджерВременныхТаблиц.Активен Тогда
Прервать;
КонецЕсли;
ПозицияПоискаТекстаДо = КоординатыТекста.Позиция0ВБлоке;
КонецЦикла;
Если МенеджерВременныхТаблиц.ПакетыЗапросов.Количество() > 0 Тогда
СтруктураТипаЦикл.ДержательМетаданных = МенеджерВременныхТаблиц;
КонецЕсли;
мПлатформа.ОбновитьДетальностьСтруктурыТипа(СтруктураТипаЦикл);
ИначеЕсли СтруктураТипаЦикл.ИмяОбщегоТипа = "МенеджерВременныхТаблиц" Тогда
ШаблонПоиска = шПредИмя + Выражение + "\s*\.\s*докДобавить\(\s*(" + шПростоеВыражениеПрограммы + ")\s*\)";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле);
Для Каждого ВхождениеСвойства Из Вхождения Цикл
Если ЛиВхождениеВЗапрешенномДиапазоне(ВхождениеСвойства, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Прервать;
КонецЕсли;
ПрисвоенноеВыражение = ВхождениеСвойства.SubMatches(0);
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, ВхождениеСвойства);
ТаблицаТиповМенеджера = ВычислитьТипЗначенияВыражения(ПрисвоенноеВыражение,,,,,,,,,, Позиция0ВМетодеОт, ВхождениеСвойства.FirstIndex);
Если ТаблицаТиповМенеджера.Количество() > 0 Тогда
ДобавляемыйМенеджер = ТаблицаТиповМенеджера[0].Метаданные;
Если ТипЗнч(ДобавляемыйМенеджер) = Тип("Структура") Тогда
Если ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("Структура") Тогда
СтруктураТипаЦикл.Метаданные = НовыйМенеджерВременныхТаблиц();
КонецЕсли;
МенеджерВременныхТаблиц = СтруктураТипаЦикл.Метаданные;
ирОбщий.ДополнитьМассивЛкс(МенеджерВременныхТаблиц.ПакетыЗапросов, ДобавляемыйМенеджер.ПакетыЗапросов);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мПлатформа.ОбновитьДетальностьСтруктурыТипа(СтруктураТипаЦикл);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Истина
И мЯзыкПрограммы = 1
И РодительскийКонтекст = ""
И СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
И МассивСтруктурПрисвоенныхТипов = Неопределено
Тогда
Если Истина
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
И КонтекстВыполнения.МенеджерВременныхТаблиц <> Неопределено
И Лев(ТекущееСлово, 1) <> "&"
Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ТекущееСлово + " ГДЕ ЛОЖЬ";
Попытка
// Активное вычисление!
СтруктураТипа.Метаданные = ВременныйЗапрос.Выполнить();
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
СтруктураТипа.ВиртуальнаяТаблица.Выражение = ТекущееСлово; // Используем не по назначению
Исключение
КонецПопытки;
Иначе
СтрокаДоступнойТаблицы = НайтиДобавитьДоступнуюВременнуюТаблицу(ТекущееСлово);
ТаблицаДоступныхПолей = ПоляДоступнойТаблицы(СтрокаДоступнойТаблицы);
Если ТаблицаДоступныхПолей.Колонки.Найти("Заголовок") = Неопределено Тогда
ТаблицаДоступныхПолей.Колонки.Добавить("Заголовок");
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
СтруктураТипа.Метаданные = ирОбщий.УстановитьМетаданныеКоллекцииЛкс(ТаблицаДоступныхПолей);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(КлючВыраженияСПозицией) Тогда
ТипыВыраженийМетода.Вставить(КлючВыраженияСПозицией, ТаблицаТипов);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
~Возврат:
Если ЛиКорневойВызов Тогда
мРекурсивныйПуть = Неопределено;
Если мМетодМодуля <> Неопределено И мМетодМодуля.КлючевыеПараметры <> Неопределено Тогда
мМетодМодуля.КлючевыеПараметры = Новый Структура(ирОбщий.СтрСоединитьЛкс(ирОбщий.ВыгрузитьСвойствоЛкс(мМетодМодуля.КлючевыеПараметры)));
КонецЕсли;
Если ТаблицаТипов.Количество() > 1 Тогда
ТаблицаТипов.Сортировать("Детальность Убыв");
КонецЕсли;
КонецЕсли;
Если ГлобальныйПоискВМодуле Тогда
ЗагрузитьМетодМодуля(СтарыйМетод);
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
//.
// Возвращаемое значение:
// Структура -
Функция НовыйМенеджерВременныхТаблиц(Знач Активен = Ложь) Экспорт
МенеджерВременныхТаблиц = Новый Структура("Тип,ПакетыЗапросов,Активен");
МенеджерВременныхТаблиц.Тип = Тип("МенеджерВременныхТаблиц");
МенеджерВременныхТаблиц.ПакетыЗапросов = Новый Массив;
МенеджерВременныхТаблиц.Активен = Активен;
Возврат МенеджерВременныхТаблиц;
КонецФункции
//.
// Параметры:
// Выражение - Строка(0) -
// ДопКлючКэша - Строка, Неопределено -
Процедура ИнициироватьРекурсивныйПуть(Знач Выражение = "", Знач ДопКлючКэша = "") Экспорт
мРекурсивныйПуть = Новый Структура;
мРекурсивныйПуть.Вставить("ДобавлятьКлючевыеПараметры", Ложь);
мРекурсивныйПуть.Вставить("ДопКлючКэша", ДопКлючКэша);
мРекурсивныйПуть.Вставить("ВходящиеВызовы", Новый Соответствие);
мРекурсивныйПуть.Вставить("ТипыВыраженийПрограммы", Новый Соответствие);
мРекурсивныйПуть.Вставить("Позиции", Новый Массив);
мРекурсивныйПуть.Вставить("СчетчикиВызовов", Новый Соответствие);
Если Выражение = мПлатформа.ИмяПеременнойВозвращаемогоЗначения() И мМетодМодуля <> Неопределено Тогда
ВычислениеРезультатаМетода = мМетодМодуля.Имя;
Иначе
ВычислениеРезультатаМетода = Неопределено;
КонецЕсли;
мРекурсивныйПуть.Вставить("ВычислениеРезультатаМетода", ВычислениеРезультатаМетода);
КонецПроцедуры
//.
// Параметры:
// Выражение - Строка(0) -
// Позиция0ВМетодеДо - Число -
// Возвращаемое значение:
// Структура -
Функция НовыеКоординатыВыражения(Знач Выражение, Знач Позиция0ВМетодеДо) Экспорт
СтруктураСтрокиМодуля = Новый Структура;
СтруктураСтрокиМодуля.Вставить("Тип", "КоординатыВыражения");
СтруктураСтрокиМодуля.Вставить("Метод", мМетодМодуля);
СтруктураСтрокиМодуля.Вставить("Модуль", мМодульМетаданных);
СтруктураСтрокиМодуля.Вставить("Позиция0ВБлоке", Позиция0ВМетодеДо);
СтруктураСтрокиМодуля.Вставить("ДлинаТекста", СтрДлина(Выражение));
СтруктураСтрокиМодуля.Вставить("Выражение", Выражение);
Возврат СтруктураСтрокиМодуля;
КонецФункции
//.
// Параметры:
// ТаблицаТипов - ТаблицаЗначений -
// СтруктураТипа - Структура -
Процедура ДобавитьЕдинственныйТип(Знач ТаблицаТипов, Знач СтруктураТипа) Экспорт
Если ТаблицаТипов.Количество() > 0 Тогда
ОтборТипов = Новый Структура("Метаданные, ИмяОбщегоТипа");
ЗаполнитьЗначенияСвойств(ОтборТипов, СтруктураТипа);
НайденныйТип = ТаблицаТипов.НайтиСтроки(ОтборТипов);
Если НайденныйТип.Количество() > 0 Тогда
// Сужаем тип, сохраняя квалификаторы и описание слова
НайденныйТип = НайденныйТип[0];
Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход
СтрокаТипа = ТаблицаТипов[-Индекс];
Если СтрокаТипа <> НайденныйТип Тогда
ТаблицаТипов.Удалить(СтрокаТипа);
КонецЕсли;
КонецЦикла;
Иначе
ТаблицаТипов.Очистить();
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// ТекстДляПоискаОпределения - , ПолеТекстовогоДокумента, ПолеФормы, Строка -
// Позиция0ВМетодеДо - Число -
// ПоследнееВхождение - ОбработкаОбъект.ирОболочкаРегВхождение, РезультатПоискаПоРегулярномуВыражению -
// ПозицияВхождения0 - Число(10,0) -
// Возвращаемое значение:
// Булево -
Функция МожноПрименитьПрисвоениеТипаИзЕсли(Знач ТекстДляПоискаОпределения, Знач Позиция0ВМетодеДо, Знач ПоследнееВхождение, Знач ПозицияВхождения0)
ПрименитьТип = Ложь;
НачальнаяПозицияЕсли = ПозицияВхождения0 + ПоследнееВхождение.Length;
ТекстПоискаЕсли = Сред(ТекстДляПоискаОпределения, НачальнаяПозицияЕсли + 1, Позиция0ВМетодеДо - НачальнаяПозицияЕсли);
ПозицияЕсли = Найти(ТекстПоискаЕсли, "Если ");
Если ПозицияЕсли = 0 Тогда
ТекстПоискаТогда = ТекстПоискаЕсли;
Иначе
ТекстПоискаТогда = Лев(ТекстПоискаЕсли, ПозицияЕсли);
КонецЕсли;
ПозицияТогда = Найти(ТекстПоискаТогда, "Тогда");
Если ПозицияТогда > 0 Тогда
ПозицияИначе = Найти(ТекстПоискаЕсли, "Иначе");
// Криво работает в случае когда "иначе" идет после "КонецЕсли". TODO искать только до первого "Если" и после последнего "КонецЕсли"
//Если Найти(Лев(ТекстПоискаЕсли, ПозицияИначе), "Если ") > 0 Тогда
// ПозицияИначе = 0;
//КонецЕсли;
Если ПозицияИначе = 0 Тогда
ЧислоЕсли = СтрЧислоВхождений(ТекстПоискаЕсли, "Если ");
ЧислоКонецЕсли = СтрЧислоВхождений(ТекстПоискаЕсли, "КонецЕсли");
Если ЧислоЕсли >= ЧислоКонецЕсли Тогда
ПрименитьТип = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПрименитьТип;
КонецФункции
//.
// Параметры:
// ТекстЗапроса - Строка -
// Возвращаемое значение:
// ПостроительЗапроса -
Функция ПостроительЗапросаИзТекстаДляТипа(Знач ТекстЗапроса, Знач ПостроительЗапроса = Неопределено) Экспорт
Если ПостроительЗапроса = Неопределено Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
КонецЕсли;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
Исключение
// Даже если текст некорректный, он сохраняется в свойстве
КонецПопытки;
ПараметрыИзТекстаЗапроса(ТекстЗапроса, Истина, ПостроительЗапроса.Параметры);
Возврат ПостроительЗапроса;
КонецФункции
Функция ЛиВхождениеВЗапрешенномДиапазоне(Знач ПоследнееВхождение, Знач ПозицияВМетодеОт = 0, Знач ПозицияВМетодеДо = 0)
Результат = Ложь
Или ПозицияВМетодеОт > 0 И ПоследнееВхождение.FirstIndex < ПозицияВМетодеОт
Или ПозицияВМетодеДо > 0 И ПоследнееВхождение.FirstIndex + ПоследнееВхождение.Length > ПозицияВМетодеДо + 2;
Возврат Результат;
КонецФункции
Функция ДиапазонТекстаДляПоиска(Знач ТекстДляПоискаОпределения = "", Знач ПозицияВМетодеОт = 0, Знач ПозицияВМетодеДо = 0)
Длина = ПозицияВМетодеДо - ПозицияВМетодеОт;
Если Длина = 0 Тогда
Длина = 1000000;
КонецЕсли;
ТекстДляПоискаОпределения = Сред(ТекстДляПоискаОпределения, ПозицияВМетодеОт, Длина);
Возврат ТекстДляПоискаОпределения;
КонецФункции
// .
// Параметры:
// ШаблонПоиска - Строка -
// ГлобальныйПоискВМодуле - Булево -
// выхТекстДляПоискаОпределения - Строка - только выход
// Возвращаемое значение:
// Массив - [ОбработкаОбъект.ирОболочкаРегВхождение, РезультатПоискаПоРегулярномуВыражению]
Функция НайтиВхожденияРегВыраженияКэш(Знач ШаблонПоиска, Знач ГлобальныйПоискВМодуле = Ложь, выхТекстДляПоискаОпределения = "")
Вхождения = Неопределено;
Если ГлобальныйПоискВМодуле Тогда
выхТекстДляПоискаОпределения = мОригинальныйТекст;
Иначе
выхТекстДляПоискаОпределения = мТекстБлока;
КонецЕсли;
Если Истина
И мМетодМодуля <> Неопределено
И Не ГлобальныйПоискВМодуле
Тогда
КэшПоиска = мМетодМодуля.КэшПоиска;
Если КэшПоиска = Неопределено Тогда
КэшПоиска = Новый Соответствие;
мМетодМодуля.КэшПоиска = КэшПоиска;
КонецЕсли;
КлючКэшаПоиска = НРег(Лев(ШаблонПоиска, 200));
Вхождения = КэшПоиска[КлючКэшаПоиска];
КонецЕсли;
Если Вхождения = Неопределено Тогда
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = ШаблонПоиска;
Вхождения = мРегВыражение.НайтиВхождения(выхТекстДляПоискаОпределения);
Если КлючКэшаПоиска <> Неопределено Тогда
КэшПоиска[КлючКэшаПоиска] = Вхождения;
КонецЕсли;
КонецЕсли;
Возврат Вхождения;
КонецФункции
Функция ЗагрузитьМетодМодуляПоПозицииИРазобратьКонтекст(Знач ГлобальныйПоискВМодуле, Знач Позиция0) Экспорт
Если Не ГлобальныйПоискВМодуле Тогда
// В рамках текущего метода
НачальнаяПозицияБлока = 0;
Иначе
Позиция1 = Позиция0 + 1;
Если ЗагрузитьМетодМодуляПоПозиции(Позиция1) Тогда
// Для ускорения отключил
//СлужебноеПолеТекстаДолгое.УстановитьГраницыВыделения(Позиция1, Позиция1);
//НачальнаяСтрока = 0;
//НачальнаяКолонка = 0;
//СлужебноеПолеТекстаДолгое.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка,,);
//КончитьОбработкуКоманды();
//РазобратьТекущийКонтекст(,,, НачальнаяСтрока, НачальнаяКолонка,, Позиция1);
КонецЕсли;
НачальнаяПозицияБлока = мПозицияТекстаДляПоискаОпределения;
КонецЕсли;
Возврат НачальнаяПозицияБлока;
КонецФункции
Функция ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(Знач ГлобальныйПоискВМодуле, Знач Вхождение, Знач ТекстДляПоискаОпределения = "")
НачальнаяПозицияБлока = ЗагрузитьМетодМодуляПоПозицииИРазобратьКонтекст(ГлобальныйПоискВМодуле, Вхождение.FirstIndex);
ТекстДоВхождения = Сред(ТекстДляПоискаОпределения, НачальнаяПозицияБлока, Вхождение.FirstIndex - 1 - НачальнаяПозицияБлока); // МультиМетка8294218
Возврат ТекстДоВхождения;
КонецФункции
//.
// Параметры:
// Выражение - Строка -
// Структура - Структура -
// ТекстДляЗаполненияМетаданных - Строка -
// ТекстДляПоискаОпределения - Строка -
// ПредшествующийТекст - Строка -
Функция СобратьТипыСвойствСтруктуры(Знач Выражение, Структура = Неопределено, Знач ГлобальныйПоискВМодуле = Ложь, Знач ТолькоПрисвоение = Ложь, Знач Позиция0ВМетодеОт = 0, Знач Позиция0ВМетодеДо = 0)
НашлиСоздание = Ложь;
//ШаблонПоиска = шПредИмя + Выражение + "\s*=\s*Новый\s+Структура\s*\(\s*(" + шСтрокаПрограммы + "|" + шИмяСТочками + ")"; // Теперь шСтрокаПрограммы разбираем сразу
ШаблонПоиска = шПредИмя + Выражение + "\s*=\s*Новый\s+Структура\s*\(\s*(" + шИмяСТочками + ")";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле);
ИндексВхождения = Вхождения.Количество();
Пока ИндексВхождения > 0 Цикл
ИндексВхождения = ИндексВхождения - 1;
ПоследнееВхождение = Вхождения[ИндексВхождения];
Если ЛиВхождениеВЗапрешенномДиапазоне(ПоследнееВхождение, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Продолжить;
КонецЕсли;
НашлиСоздание = Истина;
ПрисвоенноеВыражение = ПоследнееВхождение.SubMatches(0);
Если Лев(ПрисвоенноеВыражение, 1) = """" Тогда
ТекстовоеЗначение = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ПрисвоенноеВыражение);
Иначе
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, ПоследнееВхождение);
ТекстовоеЗначение = ВычислитьЗначениеВыражения(ПрисвоенноеВыражение,,, Позиция0ВМетодеОт, ПоследнееВхождение.FirstIndex);
КонецЕсли;
Структура = Новый Структура;
Если ЗначениеЗаполнено(ТекстовоеЗначение) Тогда
Попытка
Структура = Новый Структура(ТекстовоеЗначение);
Исключение
КонецПопытки;
КонецЕсли;
Прервать;
КонецЦикла;
Если Истина
И Не НашлиСоздание
И ТипЗнч(Структура) <> Тип("Структура")
И ТипЗнч(Структура) <> Тип("ФиксированнаяСтруктура")
Тогда
Если ТипЗнч(Структура) = Тип("ПостроительЗапроса") Тогда
Структура = ПараметрыИзТекстаЗапроса(Структура.Текст, Истина);
Иначе
Структура = Новый Структура;
КонецЕсли;
КонецЕсли;
Если ТолькоПрисвоение Тогда
Возврат Структура;
КонецЕсли;
МинДетальность = 4;
ШаблонПоиска = шПредИмя + Выражение + "\s*\.\s*Вставить\s*\(\s*(" + шСтрокаПрограммы + "|" + шИмяСТочками + ")(?:\s*,\s*((?:" + шСтрокаПрограммы + "|" + шНачалоСкобок + "|[^\)""])*))?";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска, ГлобальныйПоискВМодуле);
ПозицииВыражений = Новый Структура;
Для Каждого Вхождение Из Вхождения Цикл
Если ЛиВхождениеВЗапрешенномДиапазоне(Вхождение, Позиция0ВМетодеОт, Позиция0ВМетодеДо) Тогда
Продолжить;
КонецЕсли;
ВыражениеИмени = Вхождение.SubMatches(0);
Если Лев(ВыражениеИмени, 1) = """" Тогда
ТекстовоеЗначение = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ВыражениеИмени);
Иначе
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, Вхождение);
ТекстовоеЗначение = ВычислитьЗначениеВыражения(ВыражениеИмени,,, Вхождение.FirstIndex);
КонецЕсли;
Если ирОбщий.ЛиИмяПеременнойЛкс(ТекстовоеЗначение) Тогда
ВыражениеЗначения = Вхождение.SubMatches(1);
ТаблицаТиповЗначения = Неопределено;
ЗагрузитьМетодМодуляПоВхождениюИРазобратьКонтекст(ГлобальныйПоискВМодуле, Вхождение);
Если ЛиБулевыйЛитерал(ВыражениеЗначения) Тогда
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТиповЗначения, мПлатформа.НоваяСтруктураТипа("Булево"));
ИначеЕсли ВыражениеЗначения <> Неопределено Тогда
ТаблицаТиповЗначения = ВычислитьТипЗначенияВыражения(ВыражениеЗначения,,,,,, Ложь,,,,, Вхождение.FirstIndex);
Если ТаблицаТиповЗначения.Количество() = 0 Тогда
ТаблицаТиповЗначения = Неопределено; // Пустые таблицы запрещены, т.к. проверка пустоты участвует в разделении таблицы-значения и таблицы типов значения
КонецЕсли;
КонецЕсли;
Структура.Вставить(ТекстовоеЗначение, ТаблицаТиповЗначения);
ПозицииВыражений.Вставить(ТекстовоеЗначение, Вхождение.FirstIndex);
КонецЕсли;
КонецЦикла;
Если Истина
И Не ГлобальныйПоискВМодуле // Для сокращения редко полезных затратных вычислений
И Структура.Количество() > 0
Тогда
ШаблонПоиска = шПредИмя + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(Выражение + ".") + "(" + шИмя + ")(?![\(\d" + шБуква + "])";
Вхождения = НайтиВхожденияРегВыраженияКэш(ШаблонПоиска);
Если Вхождения.Количество() > 0 Тогда
СвойстваЧерезТочкуИзТекста = Новый Структура;
Для Каждого Вхождение Из Вхождения Цикл
СвойстваЧерезТочкуИзТекста.Вставить(Вхождение.SubMatches(0));
КонецЦикла;
ЗначениеСвойства = Неопределено;
Для Каждого КлючИЗначение Из СвойстваЧерезТочкуИзТекста Цикл
Если Не Структура.Свойство(КлючИЗначение.Ключ, ЗначениеСвойства) Тогда
Продолжить;
КонецЕсли;
Если Истина
И ЗначениеСвойства <> Неопределено
И ТипЗнч(ЗначениеСвойства) <> Тип("ТаблицаЗначений")
Тогда
Продолжить;
КонецЕсли;
ВыражениеЗначения = Выражение + "." + КлючИЗначение.Ключ;
ПозицияВМетодеОт = 0;
ПозицииВыражений.Свойство(КлючИЗначение.Ключ, ПозицияВМетодеОт);
Если ПозицияВМетодеОт = Неопределено Тогда
ПозицияВМетодеОт = 0;
КонецЕсли;
ТаблицаТиповЗначения = ВычислитьТипЗначенияВыражения(ВыражениеЗначения,,,,,, Ложь, ГлобальныйПоискВМодуле, Истина,, ПозицияВМетодеОт, Позиция0ВМетодеДо);
Если ТаблицаТиповЗначения.Количество() = 0 Тогда
// Пустые таблицы запрещены, т.к. проверка пустоты участвует в разделении таблицы-значения и таблицы типов значения
Продолжить;
КонецЕсли;
Если Структура[КлючИЗначение.Ключ] = Неопределено Тогда
Структура[КлючИЗначение.Ключ] = ТаблицаТиповЗначения;
Иначе
мПлатформа.ДобавитьВТаблицуТипов(Структура[КлючИЗначение.Ключ], ТаблицаТиповЗначения);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Структура;
КонецФункции
//.
// Параметры:
// Выражение - Строка -
// ПрисвоенныйКонтекст - Строка -
// Возвращаемое значение:
// Булево -
Функция ЛиБесполезноеПрисвоениеПеременной(Знач ПрисвоенноеВыражение) Экспорт
ПрисвоенноеВыражение = НРег(ПрисвоенноеВыражение);
Результат = Ложь
// TODO возможно повторно сломано https://www.hostedredmine.com/issues/947747
Или ПустаяСтрока(ПрисвоенноеВыражение)
Или ПрисвоенноеВыражение = "неопределено"
Или ПрисвоенноеВыражение = "undefined"
Или ПрисвоенноеВыражение = "null"
;
Возврат Результат;
КонецФункции
//.
// Параметры:
// Выражение - Строка -
// ПрисвоенныйКонтекст - Строка -
// Возвращаемое значение:
// Булево -
Функция ЛиБулевыйЛитерал(Знач ПрисвоенноеВыражение, выхЗначение = Неопределено)
ПрисвоенноеВыражение = НРег(ПрисвоенноеВыражение);
Если Ложь
Или ПрисвоенноеВыражение = "истина"
Или ПрисвоенноеВыражение = "true"
Тогда
выхЗначение = Истина;
Результат = Истина;
ИначеЕсли Ложь
Или ПрисвоенноеВыражение = "ложь"
Или ПрисвоенноеВыражение = "false"
Тогда
выхЗначение = Ложь;
Результат = Истина;
Иначе
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ШаблонПриемника - Строка - регулярное выражение
// Возвращаемое значение:
// Строка -
Функция ШаблонНазначенияТипаВыражению(Знач ШаблонПриемника, Знач ПроверятьТипЧерезЕсли = Ложь) Экспорт
ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмяСкобки + "?" + шИндекс + "?" + "(\." + шИмяСкобки + "?" + шИндекс + "?)*))\s*(?:Цикл|Do)?";
Результат = "(?:" + мПлатформа.шПустоеНачалоСтроки + "|;\s*|"
+ шПредИмя + "(Если|ИначеЕсли|И|Каждого)\s+)"
+ ШаблонПриемника
//+ "(" + шПрисвоение + ";?|" + ШаблонКоллекции + ")([ \t]*//" + шНазначениеТипа + ")?";
+ "(" + шПрисвоение + ";?|" + ШаблонКоллекции + ")(?:[ \t]*//([^\n]+))?";
Если ПроверятьТипЧерезЕсли Тогда
шУсловиеСПроверкойТипа = шПредИмя + "(?:Если|ИначеЕсли|И)\s+(?:ТипЗнч|TypeOf)\(" + ШаблонПриемника + "\)\s*=\s*((?:Тип|Type)\s*\(\s*""" + шИмяСТочками + """\s*\))";
//шУсловиеСПроверкойТипа = шПредИмя + "(?:Если|ИначеЕсли)([\s\S](?![\s\)]Тогда\s))*?(?:ТипЗнч|TypeOf)\(" + ШаблонПриемника + "\)\s*=\s*((?:Тип|Type)\s*\(\s*""" + шИмя + """\s*\))[\s\S]*?(?:[\s\)]Тогда\s)"; // Дольше на 30%
Результат = Результат + "|" + шУсловиеСПроверкойТипа;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ВыражениеТекста - Строка -
// ТекстДляЗаполненияМетаданных - Строка -
// Возвращаемое значение:
// Строка -
Функция ВычислитьЗначениеВыражения(Выражение, Знач ПредшествующийТекст, Знач ГлобальныйПоискВМодуле = Ложь, Знач Позиция0ВМетодеОт = 0, Знач Позиция0ВМетодеДо = 0, выхКоординаты = Неопределено)
Если ПустаяСтрока(Выражение) Тогда
Возврат "";
КонецЕсли;
ТаблицаТипов = ВычислитьТипЗначенияВыражения(Выражение, ПредшествующийТекст, ПредшествующийТекст,,,, Ложь, ГлобальныйПоискВМодуле, Найти(Выражение, "(") = 0, Истина, Позиция0ВМетодеОт, Позиция0ВМетодеДо);
Если ТаблицаТипов.Количество() > 0 Тогда
СтруктураТипа = ТаблицаТипов[0];
ТипЗначения = ТипЗнч(СтруктураТипа.Метаданные);
Если Ложь
Или ТипЗначения = Тип("Число")
Или ТипЗначения = Тип("Строка")
Или ТипЗначения = Тип("Тип")
Или ТипЗначения = Тип("ОписаниеТипов")
Тогда
Результат = СтруктураТипа.Метаданные;
выхКоординаты = СтруктураТипа.ДержательМетаданных;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ПрисвоенныйТип - Строка -
// ТекстДоВхождения - Строка -
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ТаблицаТиповИзТекста(Знач ТекстТипа, Знач Описание = "", Знач ТекстДоВхождения = "") Экспорт
ЭтоИмяТипа = Не мПлатформа.УдалитьПрефиксИзТекстаТипов(ТекстТипа);
ТаблицаТипов = мПлатформа.НоваяТаблицаТипов();
Если Ложь
Или Не ЗначениеЗаполнено(ТекстТипа)
Или ТекстТипа = "??"
Тогда
//
Иначе
КорневоеСловоБД = "БД.";
Если ЭтоИмяТипа Тогда
Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрЗаменить(ТекстТипа, "??,", ""), " из ", Истина);
Если Фрагменты.Количество() > 1 Тогда
ТипКоллекции = Фрагменты[0];
Если Найти(ТипКоллекции, " ") > 0 Тогда
Возврат ТаблицаТипов;
КонецЕсли;
ТипыЭлементовКоллекции = ТаблицаТиповИзТекста(Фрагменты[1], Описание);
ИмяОбщеготТипа = ТипКоллекции + "[" + мПлатформа.ПредставлениеМассиваСтруктурТипов(ТипыЭлементовКоллекции) + "]";
СтруктураТипа = мПлатформа.НоваяСтруктураТипа(ИмяОбщеготТипа);
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
ИначеЕсли Найти(ТекстТипа, "[") Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа(ТекстТипа);
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Иначе
ТекстОписания = Новый ТекстовыйДокумент;
ТекстОписания.УстановитьТекст(Описание);
ОписаниеСвойств = Новый Структура;
Для Счетчик = 2 По ТекстОписания.КоличествоСтрок() Цикл
СтрокаОписания = СокрЛП(ТекстОписания.ПолучитьСтроку(Счетчик));
Если Истина
И Лев(СтрокаОписания, 1) = "*"
И Не Лев(СтрокаОписания, 2) = "**" // TODO
Тогда
ФрагментыОписания = ирОбщий.СтрРазделитьЛкс(Сред(СтрокаОписания, 2), "-", Истина);
ИмяСвойства = ФрагментыОписания[0];
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяСвойства) И ФрагментыОписания.Количество() > 1 Тогда
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ФрагментыОписания[1]);
МетаданныеСвойства = мПлатформа.ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
Исключение
МетаданныеСвойства = ТаблицаТиповИзТекста(ФрагментыОписания[1]);
КонецПопытки;
ОписаниеСвойств.Вставить(ИмяСвойства, МетаданныеСвойства);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ФрагментыЗапятой = ирОбщий.СтрРазделитьЛкс(ТекстТипа, ",", Истина);
Для Каждого ИмяТипа Из ФрагментыЗапятой Цикл
Если Ложь
Или Не ЗначениеЗаполнено(ИмяТипа)
Или ИмяТипа = "??"
Тогда
Продолжить;
КонецЕсли;
СтруктураТипа = Неопределено;
ИмяБезВложенных = ирОбщий.ПервыйФрагментЛкс(ИмяТипа, "[");
Попытка
Тип = Тип(ИмяБезВложенных);
Исключение
Тип = Неопределено;
КонецПопытки;
Если Тип <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип);
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") Тогда
СтруктураТипа.ИмяОбщегоТипа = ИмяТипа;
КонецЕсли;
Если ОписаниеСвойств.Количество() > 0 Тогда
СтруктураТипа.Метаданные = ОписаниеСвойств;
КонецЕсли;
Иначе
ОбщиеТипы = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(Новый Структура("БазовыйТип", ИмяТипа));
Если ОбщиеТипы.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
ИмяТипа = ОбщиеТипы[0].Слово;
СтруктураТипа = мПлатформа.НоваяСтруктураТипа(ИмяТипа);
КонецЕсли;
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
КонецЕсли;
Иначе
СтруктураТипа = Неопределено;
Если Найти(ТекстТипа, "(") = 0 И Найти(ТекстТипа, ".") > 0 Тогда
ИмяМножественное = ирОбщий.МножественноеИмяМДЛкс(ирОбщий.ПервыйФрагментЛкс(ТекстТипа));
Если ирОбщий.СтрНачинаетсяСЛкс(ТекстТипа, КорневоеСловоБД) Тогда
мЯзыкПрограммы = 1;
СтруктураТипа = ВычислитьТипЗначенияВыражения(Сред(ТекстТипа, СтрДлина(КорневоеСловоБД) + 1),,,,,, Ложь)[0].Квалификаторы;
мЯзыкПрограммы = 0;
ИначеЕсли ИмяМножественное <> Неопределено Тогда
СтруктураТипа = ВычислитьСвойствоФормыПоПолномуИмени(ТекстТипа);
Если СтруктураТипа = Неопределено Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ТекстТипа);
Попытка
СтруктураТипа = ОбъектМД.Тип;
Исключение
КонецПопытки;
Если СтруктураТипа = Неопределено Тогда
Попытка
СтруктураТипа = ОбъектМД.ТипЗначения;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураТипа = Неопределено Тогда
Если Найти(ТекстТипа, "(") = 0 Тогда
ТекстТипа = ТекстТипа + "(";
КонецЕсли;
ТаблицаТипов = ВычислитьТипЗначенияВыражения(ТекстТипа, ТекстДоВхождения, ТекстДоВхождения,,,, Ложь);
Иначе
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ТаблицаТипов.Количество() = 0 Тогда
// мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, мПлатформа.НоваяСтруктураТипа());
//КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
Функция ВычислитьСвойствоФормыПоПолномуИмени(Знач ИмяТипа)
ЧастиИмени = ЧастиПолногоИмениЭлементаФормы(ИмяТипа);
Если ЧастиИмени = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Выражение =
"ПолучитьФорму(""" + ЧастиИмени.ИмяФормы + """)";
Если ЗначениеЗаполнено(ЧастиИмени.ПутьКЭлементу) Тогда
Выражение = Выражение + "." + ЧастиИмени.ПутьКЭлементу;
КонецЕсли;
выхСтруктураТипаКонтекста = ВычислитьТипЗначенияВыражения(Выражение,,,,,, Ложь,,,, Истина)[0];
Возврат выхСтруктураТипаКонтекста;
КонецФункции
// .
//
// Параметры:
// ИмяТипа - - ? -
//
// Возвращаемое значение:
// Структура -
//
Функция ЧастиПолногоИмениЭлементаФормы(Знач ИмяТипа) Экспорт
ФрагментыТочки = ирОбщий.СтрРазделитьЛкс(ИмяТипа);
Если ФрагментыТочки[2] = "Форма" Тогда
ЧислоФрагментовИмениФормы = Мин(4, ФрагментыТочки.Количество());
ИначеЕсли ФрагментыТочки[0] = "ОбщаяФорма." Тогда
ЧислоФрагментовИмениФормы = 2;
Иначе
Возврат Неопределено;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("ИмяФормы", ирОбщий.СтрСоединитьЛкс(ФрагментыТочки, ".", ЧислоФрагментовИмениФормы));
Для Счетчик = 1 По ЧислоФрагментовИмениФормы Цикл
ФрагментыТочки.Удалить(0);
КонецЦикла;
Результат.Вставить("ПутьКЭлементу", ирОбщий.СтрСоединитьЛкс(ФрагментыТочки, "."));
Возврат Результат;
КонецФункции
Функция ПараметрыИзТекстаЗапроса(Знач ТекстЗапроса, Знач ВВидеСтруктуры = Ложь, Знач СтруктураПриемник = Неопределено) Экспорт
Запрос = Новый Запрос(ТекстЗапроса);
Попытка
ПараметрыЗапроса = Запрос.НайтиПараметры();
Исключение
ПараметрыЗапроса = Новый Массив;
КонецПопытки;
Если ВВидеСтруктуры Тогда
Результат = СтруктураПриемник;
Если СтруктураПриемник = Неопределено Тогда
Результат = Новый Структура;
КонецЕсли;
Если ПараметрыЗапроса <> Неопределено Тогда
Для Каждого ОписаниеПараметра Из ПараметрыЗапроса Цикл
Результат.Вставить(ОписаниеПараметра.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Результат = ПараметрыЗапроса;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОбновитьКонтекстВыраженияЗапросаПоНастройкеКомпоновкиЛкс(НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ОчиститьТаблицуСловЛокальногоКонтекста();
Для Каждого ДоступноеПоле Из НастройкаКомпоновки.ДоступныеПоляОтбора.Элементы Цикл
НрегПервыйФрагмент = ирОбщий.ПервыйФрагментЛкс(НРег(ДоступноеПоле.Поле));
Если НрегПервыйФрагмент = НРег("ПараметрыДанных") Тогда
Для Каждого ДоступныйПараметр Из ДоступноеПоле.Элементы Цикл
ИмяСвойства = мПараметрыДиалектаSQL.ПрефиксПараметра + ирОбщий.ПоследнийФрагментЛкс(ДоступныйПараметр.Поле);
ДобавитьСловоЛокальногоКонтекста(ИмяСвойства, "Свойство", , ДоступныйПараметр,,,, "СтрокаТаблицы"); // Виртуальный тип
КонецЦикла;
Иначе
ДобавитьСловоЛокальногоКонтекста("" + ДоступноеПоле.Поле, "Свойство",, ДоступноеПоле,,,, "СтрокаТаблицы"); // Виртуальный тип
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПризнакМодифицированностиФормы()
Если ПолеТекста.ЭлементФормы.ИзменяетДанные Тогда
ФормаВладелец.Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСтруктуруТипаСправаОтРавно() Экспорт
КончитьОбработкуКоманды();
ТаблицаТипов = ТаблицаТиповТекущегоВыражения(Истина);
КончитьОбработкуКоманды();
СписокТиповКонтекста = Новый СписокЗначений;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаТипов Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если Ложь
Или Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы)
Или ТипЗнч(СтруктураТипаКонтекста.Метаданные) <> Тип("ОбъектМетаданных")
Или (Истина
И ЯзыкПрограммы = 0
И Найти(ИмяОбщегоТипа, "Ссылка.") = 0)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(СтруктураТипаКонтекста, ПредставлениеКонкретногоТипа);
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
КонецЦикла;
Если СписокТиповКонтекста.Количество() > 0 Тогда
Ответ = Вопрос("Хотите использовать предсказанные равенством метаданные?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если СписокТиповКонтекста.Количество() = 1 Тогда
ВыбраннаяСтруктураТипа = СписокТиповКонтекста[0].Значение;
КонкретныйТип = СписокТиповКонтекста[0].Представление;
ИначеЕсли СписокТиповКонтекста.Количество() > 1 Тогда
СписокТиповКонтекста.СортироватьПоПредставлению();
ВыбранныйТип = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста");
Если ВыбранныйТип <> Неопределено Тогда
ВыбраннаяСтруктураТипа = ВыбранныйТип.Значение;
КонкретныйТип = ВыбранныйТип.Представление;
КонецЕсли;
КонецЕсли;
//Если ВыбраннаяСтруктураТипа <> Неопределено Тогда
// СтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
// ЗаполнитьЗначенияСвойств(СтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
//КонецЕсли;
Возврат ВыбраннаяСтруктураТипа;
КонецФункции//ПолучитьСтруктуруТипаСправоОтРавно
Функция ТаблицаТиповТекущегоВыражения(ЛиСправаОтРавенства = Ложь, БезКонструкторов = Ложь, ПолныйАнализСоставаТипов = Истина, Знач НомерСтроки = 0, Знач НомерКолонки = 0) Экспорт
РазобратьТекущийКонтекст(ЛиСправаОтРавенства,,, НомерСтроки, НомерКолонки, Истина);
лКонтекст = ?(ЛиСправаОтРавенства, мКонтекст, мРодительскийКонтекст);
Если Истина
И Не ЛиСправаОтРавенства
И Прав(мТекущаяСтрокаНачало, 1) = "."
И ПустаяСтрока(мРодительскийКонтекст)
Тогда
Возврат мПлатформа.НоваяТаблицаТипов();
КонецЕсли;
Попытка
ТаблицаТиповКонтекста = ВычислитьТипЗначенияВыражения(лКонтекст, мТекстДляПоискаОпределения, мПредшествующийТекст, Истина,, ПолныйАнализСоставаТипов,,,,,, мПозицияВБлоке);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат мПлатформа.НоваяТаблицаТипов();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
ТаблицаТиповКонтекста = ТаблицаТиповКонтекста.Скопировать(); // Могла вернуться прямая таблица из кэша
Если БезКонструкторов Тогда
Для Каждого СтрокаТаблицы Из ТаблицаТиповКонтекста.НайтиСтроки(Новый Структура("Конструктор", Истина)) Цикл
ТаблицаТиповКонтекста.Удалить(СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
Возврат ТаблицаТиповКонтекста;
КонецФункции
Функция ПодготовитьИмяПараметраМетода(ИмяПараметра) Экспорт
//ирОбщий.ДекодироватьТекстИзXMLЛкс(СтрокаПараметра.Параметр);
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&gt;", "");
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&lt;", "");
Возврат ИмяПараметра;
КонецФункции
Функция СтрокаИменПараметровМетода() Экспорт
Возврат ирОбщий.СтрСоединитьЛкс(мПлатформа.ПараметрыМетодаМодуля(мМетодМодуля).ВыгрузитьКолонку("Имя"), ",")
КонецФункции
// Вызывает контекстную подсказку в текстовом поле.
//
// Параметры:
// Нет.
//
Процедура ОткрытьАвтодополнение(Знач КодКлавиши = "", Знач Модально = Ложь) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
// Мультиметка00452941 Удаляем лишние точки истории из-за запоминания по нажатию CTRL
УдалитьПоследнийПереходИзИстории();
ФормаАвтодополнение = ФормаАвтодополнение();
КодыКлавиш = ирКэш.КодыКлавишЛкс();
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец <> Неопределено И ФормаВладелец.ТолькоПросмотр
Или ФормаАвтодополнение.Открыта() И Не ЗначениеЗаполнено(КодКлавиши)
Тогда
Возврат;
КонецЕсли;
Если Истина
//И Найти(КодКлавиши, "04128") = 1 // CTRL+SPACE
И КодКлавиши = "" // Вызов из обработчика нажатия кнопки
И ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеHTMLДокумента")
И ирКэш.НомерВерсииПлатформыЛкс() <= 803016
Тогда
// https://github.com/salexdv/bsl_console/issues/124
ПолеТекста.РедакторHTML().triggerSuggestions();
Возврат;
КонецЕсли;
//Если Истина
// И ЯзыкПрограммы = 1
// И Не мДоступныеТаблицыПолучены
//Тогда
// Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
// ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
// Иначе
// ЗаполнитьДоступныеТаблицыADO(); // Может быть очень долго
// Для Каждого СтрокаДоступнойТаблицы Из ДоступныеТаблицы Цикл
// ДобавитьСловоЛокальногоКонтекста(СтрокаДоступнойТаблицы.Имя,,,, Истина,,, "ВременнаяТаблица");
// КонецЦикла;
// КонецЕсли;
//КонецЕсли;
СтруктураТипаКонтекста = Неопределено;
ТаблицаТиповКонтекста = Неопределено;
Модально = Модально Или Не ЛиДоступноОткрытиеСвободнойФормы();
Пока Истина Цикл
Успешно = ЗаполнитьТаблицуСлов(ТаблицаТиповКонтекста, мКонкретныйТипКонтекста, мСтруктураТипаКонтекста, Модально,, Не ЗначениеЗаполнено(КодКлавиши));
Если Не Успешно Тогда
Возврат;
КонецЕсли;
Если Истина
И ТаблицаСлов.Количество() = 0
И Не ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ЛиОткрыватьПустойСписок") = Истина
Тогда
Возврат;
КонецЕсли;
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", ЯзыкПрограммы, мКонкретныйТипКонтекста);
НайденныеСтроки = мПлатформа.ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
ТаблицаСловТЗ = ТаблицаСлов.Выгрузить(, "НСлово, Рейтинг");
ТаблицаСловТЗ.Индексы.Добавить("НСлово");
Для Каждого СтрокаРейтинга Из НайденныеСтроки Цикл
СтрокаСлова = ТаблицаСловТЗ.Найти(НРег(СтрокаРейтинга.Слово), "НСлово");
Если СтрокаСлова <> Неопределено Тогда
СтрокаСлова.Рейтинг = СтрокаРейтинга.Рейтинг;
КонецЕсли;
КонецЦикла;
ТаблицаСлов.ЗагрузитьКолонку(ТаблицаСловТЗ.ВыгрузитьКолонку("Рейтинг"), "Рейтинг");
Попытка
ФормаАвтодополнение.СтруктураТипаКонтекста = мСтруктураТипаКонтекста;
Исключение
ВызватьИсключение "Экземпляр формы автодополнения контекстной подсказки сломан ошибкой платформы. Переоткройте форму чтобы восстановить ее работу";
КонецПопытки;
//Если ЗначениеЗаполнено(мСтруктураТипаКонтекста.ТипЯзыка) Тогда
// ФормаАвтодополнение.Контекст = мСтруктураТипаКонтекста.ТипЯзыка;
//Иначе
// ФормаАвтодополнение.Контекст = мРодительскийКонтекст;
//КонецЕсли;
Если ФормаАвтодополнение.Открыта() Тогда
// Иначе будет считана некорректная позиция окна
ФормаАвтодополнение.Закрыть();
КонецЕсли;
ФормаАвтодополнение.ЗапомнитьПозициюКаретки();
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.Активизировать();
КонецЕсли;
//ирКлиент.Форма_АктивироватьОткрытьЛкс(ФормаВладелец); // https://www.hostedredmine.com/issues/911214
Если Модально Тогда
ФормаАвтодополнение.ТекущееСлово = мНачалоСлова;
ПараметрЗакрытияПодсказки = ФормаАвтодополнение.ОткрытьМодально();
Иначе
ПараметрЗакрытияПодсказки = Неопределено;
ФормаАвтодополнение.Открыть();
КонецЕсли;
Если ПараметрЗакрытияПодсказки = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаРезультата = ФормаАвтодополнение.СтрокаСловаРезультата;
Если СтрокаРезультата = Неопределено Тогда
Возврат;
КонецЕсли;
ВставитьВыбранноеСловоАвтодополнения(СтрокаРезультата, ТаблицаТиповКонтекста, ПараметрЗакрытияПодсказки);
Если ТаблицаТиповКонтекста.Количество() = 0 Тогда
Возврат;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Возвращаемое значение:
// Форма -
Функция ФормаАвтодополнение() Экспорт
Если мФормаАвтодополнение = Неопределено Тогда
Если Ложь
Или Не ирКэш.ЛиПлатформаWindowsЛкс()
Или ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс()
Тогда
ИмяФормы = "Автодополнение";
Иначе
ИмяФормы = "АвтодополнениеCOM";
КонецЕсли;
мФормаАвтодополнение = ПолучитьФорму(ИмяФормы, ФормаВладелец);
мФормаАвтодополнение.КлючСохраненияПоложенияОкна = ЯзыкПрограммы;
КонецЕсли;
Возврат мФормаАвтодополнение;
КонецФункции
Процедура УдалитьПоследнийПереходИзИстории()
Если мИсторияПереходов <> Неопределено И мИсторияПереходов.Количество() > 0 Тогда
мИсторияПереходов.Удалить(0);
КонецЕсли;
КонецПроцедуры
Функция ЗаполнитьТаблицуСлов(ТаблицаТиповКонтекста = Неопределено, выхКонкретныйТип = Неопределено, выхСтруктураТипаКонтекста = Неопределено, Знач РазрешитьОткрытиеОкон = Истина,
Знач Сортировать = Истина, Знач ДобавлятьНизкоВероятные = Ложь, Знач ОтделятьБольшиеНаборыСлов = Ложь) Экспорт
ВычислятьТипы = ПоказыватьВсеТипыВСпискеАвтодополненияHTML();
мРегВыражение.Global = Истина;
ТаблицаСтатистикиВыбора = мПлатформа.ТаблицаСтатистикиВыбора;
#Если Сервер И Не Сервер Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТаблицаТиповКонтекста = Неопределено Тогда
ТаблицаТиповКонтекста = ТаблицаТиповТекущегоВыражения();
КонецЕсли;
Если ОтделятьБольшиеНаборыСлов Тогда
мНаборыСлов = Новый Соответствие;
Иначе
мНаборыСлов = Неопределено;
КонецЕсли;
ТаблицаСлов.Очистить();
Если ТаблицаТиповКонтекста.Количество() = 0 Тогда
ЗаполнитьЗначенияСвойств(ТаблицаТиповКонтекста.Добавить(), мПлатформа.НоваяСтруктураТипа());
КонецЕсли;
мЭтоЛокальныйКонтекстТаблицыСлов = Ложь;
Если мЭтоТекстовыйЛитерал Тогда
РазрешитьОткрытиеОкон = Ложь;
КонецЕсли;
Если ЯзыкПрограммы <> 0 Тогда
ДобавлятьНизкоВероятные = Ложь;
КонецЕсли;
СписокТиповКонтекста = Новый СписокЗначений;
СоответствиеСтруктурТипов = Новый Соответствие;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаТиповКонтекста Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если ИмяОбщегоТипа = "Локальный" Тогда
мЭтоЛокальныйКонтекстТаблицыСлов = Истина;
КонецЕсли;
Если Истина
И Не ЗначениеЗаполнено(СтруктураТипаКонтекста.ТипЯзыка)
И Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, мЯзыкПрограммы)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
//Если СтруктураТипаКонтекста.СтрокаОписания <> Неопределено Тогда
// // Наверное логичнее было бы из ВычислитьТипЗначенияВыражения ее получать
// РодительскаяСтруктураТипа = мПлатформа.НоваяСтруктураТипа();
// Если СтруктураТипаКонтекста.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено Тогда
// ЗаполнитьЗначенияСвойств(РодительскаяСтруктураТипа, СтруктураТипаКонтекста);
// РодительскаяСтруктураТипа.ИмяОбщегоТипа = СтруктураТипаКонтекста.СтрокаОписания.ТипКонтекста;
// КонецЕсли;
// ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа
// + мПлатформа.ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа) + " / ";
//КонецЕсли;
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(ПредставлениеКонкретногоТипа, ПредставлениеКонкретногоТипа + " [" + СтруктураТипаКонтекста.Детальность + "]");
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа];
Если МассивСтруктурТипа = Неопределено Тогда
МассивСтруктурТипа = Новый Массив;
КонецЕсли;
МассивСтруктурТипа.Добавить(СтруктураТипаКонтекста);
СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа] = МассивСтруктурТипа;
КонецЦикла;
Если ЛиВЗаголовкеМетода() Тогда
ВыбраннаяСтруктураТипа = мПлатформа.НоваяСтруктураТипа();
мЭтоЛокальныйКонтекстТаблицыСлов = Ложь;
ИначеЕсли СписокТиповКонтекста.Количество() = 0 Тогда
ВыбраннаяСтруктураТипа = ТаблицаТиповКонтекста[0];
выхКонкретныйТип = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Иначе
ВыбраннаяСтруктураТипа = Неопределено;
Если СписокТиповКонтекста.Количество() > 1 И РазрешитьОткрытиеОкон Тогда
СписокТиповКонтекста.СортироватьПоПредставлению();
НачальныйВыбор = Неопределено;
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", мЯзыкПрограммы, "<Выбор типа>");
ВыбранныеРанееТипы = ТаблицаСтатистикиВыбора.Скопировать(КлючПоискаСтатистики);
ВыбранныеРанееТипы.Сортировать("Рейтинг Убыв");
Для Каждого СтрокаТипа Из ВыбранныеРанееТипы Цикл
Для Каждого ЭлементСписка Из СписокТиповКонтекста Цикл
Если СтрокаТипа.Слово = ЭлементСписка.Представление Тогда
НачальныйВыбор = ЭлементСписка;
Прервать;
КонецЕсли;
КонецЦикла;
Если НачальныйВыбор <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ВыбранныйЭлементСписка = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста", НачальныйВыбор);
Если ВыбранныйЭлементСписка = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
выхКонкретныйТип = ВыбранныйЭлементСписка.Значение;
// Обновим статистику выбора
КлючПоискаСтатистики.Вставить("Слово", выхКонкретныйТип);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоискаСтатистики);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
Иначе
// TODO объединить все типы контекста
ВыбранныйЭлементСписка = СписокТиповКонтекста[0];
выхКонкретныйТип = ВыбранныйЭлементСписка.Значение;
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[выхКонкретныйТип];
Для Каждого СтруктураТипа Из МассивСтруктурТипа Цикл
Если Ложь
Или ВыбраннаяСтруктураТипа = Неопределено
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданныхКонфигурация")
Тогда
ВыбраннаяСтруктураТипа = СтруктураТипа;
КонецЕсли;
КонецЦикла;
КонецЕсли;
выхСтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
ПервоеСловоРодителя = ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст);
КоллекцияЭлементовМД = Новый Массив;
Если мЭтоТекстовыйЛитерал И ВыбраннаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
// Находимся внутри строкового литерала на позиции параметра
СтрокаОписанияМетода = ВыбраннаяСтруктураТипа.СтрокаОписания;
Если Истина
И ТипЗнч(СтрокаОписанияМетода) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписанияМетода.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
Тогда
ИмяПараметра = ИмяПараметраВызоваМетода(СтрокаОписанияМетода);
Если Истина
И мНомерПараметра = 1
И мИмяМетодаВызова = "Структура"
И мЭтоКонструктор
Тогда
ПозицияОбрезки = ирОбщий.СтрНайтиЛкс(мТекущаяСтрокаНачало, "Новый " + мВызовМетода,,,, Ложь) - 1;
ТекущаяСтрокаНачало = мТекущаяСтрокаНачало;
ТекущаяСтрокаКонец = мТекущаяСтрокаКонец;
мТекущаяСтрокаНачало = Лев(мТекущаяСтрокаНачало, ПозицияОбрезки);
мТекущаяСтрокаКонец = "";
ТекущийВызовМетода();
мТекущаяСтрокаНачало = ТекущаяСтрокаНачало;
мТекущаяСтрокаКонец = ТекущаяСтрокаКонец;
ТаблицаТиповОбрамляющегоВызова = ВычислитьТипЗначенияВыражения(мВызовМетода, мТекстДляПоискаОпределения, мПредшествующийТекст,,,,,,,,,
мПозицияВТексте - мПозицияТекстаДляПоискаОпределения - 1);
ЛучшийТип = Неопределено;
Если ЛиДетальностьТиповДостаточна(ТаблицаТиповОбрамляющегоВызова, 4, ЛучшийТип) Тогда
ВыбраннаяСтруктураТипа.Метаданные = ЛучшийТип.Метаданные;
КонецЕсли;
КонецЕсли;
// Имена свойств
Если Ложь
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ТаблицаЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ДеревоЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("РезультатЗапроса")
Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Колонки;
ИначеЕсли Ложь
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ДанныеФормыКоллекция")
Тогда
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоЛкс(мПлатформа.ДочерниеСвойстваДанныхФормы(ВыбраннаяСтруктураТипа.Метаданные, Истина));
ИначеЕсли Истина
И ИмяПараметра = "Ключ"
И ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("Структура")
Тогда
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоЛкс(ВыбраннаяСтруктураТипа.Метаданные);
ИначеЕсли Истина
И ИмяПараметра = "ИмяОбласти"
И ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ТабличныйДокумент")
Тогда
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоЛкс(ВыбраннаяСтруктураТипа.Метаданные.Области,,, Тип("ОбластьЯчеекТабличногоДокумента"));
ИначеЕсли ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда // Возможно нужно добавить еще условие
Если ИмяПараметра = "Макет" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Макеты;
ИначеЕсли ИмяПараметра = "Форма" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Формы;
Иначе
ПолноеИмяМД = ВыбраннаяСтруктураТипа.Метаданные.ПолноеИмя();
Если ирОбщий.ОписаниеТипаМетаданныхЛкс(ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД)).Категория = 1 Тогда
Попытка
// Пытаемся взять реквизиты ТЧ у нехранимого в БД объекта
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Реквизиты;
Исключение
КонтекстТекстовогоЛитералаИзвестен = Ложь;
КонецПопытки;
Иначе
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
Если ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
КоллекцияЭлементовМД = ирОбщий.ПоляТаблицыБДЛкс(ИмяТаблицыБД);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из ПользователиИБ Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "Роль" Тогда
КоллекцияЭлементовМД = Метаданные.Роли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из ПользователиИБ Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "ОбщийМакет" Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеМакеты;
ИначеЕсли Истина
И СтрокаОписанияМетода.Слово = "ПолучитьОбщуюФорму"
И ИмяПараметра = "Форма"
Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеФормы;
ИначеЕсли Истина
И СтрокаОписанияМетода.Слово = "УстановитьПараметр"
И ИмяПараметра = "Имя"
Тогда
Если ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ПостроительЗапроса") Тогда
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоЛкс(ПараметрыИзТекстаЗапроса(ВыбраннаяСтруктураТипа.Метаданные.Текст));
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияМетода.Слово = "НайтиПредопределенное"
И СтрокаОписанияМетода.ТипКонтекста = "МенеджерРегламентныхЗаданий"
И ИмяПараметра = "Метаданные"
Тогда
КоллекцияЭлементовМД = Метаданные.РегламентныеЗадания;
ИначеЕсли Истина
И СтрокаОписанияМетода.Слово = "ПравоДоступа"
И ИмяПараметра = "Право"
Тогда
КоллекцияЭлементовМД = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(мПлатформа.ПолучитьМакет("ВидыПравДоступа"));
ИначеЕсли Истина
И СтрокаОписанияМетода.Слово = "ЗаполнитьЗначенияСвойств"
И (Ложь
Или ИмяПараметра = "СписокСвойств"
Или ИмяПараметра = "ИсключаяСвойства")
Тогда
СтруктураТипаПараметра = ВычислитьТипЗначенияВыражения(мПервыйФактическийПараметр, мТекстДляПоискаОпределения);
КоллекцияЭлементовМД = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипаПараметра[0]).Скопировать(Новый Структура("ТипСлова", "Свойство")).ВыгрузитьКолонку("Слово");
ИначеЕсли Истина
И СтрокаОписанияМетода.ТипКонтекста = "ОформлениеКомпоновкиДанных"
И СтрокаОписанияМетода.Слово = "УстановитьЗначениеПараметра"
И ИмяПараметра = "Параметр"
Тогда
КоллекцияЭлементовМД.Добавить("Видимость");
КоллекцияЭлементовМД.Добавить("ВыделятьОтрицательные");
КоллекцияЭлементовМД.Добавить("ГоризонтальноеПоложение");
КоллекцияЭлементовМД.Добавить("Доступность");
КоллекцияЭлементовМД.Добавить("ОтметкаНезаполненного");
КоллекцияЭлементовМД.Добавить("Отображать");
КоллекцияЭлементовМД.Добавить("Текст");
КоллекцияЭлементовМД.Добавить("ТолькоПросмотр");
КоллекцияЭлементовМД.Добавить("Формат");
КоллекцияЭлементовМД.Добавить("ЦветФона");
КоллекцияЭлементовМД.Добавить("ЦветТекста");
КоллекцияЭлементовМД.Добавить("Шрифт");
ИначеЕсли Истина
И (Ложь
Или СтрокаОписанияМетода.Слово = "ПолучитьФункциональнуюОпцию"
Или СтрокаОписанияМетода.Слово = "ПолучитьФункциональнуюОпциюИнтерфейса"
Или СтрокаОписанияМетода.Слово = "ПолучитьФункциональнуюОпциюФормы")
И ИмяПараметра = "Имя"
Тогда
КоллекцияЭлементовМД = Метаданные.ФункциональныеОпции;
ИначеЕсли Ложь
Или ИмяПараметра = "ИмяПроцедуры"
Или ИмяПараметра = "ИмяФункции"
Или ИмяПараметра = "ИмяМетода"
Или ИмяПараметра = "ИмяОбработчика"
Или ИмяПараметра = "Действие"
Тогда
СтруктураТипаМодуля = мПлатформа.НоваяСтруктураТипа(ТаблицаТиповКонтекста[0].СтрокаОписания.ТипКонтекста);
СтруктураТипаМодуля.Метаданные = ВыбраннаяСтруктураТипа.Метаданные;
Модуль = мПлатформа.ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
КоллекцияЭлементовМД = ОтобратьМетодыДляСпискаСлов(Модуль, СтрокаОписанияМетода.ТипКонтекста = "ОписаниеОповещения");
ИначеЕсли Ложь
Или ИмяПараметра = "ИмяСобытия"
Тогда
ЭлементФормыСобытия = ВыбраннаяСтруктураТипа.Метаданные;
Если ТипЗнч(ЭлементФормыСобытия) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ЭлементФормыСобытия = Неопределено;
КонецЕсли;
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоЛкс(ирОбщий.СобытияЭлементаФормыЛкс(ЭлементФормыСобытия, ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста), "Слово");
ИначеЕсли Истина
И ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ПостроительЗапроса")
И (Ложь
Или ИмяПараметра = "ПутьКДанным"
Или ИмяПараметра = "Описание")
Тогда
ИмяПараметра = "ПутьКДанным";
ПостроительЗапроса = ВыбраннаяСтруктураТипа.Метаданные;
#Если Сервер И Не Сервер Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
#КонецЕсли
КоллекцияЭлементовМД = ПостроительЗапроса.ДоступныеПоля;
Иначе
КонтекстТекстовогоЛитералаИзвестен = Ложь;
КонецЕсли;
ВыбраннаяСтруктураТипа.ТипЯзыка = ИмяПараметра;
ИначеЕсли Истина
И ТипЗнч(СтрокаОписанияМетода) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписанияМетода.Владелец().Колонки.Найти("ЛиЭкспорт") <> Неопределено
Тогда
КонтекстТекстовогоЛитералаИзвестен = Ложь;
ИмяПараметра = ИмяПараметраВызоваМетода(СтрокаОписанияМетода);
Если ЗначениеЗаполнено(ИмяПараметра) Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
Если Истина
И Найти(ИмяПараметра, "Реквизит") > 0
И Найти(СтрокаОписанияМетода.Имя, "Значен") > 0
И Найти(СтрокаОписанияМетода.Имя, "Реквизит") > 0
Тогда
// БСП https://www.hostedredmine.com/issues/966675
СтруктураТипаСсылки = ВычислитьТипЗначенияВыражения(мПервыйФактическийПараметр, мТекстДляПоискаОпределения)[0];
Если ТипЗнч(СтруктураТипаСсылки.Метаданные) = Тип("ОбъектМетаданных") Тогда
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтруктураТипаСсылки.Метаданные.ПолноеИмя());
Если ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
КоллекцияЭлементовМД = ирОбщий.ПоляТаблицыБДЛкс(ИмяТаблицыБД);
ИмяПараметра = "ИмяРеквизита";
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ИмяПараметра = "ПолноеИмяМД"
Тогда
// TODO
Иначе
КонтекстТекстовогоЛитералаИзвестен = Ложь;
КонецЕсли;
ВыбраннаяСтруктураТипа.ТипЯзыка = ИмяПараметра;
КонецЕсли;
Иначе
КонтекстТекстовогоЛитералаИзвестен = Ложь;
КонецЕсли;
выхСтруктураТипаКонтекста.ТипЯзыка = ВыбраннаяСтруктураТипа.ТипЯзыка;
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяПредопределенногоЗначения" Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов(Ложь);
КорневойТип = ПервоеСловоРодителя;
КоллекцияЭлементовМД.Добавить("ПустаяСсылка");
Если Найти(мРодительскийКонтекст, ".") > 0 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(мРодительскийКонтекст);
Если ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Перечисления.ABCКлассификация;
#КонецЕсли
Для Каждого ЗначениеПеречисления Из ОбъектМД.ЗначенияПеречисления Цикл
КоллекцияЭлементовМД.Добавить(ЗначениеПеречисления.Имя);
КонецЦикла;
Иначе
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Если Истина
И ирКэш.НомерВерсииПлатформыЛкс() > 803004
И ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип)
Тогда
Для Каждого ИмяЭлемента Из ОбъектМД.ПолучитьИменаПредопределенных() Цикл
КоллекцияЭлементовМД.Добавить(ИмяЭлемента);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Для Каждого МетаОбъект Из Метаданные[МножественноеИмяМД] Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Ложь, Ложь, Ложь) Цикл
Если Ложь
Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(СтрокаТипаМетаОбъекта.Единственное)
Или ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(СтрокаТипаМетаОбъекта.Единственное)
Тогда
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ПространствоБлокировки" Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
КорневойТип = ПервоеСловоРодителя;
ЭтоТаблицаВнешнейБД = ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
Если Истина
И ЭтоТаблицаВнешнейБД
И СтрЧислоВхождений(мРодительскийКонтекст, ".") = 1
Тогда
КоллекцияЭлементовМД.Добавить("Таблица");
ИначеЕсли Истина
И ЭтоТаблицаВнешнейБД
И СтрЧислоВхождений(мРодительскийКонтекст, ".") = 2
Тогда
Для Каждого МетаОбъект Из ирКэш.ОбъектМДПоПолномуИмениЛкс(ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(мРодительскийКонтекст)).Таблицы Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект.Имя);
КонецЦикла;
ИначеЕсли Найти(мРодительскийКонтекст, ".") > 0 Тогда
Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
КоллекцияЭлементовМД.Добавить("НаборЗаписей");
КонецЕсли;
Если ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Тогда
КоллекцияЭлементовМД.Добавить("Записи");
КонецЕсли;
Иначе
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Для Каждого МетаОбъект Из Метаданные[МножественноеИмяМД] Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Ложь, Ложь, Ложь) Цикл
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ПолеПространстваБлокировок" Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
ПространствоБлокировки = ВыбраннаяСтруктураТипа.Метаданные;
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПространствоБлокировки);
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ПространствоБлокировки);
ЭтоТаблицаВнешнейБД = ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
Если ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД) Тогда
КоллекцияЭлементовМД.Добавить("Ссылка");
Если ОбъектМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Пользователи;
#КонецЕсли
Для Каждого ПолеБлокировки Из ОбъектМД.ПоляБлокировкиДанных Цикл
КоллекцияЭлементовМД.Добавить(ПолеБлокировки.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Если ОбъектМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Если Найти(ПространствоБлокировки, "." + "НаборЗаписей") > 0 Тогда
СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(ОбъектМД.ПолноеИмя()), Ложь);
Иначе
СтруктураКлюча = Новый Структура;
Если ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("Период"));
КонецЕсли;
Если ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("Регистратор"));
КонецЕсли;
КонецЕсли;
Если ирОбщий.ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("ПериодРегистрации"));
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("ПериодДействия"));
КонецЕсли;
Если ЭтоТаблицаВнешнейБД Тогда
Для Каждого ПолеКлюча Из ОбъектМД.ПоляКлюча Цикл
СтруктураКлюча.Вставить(ПолеКлюча.Имя);
КонецЦикла;
Иначе
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СтруктураКлюча.Вставить(Измерение.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ирОбщий.СтрокиРавныЛкс(мИмяМетодаВызова, "COMОбъект")
И мНомерПараметра = 1
И ВыбраннаяСтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
Если МассивКОМКлассов = Неопределено Тогда
Компьютер = "localhost";
МассивКОМКлассов = Новый Массив;
КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog");
КаталогПриложений.Connect(Компьютер);
Компоненты = КаталогПриложений.GetCollection("InprocServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
Компоненты = КаталогПриложений.GetCollection("WOWLegacyServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
Компоненты = КаталогПриложений.GetCollection("LegacyServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
КонецЕсли;
КоллекцияЭлементовМД = МассивКОМКлассов;
КонецЕсли;
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Строка";
ИначеЕсли Истина
И мЭтоТекстовыйЛитерал
И ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа"
И мИмяМетодаВызова = "Тип"
Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
ПолеТекстаПрограммыВызова = КопияКомпоненты();
#Если Сервер И Не Сервер Тогда
ПолеТекстаПрограммыВызова = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
ПолеТекстаПрограммыВызова.РазобратьТекущийКонтекст(,, Истина, мНачальнаяСтрока, мНачальнаяКолонка - СтрДлина(мВызовМетода + мНачалоСлова), Истина);
Если Истина
И ПолеТекстаПрограммыВызова.мИмяМетодаВызова = "Добавить"
И ПолеТекстаПрограммыВызова.мНомерПараметра = 1
Тогда
ТаблицаТипов = ПолеТекстаПрограммыВызова.ВычислитьТипЗначенияВыражения(ПолеТекстаПрограммыВызова.мВызовМетода, ПолеТекстаПрограммыВызова.мТекстДляПоискаОпределения);
Если ТаблицаТипов.Количество() > 1 Тогда
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Строка";
выхСтруктураТипаКонтекста.ТипЯзыка = "ИмяТипа";
ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
Для Каждого СтруктураТипаЭлемента Из ТаблицаТипов Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = СтруктураТипаЭлемента.ИмяОбщегоТипа;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Предопределенный";
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТаблицаСлов.Количество() = 0 Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
КонецЕсли;
Иначе
КонтекстТекстовогоЛитералаИзвестен = ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
Если Истина
И мЯзыкПрограммы = 1
И (Ложь
Или мЭтоЛокальныйКонтекстТаблицыСлов
Или ВыбраннаяСтруктураТипа.ИмяОбщегоТипа = "")
Тогда
Если Истина
И ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа"
И Не мТолькоСсылочныеИменаТипов
Тогда
ИменаФиксированныхТипов = Новый Массив;
ИменаФиксированныхТипов.Добавить("БУЛЕВО");
ИменаФиксированныхТипов.Добавить("ДАТА");
ИменаФиксированныхТипов.Добавить("СТРОКА");
ИменаФиксированныхТипов.Добавить("ЧИСЛО");
Для Каждого ЭлементКоллекцииМД Из ИменаФиксированныхТипов Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = ЭлементКоллекцииМД;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Предопределенный";
СтрокаСлова.ТипЗначения = "Тип";
КонецЦикла;
КонецЕсли;
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "" Тогда
Для Каждого ОписаниеТаблицы Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("Тип, Схема", "ВременнаяТаблица", "")) Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = ОписаниеТаблицы.Имя;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Локальный";
СтрокаСлова.ТипЗначения = ОписаниеТаблицы.Тип;
КонецЦикла;
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = СокрП(мМаркерПорядкаОтладки);
СтрокаСлова.ТипСлова = "Конструкция";
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(выхСтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
КонецЕсли;
//ТаблицаТиповКонтекста.Очистить();
ДобавитьПростыеСлова(КоллекцияЭлементовМД);
КоллекцияЭлементовМД = Новый Массив;
// Имена общих методов
Если Ложь
Или ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяМетода"
Или (Истина
И Не КонтекстТекстовогоЛитералаИзвестен
И мЭтоТекстовыйЛитерал)
Тогда
КонтекстТекстовогоЛитералаИзвестен = ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяМетода";
ИменаТиповМетаданныхСМенеджерами = мПлатформа.ИменаТиповМетаданныхСМенеджерами();
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ЛиИмяОбщегоМодуля = Метаданные.ОбщиеМодули.Найти(мРодительскийКонтекст) <> Неопределено;
ЛиИмяМножественноеМетаданных = Истина
И ЗначениеЗаполнено(мРодительскийКонтекст)
И СтрЧислоВхождений(мРодительскийКонтекст, ".") < 2
И ИменаТиповМетаданныхСМенеджерами.Свойство(ПервоеСловоРодителя);
Если ЛиИмяОбщегоМодуля Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
выхСтруктураТипаКонтекста.ТипЯзыка = "ИмяМетода";
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ОбщийМодуль";
выхСтруктураТипаКонтекста.Метаданные = Метаданные.ОбщиеМодули.Найти(мРодительскийКонтекст);
ВнутренняяТаблицаСлов = мПлатформа.СловаКонтекстаМетаданные(выхСтруктураТипаКонтекста,, "Метод",,,,,, мПлатформа.НовыеФлагиКомпиляции(, Ложь, Ложь));
ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(ВнутренняяТаблицаСлов, ТаблицаСлов);
ИначеЕсли ЛиИмяМножественноеМетаданных Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
ЕдинственноеИмяМД = ирОбщий.ЕдинственноеИмяМДЛкс(ПервоеСловоРодителя);
Если СтрЧислоВхождений(мРодительскийКонтекст, ".") = 0 Тогда
выхСтруктураТипаКонтекста.ТипЯзыка = ЕдинственноеИмяМД;
Для Каждого ОбъектМД Из Метаданные[мРодительскийКонтекст] Цикл
КоллекцияЭлементовМД.Добавить(ОбъектМД.Имя);
КонецЦикла;
Иначе
выхСтруктураТипаКонтекста = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип(ЕдинственноеИмяМД + "Менеджер." + ирОбщий.ПоследнийФрагментЛкс(мРодительскийКонтекст)));
ВнутренняяТаблицаСлов = мПлатформа.СловаКонтекстаМетаданные(выхСтруктураТипаКонтекста,, "Метод",,,,,, мПлатформа.НовыеФлагиКомпиляции(, Ложь, Ложь));
ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(ВнутренняяТаблицаСлов, ТаблицаСлов);
КонецЕсли;
выхСтруктураТипаКонтекста.ТипЯзыка = "ИмяМетода";
КонецЕсли;
ИначеЕсли ДобавлятьНизкоВероятные Тогда
Для Каждого КлючИЗначение Из ирКэш.ДоступныеОбщиеМодулиЛкс(Истина, Истина, Истина) Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Значение.Имя);
КонецЦикла;
Для Каждого КлючИЗначение Из ИменаТиповМетаданныхСМенеджерами Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
КонецЕсли;
КонецЕсли;
// Имена типов и метаданных внутри комментария и текстового литерала
Если Истина
И выхСтруктураТипаКонтекста.ТипЯзыка <> "ИмяТипа"
И (Ложь
Или ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало)
Или мЭтоТекстовыйЛитерал)
Тогда
// Имена метаданных
Если Ложь
Или ВыбраннаяСтруктураТипа.ТипЯзыка = "Местоположение"
Или Найти(ВыбраннаяСтруктураТипа.ТипЯзыка, "ИмяФормы") > 0
Или Найти(ВыбраннаяСтруктураТипа.ТипЯзыка, "ПолноеИмя") > 0
Или ЗначениеЗаполнено(ирОбщий.МножественноеИмяМДЛкс(ПервоеСловоРодителя))
Или (Истина
//И ВыбраннаяСтруктураТипа.ТипЯзыка = ""
И Не КонтекстТекстовогоЛитералаИзвестен
И ДобавлятьНизкоВероятные)
Тогда
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "Местоположение" Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
ИмяДочернегоТипаМД = "Макет";
ИмяКорневогоТипаМД = "ОбщийМакет";
ИначеЕсли Найти(ВыбраннаяСтруктураТипа.ТипЯзыка, "ИмяФормы") > 0 Тогда
КонтекстТекстовогоЛитералаИзвестен = Истина;
ИмяДочернегоТипаМД = "Форма";
ИмяКорневогоТипаМД = "ОбщаяФорма";
Иначе
Если ЗначениеЗаполнено(ирОбщий.МножественноеИмяМДЛкс(ПервоеСловоРодителя)) Тогда
ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяМетаданных";
выхСтруктураТипаКонтекста.ТипЯзыка = ВыбраннаяСтруктураТипа.ТипЯзыка;
КонецЕсли;
ИмяКорневогоТипаМД = "";
ИмяДочернегоТипаМД = "";
КонецЕсли;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
Если Истина
И ЗначениеЗаполнено(ПервоеСловоРодителя)
И ирОбщий.СтрокиРавныЛкс(ИмяКорневогоТипаМД, ПервоеСловоРодителя)
Тогда
Если СтрЧислоВхождений(мРодительскийКонтекст, ".") = 0 Тогда
Для Каждого МетаМакет Из Метаданные[ирОбщий.МножественноеИмяМДЛкс(ИмяКорневогоТипаМД)] Цикл
КоллекцияЭлементовМД.Добавить(МетаМакет.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Если СтрЧислоВхождений(мРодительскийКонтекст, ".") = 0 Тогда
КорневойТип = ПервоеСловоРодителя;
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Попытка
КоллекцияМД = Метаданные[МножественноеИмяМД];
Исключение
КоллекцияМД = Новый Массив;
КонецПопытки;
Для Каждого МетаОбъект Из КоллекцияМД Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект.Имя);
КонецЦикла;
КонецЕсли;
ИначеЕсли СтрЧислоВхождений(мРодительскийКонтекст, ".") = 1 Тогда
Если ЗначениеЗаполнено(ИмяДочернегоТипаМД) Тогда
КоллекцияЭлементовМД.Добавить(ИмяДочернегоТипаМД);
Иначе
ТипыДочерние = ирКэш.ТипыМетаОбъектов().НайтиСтроки(Новый Структура("Категория", 2));
Для Каждого СтрокаТипаМетаОбъекта Из ТипыДочерние Цикл
ОтборСвойств = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова",
"ОбъектМетаданных: " + ПервоеСловоРодителя, 0, "", НРег(СтрокаТипаМетаОбъекта.Множественное), "Свойство");
Если мПлатформа.ТаблицаКонтекстов.НайтиСтроки(ОтборСвойств).Количество() = 0 Тогда
Продолжить;
КонецЕсли;
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЦикла;
КонецЕсли;
ИначеЕсли СтрЧислоВхождений(мРодительскийКонтекст, ".") = 2 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(мРодительскийКонтекст, "."));
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Если ОбъектМД <> Неопределено Тогда
ИмяМножественное = ирОбщий.МножественноеИмяМДЛкс(ирОбщий.ПоследнийФрагментЛкс(мРодительскийКонтекст));
Если ИмяМножественное <> Неопределено Тогда
Для Каждого МетаМакет Из ОбъектМД[ИмяМножественное] Цикл
КоллекцияЭлементовМД.Добавить(МетаМакет.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
СтруктураТипаКонтекста = ВычислитьСвойствоФормыПоПолномуИмени(мРодительскийКонтекст);
Если СтруктураТипаКонтекста <> Неопределено Тогда
выхСтруктураТипаКонтекста = СтруктураТипаКонтекста;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Истина, Ложь) Цикл
НадоДобавить = Не ЗначениеЗаполнено(ИмяКорневогоТипаМД);
Если Не НадоДобавить Тогда
НадоДобавить = ирОбщий.СтрокиРавныЛкс(ИмяКорневогоТипаМД, СтрокаТипаМетаОбъекта.Единственное);
КонецЕсли;
Если Не НадоДобавить Тогда
ОтборСвойств = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова",
"ОбъектМетаданных: " + СтрокаТипаМетаОбъекта.Единственное, 0, "", НРег(ирОбщий.МножественноеИмяМДЛкс(ИмяДочернегоТипаМД)), "Свойство");
НадоДобавить = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(ОтборСвойств).Количество() > 0;
КонецЕсли;
Если НадоДобавить Тогда
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
// Имена типов
Если Истина
И Не ЗначениеЗаполнено(мРодительскийКонтекст)
И Не КонтекстТекстовогоЛитералаИзвестен
И ДобавлятьНизкоВероятные
Тогда
СтруктураТипаИменТипов = мПлатформа.НоваяСтруктураТипа("");
СтруктураТипаИменТипов.ТипЯзыка = "ИмяТипа";
СтруктураТипаИменТипов.Метаданные = Метаданные;
ТаблицаИменТипов = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипаИменТипов, мЯзыкПрограммы, Конфигурация, ВнешниеФункцииКомпоновкиДанных,,,, мФлагиКомпиляции,,,,,, мНаборыСлов);
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИменТипов, ТаблицаСлов);
ИначеЕсли Истина
И ЗначениеЗаполнено(мРодительскийКонтекст)
И мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(Новый Структура("БазовыйТип, ЯзыкПрограммы", мРодительскийКонтекст, мЯзыкПрограммы)).Количество() > 0
Тогда
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = мРодительскийКонтекст;
ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
выхСтруктураТипаКонтекста.ТипЯзыка = ВыбраннаяСтруктураТипа.ТипЯзыка;
Если Найти(мРодительскийКонтекст, ".") = 0 Тогда
выхСтруктураТипаКонтекста.Метаданные = Метаданные;
КонецЕсли;
КонецЕсли;
// Имена БД
КорневоеСловоБД = "БД";
Если Истина
И Не ЗначениеЗаполнено(мРодительскийКонтекст)
И Не КонтекстТекстовогоЛитералаИзвестен
И ДобавлятьНизкоВероятные
Тогда
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = КорневоеСловоБД;
СтрокаСлова.ТипСлова = "Свойство";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ПервоеСловоРодителя, КорневоеСловоБД) Тогда
мЯзыкПрограммы = 1;
СтруктураТипаИменБД = ВычислитьТипЗначенияВыражения(Сред(мРодительскийКонтекст, СтрДлина(КорневоеСловоБД + ".") + 1))[0];
ТаблицаСловБД = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипаИменБД, 1, Конфигурация, ВнешниеФункцииКомпоновкиДанных,,,, мФлагиКомпиляции);
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаСловБД, ТаблицаСлов);
мЯзыкПрограммы = 0;
КонецЕсли;
КонецЕсли;
ДобавитьПростыеСлова(КоллекцияЭлементовМД);
ТаблицаТиповКонтекста.Очистить(); // Нужно для прерывания циклического выбора слова автодополнения
Если мЯзыкПрограммы = 0 И ирОбщий.ЛиВнутриПрепроцессораЛкс(мТекущаяСтрокаНачало) Тогда
Слова = Новый Массив;
Слова.Добавить("Если");
Слова.Добавить("Тогда");
Слова.Добавить("ИначеЕсли");
Слова.Добавить("Иначе");
Слова.Добавить("КонецЕсли");
Слова.Добавить("Вставка");
Слова.Добавить("КонецВставки");
Слова.Добавить("Удаление");
Слова.Добавить("КонецУдаления");
Слова.Добавить("Область");
Слова.Добавить("КонецОбласти");
Слова.Добавить("Клиент");
Слова.Добавить("Сервер");
Слова.Добавить("ТолстыйКлиентУправляемоеПриложение");
Слова.Добавить("ТолстыйКлиентОбычноеПриложение");
Слова.Добавить("ТонкийКлиент");
Слова.Добавить("ВебКлиент");
Слова.Добавить("МобильныйКлиент");
Слова.Добавить("ВнешнееСоединение");
Для Каждого Слово Из Слова Цикл
мПлатформа.ДобавитьВТаблицуСлов(ТаблицаСлов, Слово, "Конструкция",, "", "Предопределенный");
КонецЦикла;
ДобавлятьСтатистическиеСлова = Ложь;
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "";
выхСтруктураТипаКонтекста.ТипЯзыка = "Препроцессор";
Иначе
ДобавлятьЛокальныйКонтекст = Истина
И мЭтоЛокальныйКонтекстТаблицыСлов
И (Ложь
Или Не мЭтоТекстовыйЛитерал
Или выхСтруктураТипаКонтекста.ТипЯзыка <> ""
Или РазрешитьОткрытиеОкон)
;
Попытка
ВыгрузкаТаблицыСлов = мПлатформа.ТаблицаСловИзСтруктурыТипа(выхСтруктураТипаКонтекста, мЯзыкПрограммы, Конфигурация, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы,,,
?(мЭтоТекстовыйЛитерал И выхСтруктураТипаКонтекста.ТипЯзыка <> "ИмяТипа", Неопределено, мФлагиКомпиляции),, МодульМетаданныхКонтекста(выхСтруктураТипаКонтекста),,, ДобавлятьЛокальныйКонтекст, мНаборыСлов);
СловаДляУточненияТипа = ВыгрузкаТаблицыСлов.НайтиСтроки(Новый Структура("МожноУточнитьТип", Истина));
Если ВычислятьТипы Или СловаДляУточненияТипа.Количество() < 50 Тогда
Для Каждого ВнутренняяСтрокаСлова Из СловаДляУточненияТипа Цикл
ОбновитьТипЗначенияИзТаблицыТипов(ВнутренняяСтрокаСлова, ВнутренняяСтрокаСлова.ТаблицаТипов, Ложь);
КонецЦикла;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ВыгрузкаТаблицыСлов = Новый ТаблицаЗначений;
#КонецЕсли
Если Ложь
Или мЭтоЛокальныйКонтекстТаблицыСлов
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ВнешнийИсточникДанных.<Имя внешнего источника>.ВременнаяТаблица"
Тогда
Если ЯзыкПрограммы <> 0 И мЭтоЛокальныйКонтекстТаблицыСлов Тогда
Для Каждого СтрокаСлова Из ТаблицаЛокальногоКонтекста("Свойство") Цикл
НоваяСтрока = мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаСлова.Имя, "Свойство");
Если Не ЗначениеЗаполнено(НоваяСтрока.Определение) Тогда
НоваяСтрока.Определение = "Локальный";
КонецЕсли;
//Если ЗаполнятьТипы Тогда // Если откладывать вычисление типа, то потом через метод УточнитьТипЗначенияВСтрокеТаблицыСлов он не вычислится
НоваяСтрока.ТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(СтрокаСлова.ТаблицаТипов);
//КонецЕсли;
КонецЦикла;
КонецЕсли;
ВыгрузкаТаблицыСлов.Индексы.Добавить("Слово, ТипСлова");
Если выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ВнешнийИсточникДанных.<Имя внешнего источника>.ВременнаяТаблица" Тогда
Для Каждого СтрокаВременнойТаблицы Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("Тип", "ВременнаяТаблица")) Цикл
мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаВременнойТаблицы.Имя, "Свойство",, "ВременнаяТаблица", "Локальный");
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Истина
И мЭтоЛокальныйКонтекстТаблицыСлов
И мМетодМодуля <> Неопределено
Тогда
ПараметрыМетодаМодуля = мПлатформа.ПараметрыМетодаМодуля(мМетодМодуля);
Если ПараметрыМетодаМодуля <> Неопределено Тогда
Для Каждого СтрокаПараметра Из ПараметрыМетодаМодуля Цикл
мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаПараметра.Имя, "Свойство",, СтрокаПараметра.ТипЗначения, "Локальный");
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Истина
И мЯзыкПрограммы = 0
И Не мЭтоТекстовыйЛитерал
И мЭтоЛокальныйКонтекстТаблицыСлов
И мМодульМетаданных <> Неопределено
И ирОбщий.СтрКончаетсяНаЛкс(мИмяМодуля, ".Форма.Модуль")
И (Ложь
Или мМетодМодуля = Неопределено
Или мПозицияВТексте < мМетодМодуля.ПозицияОпределения)
Тогда
ДирективыКомпиляцииТипаМодуля = Новый Массив;
ДирективыКомпиляцииТипаМодуля.Добавить("НаСервере");
ДирективыКомпиляцииТипаМодуля.Добавить("НаКлиенте");
ДирективыКомпиляцииТипаМодуля.Добавить("НаКлиентеНаСервереБезКонтекста");
ДирективыКомпиляцииТипаМодуля.Добавить("НаСервереБезКонтекста");
Для Каждого Директива Из ДирективыКомпиляцииТипаМодуля Цикл
мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, "&" + Директива, "Конструкция",, "", "Предопределенный");
КонецЦикла;
КонецЕсли;
Если выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "МенеджерВременныхТаблиц" Тогда
мПлатформа.ДобавитьВТаблицуСлов(ТаблицаСлов, "докДобавить", "Метод",, Неопределено, "Локальный");
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ВыгрузкаТаблицыСлов, ТаблицаСлов);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат Ложь;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
выхСтруктураТипаКонтекста.ИмяОбщегоТипа, мЯзыкПрограммы, выхСтруктураТипаКонтекста.ТипЯзыка);
ДобавлятьСтатистическиеСлова = Ложь
Или ЗначениеЗаполнено(мРодительскийКонтекст)
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст"
Или ДобавлятьЛокальныйКонтекст
Или мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() > 0;
КонецЕсли;
_РежимОтладки = Ложь;
// 13мс на 1500 слов
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
СтрокаСлова.НСлово = НРег(СтрокаСлова.Слово);
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл   СтрокаСлова.НСлово = НРег(СтрокаСлова.Слово);   КонецЦикла;  
КонецЕсли;
Если РазрешитьОткрытиеОкон Или ВычислятьТипы Или ДобавлятьСтатистическиеСлова Тогда
Если ДобавлятьСтатистическиеСлова Тогда
ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Не мЭтоТекстовыйЛитерал И Не ЗначениеЗаполнено(мРодительскийКонтекст), Истина, Ложь);
//Если Истина
// И _УдалитьФункциюНовый // https://www.hostedredmine.com/issues/963017
// И мЭтоЛокальныйКонтекст
//Тогда
// СтрокаСловаНовый = ТаблицаСлов.НайтиСтроки(Новый Структура("Слово, ТипСлова", "Новый", "Метод"));
// Если СтрокаСловаНовый.Количество() > 0 Тогда
// ТаблицаСлов.Удалить(СтрокаСловаНовый[0]);
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
Если Прав(мТекущееСлово, 1) = "(" Тогда
ЧистоеТекущееСлово = Лев(мТекущееСлово, СтрДлина(мТекущееСлово) - 1);
ТипТекущегоСлова = "Метод";
Иначе
ЧистоеТекущееСлово = мТекущееСлово;
ТипТекущегоСлова = "Свойство";
КонецЕсли;
КлючПоиска = Новый Структура("НСлово, Определение, ТипСлова", НРег(ЧистоеТекущееСлово), "Статистический", ТипТекущегоСлова);
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
НайденнаяСтрока.Частота = НайденнаяСтрока.Частота - 1;
Если НайденнаяСтрока.Частота = 0 Тогда
ТаблицаСлов.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЕсли;
ТаблицаСлов.Свернуть("НСлово, Слово, ТипСлова, Определение, ТипЗначения", "Частота");
КонецЕсли;
Если Сортировать Тогда
ТаблицаСлов.Сортировать("НСлово, ТипСлова, Определение, ТипЗначения, Частота");
КонецЕсли;
Если ОтделятьБольшиеНаборыСлов Тогда
мСтруктураТипаКонтекста = выхСтруктураТипаКонтекста;
КонецЕсли;
Возврат Истина;
КонецФункции
//.
// Параметры:
// КоллекцияЭлементовМД - Массив[Строка, ОбъектМетаданных]
Процедура ДобавитьПростыеСлова(КоллекцияЭлементовМД)
Для Каждого ЭлементКоллекцииМД Из КоллекцияЭлементовМД Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
Если ТипЗнч(ЭлементКоллекцииМД) = Тип("Строка") Тогда
СтрокаСлова.Слово = ЭлементКоллекцииМД;
Иначе
СтрокаСлова.Слово = ЭлементКоллекцииМД.Имя;
КонецЕсли;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Метаданные";
СтрокаСлова.ТипЗначения = "Строка";
КонецЦикла;
КонецПроцедуры
//.
// Параметры:
// ТолькоЭкспортные - Строка -
// Возвращаемое значение:
// КоллекцияМетаданных: ФункциональныеОпции, Массив[?], Массив[Строка] -
Функция ОтобратьМетодыДляСпискаСлов(Знач Модуль, Знач ТолькоЭкспортные = Истина) Экспорт
Если Модуль = Неопределено Тогда
Модуль = мМодульМетаданных;
КонецЕсли;
ОтобранныеМетоды = Модуль.Методы;
УсловиеОтбора = "Э.Имя<>П1";
Если ТолькоЭкспортные Тогда
УсловиеОтбора = УсловиеОтбора + " И Э.ЛиЭкспорт";
КонецЕсли;
КоллекцияЭлементовМД = ирОбщий.ОтобратьКоллекциюЛкс(ОтобранныеМетоды, УсловиеОтбора,, "<>");
Возврат КоллекцияЭлементовМД;
КонецФункции
//.
// Параметры:
// КоллекцияЭлементовМД - ? -
Процедура ДобавитьКоллекциюМетаданныхВТаблицуСлов(Знач КоллекцияЭлементовМД) Экспорт
КонецПроцедуры
//.
// Параметры:
// СтрокаОписания - ? -
// Возвращаемое значение:
// Строка -
Функция ИмяПараметраВызоваМетода(СтрокаОписания) Экспорт
ИмяПараметра = "";
Если СтрокаОписания = Неопределено Тогда
Возврат ИмяПараметра;
КонецЕсли;
Если СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
ПараметрыМетодаМодуля = мПлатформа.ПараметрыМетодаМодуля(СтрокаОписания);
Если ПараметрыМетодаМодуля <> Неопределено И ПараметрыМетодаМодуля.Количество() > мНомерПараметра Тогда
ИмяПараметра = ПараметрыМетодаМодуля[мНомерПараметра - 1].Имя;
КонецЕсли;
Иначе
СтрокиПараметров = мПлатформа.ПараметрыМетодаПлатформы(СтрокаОписания);
СтрокиПараметров = СтрокиПараметров.НайтиСтроки(Новый Структура("Номер", мНомерПараметра));
Для Каждого СтрокаПараметра Из СтрокиПараметров Цикл
Если Найти(СтрокаПараметра.ТипЗначения, "Строка") > 0 Тогда
ИмяПараметра = ПодготовитьИмяПараметраМетода(СтрокаПараметра.Параметр);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ИмяПараметра;
КонецФункции
Функция КопияКомпоненты() Экспорт
КопияКопоненты = ирОбщий.НовыйАнализаторКодаЛкс();
ЗаполнитьЗначенияСвойств(КопияКопоненты, ЭтотОбъект);
Возврат КопияКопоненты;
КонецФункции
Процедура ВставитьВыбранноеСловоАвтодополнения(СтрокаРезультата, ТаблицаТиповКонтекста = Неопределено, ПараметрЗакрытияПодсказки = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТаблицаСтатистикиВыбора = мПлатформа.ТаблицаСтатистикиВыбора;
Если Найти(НРег(СтрокаРезультата.Слово), НРег(мНачалоСлова + мКонецКонтекста)) = 1 Тогда
НеобрабатываемыйКонецСтроки = Сред(мТекущаяСтрокаКонец, СтрДлина(мКонецКонтекста) + 1);
Иначе
НеобрабатываемыйКонецСтроки = мТекущаяСтрокаКонец;
мРегВыражение.Pattern = "[" + шБуква + "\d]";
Если мРегВыражение.Проверить(Лев(НеобрабатываемыйКонецСтроки, 1)) Тогда
НеобрабатываемыйКонецСтроки = " " + НеобрабатываемыйКонецСтроки;
КонецЕсли;
КонецЕсли;
СтрокаНачала = "";
Если Истина
И Не мЭтоТекстовыйЛитерал
И Не ирОбщий.ЛиВнутриКомментарияЛкс(мТекущаяСтрокаНачало)
И СтрокаРезультата.ТипСлова = "Метод"
Тогда
Если Лев(мКонецКонтекста, 1) = "(" Тогда
НеобрабатываемыйКонецСтроки = Сред(НеобрабатываемыйКонецСтроки, 2);
КонецЕсли;
СтрокаОкончания = "()";
Если Истина
И ПараметрЗакрытияПодсказки = Истина
И Прав(мТекущееСлово, 1) = "("
Тогда
СтрокаОкончания = "(";
Иначе
Если Истина
И ЯзыкПрограммы = 0
И Лев(НеобрабатываемыйКонецСтроки, 1) <> ";"
И СтрокаРезультата.ТипЗначения = ""
И СтрокаРезультата.Определение <> "Статистический"
Тогда
СтрокаОкончания = СтрокаОкончания + ";"
КонецЕсли;
КонецЕсли;
СмещениеКурсораВОкончании = СтрДлина(СтрокаОкончания);
Если ПараметрЗакрытияПодсказки = Истина Тогда
ТаблицаМетодовМодуля = мПлатформа.СловаКонтекстаМетаданные(мСтруктураТипаКонтекста, СтрокаРезультата.Слово, "Метод",,,,, Истина, мФлагиКомпиляции, МодульМетаданныхКонтекста(мСтруктураТипаКонтекста));
Если Истина
И ТаблицаМетодовМодуля.Количество() > 0
И ТаблицаМетодовМодуля[0].Слово <> "<>"
Тогда
СтрокаОписания = ТаблицаМетодовМодуля[0].ТаблицаТипов[0].СтрокаОписания;
Если Ложь
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("COMОбъект")
И СтрокаОписания.Parameters.Count > 0)
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписания.Параметры <> Неопределено)
Тогда
СмещениеКурсораВОкончании = 1;
КонецЕсли;
Иначе
МассивОбщихТипов = мПлатформа.ТаблицаОбщихТиповИзСтруктурыТипа(мСтруктураТипаКонтекста, мЭтоЛокальныйКонтекстТаблицыСлов);
КлючПоискаПараметров = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова"); // Индекс
КлючПоискаПараметров.НСлово = НРег(СтрокаРезультата.Слово);
КлючПоискаПараметров.ЯзыкПрограммы = ЯзыкПрограммы;
КлючПоискаПараметров.ТипЯзыка = "";
КлючПоискаПараметров.ТипСлова = СтрокаРезультата.ТипСлова;
СмещениеКурсораВОкончании = 2;
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
КлючПоискаПараметров.ТипКонтекста = СтрокаОбщегоТипа.ИмяОбщегоТипа;
СтрокиКонтекста = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоискаПараметров);
Если СтрокиКонтекста.Количество() > 0 Тогда
НайденныеСтроки = мПлатформа.ПараметрыМетодаПлатформы(СтрокиКонтекста[0]);
Если НайденныеСтроки.Количество() > 0 Тогда
СмещениеКурсораВОкончании = 1;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ПараметрЗакрытияПодсказки = "."
И ЯзыкПрограммы <> 0
И СтрокаРезультата.ТипСлова = "Свойство"
И Найти(СтрокаРезультата.Слово, мПараметрыДиалектаSQL.ПрефиксПараметра) = 1
Тогда
СтрокаНачала = "(";
СтрокаОкончания = ")";
СмещениеКурсораВОкончании = 1;
Иначе
СтрокаОкончания = "";
СмещениеКурсораВОкончании = 0;
КонецЕсли;
// Обновим статистику выбора
Если Истина
И СтрокаРезультата.Определение <> "Локальный"
И СтрокаРезультата.Определение <> "Статистический"
Тогда
КлючПоиска = Новый Структура("ЯзыкПрограммы, ТипКонтекста, Слово", ЯзыкПрограммы, мКонкретныйТипКонтекста, СтрокаРезультата.Слово);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоиска);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
КонецЕсли;
СтрокаДобавка = СтрокаНачала + СтрокаРезультата.Слово + СтрокаОкончания;
Если мРодительскийКонтекст <> "" Тогда
СтрокаДобавка = мРодительскийКонтекст + "." + СтрокаДобавка;
КонецЕсли;
мРодительскийКонтекст = СтрокаДобавка;
Если Истина
И ПараметрЗакрытияПодсказки <> Истина
Тогда
СтрокаДобавка = СтрокаДобавка + ПараметрЗакрытияПодсказки;
мТекущееСлово = СтрокаРезультата.Слово;
Если ПараметрЗакрытияПодсказки = "." Тогда
Если СтрокаРезультата.Определение = "Статистический" Тогда
ТаблицаТиповКонтекста = ВычислитьТипЗначенияВыражения(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
Иначе
ТаблицаТиповКонтекста = ВычислитьТипДочернегоЭлемента(ирОбщий.ЗначенияВМассивЛкс(мСтруктураТипаКонтекста), мТекущееСлово, СтрокаРезультата.ТипСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
мТекущаяСтрокаНачало = Лев(мТекущаяСтрокаНачало, мКонечнаяКолонка - 1 - СтрДлина(мНачалоКонтекста)) + СтрокаДобавка;
ТекущаяСтрока = мТекущаяСтрокаНачало + НеобрабатываемыйКонецСтроки;
Если мОригинальныйТекст = "" Тогда
ВыделенныйТекст("" + ТекущаяСтрока);
Иначе
Если ПолеТекста.КоличествоСтрок() < мКонечнаяСтрока Тогда
ПолеТекста.ДобавитьСтроку(ТекущаяСтрока);
Иначе
ПолеТекста.ЗаменитьСтроку(мКонечнаяСтрока, ТекущаяСтрока); // Баг платформы. Вызывает выделение всего предшествующего текста на 8.3.18
КонецЕсли;
КонецЕсли;
УстановитьПризнакМодифицированностиФормы();
мОткрытьСправкуПоПараметру = АвтоматическаяПодсказкаПоВызовуМетода() И СмещениеКурсораВОкончании = 1;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(СтрокаДобавка) - СтрДлина(мНачалоКонтекста) - СтрДлина(СтрокаОкончания) + СмещениеКурсораВОкончании;
мНачальнаяКолонка = мКонечнаяКолонка;
мНачалоКонтекста = мРодительскийКонтекст + ".";
мНачалоСлова = "";
ВосстановитьГраницыВыделенияПослеКоманды();
КонецПроцедуры
Функция АвтоматическаяПодсказкаПоВызовуМетода(Обновить = Ложь) Экспорт
Если АвтоматическаяПодсказкаПоВызовуМетода = Неопределено Или Обновить Тогда
АвтоматическаяПодсказкаПоВызовуМетода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаПоВызовуМетода") <> Ложь;
КонецЕсли;
Возврат АвтоматическаяПодсказкаПоВызовуМетода;
КонецФункции
Функция АвтоматическаяПодсказкаАвтодополненияHTML(Обновить = Ложь) Экспорт
Если АвтоматическаяПодсказкаАвтодополненияHTML = Неопределено Или Обновить Тогда
АвтоматическаяПодсказкаАвтодополненияHTML = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаАвтодополненияHTML") <> Ложь;
КонецЕсли;
Возврат АвтоматическаяПодсказкаАвтодополненияHTML;
КонецФункции
Функция ПоказыватьВсеТипыВСпискеАвтодополненияHTML(Обновить = Ложь) Экспорт
Если ПоказыватьВсеТипыВСпискеАвтодополненияHTML = Неопределено Или Обновить Тогда
ПоказыватьВсеТипыВСпискеАвтодополненияHTML = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПоказыватьВсеТипыВСпискеАвтодополненияHTML") = Истина;
КонецЕсли;
Возврат ПоказыватьВсеТипыВСпискеАвтодополненияHTML;
КонецФункции
Функция ПредпочитатьHTMLРедакторКода(Обновить = Ложь) Экспорт
Если Не ирКэш.ДоступенРедакторМонакоЛкс() Тогда
Возврат Ложь;
КонецЕсли;
Если ПредпочитатьHTMLРедакторКода = Неопределено Или Обновить Тогда
ПредпочитатьHTMLРедакторКода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитатьHTMLРедакторКода") = Истина;
КонецЕсли;
Возврат ПредпочитатьHTMLРедакторКода;
КонецФункции
Процедура ДобавитьCOMКлассыВСписокСлов(Знач КоллекцияКолонок, Знач Компоненты)
Для Каждого Класс Из Компоненты Цикл
Если Не ЗначениеЗаполнено(Класс.Name) Тогда
Продолжить;
КонецЕсли;
ИмяКласса = Класс.Name;
КоллекцияКолонок.Добавить(ИмяКласса);
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(Знач ВнутренняяТаблицаСлов, Знач ВыгрузкаТаблицыСлов)
Для Каждого ВнутренняяСтрокаСлова Из ВнутренняяТаблицаСлов Цикл
НоваяСтрока = ВыгрузкаТаблицыСлов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВнутренняяСтрокаСлова);
ТаблицаТипов = ВнутренняяСтрокаСлова.ТаблицаТипов;
Если ТаблицаТипов <> Неопределено Тогда
ОбновитьТипЗначенияИзТаблицыТипов(НоваяСтрока, ТаблицаТипов);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция УточнитьТипЗначенияВСтрокеТаблицыСлов(Знач СтруктураТипаКонтекста, Знач ТекущаяСтрока, Знач ВернутьСтруктуруТипа = Ложь, Знач НужноУточнитьТип = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ТекущаяСтрока = ТаблицаСлов.Добавить();
#КонецЕсли
ТаблицаТипов = Неопределено;
НужноУточнитьТип = Ложь
Или НужноУточнитьТип
Или Лев(ТекущаяСтрока.ТипЗначения, 2) = "??"
Или Найти(ТекущаяСтрока.ТипЗначения, "<") > 0;
Если НужноУточнитьТип Или ВернутьСтруктуруТипа Тогда
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТекущаяСтрока.Определение = "Статистический" Тогда
ТаблицаТипов = ВычислитьТипЗначенияВыражения(ТекущаяСтрока.Слово, мТекстДляПоискаОпределения);
Иначе
ОписанияСлов = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипаКонтекста, мЯзыкПрограммы, Конфигурация,, Истина,, ТекущаяСтрока.ТипСлова, мФлагиКомпиляции, ТекущаяСтрока.Слово,
МодульМетаданныхКонтекста(СтруктураТипаКонтекста), НужноУточнитьТип,, мЭтоЛокальныйКонтекстТаблицыСлов);
Если ОписанияСлов.Количество() > 0 Тогда
ТаблицаТипов = ОписанияСлов[0].ТаблицаТипов;
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов <> Неопределено И НужноУточнитьТип Тогда
ОбновитьТипЗначенияИзТаблицыТипов(ТекущаяСтрока, ТаблицаТипов, ТекущаяСтрока.Определение <> "Метаданные");
КонецЕсли;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
Процедура ОткрытьСписокМетодов(Знач СтрокаПоиска = "", Знач ТолькоЭтогоМодуля = Ложь) Экспорт
Если Не ЗначениеЗаполнено(СтрокаПоиска) Тогда
//СтрокаПоиска = ирОбщий.ПервыйФрагментЛкс(мТекущееСлово, "("); // Часто вредно
КонецЕсли;
Если ТолькоЭтогоМодуля Тогда
НовыйКлючСохраненияПоложенияОкна = "ОдинМодуль";
НовыйКлючУникальности = мМодульМетаданных.Имя;
КонецЕсли;
ФормаВыбора = ПолучитьФорму("МетодыМодулей",, НовыйКлючУникальности);
ФормаВыбора.ПараметрСтрокаПоиска = СтрокаПоиска;
Если Не ФормаВыбора.Открыта() Тогда
ФормаВыбора.КлючСохраненияПоложенияОкна = НовыйКлючСохраненияПоложенияОкна;
КонецЕсли;
ФормаВыбора.ПараметрМодуль = мМодульМетаданных;
Если мМетодМодуля <> Неопределено Тогда
ФормаВыбора.ПараметрИмяМетода = мМетодМодуля.Имя;
КонецЕсли;
ФормаВыбора.Открыть();
КонецПроцедуры
Процедура ОткрытьПоискВызововМетода(Знач ИмяМетода = Неопределено, Знач ИскатьНепрямые = Неопределено, Знач Автозапуск = Истина) Экспорт
Если ИмяМетода = Неопределено Тогда
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст();
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ТаблицаТиповРодителя = ВычислитьТипЗначенияВыражения(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаРодителя = ТаблицаТиповРодителя[0];
Иначе
СтруктураТипаРодителя = мМодульМетаданных.СтруктураТипа;
КонецЕсли;
ИмяМетода = мКонтекст;
Если Прав(мКонтекст, 1) <> "(" И ЛиВЗаголовкеМетода() Тогда
ИмяМетода = мМетодМодуля.Имя + "(";
ИмяПараметра = мКонтекст;
КонецЕсли;
Иначе
ИмяМетода = ИмяМетода + "(";
КонецЕсли;
ТаблицаТиповКонтекста = ВычислитьТипЗначенияВыражения(ИмяМетода, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаКонтекста = ТаблицаТиповКонтекста[0];
ПолноеИмяМетода = "";
Если СтруктураТипаКонтекста.ТипЯзыка = "ИмяТипа" Тогда
ПолноеИмяМетода = "Новый ";
Если ИскатьНепрямые = Неопределено Тогда
ИскатьНепрямые = Ложь;
КонецЕсли;
Если Прав(ИмяМетода, 1) <> "(" Тогда
ИмяМетода = ИмяМетода + "(";
КонецЕсли;
СтруктураТипаКонтекста = Неопределено;
Иначе
Если Истина
И СтруктураТипаРодителя <> Неопределено
И СтруктураТипаРодителя.ИмяОбщегоТипа = "ОбщийМодуль"
Тогда
ПолноеИмяМетода = СтруктураТипаРодителя.Метаданные.Имя + ".";
Если ИскатьНепрямые = Неопределено Тогда
ИскатьНепрямые = Ложь;
КонецЕсли;
СтруктураТипаКонтекста = Неопределено;
ИначеЕсли ИскатьНепрямые = Неопределено Тогда
Если Истина
И СтруктураТипаКонтекста.СтрокаОписания <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания.ТипКонтекста = "Глобальный"
Тогда
ИскатьНепрямые = Ложь;
ИначеЕсли Истина
И СтруктураТипаКонтекста <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания <> Неопределено
И мМодульМетаданных <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания.Владелец() = мМодульМетаданных.Методы
И Не мМетодМодуля.ЛиЭкспорт
Тогда
ИскатьНепрямые = Ложь;
Иначе
ИскатьНепрямые = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ПолноеИмяМетода = ПолноеИмяМетода + ирОбщий.СтрокаБезКонцаЛкс(ирОбщий.ПоследнийФрагментЛкс(ИмяМетода), 1);
ПоискВызововМетода = ПолучитьФорму("СсылкиНаМетод",, ПолноеИмяМетода);
ПоискВызововМетода.ПараметрИскатьНепрямые = ИскатьНепрямые;
ПоискВызововМетода.ПараметрСтруктураТипаКонтекста = СтруктураТипаКонтекста;
ПоискВызововМетода.ПараметрИмяПараметра = ИмяПараметра;
ПоискВызововМетода.Открыть();
Если Прав(ИмяМетода, 1) = "(" И Автозапуск Тогда
ПоискВызововМетода.ОбновитьДанные();
КонецЕсли;
КонецПроцедуры
// Заменяет все символы табуляции в строке после первого печатного символа эквивалентным количеством пробелов.
//
// Параметры:
// Строка - Строка;
//
// Возвращаемое значение:
// Строка.
//
Функция ЗаменитьТабуляцииВСтроке(Знач Строка, ЛиТекущая = Ложь)
Табы = "";
А = 1; НачалоСтроки = Истина;
Пока А <= СтрДлина(Строка) Цикл
Если Сред(Строка, А, 1) <> Символы.Таб И НачалоСтроки Тогда
// Найдем начало строки без табов
Табы = Лев(Строка, А-1);
Строка = Прав(Строка, СтрДлина(Строка) - А + 1);
НачалоСтроки = Ложь;
ИначеЕсли Сред(Строка, А, 1) = Символы.Таб И НЕ НачалоСтроки Тогда
// Удалим табы из строки
Строка = Лев(Строка, А - 1) + Лев(" ", 4 - СтрДлина(Лев(Строка, А - 1)) % 4)
+ Прав(Строка, СтрДлина(Строка) - А);
Если Истина
И ЛиТекущая
И мКонечнаяКолонка > А
Тогда
мКонечнаяКолонка = мКонечнаяКолонка + 3 - СтрДлина(Лев(Строка, А - 1)) % 4;
КонецЕсли;
КонецЕсли;
А = А + 1;
КонецЦикла;
Возврат Табы + Строка;
КонецФункции
// Заменяет все символы табуляции в каждой строке текста после первого печатного символа эквивалентным
// количеством пробелов.
//
// Параметры:
// Нет.
//
Процедура ЗаменитьТабуляции()
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
КоличествоСтрок = ПолеТекста.КоличествоСтрок();
Для А = 1 По КоличествоСтрок Цикл
Строка = ЗаменитьТабуляцииВСтроке(ПолеТекста.ПолучитьСтроку(А), (А = мКонечнаяСтрока));
ПолеТекста.ЗаменитьСтроку(А, Строка);
КонецЦикла;
УстановитьПризнакМодифицированностиФормы();
мНачальнаяКолонка = мКонечнаяКолонка;
КонецПроцедуры
Процедура УстановитьАвтоКонтекстнаяПомощь(НовыйРежим)
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь");
Если Кнопка = Неопределено Тогда
// Это сделано временно для работы в ссылочном режиме
Возврат;
КонецЕсли;
мАвтоКонтекстнаяПомощь = НовыйРежим;
Если мАвтоКонтекстнаяПомощь Тогда
ФормаВладелец.ПодключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку", 1);
Иначе
ФормаВладелец.ОтключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку");
КонецЕсли;
Кнопка.Пометка = мАвтоКонтекстнаяПомощь;
КонецПроцедуры
// Удаляет все символы переноса строки из текста.
//
// Параметры:
// Нет.
//
Процедура УдалитьПереносы()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
Текст = ПолеТекста.ПолучитьТекст();
Текст = СокрЛП(Текст);
Если Истина
И Лев(Текст, 1) = """"
И Лев(Текст, 2) <> """"""
Тогда
Текст = "|" + Сред(Текст, 2);
КонецЕсли;
ОбработанныеСтроки = Новый Массив;
Для Каждого СтрокаТекста Из ирОбщий.СтрРазделитьЛкс(Текст, Символы.ПС) Цикл
Если Лев(СокрЛ(СтрокаТекста), 1) = "|" Тогда
СтрокаТекста = СтрЗаменить(СтрокаТекста, """""", """");
СтрокаТекста = СтрЗаменить(СтрокаТекста, "|", "");
КонецЕсли;
ОбработанныеСтроки.Добавить(СтрокаТекста);
КонецЦикла;
Текст = ирОбщий.СтрСоединитьЛкс(ОбработанныеСтроки, Символы.ПС);
Если Истина
И Прав(Текст, 1) = """"
И Прав(Текст, 2) <> """"""
Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 1);
КонецЕсли;
Если Истина
И Прав(Текст, 2) = """;"
И Прав(Текст, 3) <> """"";"
Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 2);
КонецЕсли;
ПолеТекста.УстановитьТекст(Текст);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьПолучитьФорму(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
ИмяФормы = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если ИмяФормы = Неопределено Тогда
//СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ирОбщий.ТипУправляемаяФормаЛкс());
Иначе
Если Найти(ИмяФормы, ".") = 0 Тогда
Если ирОбщий.СтрокиРавныЛкс("ПолучитьОбщуюФорму", Слово) Тогда
МетаФорма = Метаданные.ОбщиеФормы.Найти(ИмяФормы);
Иначе
ОбъектМД = РодительскаяСтруктураТипа.Метаданные;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.ирАлгоритмы;
#КонецЕсли
Если ТипЗнч(ОбъектМД) <> Тип("ОбъектМетаданных") Тогда
Возврат Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяФормы) Тогда
МетаФорма = ОбъектМД.Формы.Найти(ИмяФормы);
ИначеЕсли ирОбщий.СтрокиРавныЛкс("ПолучитьФормуСписка", Слово) Тогда
МетаФорма = ОбъектМД.ОсновнаяФормаСписка;
ИначеЕсли ирОбщий.СтрокиРавныЛкс("ПолучитьФормуВыбора", Слово) Тогда
МетаФорма = ОбъектМД.ОсновнаяФормаДляВыбора;
Иначе
ИменаСвойствОсновнойФормы = Новый Массив();
ИменаСвойствОсновнойФормы.Добавить("ОсновнаяФорма");
ИменаСвойствОсновнойФормы.Добавить("ОсновнаяФормаОбъекта");
ИменаСвойствОсновнойФормы.Добавить("ОсновнаяФормаЗаписи");
Для Каждого ИмяСвойстваОсновнойФормы Из ИменаСвойствОсновнойФормы Цикл
Попытка
МетаФорма = ОбъектМД[ИмяСвойстваОсновнойФормы];
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если МетаФорма = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИмяФормы = МетаФорма.ПолноеИмя();
КонецЕсли;
ФормаИлиИмитатор = мПлатформа.ПассивнаяФормаПоИмениКэш(ИмяФормы);
Если ФормаИлиИмитатор <> Неопределено Тогда
Если ТипЗнч(ФормаИлиИмитатор) = Тип("Структура") Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ФормаИлиИмитатор.Тип);
СтруктураТипа.Метаданные = ФормаИлиИмитатор;
Иначе
Форма = ФормаИлиИмитатор;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Форма);
КонецЕсли;
Если ТипЗнч(Форма) = Тип("Форма") Тогда
СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанныеФормы <> Неопределено Тогда
СлужебныеДанныеФормы.ИмяФормы = ИмяФормы;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураТипа <> Неопределено Тогда
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
КонецЕсли;
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьПолучитьМакет(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
ИмяМакета = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если ИмяМакета = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Макет = Неопределено;
Если ирОбщий.СтрокиРавныЛкс("ПолучитьОбщийМакет", Слово) Тогда
МетаМакет = Метаданные.ОбщиеМакеты.Найти(ИмяМакета);
Если МетаМакет <> Неопределено Тогда
Макет = ПолучитьОбщийМакет(ИмяМакета);
КонецЕсли;
Иначе
ОбъектМД = РодительскаяСтруктураТипа.Метаданные;
//ОбъектМД = Метаданные.Справочники.ирАлгоритмы; // для подсказки
Если ТипЗнч(ОбъектМД) <> Тип("ОбъектМетаданных") Тогда
Возврат Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяМакета) Тогда
МетаМакет = ОбъектМД.Макеты.Найти(ИмяМакета);
Если МетаМакет <> Неопределено Тогда
Менеджер = Новый(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД.ПолноеИмя(), "Менеджер")); // ОбработкаМенеджер.ирПлатформа
Макет = Менеджер.ПолучитьМакет(ИмяМакета);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если МетаМакет = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Макет);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьПрочитатьЗначениеJSON(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
Текст = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если Текст = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
ДанныеИзТекста = ирОбщий.ОбъектИзСтрокиJSONЛкс(Текст);
Исключение
Возврат Неопределено;
КонецПопытки;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ДанныеИзТекста);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьФабрикаXDTOПрочитатьJSON(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
Текст = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если Текст = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
Чтение = Новый("ЧтениеJSON"); // В 8.2 нет
Чтение.УстановитьСтроку(Текст);
ДанныеИзТекста = ФабрикаXDTO.ПрочитатьJSON(Чтение);
Исключение
Возврат Неопределено;
КонецПопытки;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ДанныеИзТекста);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьФабрикаXDTOПрочитатьXML(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
Текст = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если Текст = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(Текст);
ДанныеИзТекста = ФабрикаXDTO.ПрочитатьXML(Чтение);
Исключение
Возврат Неопределено;
КонецПопытки;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ДанныеИзТекста);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьПолучитьОбласть(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = МассивПараметров[0];
ИмяОбласти = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если Ложь
Или ИмяОбласти = Неопределено
Или ТипЗнч(РодительскаяСтруктураТипа.Метаданные) <> Тип("ТабличныйДокумент")
Или РодительскаяСтруктураТипа.Метаданные.Области.Найти(ИмяОбласти) = Неопределено
Тогда
Возврат Неопределено;
КонецЕсли;
ОбластьЯчеек = РодительскаяСтруктураТипа.Метаданные.ПолучитьОбласть(ИмяОбласти);
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ОбластьЯчеек);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьРеквизитФормыВЗначение(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Если Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа <> "ФормаКлиентскогоПриложения"
И Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение формы")
Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
ИмяРеквизита = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если ПустаяСтрока(ИмяРеквизита) Тогда
Возврат Неопределено;
КонецЕсли;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(РодительскаяСтруктураТипа.Метаданные);
Если Истина
И СлужебныеДанные <> Неопределено
И СлужебныеДанные.Свойство("Реквизиты")
И Найти(ИмяРеквизита, ".") = 0
Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(СлужебныеДанные.Реквизиты.Найти(ИмяРеквизита, "НИмя").ОписаниеТипов.Типы()[0]);
КонецЕсли;
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
// МассивПараметров - Массив -
Функция ВычислитьКоллекцияДобавить(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Если РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВсеЭлементыФормы" Тогда
ИндексПараметраТипа = 1;
Иначе
ИндексПараметраТипа = 0;
КонецЕсли;
Если МассивПараметров.ВГраница() < ИндексПараметраТипа Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[ИндексПараметраТипа]);
Если Не ирОбщий.СтрНачинаетсяСЛкс(ПервыйПараметр, "тип(""", Истина) Тогда
Возврат Неопределено;
КонецЕсли;
ИмяТипа = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(ПервыйПараметр, "тип(", ")"));
Попытка
ТипЭлемента = Тип(ИмяТипа);
Исключение
Возврат Неопределено;
КонецПопытки;
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ТипЭлемента);
ДобавитьЕдинственныйТип(ТаблицаТипов, СтруктураТипа);
Возврат ТаблицаТипов;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. мПлатформа.НоваяСтруктураТипа() -
// ТаблицаТипов - см. мПлатформа.НоваяТаблицаТипов() -
Функция ВычислитьРезультатЗапросаВыгрузить(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
ПервыйПараметр = "";
Иначе
ПервыйПараметр = НРег(МассивПараметров[0]);
КонецЕсли;
Если Ложь
Или Не ЗначениеЗаполнено(ПервыйПараметр)
Или ирОбщий.СтрокиРавныЛкс(ПервыйПараметр, "ОбходРезультатаЗапроса.Прямой")
Тогда
ИмяОбщегоТипа = "ТаблицаЗначений";
Иначе
ИмяОбщегоТипа = "ДеревоЗначений";
КонецЕсли;
СтрокаТипа = ТаблицаТипов.Найти(ИмяОбщегоТипа, "ИмяОбщегоТипа");
ДобавитьЕдинственныйТип(ТаблицаТипов, СтрокаТипа);
Возврат ТаблицаТипов;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьНайтиЭлементКоллекцииЛкс(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Результат = ВычислитьТипЗначенияВыражения(МассивПараметров[0] + "[0]",,,,,, Ложь,,,, Истина);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьОтобратьКоллекциюЛкс(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() < 1 Тогда
Возврат Неопределено;
КонецЕсли;
ТаблицаТиповЭлементов = ВычислитьТипЗначенияВыражения(МассивПараметров[0] + "[0]",,,,,, Ложь,,,, Истина);
ИмяОбщегоТипа = "Массив[" + мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаТиповЭлементов) + "]";
//Результат = мПлатформа.ТаблицаСловИзСтруктурыТипа(РодительскаяСтруктураТипа,,,, Ложь,, "Метод", мФлагиКомпиляции, Слово)[0].ТаблицаТипов; // см. мПлатформа.НоваяТаблицаТипов()
//Результат[0].ИмяОбщегоТипа = ИмяОбщегоТипа;
//Пока Результат.Количество() > 1 Цикл
// // Удаляем статически вычисленные типы
// Результат.Удалить(1);
//КонецЦикла;
СтруктураТипа = мПлатформа.НоваяСтруктураТипа(ИмяОбщегоТипа);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьСоздатьОбъектПоИмениМетаданныхЛкс(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
Текст = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Попытка
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Текст, "Объект");
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа);
Исключение
Возврат Неопределено;
КонецПопытки;
Результат = мПлатформа.ДобавитьВТаблицуТипов(, ОписаниеТипов);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьВычислить(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = НРег(МассивПараметров[0]);
Текст = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Если Ложь
Или ТипЗнч(Текст) <> Тип("Строка")
Или Найти(Текст, "(") > 0
Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
Значение = Вычислить(Текст);
Исключение
Возврат Неопределено;
КонецПопытки;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Значение);
Если СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль" Тогда
СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули.Найти(Текст);
КонецЕсли;
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьОбщийМодуль(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = МассивПараметров[0];
ИмяМодуля = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
ОбъектМД = Метаданные.ОбщиеМодули.Найти(ИмяМодуля);
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип("ОбщийМодуль"));
СтруктураТипа.Метаданные = ОбъектМД;
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьМакетПечатнойФормыБСП(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйПараметр = МассивПараметров[0];
ИмяМакета = ВычислитьЗначениеВыражения(ПервыйПараметр, ПредшествующийТекст,,, ПозицияВМетоде);
Попытка
Макет = ирСервер.ВычислитьВыражение("УправлениеПечатью.МакетПечатнойФормы(""" + ИмяМакета + """)");
Исключение
Макет = Неопределено;
КонецПопытки;
Если Макет = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Макет);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьЗначенияРеквизитовОбъектаБСП(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
ИменаРеквизитов = ВычислитьЗначениеВыражения(МассивПараметров[1], ПредшествующийТекст,,, ПозицияВМетоде);
Если ТипЗнч(ИменаРеквизитов) <> Тип("Строка") Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
Структура = Новый Структура(ИменаРеквизитов);
Исключение
Возврат Неопределено;
КонецПопытки;
ТипыСсылки = ВычислитьТипЗначенияВыражения(МассивПараметров[0], ПредшествующийТекст,,,,, Ложь,,,,, ПозицияВМетоде);
Если ТипЗнч(ТипыСсылки[0].Метаданные) = Тип("ОбъектМетаданных") Тогда
ТипСсылки = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ТипыСсылки[0].Метаданные.ПолноеИмя());
Попытка
ПустаяСсылка = Новый (ТипСсылки);
ЗаполнитьЗначенияСвойств(Структура, ПустаяСсылка);
Исключение
КонецПопытки;
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Структура);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// .
// Параметры:
// РодительскаяСтруктураТипа - см. Обработки.ирПлатформа.Создать().НоваяСтруктураТипа() -
Функция ВычислитьСтрокаТаблицыЗначенийВСтруктуруБСП(Знач РодительскаяСтруктураТипа, Знач МассивПараметров, Знач Слово = "", Знач ПредшествующийТекст = "", Знач ПозицияВМетоде = 0, Знач ТаблицаТипов = Неопределено)
Если МассивПараметров.Количество() < 1 Тогда
Возврат Неопределено;
КонецЕсли;
ТаблицаТипов = ВычислитьТипЗначенияВыражения(МассивПараметров[0], ПредшествующийТекст,,,,, Ложь,,,,, ПозицияВМетоде);
ТаблицаСвойств = мПлатформа.ТаблицаСловИзСтруктурыТипа(ТаблицаТипов[0],,,, Ложь,, "Свойство");
Структура = новый Структура;
Для Каждого СтрокаСвойства Из ТаблицаСвойств Цикл
Структура.Вставить(СтрокаСвойства.Слово, СтрокаСвойства.ТаблицаТипов);
КонецЦикла;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Структура);
Результат = мПлатформа.ДобавитьВТаблицуТипов(, СтруктураТипа);
Возврат Результат;
КонецФункции
// Добавляет переменную локального контекста.
//
// Параметры:
// ИмяПеременной - Строка;
// ДопустимыеТипы - Строка, ТаблицаЗначений;
//
Процедура ДобавитьПеременнуюЛокальногоКонтекста(ИмяПеременной, ДопустимыеТипы) Экспорт
НоваяСтрока = ДобавитьСловоЛокальногоКонтекста(ИмяПеременной);
Если ТипЗнч(ДопустимыеТипы) = Тип("Строка") Тогда
МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";");
ТаблицаТипов = НоваяСтрока.ТаблицаТипов;
Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
СтруктураТипа = мПлатформа.СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
СтруктураТипа.Вставить("СтрокаОписания", НоваяСтрока); // Циклическая ссылка СтрокаОписания
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
НоваяСтрока.ТаблицаТипов = ТаблицаТипов;
Иначе
НоваяСтрока.ТаблицаТипов = ДопустимыеТипы;
КонецЕсли;
КонецПроцедуры
// Удаляет слово локального контекста.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка.
//
Процедура УдалитьСловоЛокальногоКонтекста(Слово, ТипСлова) Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("нИмя", НРег(Слово));
СтрокиСлова = ТаблицаЛокальногоКонтекста(ТипСлова).НайтиСтроки(КлючСтроки);
Если СтрокиСлова.Количество() > 0 Тогда
СтрокиСлова[0].Владелец().Удалить(СтрокиСлова[0]);
КонецЕсли;
КонецПроцедуры
// Устанавливает доступность действий, изменяющих данные.
//
// Параметры:
// НовыйТолькоПросмотр - Булево.
//
Процедура УстановитьТолькоПросмотр(НовыйТолькоПросмотр) Экспорт
ФормаКласса = ПолучитьФорму("ФормаМакет");
МассивКоллекцийКнопок = Новый Массив;
МассивКоллекцийКнопок.Добавить(ФормаКласса.ЭлементыФормы["КоманднаяПанель" + Формат(ЯзыкПрограммы, "ЧН=")].Кнопки);
МассивКоллекцийКнопок.Добавить(ФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки);
Для Каждого КнопкиМакета Из МассивКоллекцийКнопок Цикл
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Если КнопкаМакета.ТипКнопки <> ТипКнопкиКоманднойПанели.Действие Тогда
Продолжить;
КонецЕсли;
КонечноеИмя = ирКлиент.СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ЭтотОбъект, КнопкаМакета.Имя);
Кнопка = КоманднаяПанель.Кнопки.Найти(КонечноеИмя);
Если Кнопка.ИзменяетДанные Тогда
Кнопка.Доступность = Не НовыйТолькоПросмотр;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры // УстановитьТолькоПросмотр()
Процедура ОформитьЯчейкуТипаЗначения(ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Истина
И ОформлениеСтроки.Ячейки.ТипЗначения.Видимость
И ЗначениеЗаполнено(ДанныеСтроки.ТипЗначения)
//И Найти(ДанныеСтроки.ТипЗначения, ",") = 0
Тогда
СтрокаИменТипов = ирОбщий.ПервыйФрагментЛкс(ДанныеСтроки.ТипЗначения, "[");
мРегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
#Если Сервер И Не Сервер Тогда
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = "\(.*?\)";
СтрокаИменТипов = мРегВыражение.Заменить(СтрокаИменТипов, "");
Попытка
ОписаниеТипов = Новый ОписаниеТипов(СтрокаИменТипов);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
КартинкаТипа = ирКлиент.КартинкаТипаЛкс(Типы[0]);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеСтроки.Ячейки.ТипЗначения.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Выполняет шаблон текста.
//
// Параметры:
// Нет.
//
Процедура ВыполнитьШаблонТекста()
Если ПолеТекста.ТолькоПросмотр() Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПрочитатьНачалоИКонецТекущейСтроки();
//РазобратьКонтекстСтроки();
НадежноУстановитьФокус = Ложь;
ПоследняяПозицияКурсора = 0;
ТаблицаШаблоновТекста = мПлатформа.ПолучитьТаблицуШаблоновТекста(ИмяКласса);
КонечныйТекстЗамены = " ";
Если Ложь
Или ТаблицаШаблоновТекста = Неопределено
Или ТаблицаШаблоновТекста.Количество() = 0
Тогда
//
Иначе
мРегВыражение.Global = Ложь;
СтрокаРазделителейШаблоновТекста = ";.,:()[]";
мРегВыражение.Pattern = "([^\s" + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(СтрокаРазделителейШаблоновТекста) + "]*)$";
Результат = мРегВыражение.НайтиВхождения(мТекущаяСтрокаНачало);
Если Результат.Количество() > 0 Тогда
НачалоМаркера = Результат[0].SubMatches(0);
Если ЗначениеЗаполнено(НачалоМаркера) Тогда
//СтрокаШаблона = ТаблицаШаблоновТекста.Найти(НРег(НачалоМаркера), "ШаблонБезКвадратныхСкобок");
СтрокаШаблона = Неопределено;
Для каждого ТекСтрокаШаблона Из ТаблицаШаблоновТекста Цикл
Если ТекСтрокаШаблона.Шаблон = НРег(НачалоМаркера) Тогда
СтрокаШаблона = ТекСтрокаШаблона;
Прервать;
КонецЕсли;
МинимальнаяДлинаСовпадения = Найти(ТекСтрокаШаблона.Шаблон, "[");
Если МинимальнаяДлинаСовпадения > 0 Тогда
Если СтрДлина(НачалоМаркера) < МинимальнаяДлинаСовпадения - 1 Тогда
Продолжить;
КонецЕсли;
ШаблонБезСкобок = СтрЗаменить(ТекСтрокаШаблона.Шаблон, "[", "");
ШаблонБезСкобок = СтрЗаменить(ШаблонБезСкобок, "]", "");
Если Найти(ШаблонБезСкобок, НРег(НачалоМаркера)) = 1 Тогда
СтрокаШаблона = ТекСтрокаШаблона;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СтрокаШаблона = Неопределено Тогда
НачалоМаркера = "";
Иначе
мРегВыражение.Global = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Pattern = "(<\?\s*(""[^""\^]*"")?(?:,\s*(" + мПлатформа.шИмя + "))?>)|(.|\r|\n)";
Результат = мРегВыражение.НайтиВхождения(СтрокаШаблона.Замена);
КонечныйТекстЗамены = "";
КешПараметров = Новый ТаблицаЗначений;
КешПараметров.Колонки.Добавить("ИмяПараметра");
КешПараметров.Колонки.Добавить("ЗначениеПараметра");
Для Каждого Match Из Результат Цикл
УправляющаяКонструкция = Match.SubMatches(0);
Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(УправляющаяКонструкция) Тогда
КонечныйТекстЗамены = КонечныйТекстЗамены + Match.SubMatches(3);
Иначе
ИмяПараметраШаблона = Match.SubMatches(1);
ТипШаблона = Match.SubMatches(2);
Если ТипШаблона = "КонструкторОписанияТипов" Тогда
КонечныйТекстЗамены = ТекстИзКонструктораОписанияТипов();
ИначеЕсли ТипШаблона = "ТекстЗапроса" Тогда
//ВызватьКонструкторЗапросов();
ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ИмяПараметраШаблона) Тогда
ИмяПараметраШаблона = Сред(ИмяПараметраШаблона, 2, СтрДлина(ИмяПараметраШаблона) - 2);
ВведеннаяСтрока = "";
Если ИмяПараметраШаблона <> "" Тогда
СтрокаКэша = КешПараметров.Найти(ИмяПараметраШаблона, "ИмяПараметра");
Если СтрокаКэша <> Неопределено Тогда
ВведеннаяСтрока = СтрокаКэша.ЗначениеПараметра;
Иначе
СтрокаКэша = КешПараметров.Добавить();
СтрокаКэша.ИмяПараметра = ИмяПараметраШаблона;
НадежноУстановитьФокус = Истина;
ВвестиЗначение(ВведеннаяСтрока, ИмяПараметраШаблона, Тип("Строка"));
СтрокаКэша.ЗначениеПараметра = ВведеннаяСтрока;
КонецЕсли;
КонецЕсли;
КонечныйТекстЗамены = КонечныйТекстЗамены + ВведеннаяСтрока;
Иначе
ПоследняяПозицияКурсора = СтрДлина(КонечныйТекстЗамены) + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", мШиринаТабуляции);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КонечныйТекстЗамены <> Неопределено Тогда
КонечныйТекстЗаменыТД = Новый ТекстовыйДокумент;
КонечныйТекстЗаменыТД.УстановитьТекст(КонечныйТекстЗамены);
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
Если ПоследняяПозицияКурсора > 0 Тогда
мПолеТекстаВременное.УстановитьТекст(КонечныйТекстЗамены);
Если ПоследняяПозицияКурсора <= СтрДлина(КонечныйТекстЗамены) Тогда
мПолеТекстаВременное.УстановитьГраницыВыделения(ПоследняяПозицияКурсора, ПоследняяПозицияКурсора);
мПолеТекстаВременное.ПолучитьГраницыВыделения(лКонечнаяСтрока, лКонечнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
Иначе
лКонечнаяСтрока = КонечныйТекстЗаменыТД.КоличествоСтрок();
лКонечнаяКолонка = СтрДлина(КонечныйТекстЗаменыТД.ПолучитьСтроку(КонечныйТекстЗаменыТД.КоличествоСтрок())) + 1;
КонецЕсли;
КонецЕсли;
ЧислоСтрокЗамены = КонечныйТекстЗаменыТД.КоличествоСтрок();
СтрокаДобавка = КонечныйТекстЗаменыТД.ПолучитьСтроку(1);
ДлинаНачалаСтроки = мКонечнаяКолонка - СтрДлина(НачалоМаркера) - 1;
НачалоСтроки = Лев(мТекущаяСтрокаНачало, ДлинаНачалаСтроки);
мТекущаяСтрокаНачало = НачалоСтроки + СтрокаДобавка;
ТекущаяСтрока = мТекущаяСтрокаНачало;
Если ЧислоСтрокЗамены = 1 Тогда
ТекущаяСтрока = ТекущаяСтрока + мТекущаяСтрокаКонец;
КонецЕсли;
ПолеТекста.ЗаменитьСтроку(мКонечнаяСтрока, "" + ТекущаяСтрока);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / мШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % мШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
Для Счетчик = 2 По ЧислоСтрокЗамены - 1 Цикл
ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(Счетчик);
ПолеТекста.ВставитьСтроку(мКонечнаяСтрока + Счетчик - 1, НачалоНовойСтроки + ТекущаяСтрокаВставки);
КонецЦикла;
Если ЧислоСтрокЗамены > 1 Тогда
ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(ЧислоСтрокЗамены);
ПолеТекста.ВставитьСтроку(мКонечнаяСтрока + ЧислоСтрокЗамены - 1, НачалоНовойСтроки + ТекущаяСтрокаВставки + мТекущаяСтрокаКонец);
КонецЕсли;
Если лКонечнаяСтрока > 0 Тогда
Если лКонечнаяСтрока = 1 Тогда
лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоСтроки);
Иначе
лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоНовойСтроки);
КонецЕсли;
лКонечнаяСтрока = лКонечнаяСтрока + мКонечнаяСтрока - 1;
мКонечнаяКолонка = лКонечнаяКолонка;
мКонечнаяСтрока = лКонечнаяСтрока;
Иначе
Если ЧислоСтрокЗамены > 0 Тогда
мКонечнаяСтрока = мКонечнаяСтрока + ЧислоСтрокЗамены - 1;
КонецЕсли;
Если ЧислоСтрокЗамены > 1 Тогда
мКонечнаяКолонка = СтрДлина(НачалоСтроки + ТекущаяСтрокаВставки) + 1;
Иначе
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонечныйТекстЗамены) - СтрДлина(НачалоМаркера);
КонецЕсли;
КонецЕсли;
мНачальнаяСтрока = мКонечнаяСтрока;
мНачальнаяКолонка = мКонечнаяКолонка;
КонецЕсли;
УстановитьФокус();
КонецПроцедуры
Функция ТекстИзКонструктораОписанияТипов()
ОписаниеТипов = ирКлиент.РедактироватьОписаниеРедактируемыхТиповЛкс();
Если ОписаниеТипов <> Неопределено Тогда
Результат = ирОбщий.ВыражениеВстроенногоЯзыкаСозданиеОписанияТиповЛкс(ОписаниеТипов);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура КонструкторОписанияТипов()
НовыйТекст = ТекстИзКонструктораОписанияТипов();
Если ЗначениеЗаполнено(НовыйТекст) Тогда
ПолеТекста.ВыделенныйТекст(НовыйТекст);
КонецЕсли;
КонецПроцедуры
Процедура ОкружитьВыделенныеСтроки(Знач НачалоОкружения, Знач КонецОкружения, Знач СмещатьВправо = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
НомерНачальнойСтроки = ПолучитьНомерТекущейСтроки(Истина);
ВыделенныйТекст = ПолеТекста.ВыделенныйТекст();
Смещение = "";
Если СмещатьВправо Тогда
Смещение = Символы.Таб;
КонецЕсли;
СмещениеПервойСтроки = Лев(ВыделенныйТекст, СтрДлина(ВыделенныйТекст) - СтрДлина(СокрЛ(ВыделенныйТекст)));
ПолеТекста.ВставитьТекст(
"" + СмещениеПервойСтроки + НачалоОкружения + "
|" + Смещение + ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс("", ВыделенныйТекст, Смещение) + "
|" + СмещениеПервойСтроки + КонецОкружения);
НомерНачальнойКолонки = СтрДлина(СмещениеПервойСтроки) + 1;
ПолеТекста.УстановитьГраницыВыделения(НомерНачальнойСтроки, НомерНачальнойКолонки, НомерНачальнойСтроки, НомерНачальнойКолонки,, ФормаВладелец);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
Функция ПредставлениеЗначенияВЯзыкеЗапросов(Знач Значение, Знач ВыводитьСообщение = Ложь, Знач ПараметрыДиалектаSQL = Неопределено, Знач Английский1С = Неопределено) Экспорт
Если Английский1С = Неопределено Тогда
Английский1С = мАнглийский1С;
КонецЕсли;
Результат = "";
ТипЗначенияПараметра = ТипЗнч(Значение);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если ОбъектМД <> Неопределено Тогда
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
Если ирОбщий.ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗначенияПараметра) Тогда
Результат = "ТочкаМаршрута." + Значение.Имя;
ИначеЕсли Значение.Пустая() Тогда
Результат = "ПустаяСсылка";
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда
Результат = XMLСтрока(Значение);
ИначеЕсли ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если Значение.Предопределенный Тогда
Результат = ирОбщий.ПолучитьМенеджерЛкс(ОбъектМД).ПолучитьИмяПредопределенного(Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияБухгалтерии") Тогда
Результат = "ВидДвиженияБухгалтерии." + Значение;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияНакопления") Тогда
Результат = "ВидДвиженияНакопления." + Значение;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Если ОбъектМД <> Неопределено Тогда
Результат = ОбъектМД.ПолноеИмя() + "." + Результат;
КонецЕсли;
Результат = "ЗНАЧЕНИЕ(" + Результат + ")";
ИначеЕсли ТипЗначенияПараметра = Тип("Неопределено") Тогда
Результат = СловоЯзыкаЗапросов("UNDEFINED", ПараметрыДиалектаSQL, Английский1С);
ИначеЕсли ТипЗначенияПараметра = Тип("Null") Тогда
Результат = "NULL";
Иначе
Если ПараметрыДиалектаSQL = Неопределено Тогда
ПараметрыДиалектаSQL = мПараметрыДиалектаSQL;
КонецЕсли;
Если ТипЗначенияПараметра = Тип("СтандартнаяДатаНачала") Тогда
Значение = Значение.Дата;
ТипЗначенияПараметра = ТипЗнч(Значение);
КонецЕсли;
Если ТипЗначенияПараметра = Тип("Дата") Тогда
Если ПараметрыДиалектаSQL.Это1С Тогда
Результат = СловоЯзыкаЗапросов("DATETIME", ПараметрыДиалектаSQL, Английский1С) + "(" + XMLСтрока(Год(Значение)) + ", " + XMLСтрока(Месяц(Значение)) + ", " + XMLСтрока(День(Значение));
Если НачалоДня(Значение) <> Значение Тогда
Результат = Результат + ", " + XMLСтрока(Час(Значение)) + ", " + XMLСтрока(Минута(Значение)) + ", " + XMLСтрока(Секунда(Значение));
КонецЕсли;
Результат = Результат + ")";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ПараметрыДиалектаSQL.Диалект, "WQL") Тогда
Значение = ирОбщий.ПолучитьЛитералДатыДляWQLЛкс(Значение);
Иначе// Если ирОбщий.СтрокиРавныЛкс(КодЯзыка, "WQL") Тогда
Результат = "'" + Формат(Значение, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("Число") Тогда
Результат = XMLСтрока(Значение);
ИначеЕсли ТипЗначенияПараметра = Тип("Булево") Тогда
Если Значение Тогда
Результат = СловоЯзыкаЗапросов("TRUE", ПараметрыДиалектаSQL, Английский1С);
Иначе
Результат = СловоЯзыкаЗапросов("FALSE", ПараметрыДиалектаSQL, Английский1С);
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("Строка") Тогда
Если ПараметрыДиалектаSQL.Это1С Тогда
Результат = """" + СтрЗаменить(Значение, """", """""") + """";
Иначе
Результат = "'" + Значение + "'";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат = "" Тогда
Если ВыводитьСообщение Тогда
ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("Литеральное представление значения ""%1"" в языке запросов не предусмотрено", ирОбщий.РасширенноеПредставлениеЗначенияЛкс(Значение)));
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СловоЯзыкаЗапросов(Ключ, ПараметрыДиалектаSQL = Неопределено, Английский1С = Неопределено) Экспорт
Если ПараметрыДиалектаSQL = Неопределено Тогда
ПараметрыДиалектаSQL = мПараметрыДиалектаSQL;
КонецЕсли;
Если Английский1С = Неопределено Тогда
Английский1С = мАнглийский1С;
КонецЕсли;
Результат = Неопределено;
Если ирОбщий.СтрокиРавныЛкс("AS", Ключ) Тогда
Если Не ПараметрыДиалектаSQL.КАК Тогда
Результат = "";
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
СтрокаТерминала = мТерминалыЯзыкаЗапросов.Найти(Ключ, "Ключ");
Если ПараметрыДиалектаSQL <> Неопределено И ПараметрыДиалектаSQL.Это1С Тогда
Если СтрокаТерминала = Неопределено Тогда
ВызватьИсключение "Не найден терминал """ + Ключ + """ языка запросов 1C";
КонецЕсли;
Если Не Английский1С Тогда
Результат = СтрокаТерминала.Русский;
Иначе
Результат = СтрокаТерминала.Английский;
КонецЕсли;
Иначе
Результат = Ключ;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиВыбранныеТаблицыВТекстеЗапроса(Знач СтрокаЗапросаПакета, Знач НачальнаяПозицияЗапроса, Знач ПолеТекстаЗапроса) Экспорт
#Если Сервер И Не Сервер Тогда
СтрокаЗапросаПакета = Новый ДеревоЗначений;
#КонецЕсли
СтрокаЗапросаПакета.СложныйАнализВыполнен = Истина;
//Шаблон = шИЗ;
Шаблон = "((?:ИЗ|FROM)" + шРазделитель + "+" + шОписаниеТаблицы + "[\s\S]*?)(?:$|\sОБЪЕДИНИТЬ(?:\s+ВСЕ)?\s+|\sUNION(?:\s+ALL)?\s+|\sУПОРЯДОЧИТЬ\s+[^\)]*$|\ORDER\s+[^\)]*$)";
ВхожденияИЗ = ирОбщий.НайтиРегВыражениеЛкс(СтрокаЗапросаПакета.Текст, Шаблон);
НачальнаяПозицияЧасти = НачальнаяПозицияЗапроса;
Для Каждого ВхождениеИЗ Из ВхожденияИЗ Цикл
Если ВхожденияИЗ.Количество() > 1 Тогда
СтрокаЧастиОбъединения = СтрокаЗапросаПакета.Строки.Вставить(0);
Если Истина
И СтрокаЗапросаПакета.ТипУзла = "<CreateRoot>"
И СтрокаЗапросаПакета.Строки.Количество() = 1
Тогда
СтрокаЧастиОбъединения.ТипУзла = "<CreateQuery>";
Иначе
СтрокаЧастиОбъединения.ТипУзла = "<SelectQuery>";
КонецЕсли;
СтрокаЧастиОбъединения.СложныйАнализВыполнен = Истина;
СтрокаЧастиОбъединения.Порядок = -СтрокаЗапросаПакета.Строки.Количество();
СтрокаЧастиОбъединения.Имя = "Выборка";
КонечнаяПозицияЧасти = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + СтрДлина(ВхождениеИЗ.Подгруппа0);
ПолеТекстаЗапроса.УстановитьГраницыВыделения(НачальнаяПозицияЧасти, КонечнаяПозицияЧасти);
ТекстИсточника = ПолеТекстаЗапроса.ВыделенныйТекст;
//ТекстИсточника = Сред(СлужебноеПолеТекста.Получитьтекст(), НачальнаяПозицияЧасти, КонечнаяПозицияЧасти - НачальнаяПозицияЧасти);
НачальнаяПозицияЧасти = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + СтрДлина(ВхождениеИЗ.ТекстВхождения);
ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(СтрокаЧастиОбъединения, ПолеТекстаЗапроса);
Иначе
СтрокаЧастиОбъединения = СтрокаЗапросаПакета;
КонецЕсли;
Найденные = ирОбщий.НайтиРегВыражениеЛкс(ВхождениеИЗ.ТекстВхождения, шОписаниеТаблицыСЗахватом);
Для Каждого Найденное Из Найденные Цикл
НачальнаяПозиция = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + Найденное.ПозицияВхождения;
КонечнаяПозиция = НачальнаяПозиция + СтрДлина(Найденное.Подгруппа0);
Если Лев(Найденное.Подгруппа0, 1) = "(" Тогда
НачальнаяПозиция = НачальнаяПозиция + 1;
КонечнаяПозиция = КонечнаяПозиция - 1;
ТипУзла = "<FromUnion>";
Иначе
ТипУзла = "<TableWithName>";
КонецЕсли;
ПолеТекстаЗапроса.УстановитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция);
ТекстИсточника = ПолеТекстаЗапроса.ВыделенныйТекст;
//ТекстИсточника = Сред(СлужебноеПолеТекста.Получитьтекст(), НачальнаяПозиция, КонечнаяПозиция - НачальнаяПозиция);
КорневойТипТаблицы = ирОбщий.ПервыйФрагментЛкс(СокрЛ(ТекстИсточника));
Если Ложь
Или Найденное.Подгруппа4 = "ЧИСЛО" // Ложное срабатываение ВЫРАЗИТЬ ВЫБОР ... КОНЕЦ КАК ЧИСЛО
Или ТекстИсточника = "КОНЕЦ" // Ложное срабатываение ВЫРАЗИТЬ ВЫБОР ... КОНЕЦ КАК ЧИСЛО
Или (Истина
// {ГДЕ (АналитикаУчета.Договор) КАК Договор}
// ОБЪЕДИНИТЬ ВЫБРАТЬ АналитикаУчета.Партнер КАК Партнер
И мПараметрыДиалектаSQL.Это1С
И Найти(ТекстИсточника, ".") > 0
И Не ирОбщий.ЛиКорневойТипТаблицыБДЛкс(КорневойТипТаблицы)
И Не ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТипТаблицы)
И Не ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(ТекстИсточника), "ВЫБРАТЬ")
И Не ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(ТекстИсточника), "SELECT")
)
Тогда
Продолжить;
КонецЕсли;
СтрокаИсточника = СтрокаЧастиОбъединения.Строки.Вставить(0);
СтрокаИсточника.Порядок = -СтрокаЧастиОбъединения.Строки.Количество();
СтрокаИсточника.Имя = Найденное.Подгруппа4;
СтрокаИсточника.ТипУзла = ТипУзла;
ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(СтрокаИсточника, ПолеТекстаЗапроса);
КонецЦикла;
КонецЦикла;
КонецФункции
Процедура ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(Знач СтрокаДерева, Знач ПолеТекстаЗапроса)
лНачальнаяСтрока = 0;
лНачальнаяКолонка = 0;
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
ПолеТекстаЗапроса.ПолучитьГраницыВыделения(лНачальнаяСтрока, лНачальнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
СтрокаДерева.Текст = ПолеТекстаЗапроса.ВыделенныйТекст;
ГраницыДвумерные = Новый Структура();
ГраницыДвумерные.Вставить("НачальнаяСтрока", лНачальнаяСтрока);
ГраницыДвумерные.Вставить("НачальнаяКолонка", лНачальнаяКолонка);
ГраницыДвумерные.Вставить("КонечнаяСтрока", лКонечнаяСтрока);
ГраницыДвумерные.Вставить("КонечнаяКолонка", лКонечнаяКолонка);
СтрокаДерева.СтрокаДанных = ГраницыДвумерные;
КонецПроцедуры
// Скопировано от РедакторHTML_ПриАктивацииСтрокиАвтодополнения
Функция ОписаниеТекущегоСловаАвтодополнения(Знач Слово, Знач ЛиМетод, Знач КлючНабораСлов = "", Знач ЛиОтдельноеОписаниеАктивно = Истина) Экспорт
ТолькоПолезноеОписание = Истина;
Если ЗначениеЗаполнено(КлючНабораСлов) Тогда
ТаблицаПоиска = мНаборыСлов[КлючНабораСлов];
Иначе
ТаблицаПоиска = ТаблицаСлов;
КонецЕсли;
НайденныеСтроки = ТаблицаПоиска.НайтиСтроки(Новый Структура("Слово", Слово));
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Если Ложь
Или НайденнаяСтрока.ТипСлова = "Метод" И ЛиМетод
Или НайденнаяСтрока.ТипСлова <> "Метод" И Не ЛиМетод
Тогда
СтрокаТаблицыСлов = НайденнаяСтрока;
Прервать;
КонецЕсли;
КонецЦикла;
ЕстьПараметры = Ложь;
Если СтрокаТаблицыСлов <> Неопределено Тогда
ТаблицаТипов = УточнитьТипЗначенияВСтрокеТаблицыСлов(мСтруктураТипаКонтекста, СтрокаТаблицыСлов, ЛиОтдельноеОписаниеАктивно);
СтруктураОписания = Новый Массив;
Если мСтруктураТипаКонтекста.Конструктор Тогда
ДетальноеОписаниеДляСписка = "";
Иначе
ДетальноеОписаниеДляСписка = СтрокаТаблицыСлов.ТипЗначения;
КонецЕсли;
Если ЛиОтдельноеОписаниеАктивно И ТаблицаТипов <> Неопределено Тогда
Если Ложь
Или мСтруктураТипаКонтекста.Конструктор
Или СтрокаТаблицыСлов.ТипСлова = "Метод"
Тогда
Если мСтруктураТипаКонтекста.Конструктор Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Глобальный";
ТаблицаТипов = мПлатформа.СловаКонтекстаПредопределенные(СтруктураТипа, СтрокаТаблицыСлов.Слово, "Конструктор",, ЯзыкПрограммы, Конфигурация)[0].ТаблицаТипов;
КонецЕсли;
Если ТаблицаТипов.Количество() > 0 Тогда
//ПараметрыМетода = мПлатформа.ПараметрыМетодаПлатформы(ТаблицаТипов[0]);
СтруктураПодсказкиМетода = СтруктураПодсказкиМетода(ТаблицаТипов[0], ТолькоПолезноеОписание, Истина, ЕстьПараметры);
Если СтруктураПодсказкиМетода.Количество() > 0 Тогда
СтруктураОписания.Вставить(0, "> Параметры: " + СтруктураПодсказкиМетода[0].label);
Если СтруктураПодсказкиМетода.Количество() > 1 Тогда
СтруктураОписания.Вставить(0, "> Варианты: " + СтруктураПодсказкиМетода.Количество());
КонецЕсли;
ОписаниеСлова = СтруктураПодсказкиМетода[0].documentation;
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
СтруктураОписания.Добавить("> Описание: " + ОписаниеСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураОписания.Добавить("> Определение: " + СтрокаТаблицыСлов.Определение);
ДетальноеОписаниеОтдельное = ирОбщий.СтрСоединитьЛкс(СтруктураОписания, Символы.ПС);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Описание", "" + ДетальноеОписаниеОтдельное);
Результат.Вставить("Тип", ДетальноеОписаниеДляСписка);
Результат.Вставить("ЕстьПараметры", ЕстьПараметры);
Возврат Результат;
КонецФункции
// Функция - Установить текст
//
// Параметры:
// Текст - Строка, Неопределено - "Неопределено" не меняет текст поля
// Активировать - -
// НачальныйТекстДляСравнения - -
// СохранитьГраницыВыделения - -
// ПолноеИмя - Строка - например Обработка.ирКонсольЗапросов.МодульОбъекта
//
Функция УстановитьТекст(Знач Текст = Неопределено, Знач Активировать = Ложь, Знач НачальныйТекстДляСравнения = Неопределено, Знач СохранитьГраницыВыделения = Ложь, Знач СжатоеИмяМодуля = Неопределено,
Знач ИмяМодуля = Неопределено, Знач НовоеНачалоВыделения = 0, Знач НовоеКонецВыделения = 0) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОчиститьИсториюПереходов();
Если Текст <> Неопределено Тогда
ПолеТекста.УстановитьТекст(Текст, Активировать, НачальныйТекстДляСравнения, СохранитьГраницыВыделения);
КонецЕсли;
Если ЗначениеЗаполнено(НовоеКонецВыделения) Тогда
УстановитьГраницыВыделения(НовоеНачалоВыделения, НовоеКонецВыделения,,, Ложь);
Иначе
НовоеКонецВыделения = мПозицияВТексте;
КонецЕсли;
ОчиститьТаблицуСловЛокальногоКонтекста();
мФлагиКомпиляции = мПлатформа.НовыеФлагиКомпиляции();
мКорневаяТаблицаТипов = Неопределено;
Если Не ЗначениеЗаполнено(СжатоеИмяМодуля) И Не ЗначениеЗаполнено(ИмяМодуля) Тогда
Если ЗначениеЗаполнено(мИмяМодуля) Тогда
мМодульМетаданных = Неопределено;
ОбновитьМодульМетаданных(""); // Чтобы пересоздался мМодульМетаданных, иначе передача текста без указания имени модуля может перезаписать чужой текст модуля в кэше
КонецЕсли;
Возврат Неопределено;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ИмяМодуля <> Неопределено И СжатоеИмяМодуля = Неопределено Тогда
СжатоеИмяМодуля = ИмяМодуля;
Если ирОбщий.СтрКончаетсяНаЛкс(СжатоеИмяМодуля, ".Форма.Модуль") Тогда
СжатоеИмяМодуля = СтрЗаменить(СжатоеИмяМодуля, ".Форма.Модуль", "");
СжатоеИмяМодуля = СтрЗаменить(СжатоеИмяМодуля, ".Форма.", ".");
КонецЕсли;
Если ирОбщий.СтрНачинаетсяСЛкс(СжатоеИмяМодуля, "Конфигурация.") Тогда
СжатоеИмяМодуля = СтрЗаменить(СжатоеИмяМодуля, "Конфигурация.", "");
КонецЕсли;
КонецЕсли;
Фрагменты = ирОбщий.СтрРазделитьЛкс(СжатоеИмяМодуля, "::");
ИмяМодуля = СжатоеИмяМодуля;
Если Фрагменты.Количество() > 1 Тогда
// Внешняя обработка/отчет
ИмяФайла = Фрагменты[1];
ТипМодуля = Фрагменты[2];
//КлючПоиска = Новый Структура;
//КлючПоиска.Вставить("БазовыйТип", ИмяОбщегоТипа + "Объект");
//КлючПоиска.Вставить("ЯзыкПрограммы", 0);
//ИмяОбщегоТипа = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска)[0].Слово;
ОшибкаКомпиляции = "";
Попытка
МенеджерОбъекта = ирОбщий.МенеджерВнешнегоОбъектаЛкс(ИмяФайла);
ОбъектМД = МенеджерОбъекта.Метаданные();
Исключение
ОшибкаКомпиляции = ОписаниеОшибки(); // Для отладки
ОбъектМД = Новый Структура("Имя", "Нескомпилированный");
КонецПопытки;
ИмяМодуля = Фрагменты[0] + "::" + ИмяФайла + "::" + ОбъектМД.Имя;
Если ирОбщий.СтрокиРавныЛкс(ТипМодуля, "МодульОбъекта") Тогда
Если ЗначениеЗаполнено(ОшибкаКомпиляции) Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа("ВнешняяОбработкаОбъект.<Имя внешней обработки>");
СтруктураТипа.Метаданные = ОбъектМД;
Иначе
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(МенеджерОбъекта);
КонецЕсли;
ТипМодуля = "МодульОбъекта";
ИмяМодуля = ИмяМодуля + "." + ТипМодуля;
Иначе
ИмяОбщегоТипа = "Форма";
ИмяМодуля = ИмяМодуля + "." + "Форма" + "." + ТипМодуля;
Форма = мПлатформа.ПассивнаяФормаПоИмениКэш(ИмяМодуля);
ТипМодуля = "Форма.Модуль";
ИмяМодуля = ИмяМодуля + "." + ТипМодуля;
Если ТипЗнч(Форма) = Тип("Структура") Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Форма.Тип);
СтруктураТипа.Метаданные = Форма;
ИначеЕсли Форма <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Форма);
Иначе
СтруктураТипа = мПлатформа.НоваяСтруктураТипа("Форма");
СтруктураТипа.Метаданные = ОбъектМД;
//ТипМодуля = ИмяМодуля;
КонецЕсли;
КонецЕсли;
Иначе
ИмяРасширения = Неопределено;
ФрагментыПробела = ирОбщий.СтрРазделитьЛкс(СжатоеИмяМодуля, " ");
Если ФрагментыПробела.Количество() > 1 Тогда
ИмяРасширения = ФрагментыПробела[0];
ИмяМодуля = ФрагментыПробела[1];
КонецЕсли;
Фрагменты = ирОбщий.СтрРазделитьЛкс(ИмяМодуля);
ИмяОбщегоТипа = Фрагменты[0];
ТипМодуля = "";
Если Фрагменты.Количество() = 1 Тогда
ОбъектМД = Метаданные;
ИмяОбщегоТипа = "Глобальный";
ТипМодуля = ИмяМодуля;
ИмяМодуля = "Конфигурация";
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "WebСервис"
Или ИмяОбщегоТипа = "HttpСервис"
Или ИмяОбщегоТипа = "ОбщийМодуль"
Или ИмяОбщегоТипа = "ОбщаяКоманда"
Тогда
ОбъектМД = Метаданные[ирОбщий.МножественноеИмяМДЛкс(ИмяОбщегоТипа)].Найти(Фрагменты[1]);
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "Команда"
Тогда
// Конфигуратор оставил нам только полный перебор, т.к. не показывает имя родительского объекта в заголовке
Для Каждого СтрокаТипаМетаданных Из ирКэш.ТипыМетаОбъектов(, Ложь, Ложь) Цикл
Если СтрокаТипаМетаданных.Единственное = "Перерасчет" Тогда
Продолжить;
КонецЕсли;
Для Каждого ОбъектМДЦикл Из Метаданные[СтрокаТипаМетаданных.Множественное] Цикл
#Если Сервер И Не Сервер Тогда
ОбъектМДЦикл = Метаданные.Обработки.ирКонсольЗапросов;
#КонецЕсли
Попытка
Команды = ОбъектМДЦикл.Команды;
Исключение
Прервать;
КонецПопытки;
КомандаМД = Команды.Найти(Фрагменты[1]);
Если КомандаМД <> Неопределено Тогда
ОбъектМД = ОбъектМДЦикл;
Перейти ~ВыходЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
~ВыходЦикла:
Если ОбъектМД <> Неопределено Тогда
ИмяМодуля = ОбъектМД.ПолноеИмя() + "." + ИмяМодуля;
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Фрагменты[0], "ОбщаяФорма") Тогда
ИмяОбщегоТипа = "Форма";
ТипМодуля = "Форма.Модуль";
ОбъектМД = Метаданные.ОбщиеФормы.Найти(Фрагменты[1]);
Иначе
ТипМодуля = Фрагменты[Фрагменты.ВГраница()];
ИмяОбщегоТипа = Фрагменты[0];
Если ирОбщий.СтрокиРавныЛкс(ТипМодуля, "МодульОбъекта") Тогда
Подтип = "Объект";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТипМодуля, "МодульМенеджера") Тогда
Подтип = "Менеджер";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТипМодуля, "МодульНабораЗаписей") Тогда
Подтип = "НаборЗаписей";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТипМодуля, "МодульМенеджераЗначения") Тогда
Подтип = "МенеджерЗначения";
Иначе
ТипМодуля = "Форма.Модуль";
Подтип = "";
КонецЕсли;
Если ЗначениеЗаполнено(Подтип) Тогда
Фрагменты.Удалить(Фрагменты.ВГраница());
КлючПоиска = Новый Структура;
КлючПоиска.Вставить("БазовыйТип", ИмяОбщегоТипа + Подтип);
КлючПоиска.Вставить("ЯзыкПрограммы", 0);
ИмяОбщегоТипа = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска)[0].Слово;
Иначе
ИмяОбщегоТипа = "Форма";
Фрагменты.Вставить(Фрагменты.ВГраница(), ИмяОбщегоТипа);
КонецЕсли;
ИмяМодуля = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ИмяМодуля);
КонецЕсли;
СтруктураТипа = мПлатформа.НоваяСтруктураТипа(ИмяОбщегоТипа);
Если ОбъектМД = Неопределено Тогда
Если ИмяОбщегоТипа = "Форма" Тогда
СтруктураТипа.Метаданные = Новый Структура("ИмяФормы", ИмяМодуля);
Иначе
СтруктураТипа.Метаданные = ИмяМодуля;
КонецЕсли;
КонецЕсли;
Если ИмяОбщегоТипа = "Форма" Тогда
Форма = мПлатформа.ПассивнаяФормаПоИмениКэш(ИмяМодуля);
Если Форма = Неопределено Тогда
ОбъектМД = Метаданные;
Иначе
ОбъектМД = Форма;
КонецЕсли;
Если ТипЗнч(ОбъектМД) = Тип("Структура") Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ОбъектМД.Тип);
ИначеЕсли ТипЗнч(ОбъектМД) <> ТипЗнч(Метаданные) Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ОбъектМД);
КонецЕсли;
КонецЕсли;
Если ОбъектМД <> Неопределено Тогда
СтруктураТипа.Метаданные = ОбъектМД;
КонецЕсли;
Если ЗначениеЗаполнено(ТипМодуля) Тогда
ИмяМодуля = ИмяМодуля + "." + ТипМодуля;
КонецЕсли;
СтруктураТипа.ДержательМетаданных = ИмяРасширения;
КонецЕсли;
мМодульМетаданных = мПлатформа.ПодготовитьМодульМетаданных(СтруктураТипа, ТипМодуля,, Текст, НовоеКонецВыделения);
Если мСтарыйОригинальныйТекст <> Текст Тогда
мСтарыйОригинальныйТекст = Текст;
СлужебноеПолеТекстаДолгое.УстановитьТекст(Текст);
КонецЕсли;
мФлагиКомпиляции = ирОбщий.СкопироватьКоллекциюЛкс(мМодульМетаданных.ФлагиКомпиляции);
Если ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Строка") Тогда
ИмяМодуля = СтруктураТипа.ДержательМетаданных + " " + ИмяМодуля;
КонецЕсли;
Если мИмяМодуля <> ИмяМодуля Тогда
мПлатформа.СброситьКэшиТиповВыраженийМодулей(мИмяМодуля);
КонецЕсли;
мИмяМодуля = ИмяМодуля;
Результат = Неопределено;
Если ИмяОбщегоТипа = "Форма" Тогда
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанные.Тип = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
Результат = ирОбщий.СвойствоСтруктурыЛкс(СлужебныеДанные, "ДатаОбновления", Дата(1,1,1));
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
///////////////////
// Редактор HTML
Процедура РедакторHTML_Инициировать(ПолеHTML) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаКласса = мПлатформа.ПолучитьМакетКомпоненты(ЭтотОбъект);
КнопкиМакета = ФормаКласса.ЭлементыФормы.КПРедакторHTML.Кнопки.КонтекстноеМеню.Кнопки;
КонтекстноеМеню = ПолеHTML.КонтекстноеМеню;
Если КонтекстноеМеню = Неопределено Тогда
КонтекстноеМеню = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КонтекстноеМеню" + ПолеHTML.Имя, Ложь);
КонтекстноеМеню.ИсточникДействий = ПолеHTML;
ПолеHTML.КонтекстноеМеню = КонтекстноеМеню;
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КонтекстноеМеню,,, Истина);
ПолеТекстаHTML = ирКлиент.ОболочкаПоляТекстаЛкс(ПолеHTML);
#Если Сервер И Не Сервер Тогда
ПолеТекстаHTML = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекстаHTML.Инициировать();
РедакторHTML = ПолеHTML.Документ.defaultView;
Инфо = Новый СистемнаяИнформация();
РедакторHTML.minimap(Ложь);
РедакторHTML.init(Инфо.ВерсияПриложения);
Если ЯзыкПрограммы = 1 Тогда
РедакторHTML.setLanguageMode("bsl_query");
ИначеЕсли ЯзыкПрограммы = 2 Тогда
РедакторHTML.setLanguageMode("dcs_query");
КонецЕсли;
РедакторHTML.setOption("disableContextQueryConstructor", Истина);
РедакторHTML.setOption("disableNativeSuggestions", Истина); // События не перестают вызываться
РедакторHTML.setOption("disableNativeSignatures", Истина); // События не перестают вызываться
РедакторHTML.setOption("disableNativeHovers", Истина); // События не перестают вызываться
РедакторHTML.setOption("skipInsertSuggestionAcceptor", Истина); // Отключаем вставку точки при выборе слова из списка https://github.com/salexdv/bsl_console/issues/120#issuecomment-844372676
РедакторHTML.setOption("skipAcceptionSelectedSuggestion", Истина); // Отключаем стандартную обработку вставки активного пункта подсказки. Практически 'СтандартнаяОбработка = Ложь'
РедакторHTML.setOption("renderQueryDelimiters", Истина); // Разделители запросов пакета https://github.com/salexdv/bsl_console/issues/218
//РедакторHTML.enableBeforeSignatureEvent(Истина);
РедакторHTML.setOption("generateBeforeSignatureEvent", Истина);
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
//РедакторHTML.enableSelectSuggestEvent(Истина);
РедакторHTML.setOption("generateSelectSuggestEvent", Истина);
//РедакторHTML.enableBeforeHoverEvent(Истина);
РедакторHTML.setOption("generateBeforeHoverEvent", Истина);
//РедакторHTML.enableModificationEvent(Истина);
РедакторHTML.setOption("generateModificationEvent", Истина);
РедакторHTML.disableKeyBinding(2082); // CTRL(2048)+D(34) - CTRL+D
РедакторHTML.disableKeyBinding(2118); // CTRL(2048)+D(70) - F12
РедакторHTML.setActiveSuggestionAcceptors("."); // По нажатию точки выполняется вставка активного слова и ввод точки // Много нежелательных срабатываний
КонецПроцедуры
Функция ДобавитьПодсказкуПоЗначениюВыражения(Знач ЗначениеВыражения = Неопределено, Знач ОбъектноеВыражение, Знач ПодсказкаМассив, СтруктураТипа = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПодсказкаМассив = Новый Массив;
#КонецЕсли
ЕстьОписаниеТипа = Ложь;
Если СтруктураТипа = Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ЗначениеВыражения, ЯзыкПрограммы);
КонецЕсли;
ИмяТипаЗначения = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
СтрокаОбщегоТипа = мПлатформа.ТаблицаОбщихТипов.Найти(НРег(ИмяОбщегоТипа), "НСлово");
Если СтрокаОбщегоТипа <> Неопределено Тогда
ЕстьОписаниеТипа = ЗначениеЗаполнено(СтрокаОбщегоТипа.ПутьКОписанию);
КонецЕсли;
Если ИмяТипаЗначения = "Строка" Тогда
ПодсказкаЗначения = "Знач: """ + ЗначениеВыражения + """";
Иначе
Если ТипЗнч(ЗначениеВыражения) = Тип("Строка") Тогда
ПодсказкаЗначения = ЗначениеВыражения;
Иначе
ПодсказкаЗначения = ирОбщий.РасширенноеПредставлениеЗначенияЛкс(ЗначениеВыражения,, Ложь, Истина);
КонецЕсли;
Если Ложь
Или ТипЗнч(ЗначениеВыражения) = Тип("Неопределено")
Или ТипЗнч(ЗначениеВыражения) = Тип("Null")
Тогда
ПодсказкаЗначения = "Знач: " + ПодсказкаЗначения;
Иначе
ПодсказкаЗначения = "[Знач](" + ОбъектноеВыражение + "): " + ПодсказкаЗначения;
КонецЕсли;
Если ПодсказкаЗначения = ИмяТипаЗначения Тогда
ПодсказкаЗначения = "";
Иначе
ПодсказкаЗначения = ПодсказкаЗначения + " ";
КонецЕсли;
Если ЕстьОписаниеТипа Тогда
ИмяСсылкиТипа = "_Тип" + XMLСтрока(мСтруктурыТиповПодсказкиУдержания.Количество());
ПодсказкаЗначения = ПодсказкаЗначения + "[[" + ИмяТипаЗначения + "]](" + ИмяСсылкиТипа + ")";
мСтруктурыТиповПодсказкиУдержания.Вставить(ИмяСсылкиТипа, СтруктураТипа);
Иначе
ПодсказкаЗначения = ПодсказкаЗначения + "[" + ИмяТипаЗначения + "]";
КонецЕсли;
КонецЕсли;
ПодсказкаМассив.Добавить(ПодсказкаЗначения);
Возврат ИмяТипаЗначения;
КонецФункции
Функция ДобавитьПодсказкуПоДопустимымТипам(Знач ИмяТипаЗначения, Знач ПодсказкаМассив, Знач ОбъектноеВыражение) Экспорт
ТаблицаТипов = ТаблицаТиповТекущегоВыражения(Истина, Истина, Ложь);
Если Истина
И ЯзыкПрограммы = 1
И ТаблицаТипов[0].ИмяОбщегоТипа = "ВременнаяТаблица"
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ИмяВременнойТаблицы = ТаблицаТипов[0].ВиртуальнаяТаблица.Выражение;
ВременныйЗапрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ " + ИмяВременнойТаблицы;
КоличествоСтрокВТаблице = ВременныйЗапрос.Выполнить().Выгрузить()[0][0];
ДобавитьПодсказкуПоЗначениюВыражения(ИмяВременнойТаблицы + "(" + КоличествоСтрокВТаблице + ")", ОбъектноеВыражение, ПодсказкаМассив, ТаблицаТипов[0]);
КонецЕсли;
ПредставлениеДопустимыхТипов = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаТипов, Истина);
Если Истина
И ПредставлениеДопустимыхТипов <> "?"
И ПредставлениеДопустимыхТипов <> "ОбщийМодуль"
И ПредставлениеДопустимыхТипов <> "ВременнаяТаблица"
И ЗначениеЗаполнено(ПредставлениеДопустимыхТипов)
И ПредставлениеДопустимыхТипов <> ИмяТипаЗначения
Тогда
ИмяСсылкиТипа = "_Тип" + XMLСтрока(мСтруктурыТиповПодсказкиУдержания.Количество());
мСтруктурыТиповПодсказкиУдержания.Вставить(ИмяСсылкиТипа, ТаблицаТипов);
ПредставлениеДопустимыхТипов = "[Допустимые типы](" + ИмяСсылкиТипа + "): " + ПредставлениеДопустимыхТипов;
ПодсказкаМассив.Добавить(ПредставлениеДопустимыхТипов);
КонецЕсли;
Если ПредставлениеДопустимыхТипов <> "ОбщийМодуль" Тогда
ПодсказкаМассив.Добавить("[Определение](" + XMLСтрока(мКонечнаяСтрока) + "," + XMLСтрока(мКонечнаяКолонка) + ")");
КонецЕсли;
Возврат ПредставлениеДопустимыхТипов;
КонецФункции
Процедура ОткрытьОписаниеТипаПоГиперссылке(Знач ИмяОбщегоТипа) Экспорт
Если Истина
И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипа, "_Тип")
И мСтруктурыТиповПодсказкиУдержания.Свойство(ИмяОбщегоТипа)
Тогда
СтруктураТипа = мСтруктурыТиповПодсказкиУдержания[ИмяОбщегоТипа];
Если ТипЗнч(СтруктураТипа) = Тип("ТаблицаЗначений") Тогда
ТаблицаДляПользователя = мПлатформа.ТаблицаТиповДляПользователя(СтруктураТипа, Ложь);
СписокВыбора = Новый СписокЗначений;
Для Каждого СтрокаТаблицы Из ТаблицаДляПользователя Цикл
Если ирОбщий.СтрокиРавныЛкс(СтрокаТаблицы.Имя, "null") Тогда
Продолжить;
КонецЕсли;
СписокВыбора.Добавить(СтрокаТаблицы.СтруктураТипа, СтрокаТаблицы.Имя);
КонецЦикла;
СписокВыбора = ирОбщий.СвернутьСписокЗначенийПоПредставлениюЛкс(СписокВыбора);
Если СписокВыбора.Количество() = 1 Тогда
СтруктураТипа = СписокВыбора[0];
Иначе
СтруктураТипа = СписокВыбора.ВыбратьЭлемент("Выберите тип значения");
Если СтруктураТипа = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
СтруктураТипа = СтруктураТипа.Значение;
КонецЕсли;
ОткрытьОпределениеСтруктурыТипа(СтруктураТипа, Истина);
Иначе
ирКлиент.ОткрытьОписаниеТипаПоИмениТипаЛкс(ИмяОбщегоТипа);
КонецЕсли;
КонецПроцедуры
// антибаг редактора https://github.com/salexdv/bsl_console/issues/78#issuecomment-836447865
Функция ЧистоеСловоСпискаПодсказкиHTML(ВыбранноеСлово) Экспорт
Возврат ирОбщий.ТекстМеждуМаркерамиЛкс(ВыбранноеСлово, "Элемент ", ",", Истина);
КонецФункции
Процедура РедакторHTML_ПередПоказомПодсказкиУдержания(Знач Событие, Знач ФункцияВычислитьВыражение) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
НомерКолонки23 = Событие.params.column;
НомерСтроки23 = Событие.params.line;
ТекущееСлово = Событие.params.word;
мСтруктурыТиповПодсказкиУдержания = Новый Структура;
Если ТекущееСлово = Неопределено Тогда
Возврат;
КонецЕсли;
КончитьОбработкуКоманды();
ОбъектноеВыражение = ТекущееОбъектноеВыражение(НомерСтроки23, НомерКолонки23,, Ложь);
ПодсказкаМассив = Новый Массив;
Если Истина
И (Ложь
Или Найти(ОбъектноеВыражение, "(") = 0
Или ирОбщий.СтрКончаетсяНаЛкс(ОбъектноеВыражение, "(")
Или ирОбщий.СтрНачинаетсяСЛкс(ОбъектноеВыражение, "("))
И (Ложь
Или ирОбщий.ЛиИмяПеременнойЛкс(Лев(ОбъектноеВыражение, 1))
Или Лев(ОбъектноеВыражение, 1) = мПараметрыДиалектаSQL.ПрефиксПараметра
Или Лев(ОбъектноеВыражение, 1) = "(")
Тогда
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
ИмяТипаЗначения = "";
Если Ложь
Или (ЯзыкПрограммы > 0 И Лев(ОбъектноеВыражение, 1) = мПараметрыДиалектаSQL.ПрефиксПараметра)
Или (ЯзыкПрограммы = 0 И Не ирОбщий.СтрКончаетсяНаЛкс(ОбъектноеВыражение, "("))
Тогда
УспехЗначения = Истина;
ЗначениеВыражения = Вычислить("ФормаВладелец." + ФункцияВычислитьВыражение + "(ОбъектноеВыражение, УспехЗначения)");
Если УспехЗначения Тогда
ИмяТипаЗначения = ДобавитьПодсказкуПоЗначениюВыражения(ЗначениеВыражения, ОбъектноеВыражение, ПодсказкаМассив);
КонецЕсли;
КонецЕсли;
ПредставлениеДопустимыхТипов = ДобавитьПодсказкуПоДопустимымТипам(ИмяТипаЗначения, ПодсказкаМассив, ОбъектноеВыражение);
КонецЕсли;
КончитьОбработкуКоманды();
СтруктураПодсказки = Новый Соответствие;
СтруктураПодсказки.Вставить(ТекущееСлово.word, ПодсказкаМассив);
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.setCustomHovers(ирОбщий.ОбъектВСтрокуJSONЛкс(СтруктураПодсказки));
КонецПроцедуры
Процедура РедакторHTML_ПередПоказомСигнатуры(НомерПараметра, ИмяМетодаОтРедактора, НомерСигнатуры, Триггер) Экспорт
Если РазрешеноСобытиеПередПоказомАвтодополнения = Ложь Или НомерСигнатуры > 0 Тогда
// https://github.com/salexdv/bsl_console/issues/182
РазрешеноСобытиеПередПоказомАвтодополнения = Истина;
Возврат;
КонецЕсли;
Если Триггер <> Неопределено И Не АвтоматическаяПодсказкаПоВызовуМетода() Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
//РедакторHTML.hideSignatureList();
Если Не ЛиДоступноОткрытиеСвободнойФормы() Тогда
КончитьОбработкуКоманды();
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
СтруктураПодсказки = СтруктураПодсказкиМетода(, Триггер <> Неопределено);
Если СтруктураПодсказки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ВариантыСинтаксиса = Новый Соответствие;
ВариантыСинтаксиса.Вставить(ирОбщий.ПоследнийФрагментЛкс(ИмяМетодаОтРедактора, " "), СтруктураПодсказки);
РедакторHTML.setCustomSignatures(ирОбщий.ОбъектВСтрокуJSONЛкс(ВариантыСинтаксиса));
//РедакторHTML.enableBeforeShowSuggestEvent(Ложь);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РазрешеноСобытиеПередПоказомАвтодополнения = Ложь;
РедакторHTML.triggerSigHelp();
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
//ИмяМетодаОтРедактора = ФормаВызовМетода.ИмяМетода;
//НомерПараметра = мНомерПараметра - 1;
КонецЕсли;
КонецПроцедуры
Функция СтруктураПодсказкиМетода(Знач ПараметрПостояннаяСтруктураТипа = Неопределено, Знач ТолькоПолезноеОписание = Истина, Знач ДляСпискаАвтодополнения = Ложь, выхЕстьПараметры = Ложь)
СтруктураПодсказки = Новый Массив;
ФормаВызовМетода = ФормаВызовМетода();
ФормаВызовМетода.ПараметрПостояннаяСтруктураТипа = ПараметрПостояннаяСтруктураТипа;
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму(, Истина);
Если Не ФормаВызовМетода.ЕстьПолезнаяИнформация И ТолькоПолезноеОписание Тогда
Возврат СтруктураПодсказки;
КонецЕсли;
Для ИндексВарианта = 0 По ФормаВызовМетода.ВариантыСинтаксиса.Количество() - 1 Цикл
Если Истина
И ФормаВызовМетода.ВариантыСинтаксиса.Количество() > 1
Тогда
ФормаВызовМетода.УстановитьВариантСинтаксисаПоИндексу(ИндексВарианта);
КонецЕсли;
ПодсказкаСлова = Новый Структура();
ПараметрыМетода = Новый Массив;
КраткиеОписанияПараметров = Новый Массив;
Для Каждого СтрокаПараметра Из ФормаВызовМетода.ТаблицаПараметров Цикл
ЛиНеОбязательный = ФормаВызовМетода.ЛиНеОбязательныйПараметр(СтрокаПараметра);
СтруктураПараметра = Новый Структура();
КраткоеПредставлениеПараметра = ""
//+ ?(СтрокаПараметра.Знач = "Знач", "`", СтрокаПараметра.Знач)
+ СтрокаПараметра.Имя
+ ?(ЛиНеОбязательный, "?", "");
// Мало пользы, лишние неудобства при поиске нужного параметра. Поэтому пока отключено
//Если ЗначениеЗаполнено(СтрЗаменить(СтрокаПараметра.ТипЗначения, "?", "")) Тогда
// КраткоеПредставлениеПараметра = КраткоеПредставлениеПараметра + " [" + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(СтрокаПараметра.ТипЗначения), 20) + "]";
//КонецЕсли;
КраткиеОписанияПараметров.Добавить(КраткоеПредставлениеПараметра);
СтруктураПараметра.Вставить("label", КраткоеПредставлениеПараметра);
ОписаниеПараметра =
"Обяз.: " + ?(Не ЛиНеОбязательный, "Да", "Нет, " + СтрокаПараметра.Значение) + "; Возвр.: " + ?(Не ЗначениеЗаполнено(СтрокаПараметра.Знач), "?", ?(СтрокаПараметра.Знач = "Знач", "Нет", "Да")) + "
|Тип: " + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(СтрокаПараметра.ТипЗначения), 200) + ".";
Если ЗначениеЗаполнено(СтрокаПараметра.Описание) Тогда
ОписаниеПараметра = ОписаниеПараметра + "
|> " + СтрокаПараметра.Описание;
КонецЕсли;
СтруктураПараметра.Вставить("documentation", ОписаниеПараметра);
ПараметрыМетода.Добавить(СтруктураПараметра);
выхЕстьПараметры = Истина;
КонецЦикла;
ПредставлениеМетода = "";
Если Не ДляСпискаАвтодополнения Тогда
ПредставлениеМетода = ПредставлениеМетода + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(ФормаВызовМетода.ИмяМетода, 13);
КонецЕсли;
ПредставлениеМетода = ПредставлениеМетода + "(" + ирОбщий.СтрСоединитьЛкс(КраткиеОписанияПараметров, ", ") + ")";
Если ЗначениеЗаполнено(ФормаВызовМетода.ТипЗначенияМетода) Тогда
Если Не ДляСпискаАвтодополнения Тогда
ПредставлениеМетода = ПредставлениеМетода + " [" + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(ФормаВызовМетода.ТипЗначенияМетода), 15) + "]";
КонецЕсли;
КонецЕсли;
ПодсказкаСлова.Вставить("label", ПредставлениеМетода);
ПодсказкаСлова.Вставить("parameters", ПараметрыМетода);
ОписаниеМетода = "";
Если ЗначениеЗаполнено(ФормаВызовМетода.ТекущийВариант) Тогда
ОписаниеМетода = ОписаниеМетода + "Вариант: " + ФормаВызовМетода.ТекущийВариант + "." + Символы.ПС;
КонецЕсли;
ОписаниеМетода = ОписаниеМетода + ФормаВызовМетода.ОписаниеМетода;
ПодсказкаСлова.Вставить("documentation", ОписаниеМетода);
СтруктураПодсказки.Добавить(ПодсказкаСлова);
КонецЦикла;
Возврат СтруктураПодсказки;
КонецФункции
Процедура РедакторHTML_ПередПоказомАвтодополнения(Триггер, ПоследнееВыражение, ПоследнееСлово) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
//РедакторHTML.hideSuggestionsList();
ПоказатьСписок = МожноПоказатьСписокСлов(Триггер, ПоследнееВыражение, ПоследнееСлово);
//Сообщить(Триггер);
Если ПоказатьСписок Тогда
Если Триггер = "backspace" Тогда
//РедакторHTML.enableBeforeShowSuggestEvent(Ложь);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РедакторHTML.showPreviousCustomSuggestions();
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
Иначе
ФормаВызовМетода = ФормаВызовМетода();
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.Закрыть();
КонецЕсли;
КончитьОбработкуКоманды();
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
РазобратьТекущийКонтекст(,,,,, Истина);
Если ЯзыкПрограммы = 0 И Триггер = """" Тогда
ПоказатьСписок = мЭтоТекстовыйЛитерал;
ИначеЕсли Истина
И Триггер <> "space"
И ЯзыкПрограммы = 1
И мЭтоОбъявлениеПсевдонима
Тогда
ПоказатьСписок = Ложь;
Иначе
ПоказатьСписок = Не (мКонтекст = "" И Триггер = ".");
КонецЕсли;
Если Не ПоказатьСписок Тогда
Возврат;
КонецЕсли;
//РедакторHTML.enableSuggestActivationEvent(Истина, Истина); // Второй параметр включает отображение типов для всех слов списка автодополнения https://github.com/salexdv/bsl_console/issues/119
РедакторHTML.setOption("generateSuggestActivationEvent", Истина);
РедакторHTML.setOption("alwaysDisplaySuggestDetails", Истина);
УспехЗаполнения = ЗаполнитьТаблицуСлов(, мКонкретныйТипКонтекста, мСтруктураТипаКонтекста, Триггер = "space", Ложь);
Если Истина
И УспехЗаполнения
И (Ложь
Или Триггер = "space"
Или ТаблицаСлов.Количество() > 0)
Тогда
СтруктураПодсказки = Новый Массив;
КодыТиповСлов = Новый Структура;
СоответствиеТипаСлова();
Для Каждого СтрокаСоответствия Из мСоответствиеТиповСловHTML Цикл
Если Не ЗначениеЗаполнено(СтрокаСоответствия.Имя) Тогда
Продолжить;
КонецЕсли;
КодыТиповСлов.Вставить(СтрокаСоответствия.Имя, СоответствиеТипаСлова(СтрокаСоответствия.Имя).Код);
КонецЦикла;
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
ПодсказкаСлова = Новый Структура();
ПодсказкаСлова.Вставить("name", СтрокаСлова.Слово);
//ТекстВставки = СтрокаСлова.Слово;
//ПодсказкаСлова.Вставить("text", ТекстВставки); // Закомментировал, т.к. пользы от этого нет, а вред есть https://github.com/salexdv/bsl_console/issues/171
ПодсказкаСлова.Вставить("kind", КодыТиповСлов[СтрокаСлова.ТипСлова]);
ПодсказкаСлова.Вставить("detail", СтрокаСлова.ТипЗначения);
Если СтрокаСлова.ТипСлова = "Конструкция" Тогда
ПодсказкаСлова.Вставить("sort", "-1"); // https://www.hostedredmine.com/issues/963233
КонецЕсли;
ПодсказкаСлова.Вставить("detail", СтрокаСлова.ТипЗначения);
ПодсказкаСлова.Вставить("documentation", "_"); // Нужно чтобы окно детального описания открывалось
СтруктураПодсказки.Добавить(ПодсказкаСлова);
КонецЦикла;
СтрокаСпискаАвтодополненияHTML = ирОбщий.ОбъектВСтрокуJSONЛкс(СтруктураПодсказки);
Если СтрокаСпискаАвтодополненияHTML <> Неопределено Тогда
РедакторHTML.setOption("showSnippetsOnCustomSuggestions", мСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"); // Штатные сниппеты https://github.com/salexdv/bsl_console/issues/200
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РедакторHTML.showCustomSuggestions(СтрокаСпискаАвтодополненияHTML);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// Триггер - Строка -
// ПоследнееВыражение - Строка -
// ПоследнееСлово - Строка -
// Возвращаемое значение:
// Булево -
Функция МожноПоказатьСписокСлов(Триггер, ПоследнееВыражение, ПоследнееСлово) Экспорт
Последние2Символа = Прав(ПоследнееВыражение, 2);
ПрефиксПараметра = мПараметрыДиалектаSQL.ПрефиксПараметра;
ОтображатьСписок = Ложь
Или Триггер = "space"
Или (Истина
И АвтоматическаяПодсказкаАвтодополненияHTML()
И (Ложь
Или Триггер = Неопределено // ввод буквы или после выбора слова списка вводом "."
Или Триггер = "." И Последние2Символа <> ".."
Или ЯзыкПрограммы <> 0 И Триггер = ПрефиксПараметра И Последние2Символа <> (ПрефиксПараметра + ПрефиксПараметра)
Или ЯзыкПрограммы = 0 И Триггер = """" И Последние2Символа <> """"""
Или ирОбщий.ЛиИмяПеременнойЛкс(Триггер) // Иначе слишком часто вызывается затратное обновление списка слов локального контекста
Или ЯзыкПрограммы = 0 И ирОбщий.СтрокиРавныЛкс(ПоследнееСлово, "новый")
Или ЯзыкПрограммы = 0 И ирОбщий.СтрокиРавныЛкс(ПоследнееСлово, "new")));
Возврат ОтображатьСписок;
КонецФункции
Функция СоответствиеТипаСлова(Знач ВстроенныйТипСлова = "", Знач ИмяКлюча = "Имя")
Если мСоответствиеТиповСловHTML = Неопределено Тогда
мСоответствиеТиповСловHTML = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("ТипыСловHTML"));
#Если Сервер И Не Сервер Тогда
мСоответствиеТиповСловHTML = Новый ТаблицаЗначений;
#КонецЕсли
мСоответствиеТиповСловHTML.Колонки.Добавить("НКод");
мСоответствиеТиповСловHTML.Индексы.Добавить("Имя");
мСоответствиеТиповСловHTML.Индексы.Добавить("НКод");
Для Каждого СтрокаТЗ Из мСоответствиеТиповСловHTML Цикл
СтрокаТЗ.НКод = НРег(СтрокаТЗ.Код);
КонецЦикла;
КонецЕсли;
НайденнаяСтрока = мСоответствиеТиповСловHTML.Найти(ВстроенныйТипСлова, ИмяКлюча);
//Если НайденнаяСтрока = Неопределено Тогда
// НайденнаяСтрока = мСоответствиеТиповСловHTML[0];
//КонецЕсли;
Возврат НайденнаяСтрока;
КонецФункции
Процедура РедакторHTML_ПриВыбореСтрокиАвтодополнения(Триггер, ПоследнееВыражение, ВыбранноеСлово, ТипСловаHTML, ТекстВставки, ПоследнееСлово)
Если ирОбщий.СтрНачинаетсяСЛкс(Триггер, "force-") Тогда
ПараметрЗакрытия = Прав(Триггер, 1);
Если Найти(ПоследнееВыражение, ".") > 0 Тогда
ВыделенныйТекст(ПараметрЗакрытия);
Возврат;
КонецЕсли;
Иначе
ПараметрЗакрытия = Истина;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.hideSuggestionsList();
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,,,,, Истина);
ОтборСлов = Новый Структура("Слово", ЧистоеСловоСпискаПодсказкиHTML(ВыбранноеСлово));
ТипСлова = ТипСловаИзТипаСловаHTML(ТипСловаHTML);
Если ТипСлова = "Шаблон" Тогда
мНачальнаяКолонка = мНачальнаяКолонка - СтрДлина(ПоследнееСлово);
УстановитьГраницыВыделения();
РедакторHTML.insertSnippet(ТекстВставки);
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(ТипСлова) Тогда
ОтборСлов.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(ОтборСлов);
Если НайденныеСтроки.Количество() = 0 Тогда
//Возврат;
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Слово = ВыбранноеСлово;
НоваяСтрока.ТипСлова = "Свойство";
НайденныеСтроки = ирОбщий.ЗначенияВМассивЛкс(НоваяСтрока);
КонецЕсли;
СтрокаТаблицыСлов = НайденныеСтроки[0];
ВставитьВыбранноеСловоАвтодополнения(СтрокаТаблицыСлов,, ПараметрЗакрытия);
Если ПараметрЗакрытия = "." Тогда
РедакторHTML.triggerSuggestions();
КонецЕсли;
Если мОткрытьСправкуПоПараметру = Истина Тогда
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
ОткрытьСправкуПоПараметру(, Ложь);
Иначе
РедакторHTML.triggerSigHelp();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ТипСловаИзТипаСловаHTML(Знач ТипСловаHTML)
ТипСлова = СоответствиеТипаСлова(ирОбщий.ПоследнийФрагментЛкс(ТипСловаHTML, "-"), "НКод").Имя;
Возврат ТипСлова;
КонецФункции
Функция ЛиДоступноОткрытиеСвободнойФормы()
Возврат Не (Ложь
Или ирКэш.ЛиСеансТолстогоКлиентаУПЛкс()
Или ФормаВладелец <> Неопределено И ФормаВладелец.МодальныйРежим);
КонецФункции
Процедура РедакторHTML_ОбработатьСобытие(Событие) Экспорт
//Сообщить("Отладка. " + Событие.event);
Попытка
Если Событие.event = "EVENT_BEFORE_SIGNATURE" Тогда
РедакторHTML_ПередПоказомСигнатуры(Событие.params.activeParameter, Событие.params.word, Событие.params.activeSignature, Событие.params.triggerCharacter);
ИначеЕсли Событие.event = "EVENT_ON_SELECT_SUGGEST_ROW" Тогда
РедакторHTML_ПриВыбореСтрокиАвтодополнения(Событие.params.trigger, Событие.params.last_expression, Событие.params.selected, Событие.params.kind, Событие.params.insert_text, Событие.params.last_word);
ИначеЕсли Ложь
Или Событие.event = "EVENT_ON_ACTIVATE_SUGGEST_ROW"
Или Событие.event = "EVENT_ON_DETAIL_SUGGEST_ROW"
Тогда
РедакторHTML_ПриАктивацииСтрокиАвтодополнения(Событие.params.trigger, Событие.params.focused, Событие.params.row_id, Событие.params.sideDetailIsOpened, Событие.params.kind);
ИначеЕсли Событие.event = "EVENT_BEFORE_SHOW_SUGGEST" Тогда
РедакторHTML_ПередПоказомАвтодополнения(Событие.params.trigger, Событие.params.last_expression, Событие.params.last_word);
КонецЕсли;
Исключение
// Антибаг платформы https://www.hostedredmine.com/issues/962188
ирОбщий.СообщитьЛкс(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура РедакторHTML_ПриАктивацииСтрокиАвтодополнения(Триггер, ТекущееСлово, НомерСлова, ЛиОтдельноеОписаниеАктивно, ТипСловаHTML) Экспорт
// Показывать надо обязательно каждый раз, т.к. редактор забывает предыдущие уточнения типа
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТипСлова = ТипСловаИзТипаСловаHTML(ТипСловаHTML);
Если ТипСлова = "Шаблон" Тогда
Возврат;
КонецЕсли;
РедакторHTML = ПолеТекста.РедакторHTML();
СтрокаТаблицыСлов = ТаблицаСлов.Найти(ЧистоеСловоСпискаПодсказкиHTML(ТекущееСлово), "Слово");
Если СтрокаТаблицыСлов <> Неопределено Тогда
ТаблицаТипов = УточнитьТипЗначенияВСтрокеТаблицыСлов(мСтруктураТипаКонтекста, СтрокаТаблицыСлов, ЛиОтдельноеОписаниеАктивно);
СтруктураОписания = Новый Массив;
Если мСтруктураТипаКонтекста.Конструктор Тогда
ДетальноеОписаниеДляСписка = "";
Иначе
ДетальноеОписаниеДляСписка = СтрокаТаблицыСлов.ТипЗначения;
Если ЗначениеЗаполнено(ДетальноеОписаниеДляСписка) Тогда
СтруктураОписания.Добавить("> Тип: " + ДетальноеОписаниеДляСписка);
КонецЕсли;
КонецЕсли;
Если ЛиОтдельноеОписаниеАктивно И ТаблицаТипов <> Неопределено Тогда
Если Ложь
Или мСтруктураТипаКонтекста.Конструктор
Или СтрокаТаблицыСлов.ТипСлова = "Метод"
Тогда
Если мСтруктураТипаКонтекста.Конструктор Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Глобальный";
ТаблицаТипов = мПлатформа.СловаКонтекстаПредопределенные(СтруктураТипа, СтрокаТаблицыСлов.Слово, "Конструктор",, ЯзыкПрограммы, Конфигурация)[0].ТаблицаТипов;
КонецЕсли;
//ПараметрыМетода = мПлатформа.ПараметрыМетодаПлатформы(ТаблицаТипов[0]);
СтруктураПодсказкиМетода = СтруктураПодсказкиМетода(ТаблицаТипов[0], Триггер <> Неопределено, Истина);
Если СтруктураПодсказкиМетода.Количество() > 0 Тогда
СтруктураОписания.Вставить(0, "> Параметры: " + СтруктураПодсказкиМетода[0].label);
Если СтруктураПодсказкиМетода.Количество() > 1 Тогда
СтруктураОписания.Вставить(0, "> Варианты: " + СтруктураПодсказкиМетода.Количество());
КонецЕсли;
ОписаниеСлова = СтруктураПодсказкиМетода[0].documentation;
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
СтруктураОписания.Добавить("> Описание: " + ОписаниеСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураОписания.Добавить("> Определение: " + СтрокаТаблицыСлов.Определение);
ДетальноеОписаниеОтдельное = ирОбщий.СтрСоединитьЛкс(СтруктураОписания, Символы.ПС);
Если Триггер = "hover" Тогда
РедакторHTML.setSuggestItemDetailById(НомерСлова, ДетальноеОписаниеДляСписка, ДетальноеОписаниеОтдельное);
Иначе
МаксВысотаТочек = 800;
РедакторHTML.setActiveSuggestDetail(ДетальноеОписаниеДляСписка, ДетальноеОписаниеОтдельное, МаксВысотаТочек);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура РедакторHTML_ОтключитьСочетанияПереключенияСигнатуры() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
// https://github.com/salexdv/bsl_console/issues/130
// Коды клавиш https://microsoft.github.io/monaco-editor/api/enums/monaco.keycode.html
РедакторHTML.disableKeyBinding(512+16); // ALT(512)+ArrowUp(16)
РедакторHTML.disableKeyBinding(512+18); // ALT(512)+ArrowDown(18)
КонецПроцедуры
Процедура РедакторHTML_ВключитьСочетанияПереключенияСигнатуры() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
// https://github.com/salexdv/bsl_console/issues/130
РедакторHTML.enableKeyBinding(528); // ALT(512)+ArrowUp(16)
РедакторHTML.enableKeyBinding(530); // ALT(512)+ArrowDown(18)
КонецПроцедуры
Процедура РедакторHTML_ОбработатьКликНаГиперссылке(Событие, ФункцияПерейтиКОпределению, ФункцияВычислитьВыражение) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ПолеТекста.ОбработатьКликНаГиперссылке(Событие) Тогда
Возврат;
КонецЕсли;
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.hideHoverList();
ЗаголовокГиперссылки = Событие.params.label;
ЗначениеГиперссылки = Событие.params.href;
Если ЗаголовокГиперссылки = "Определение" Тогда
Координаты = ирОбщий.СтрРазделитьЛкс(ЗначениеГиперссылки, ",");
НомерСтроки = Число(Координаты[0]);
НомерКолонки = Число(Координаты[1]);
Если Не Вычислить("ФормаВладелец." + ФункцияПерейтиКОпределению + "(НомерСтроки, НомерКолонки)") Тогда
ПерейтиКОпределению(НомерСтроки, НомерКолонки);
КонецЕсли;
ИначеЕсли ЗаголовокГиперссылки = "Знач" Тогда
УспехВычисления = Истина;
ЗначениеВыражения = Вычислить("ФормаВладелец." + ФункцияВычислитьВыражение + "(ЗначениеГиперссылки, УспехВычисления)");
Если УспехВычисления Тогда
ирКлиент.ОткрытьЗначениеЛкс(ЗначениеВыражения);
КонецЕсли;
ИначеЕсли Ложь
Или Лев(ЗаголовокГиперссылки, 1) = "["
Или ЗаголовокГиперссылки = "Допустимые типы"
Тогда
ОткрытьОписаниеТипаПоГиперссылке(ЗначениеГиперссылки);
Иначе
ОткрытьКонтекстнуюСправку(ЗначениеГиперссылки);
КонецЕсли;
КонецПроцедуры
Процедура КомандаРедактораHTML(Команда)
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.editor.trigger("", Команда);
КонецПроцедуры
Процедура ЗаменитьВхожденияHTML()
КомандаРедактораHTML("editor.action.changeAll");
КонецПроцедуры
Процедура СочетанияКлавишHTML()
ирКлиент.ОткрытьТекстЛкс(ПолучитьМакет("СочетанияКлавишHTML").ПолучитьТекст(), "Сочетания клавиш HTML редактора", "Обычный", Истина, "СочетанияКлавишHTML");
КонецПроцедуры
Процедура ОткрытьКонструкторФорматнойСтроки(ФорматнаяСтрока)
Конструктор = Новый КонструкторФорматнойСтроки();
Попытка
Конструктор.Текст = ФорматнаяСтрока;
Исключение
Инфо = ИнформацияОбОшибке();
ирОбщий.СообщитьЛкс("Ошибка в тексте форматной строки:" + Символы.ПС + Инфо.Причина.Описание);
Возврат;
КонецПопытки;
Если Конструктор.ОткрытьМодально() Тогда
Результат = Конструктор.Текст;
Результат = СтрЗаменить(Результат, "'", "");
Результат = """" + Результат + """";
ВыделенныйТекст(Результат);
КонецЕсли;
КонецПроцедуры
Процедура КонструкторФорматнойСтроки()
ФорматнаяСтрока = ВыделитьТекстовыйЛитерал();
ОткрытьКонструкторФорматнойСтроки(ФорматнаяСтрока);
КонецПроцедуры
Процедура НайтиСледующееHTML()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.nextMatch();
КонецПроцедуры
Процедура НайтиПредыдущееHTML()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.previousMatch();
КонецПроцедуры
Процедура РедакторHTML_Перерисовать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
//ПолеТекста.Перерисовать();
//ОбновитьПодсказкуПоВызовуМетода();
КонецПроцедуры
Процедура ПанельРедактораКодаПриСменеСтраницы(Знач ПанельРедактора, Знач Поле1, Знач Поле2, Знач ИсходныйТекст) Экспорт
#Если Сервер И Не Сервер Тогда
Поле1 = Обработки.ирОболочкаПолеТекста.Создать();
Поле2 = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущаяСтраница = ПанельРедактора.ТекущаяСтраница;
Если ТекущаяСтраница = ПанельРедактора.Страницы.РедакторHTML Тогда
ЭтотОбъект.ПолеТекста = Поле2;
ПолеТекста.ЗагрузитьСостояниеИзПоляТекстаЛкс(Поле1, ИсходныйТекст);
Иначе
ЭтотОбъект.ПолеТекста = Поле1;
ПолеТекста.ЗагрузитьСостояниеИзПоляТекстаЛкс(Поле2, ИсходныйТекст);
КонецЕсли;
КонецПроцедуры
#КонецЕсли
// Добавляет правило вычисления типа значения функции.
// При вызове правила вычисляется "Правило(<СтрокаАргументов>)", а оно должно вернуть ТаблицаТипов.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка - "Метод", "Свойство";
// *ТипЗначения - ОписаниеТипов, *Неопределено;
// *Метаданные - Произвольный, *Неопределено;
//
Процедура ДобавитьПравилоВычисленияФункции(ИмяФункции, Правило, ТипКонтекста = "Локальный") Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("НСлово", Нрег(ИмяФункции));
КлючСтроки.Вставить("ТипКонтекста", ТипКонтекста);
НайденныеСтроки = мПравилаВычисленияФункций.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = мПравилаВычисленияФункций.Добавить();
Иначе
НоваяСтрока = НайденныеСтроки[0];
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючСтроки);
НоваяСтрока.Правило = Правило;
НоваяСтрока.Слово = ИмяФункции;
КонецПроцедуры
//.
// Параметры:
// ТекущееСлово - Строка, Строка(256) -
// РодительскаяСтруктураТипа - ? -
// Возвращаемое значение:
// СтрокаТаблицыЗначений -
Функция НайтиПравилоВычисленияФункции(Знач ИмяМетода, Знач РодительскаяСтруктураТипа) Экспорт
Если РодительскаяСтруктураТипа = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТипКонтекста = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
Если Истина
И ТипКонтекста = "ОбщийМодуль"
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
ТипКонтекста = ТипКонтекста + "." + РодительскаяСтруктураТипа.Метаданные.Имя;
КонецЕсли;
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("ТипКонтекста", ТипКонтекста);
КлючСтроки.Вставить("НСлово", НРег(ИмяМетода));
НайденныеСтроки = мПравилаВычисленияФункций.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
КлючСтроки.ТипКонтекста = "*";
НайденныеСтроки = мПравилаВычисленияФункций.НайтиСтроки(КлючСтроки);
КонецЕсли;
ПравилоВычисленияФункции = Неопределено;
Если НайденныеСтроки.Количество() > 0 Тогда
ПравилоВычисленияФункции = НайденныеСтроки[0];
КонецЕсли;
Возврат ПравилоВычисленияФункции;
КонецФункции
Процедура УстановитьКонфигурациюМетаданных(пКонфигурация = Неопределено, пКонтекстВыполнения = Неопределено, Знач ДиалектSQL = Неопределено, РасширенноеПолучениеМетаданныхADO = Ложь) Экспорт
//Если ЯзыкПрограммы = 1 Тогда
Если ДиалектSQL = Неопределено Тогда
Если пКонфигурация <> Неопределено Тогда
ЭтотОбъект.Конфигурация = пКонфигурация;
Иначе
ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
КонецЕсли;
Если ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ЭтотОбъект.мДиалектSQL = "1С";
Иначе
ЭтотОбъект.мДиалектSQL = "MSSQL";
Попытка
Пустышка = Конфигурация.Provider;
Исключение
Пустышка = Неопределено;
КонецПопытки;
Если Пустышка <> Неопределено Тогда
// Это ADODB.Connection
Если Конфигурация.State = 1 Тогда
ДиалектSQL = Конфигурация.Properties("DBMS Name").Value;
Иначе
// Не меняем мДиалектSQL!
КонецЕсли;
Иначе
ДиалектSQL = "WQL";
КонецЕсли;
КонецЕсли;
Иначе
Если ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
Иначе
ЭтотОбъект.Конфигурация = пКонфигурация;
КонецЕсли;
КонецЕсли;
Если мДиалектыSQL = Неопределено Тогда
Если мПлатформа.мДиалектыSQL = Неопределено Тогда
мПлатформа.мДиалектыSQL = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("ДиалектыSQL"),,, Ложь, Истина);
КонецЕсли;
ЭтотОбъект.мДиалектыSQL = мПлатформа.мДиалектыSQL;
КонецЕсли;
Если мДиалектыSQL.Найти(ДиалектSQL, "Диалект") <> Неопределено Тогда
ЭтотОбъект.мДиалектSQL = ДиалектSQL;
КонецЕсли;
ЭтотОбъект.мПараметрыДиалектаSQL = мДиалектыSQL.Найти(мДиалектSQL, "Диалект");
ЭтотОбъект.мРасширенноеПолучениеМетаданныхADO = РасширенноеПолучениеМетаданныхADO = Истина;
//Иначе
// Если пКонфигурация <> Неопределено Тогда
// ЭтотОбъект.Конфигурация = пКонфигурация;
// Иначе
// ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
// КонецЕсли;
//КонецЕсли;
//Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
// мДоступныеТаблицыПолучены = Истина;
//ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
// //ЗаполнитьДоступныеТаблицыWQL(); // Слишком долго
// мДоступныеТаблицыПолучены = Истина;
//Иначе
// мДоступныеТаблицыПолучены = Ложь;
//КонецЕсли;
ЭтотОбъект.КонтекстВыполнения = пКонтекстВыполнения;
КонецПроцедуры
// Очишает таблицу слов локального контекста.
//
// Параметры:
// Нет.
//
Процедура ОчиститьТаблицуСловЛокальногоКонтекста() Экспорт
Если Ложь
Или мМетодМодуля = Неопределено // Для консоли кода без режима Модуль
Или ЗначениеЗаполнено(мМодульМетаданных.Имя)
Тогда
Возврат;
КонецЕсли;
ОчиститьТаблицуСловЛокальногоКонтекстаПоТипуСлова();
ОчиститьТаблицуСловЛокальногоКонтекстаПоТипуСлова("Метод");
КонецПроцедуры
Процедура ОчиститьТаблицуСловЛокальногоКонтекстаПоТипуСлова(Знач ТипСлова = "Свойство")
ОтборСтрок = Новый Структура("ПозицияСОписанием", Неопределено);
ТаблицаЛокальногоКонтекста = ТаблицаЛокальногоКонтекста(ТипСлова);
ВыбранныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(ОтборСтрок);
Для Каждого ВыбраннаяСтрока Из ВыбранныеСтроки Цикл
ВыбраннаяСтрока.ТаблицаТипов = Неопределено; // Мультиметка4529884 Разрываем циклические ссылки во вложенной колонке СтрокаОписания. Возможно уже не нужно
ТаблицаЛокальногоКонтекста.Удалить(ВыбраннаяСтрока);
КонецЦикла;
КонецПроцедуры
Функция ПроверитьТекстИВернутьОшибку(ТекстДляПроверки = Неопределено, СтартоваяСтрока = 0, СтартоваяКолонка = 0, Контекст = Неопределено, СамаяВложеннаяПричина = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстИнициализации = "";
Если ЯзыкПрограммы = 0 Тогда
Если мМодульМетаданных <> Неопределено Тогда
Для Каждого ЛокальноеСлово Из мМодульМетаданных.Переменные Цикл
Если ТипТекста = "Алгоритм" Тогда
ТекстИнициализации = ЛокальноеСлово.Имя + " = 0; " + ТекстИнициализации;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если ТипТекста = "Алгоритм" И СтрокаПараметра.Вход Тогда
ТекстИнициализации = СтрокаПараметра.Имя + " = 0; " + ТекстИнициализации;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТекстДляПроверки = Неопределено Тогда
ТекстДляПроверки = ПолеТекста.ПолучитьТекст();
Если Не ЭтоМодуль И мМодульМетаданных <> Неопределено И мМодульМетаданных.Методы.Количество() > 0 Тогда
ВызватьИсключение "Текст программы не допускает определения методов";
КонецЕсли;
КонецЕсли;
СтартоваяСтрока = 0;
СтартоваяКолонка = 0;
Если ЯзыкПрограммы = 1 Тогда
ТекстЗапроса = ТекстДляПроверки;
Если ТекстЗапроса <> "" Тогда
Если ТипТекста = "Выражение" Тогда
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстЗапроса, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
СтартоваяСтрока = -1;
Иначе
Если мДиалектSQL <> "1С" Тогда
РезультатРазбора = Ложь;
#Если Клиент Тогда
РезультатРазбора = ЗагрузитьТекстВКонструктор(ТекстЗапроса);
#КонецЕсли
Если Не РезультатРазбора Тогда
ИнформацияОбОшибке = 1;
КонецЕсли;
Иначе
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
ПроверочныйЗапрос = Новый Запрос;
ПроверочныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ПроверочныйЗапрос.Текст = ТекстЗапроса;
Попытка
ПроверочныйЗапрос.НайтиПараметры();
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
Иначе
КонструкторЗапроса = Новый КонструкторЗапроса;
КонструкторЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
Попытка
КонструкторЗапроса.Текст = ТекстЗапроса;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЯзыкПрограммы = 0 Тогда
ТекстДляВыполнения = ТекстИнициализации;
Если ТипТекста = "Выражение" Тогда
Если ТекстДляПроверки = "" Тогда
ТекстДляПроверки = 0;
КонецЕсли;
ТекстДляВыполнения = ТекстДляВыполнения + "?(Истина, 0, " + Символы.ПС + ТекстДляПроверки + Символы.ПС + ")";
Иначе
//ТекстДляВыполнения = ТекстДляВыполнения + "Если Ложь Тогда " + Символы.ПС + ТекстДляПроверки + Символы.ПС + " КонецЕсли"; // Заменено 06.12.2011
ТекстДляВыполнения = "Если Ложь Тогда Попытка " + ТекстДляВыполнения + Символы.ПС + ТекстДляПроверки + Символы.ПС + " Исключение КонецПопытки КонецЕсли";
КонецЕсли;
Если Нрег(Контекст) = Нрег("Сервер") Тогда
лКонтекстВыполнения = ирСервер;
лМетодВыполнения = "ВыполнитьАлгоритм";
ИначеЕсли Контекст <> Неопределено Тогда
лКонтекстВыполнения = Контекст;
лМетодВыполнения = "ВыполнитьАлгоритм";
Иначе
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
КонецЕсли;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстДляВыполнения, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
СтартоваяСтрока = - 1;
ИначеЕсли ЯзыкПрограммы = 2 Тогда
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстДляПроверки, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
КонецЕсли;
Если СамаяВложеннаяПричина И ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
КонецЕсли;
Возврат ИнформацияОбОшибке;
КонецФункции
// Выполняет проверку синтаксиса программного кода или текста запроса.
//
// Параметры:
// *СообщатьОбУспешнойПроверке - Булево, *Ложь;
// *ТекстДляПроверки - Строка, *Неопределено - проверяемый текст (используется весь текст или этот).
//
// Возвращаемое значение:
// Булево - результат проверки.
//
Функция ПроверитьПрограммныйКод(СообщатьОбУспешнойПроверке = Ложь, ТекстДляПроверки = Неопределено, Контекст = Неопределено) Экспорт
СтартоваяСтрока = 0;
СтартоваяКолонка = 0;
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстДляПроверки, СтартоваяСтрока, СтартоваяКолонка, Контекст);
Если ЗначениеЗаполнено(Контекст) Тогда
ПредставлениеКонтекста = " (Проверка " + Контекст + ")";
КонецЕсли;
Если ИнформацияОбОшибке <> Неопределено Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
#Если Клиент Тогда
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
КонецЕсли;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, СтартоваяСтрока, СтартоваяКолонка, ЯзыкПрограммы, , ИнформацияОбОшибке,, ПредставлениеКонтекста);
#КонецЕсли
Иначе
// Ошибка обработана и отображена ранее
КонецЕсли;
Иначе
Если СообщатьОбУспешнойПроверке Тогда
СообщитьОбУспешнойПроверке(ПредставлениеКонтекста);
КонецЕсли;
КонецЕсли;
Возврат ИнформацияОбОшибке = Неопределено;
КонецФункции
Процедура СообщитьОбУспешнойПроверке(Знач ПредставлениеКонтекста = "") Экспорт
ирОбщий.СообщитьСУчетомМодальностиЛкс(ирОбщий.ПредставлениеИзИдентификатораЛкс(ПолеТекста.ЭлементФормы.Имя)
+ ПредставлениеКонтекста + ": Синтаксических ошибок не обнаружено!");
КонецПроцедуры
Процедура СброситьРезультатРазбораПозицииВТексте()
мНомерПараметра = 0;
мНачалоКонтекста = "";
мНачалоСлова = "";
мКонецКонтекста = "";
выхЕстьТочкаСправа = Ложь;
мРодительскийКонтекст = "";
мКонтекст = "";
мЭтоТекстовыйЛитерал = Ложь;
мЭтоОбъявлениеПсевдонима = Ложь;
мЭтоКонструктор = Ложь;
мАргументы = "";
мПервыйФактическийПараметр = "";
мФактическиеПараметры = Новый Массив;
КонецПроцедуры
// Заменяет все печатаемые символы, кроме идентификаторов в кавычках, внутри комментариев и строковых литералов на заданный символ.
//
// Параметры:
// Текст - - Строка;
// СимволЗамена - - Строка.
// ЗалитьСтроковыеЛитералы - -
// ЗалитьУсловия - Булево - очень долго, вроде бы уже не применяется
//
// Возвращаемое значение:
// Строка - .
//
Функция ЗалитьКомментарииИСтроковыеЛитералы(Знач Текст, СимволЗамена = " ", ЗалитьСтроковыеЛитералы = Ложь, ЗалитьУсловия = Ложь) Экспорт
Если Не ЗначениеЗаполнено(Текст) Тогда
Возврат Текст;
КонецЕсли;
мРегВыражение.Global = Истина;
мРегВыражение.Multiline = Ложь;
// Количество символов в тексте меняется, но позиции строк сохраняются
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
////RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
мРегВыражение.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
ИначеЕсли ЯзыкПрограммы = 0 Тогда
//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаПрограммы + ")|(.|\n|\r)";
шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n])*""?";
шОднострочнаяСтрокаПрограммыСЧерты = "(?:(\n)\s*\|(?:(?:"""")|[^""\n])*""?)";
// + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|(.|\n|\r)";
мРегВыражение.Pattern = "(""" + шИмя + "(?:\.[" + шБуква + "\d]+)*"")" // имена ProgId от COM объектов бывают "Forms.TextBox.1"
+ "|(""(?:" + шИмя + "\s*,\s*)*" + шИмя + """)" // создание структуры
+ "|" + мПлатформа.шПустоеНачалоСтроки + "//[^\n]*" // комментарии с начала строки
+ "|#[^\n]*" // Инструкции препроцессора
+ "|";
ШаблонЗамены = "$1$2$3";
Если ЗалитьСтроковыеЛитералы Тогда
мРегВыражение.Pattern = мРегВыражение.Pattern + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "";
ШаблонЗамены = ШаблонЗамены + "$4";
Иначе
// http://www.hostedredmine.com/issues/885452
КонецЕсли;
мРегВыражение.Pattern = мРегВыражение.Pattern + "|([\s\S])";
КонецЕсли;
ЗалитыйТекст = мРегВыражение.Заменить(Текст, ШаблонЗамены);
Если Истина
И мЯзыкПрограммы = 0
И ЗалитьУсловия
И СтрДлина(ЗалитыйТекст) < 10000 // Долго на больших текстах!
Тогда
// Заливаем условия, чтобы проверка равенства в них не считалась присвоением
// В будущем можно отказаться от этого блока и собирать все возможные типы, а потом давать юзеру выбирать.
мРегВыражение.Pattern = "(" + шЕсли + ")|(" + шПока + ")";
ЗалитыйТекстОригинал = ЗалитыйТекст;
Результат = мРегВыражение.НайтиВхождения(ЗалитыйТекстОригинал);
ЗалитыйТекст = Новый ЗаписьXML;
ЗалитыйТекст.УстановитьСтроку("");
ТекущаяПозицияВОригинале = 1;
Для Каждого Match Из Результат Цикл
НайденныйТекст = Неопределено;
НачалоТокена = "";
Если Match.SubMatches(0) <> Неопределено Тогда
НайденныйТекст = Match.SubMatches(0);
НачалоТокена = Match.SubMatches(1);
ИначеЕсли Match.SubMatches(3) <> Неопределено Тогда
НайденныйТекст = Match.SubMatches(3);
НачалоТокена = Match.SubMatches(4);
КонецЕсли;
ЗалитыйТекст.ЗаписатьБезОбработки(Сред(ЗалитыйТекстОригинал, ТекущаяПозицияВОригинале, Match.FirstIndex + 1 - ТекущаяПозицияВОригинале));
ЗалитыйТекст.ЗаписатьБезОбработки(НачалоТокена + мРегВыражение.Заменить(Сред(НайденныйТекст, 1 + СтрДлина(НачалоТокена), СтрДлина(НайденныйТекст) - СтрДлина(НачалоТокена)), СимволЗамена));
ТекущаяПозицияВОригинале = Match.FirstIndex + 1 + СтрДлина(Match.Value);
КонецЦикла;
ЗалитыйТекст.ЗаписатьБезОбработки(Сред(ЗалитыйТекстОригинал, ТекущаяПозицияВОригинале));
ЗалитыйТекст = ЗалитыйТекст.Закрыть();
КонецЕсли;
Возврат ЗалитыйТекст;
КонецФункции
Процедура ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(ОчиститьТаблицуСлов = Истина, Знач ВключатьКонструкции = Истина, УчитыватьРодительскийКонтекст = Ложь, ОбновитьТекстДляАнализа = Истина,
ВключатьГлобальныйКонтекст = Ложь, Знач ТекстДляАнализа = "", Знач ТекстСинтаксическиКорректен = Ложь, Знач ТолькоСвойства = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(, "Заполнение параметров", Истина) Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТекстДляАнализа) Тогда
Если Ложь
Или ОбновитьТекстДляАнализа
Или мТекстБезТекстовыхЛитералов = ""
Тогда
Если ЗначениеЗаполнено(мТекстБлока) Тогда
ТекстДляАнализа = мТекстБлока;
//Иначе
// ТекстДляАнализа = ПолеТекста.ПолучитьТекст(); // Опасно. На больших модулях между методами срабатывает.
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстДляАнализа) Тогда
мТекстБезТекстовыхЛитералов = ЗалитьКомментарииИСтроковыеЛитералы(ТекстДляАнализа,, Истина);
ИначеЕсли ОбновитьТекстДляАнализа Тогда
мТекстБезТекстовыхЛитералов = ТекстДляАнализа;
КонецЕсли;
Если ОчиститьТаблицуСлов Тогда
ТаблицаСлов.Очистить();
ИначеЕсли ВключатьГлобальныйКонтекст Тогда
ВызватьИсключение "Запрещенное сочетание параметров ОчиститьТаблицуСлов и ВключатьГлобальныйКонтекст";
КонецЕсли;
Если ВключатьГлобальныйКонтекст Тогда
// 23мс
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Глобальный";
СтруктураТипа.Метаданные = Метаданные;
ТаблицаГлобальногоКонтекста = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипа,, Конфигурация,, Ложь,,, мФлагиКомпиляции);
ТаблицаСлов.Загрузить(ТаблицаГлобальногоКонтекста);
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаСлов, "Слово", "НСлово");
ТаблицаГлобальногоКонтекста = Неопределено;
КонецЕсли;
ЛитералыЗначения = мПлатформа.ЛитералыЗначенияВсехЯзыков1С();
Если мЯзыкПрограммы = 0 Тогда
КлючевыеСловаЯзыка = мПлатформа.КлючевыеСловаВстроенногоЯзыка();
ИначеЕсли мЯзыкПрограммы = 1 Тогда
ВключаяРусские = ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация");
КлючевыеСловаЯзыка = мПлатформа.КлючевыеСловаЯзыкаЗапросов(РежимКомпоновкиДанных, ВключаяРусские, Истина);
ИначеЕсли мЯзыкПрограммы = 2 Тогда
//СписокСловЯзыка = мПлатформа.КлючевыеСловаЯзыкаЗапросов();
КлючевыеСловаЯзыка = Новый СписокЗначений;
КлючевыеСловаЯзыка.Добавить("РАЗЛИЧНЫЕ"); // Криво https://www.hostedredmine.com/issues/931487
КонецЕсли;
Если ВключатьКонструкции Тогда
Для Каждого ЭлементСписка Из КлючевыеСловаЯзыка Цикл
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Слово = ЭлементСписка.Значение;
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
НоваяСтрока.ТипСлова = "Конструкция";
НоваяСтрока.Определение = "Предопределенный";
КонецЦикла;
Для Каждого ЭлементСписка Из ЛитералыЗначения Цикл
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Слово = ЭлементСписка.Значение;
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
НоваяСтрока.ТипЗначения = ЭлементСписка.Представление;
НоваяСтрока.ТипСлова = "Свойство";
НоваяСтрока.Определение = "Предопределенный";
КонецЦикла;
КонецЕсли;
//Поиск использованных свойств и методов данного контекста.
мРегВыражение.Global = Истина;
Если Ложь
Или Не УчитыватьРодительскийКонтекст
Или мРодительскийКонтекст = ""
Тогда
Если ТолькоСвойства Тогда
Шаблон = "(ъъъъ)|(ъъъъ)";
Иначе
Шаблон = "(?:" + шПредИмя + "(" + шИмя + ")(?=\s*\())"
+ "|(" + шПараметрЗапроса + ")";
КонецЕсли;
шКлючевыеСлова = ирОбщий.СтрСоединитьЛкс(КлючевыеСловаЯзыка.ВыгрузитьЗначения(), "|");
шЛитералыЗначения = ирОбщий.СтрСоединитьЛкс(ЛитералыЗначения.ВыгрузитьЗначения(), "|");
Шаблон = Шаблон + "|" + шПредИмя + "(?!(?:" + шКлючевыеСлова + "|" + шЛитералыЗначения + ")[^?:\." + шБуква + "\d])(" + шИмя + ")(?=(?:\.(?:" + шИмя + ")?)+|[^?:\(\." + шБуква + "\d]|$)";
КоличествоПодгрупп = 3;
Иначе
Если ТолькоСвойства Тогда
Шаблон = "(ъъъъ)";
Иначе
Шаблон = шПредИмя + "(?:" + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(мРодительскийКонтекст) + "\.(" + шИмя + ")(?=\s*\())";
КонецЕсли;
Шаблон = Шаблон + "|" + шПредИмя + "(?:" + ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(мРодительскийКонтекст) + "\.(" + шИмя + ")(?=[^\(?:" + шБуква + "\d]|$))";
КоличествоПодгрупп = 2;
КонецЕсли;
ТаблицаСловТЗ = ТаблицаСлов.Выгрузить(, "НСлово, ТипСлова, Частота");
ТаблицаСловТЗ.Индексы.Добавить("НСлово");
Если ЯзыкПрограммы = 0 Тогда
мРегВыражение.Pattern = "(?:" + шСтрокаПрограммы + "|" + шКомментарий + "|(?:Новый|New)\s+" + шИмя + ")";
Иначе
мРегВыражение.Pattern = "(?:" + шСтрокаПрограммы + "|" + шКомментарий + ")";
КонецЕсли;
ВременныйТекст = мРегВыражение.Заменить(мТекстБезТекстовыхЛитералов, "");
мРегВыражение.Pattern = Шаблон;
Результат = мРегВыражение.НайтиВхождения(ВременныйТекст,, Истина);
Счетчик = 0;
Для Каждого Match Из Результат Цикл
Счетчик = Счетчик + 1;
Если Счетчик = МаксСловНаходитьВТекстеПрограммы Тогда
// Обрезка контекста для ускорения
Прервать;
КонецЕсли;
Подгруппа1 = Match.SubMatches(0);
Подгруппа2 = Match.SubMatches(1);
Если КоличествоПодгрупп = 3 Тогда
Подгруппа3 = Match.SubMatches(2);
Иначе
Подгруппа3 = Неопределено;
КонецЕсли;
Если Подгруппа1 <> Неопределено Тогда
Слово = Подгруппа1;
ТипСлова = "Метод";
ИначеЕсли Подгруппа2 <> Неопределено Тогда
Слово = Подгруппа2;
ТипСлова = "Свойство";
ИначеЕсли Подгруппа3 <> Неопределено Тогда
Слово = Подгруппа3;
ТипСлова = "Свойство";
Если Истина
И ОчиститьТаблицуСлов
И ВключатьГлобальныйКонтекст
И ЗначениеЗаполнено(ТекстДляАнализа)
И ТекстСинтаксическиКорректен
И (Ложь
Или Не УчитыватьРодительскийКонтекст
Или мРодительскийКонтекст = "")
Тогда
// Подмена контекста нужна, чтобы избежать бесконечной рекурсии через вызов КонсольКода.ЗаполнитьПараметрыВыхода в режиме ЭтоМодуль
КонтекстВыполненияПроверки = ?(мФлагиКомпиляции.Сервер, ирСервер, ирОбщий);
// Вызов из консоли кода для заполнения выходных параметров. https://www.hostedredmine.com/issues/947841
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстДляАнализа + ";Сообщить(" + Слово + ")",,, КонтекстВыполненияПроверки);
Если Истина
И ИнформацияОбОшибке <> Неопределено
И ирОбщий.СтрНайтиЛкс(ИнформацияОбОшибке.Причина.Описание, "функция",,,, Ложь) = 0
И ирОбщий.СтрНайтиЛкс(ИнформацияОбОшибке.Причина.Описание, "function",,,, Ложь) = 0
Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Иначе
Продолжить;
КонецЕсли;
СтруктураКлюча = Новый Структура("НСлово", НРег(Слово));
Если ТипСлова = "Метод" Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаСловТЗ.НайтиСтроки(СтруктураКлюча);
Если Истина
И ТаблицаГлобальногоКонтекста <> Неопределено
И НайденныеСтроки.Количество() = 0
Тогда
НайденныеСтроки = ТаблицаГлобальногоКонтекста.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
НоваяСтрока = Неопределено;
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Если Ложь
Или ЯзыкПрограммы = 1
Или ТипСлова = "Метод"
Или (Истина
И ТипСлова <> "Метод"
И НайденнаяСтрока.ТипСлова <> "Метод")
Тогда
НоваяСтрока = НайденнаяСтрока;
Прервать;
КонецЕсли;
КонецЦикла;
Если НоваяСтрока = Неопределено Тогда
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Определение = "Статистический";
НоваяСтрока.Слово = Слово;
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
НоваяСтрока.ТипСлова = ТипСлова;
НоваяСтрока.ТипЗначения = "??";
НоваяСтрока = ТаблицаСловТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураКлюча);
КонецЕсли;
НоваяСтрока.Частота = НоваяСтрока.Частота + 1;
КонецЦикла;
ТаблицаСлов.ЗагрузитьКолонку(ТаблицаСловТЗ.ВыгрузитьКолонку("Частота"), "Частота");
КонецПроцедуры
// Процедура - Обновить тип значения из таблицы типов
//
// Параметры:
// НоваяСтрока - -
// ТаблицаТипов - см. мПлатформа.НоваяТаблицаТипов() -
// ЗаменитьСуществующий - -
//
Процедура ОбновитьТипЗначенияИзТаблицыТипов(Знач НоваяСтрока, Знач ТаблицаТипов, ЗаменитьСуществующий = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтарыйТипЗначения = НоваяСтрока.ТипЗначения;
Если Лев(СтарыйТипЗначения, 2) = "??" Тогда
НовыйТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаТипов);
//Если Истина
// И ЗначениеЗаполнено(НовыйТипЗначения)
// И Найти(НРег(СтарыйТипЗначения), НРег(НовыйТипЗначения)) > 0
// И НовыйТипЗначения <> "??"
//Тогда
// НовыйТипЗначения = "";
//КонецЕсли;
ОстатокТипа = СокрЛП(Сред(СтарыйТипЗначения, 4));
Если Истина
И ОстатокТипа <> ""
И (Ложь
Или Найти("," + Нрег(НовыйТипЗначения) + ",", "," + Нрег(ОстатокТипа) + ",") > 0
Или ТаблицаТипов.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", ОстатокТипа)).Количество() > 0
)
Тогда
НоваяСтрока.ТипЗначения = НовыйТипЗначения;
Иначе
НоваяСтрока.ТипЗначения = СтрЗаменить(СтарыйТипЗначения, "??", НовыйТипЗначения);
КонецЕсли;
Если Не ЗначениеЗаполнено(НоваяСтрока.ТипЗначения) Тогда
НоваяСтрока.ТипЗначения = "?";
ИначеЕсли Лев(НоваяСтрока.ТипЗначения, 1) = "," Тогда
НоваяСтрока.ТипЗначения = СокрЛ(Сред(НоваяСтрока.ТипЗначения, 2));
КонецЕсли;
ИначеЕсли Ложь
Или ЗаменитьСуществующий
Или Не ЗначениеЗаполнено(СтарыйТипЗначения)
Или Найти(СтарыйТипЗначения, "<") > 0
Тогда
НоваяСтрока.ТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаТипов);
КонецЕсли;
КонецПроцедуры
Функция СобратьКомментарийМетода(ОписаниеМетода = "", Знач СтрокаРезультата = Неопределено, ЗначенияПараметров = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ЗначенияПараметров = Новый Структура;
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПрефиксОписанияПараметра = "// ";
КомментарийМетода = Новый Массив;
Для Каждого Параметр Из Параметры Цикл
ТаблицаСвойств = Неопределено;
Если Не ЗначениеЗаполнено(Параметр.ТипЗначения) Тогда
ЗначениеПараметра = Параметр.Значение;
Если ЗначенияПараметров <> Неопределено И ЗначенияПараметров.Свойство(Параметр.Имя) Тогда
ЗначениеПараметра = ЗначенияПараметров[Параметр.Имя];
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ЗначениеПараметра);
ИмяОбщегоТипа = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ТаблицаЗначений = Неопределено;
Если Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("Структура")
Или ТипЗнч(ЗначениеПараметра) = Тип("ФиксированнаяСтруктура")
Тогда
ТаблицаСвойств = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипа,,,,,, "Свойство");
ИначеЕсли Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений")
Или ТипЗнч(ЗначениеПараметра) = Тип("ДеревоЗначений")
Тогда
ТаблицаЗначений = ЗначениеПараметра;
ИначеЕсли Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(ЗначениеПараметра) = Тип("СтрокаДереваЗначений")
Тогда
ТаблицаЗначений = ЗначениеПараметра.Владелец();
КонецЕсли;
Если ТаблицаЗначений <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ТаблицаЗначений);
ТаблицаСвойств = мПлатформа.ТаблицаСловИзСтруктурыТипа(СтруктураТипа,,,,,, "Метод",,, "Найти");
ТаблицаСвойств = мПлатформа.ТаблицаСловИзСтруктурыТипа(ТаблицаСвойств[0].ТаблицаТипов[0],,,,,, "Свойство");
КонецЕсли;
Параметр.ТипЗначения = ИмяОбщегоТипа;
КонецЕсли;
КомментарийМетода.Добавить(ПрефиксОписанияПараметра + Параметр.Имя + " - " + Параметр.ТипЗначения + " - " + Параметр.Комментарий);
Если ТаблицаСвойств <> Неопределено И ТаблицаСвойств.Количество() > 0 Тогда
КомментарийМетода[КомментарийМетода.ВГраница()] = КомментарийМетода[КомментарийМетода.ВГраница()] + ":";
Для Каждого Свойство Из ТаблицаСвойств Цикл
ОбновитьТипЗначенияИзТаблицыТипов(Свойство, Свойство.ТаблицаТипов);
КомментарийМетода.Добавить(ПрефиксОписанияПараметра + " * " + Свойство.Слово + " - " + Свойство.ТипЗначения + " - " + Параметр.Комментарий);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КомментарийМетода = ирОбщий.СтрСоединитьЛкс(КомментарийМетода, Символы.ПС);
Если ЗначениеЗаполнено(КомментарийМетода) Тогда
КомментарийМетода = "// Параметры:" + Символы.ПС + КомментарийМетода + Символы.ПС;
КонецЕсли;
Если ЗначениеЗаполнено(ОписаниеМетода) Тогда
КомментарийМетода = Сред(ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(, ОписаниеМетода, "// ", Истина), 2) + Символы.ПС + КомментарийМетода;
ИначеЕсли Ложь
Или ЗначениеЗаполнено(КомментарийМетода)
Или СтрокаРезультата <> Неопределено
Тогда
КомментарийМетода = "//.
|" + КомментарийМетода;
КонецЕсли;
Если СтрокаРезультата <> Неопределено Тогда
КомментарийМетода = КомментарийМетода + "// Возвращаемое значение:" + Символы.ПС + ПрефиксОписанияПараметра + СтрокаРезультата.ТипЗначения + " - " + СтрокаРезультата.Комментарий + Символы.ПС;
КонецЕсли;
Если Не ЗначениеЗаполнено(КомментарийМетода) Тогда
КомментарийМетода = "";
КонецЕсли;
Возврат КомментарийМетода;
КонецФункции
Процедура УстановитьКлиентСерверКонтекст(Знач НовыйНаСервере = Истина) Экспорт
мФлагиКомпиляции = мПлатформа.НовыеФлагиКомпиляции(НовыйНаСервере, Не НовыйНаСервере, Не НовыйНаСервере);
Если мМодульМетаданных <> Неопределено Тогда
УстановитьФлагиКомпиляцииМодуля();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьФлагиКомпиляцииМодуля() Экспорт
Если мФлагиКомпиляции = Неопределено Тогда
мФлагиКомпиляции = мПлатформа.НовыеФлагиКомпиляции();
КонецЕсли;
мМодульМетаданных.ФлагиКомпиляции = ирОбщий.СкопироватьКоллекциюЛкс(мФлагиКомпиляции);
КонецПроцедуры
Функция ПроверитьОписаниеФормыИзБуфераОбмена(ТекстОписания) Экспорт
ИмяФормы = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстОписания, "},""", """", Ложь);
Возврат ЗначениеЗаполнено(ИмяФормы) И ирОбщий.СтрКончаетсяНаЛкс(мИмяМодуля, ИмяФормы + ".Форма.Модуль");
КонецФункции
Процедура УстановитьСлужебныеДанныеФормы(Знач Текст) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(мМодульМетаданных.СтруктураТипа.Метаданные);
Если ТипЗнч(мМодульМетаданных.СтруктураТипа.Метаданные) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
Форма = мМодульМетаданных.СтруктураТипа.Метаданные;
КонецЕсли;
мПлатформа.ОбновитьКэшСтруктурыФормыИзБуфера(СлужебныеДанные, Текст, Форма);
КонецПроцедуры
Функция ИмяТипаКонтекста(ТаблицаТипов) Экспорт
Результат = "?";
Если ТаблицаТипов.Количество() > 0 Тогда
Результат = мПлатформа.ИмяТипаИзСтруктурыТипа(ТаблицаТипов[0]);
Если Истина
И Результат = "Локальный"
И мМодульМетаданных <> Неопределено
И мМодульМетаданных.СтруктураТипа <> Неопределено
Тогда
Результат = мПлатформа.ИмяТипаИзСтруктурыТипа(мМодульМетаданных.СтруктураТипа);
КонецЕсли;
Иначе
ПУстышка = 0;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиНуженОбъектИзКонфигуратора() Экспорт
Возврат мОбъектИзКонфигуратора = Неопределено;
КонецФункции
Процедура УстановитьДанныеОбъектаИзКонфигуратора(Знач КодированнаяСтрока) Экспорт
ДвоичныеДанные = Base64Значение(ирОбщий.ТекстМеждуМаркерамиЛкс(КодированнаяСтрока, "#base64:", "}"));
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения());
ТекстФайла = Текст.ПолучитьТекст();
мОбъектИзКонфигуратора = ирОбщий.ДокументDOMИзСтрокиВнутрЛкс(ТекстФайла);
//XMLСтрока = СтрокаВнутрВХМЛТелоЛкс(ТекстФайла);
//мОбъектИзКонфигуратора = ТекстВДокументDOMЛкс(XMLСтрока);
//Выражение = "/e/e[1]/e/d[6]/text()"; // Корневые элементы
//Выражение = "/e/e[1]/e//d[(position()=5 or position()=6) and starts-with(text(), '""') and text()!='""""']/text()"; // Все элементы
//Выражение = "/e/e[3]/e/d[2]/text()"; // Все параметры
////Выражение = "/e/e[4]/e/d[2]/text()"; // Все команды
////Выражение = "/e/e[2]/e/d[3]/text()"; // Корневые реквизиты
//Разыменователь = Новый РазыменовательПространствИменDOM(Новый Соответствие);
//НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка);
//УзелDOM = НаборУзлов.ПолучитьСледующий();
//Пока УзелDOM <> Неопределено Цикл
// Сообщить(УзелDOM.ТекстовоеСодержимое);
// УзелDOM = НаборУзлов.ПолучитьСледующий();
//КонецЦикла;
КонецПроцедуры
Процедура ОбновитьМодульМетаданных(Знач Текст = Неопределено)
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Текст = Неопределено Тогда
Текст = ПолеТекста.ПолучитьТекст();
КонецЕсли;
СтарыйМодульМетаданных = мМодульМетаданных;
Если мМодульМетаданных <> Неопределено И мМодульМетаданных.СтруктураТипа <> Неопределено Тогда
мМодульМетаданных = мПлатформа.ПодготовитьМодульМетаданных(мМодульМетаданных.СтруктураТипа, ирОбщий.ПоследнийФрагментЛкс(мИмяМодуля),, Текст, мПозицияВТексте);
Иначе
мИмяМодуля = мПлатформа.ИмяДинамическогоМодуля();
мМодульМетаданных = мПлатформа.МодульМетаданных(Текст,, мИмяМодуля);
УстановитьФлагиКомпиляцииМодуля();
КонецЕсли;
Если Истина
И СтарыйМодульМетаданных <> Неопределено
И Не ЗначениеЗаполнено(СтарыйМодульМетаданных.Имя)
И Не ЗначениеЗаполнено(мМодульМетаданных.Имя)
Тогда
СкопироватьСпециальныеЭлементыМодуля(СтарыйМодульМетаданных.Методы, мМодульМетаданных.Методы);
СкопироватьСпециальныеЭлементыМодуля(СтарыйМодульМетаданных.Переменные, мМодульМетаданных.Переменные);
КонецЕсли;
КонецПроцедуры
Процедура ПодготовитьГлобальныйКонтекст() Экспорт
ГлобальныйКонтекст = мПлатформа.НоваяСтруктураТипа("Глобальный");
ГлобальныйКонтекст.Метаданные = Метаданные;
мПлатформа.ТаблицаСловИзСтруктурыТипа(ГлобальныйКонтекст,, Метаданные,, Ложь,,, мФлагиКомпиляции);
Попытка
Пустышка = БиблиотекаКартинок["!"]; // Путем обращения к заведомо несуществующей картинке вызываем полную загрузку кэша картинок платформой. В редких случаях встречается длительное выполнение.
Исключение
КонецПопытки;
КонецПроцедуры
//.
// Параметры:
// СтараяКоллекцияМодуля - Строка -
// НоваяКоллекцияМодуля - Строка -
Процедура СкопироватьСпециальныеЭлементыМодуля(СтараяКоллекцияМодуля, НоваяКоллекцияМодуля) Экспорт
Если Истина
И СтараяКоллекцияМодуля.Количество() > 0
И СтараяКоллекцияМодуля[СтараяКоллекцияМодуля.Количество() - 1].ПозицияСОписанием = Неопределено
Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтараяКоллекцияМодуля.Скопировать(Новый Структура("ПозицияСОписанием")), НоваяКоллекцияМодуля);
КонецЕсли;
КонецПроцедуры
Процедура ОчиститьИсториюПереходов() Экспорт
мИсторияПереходов = Неопределено;
КонецПроцедуры
Процедура ЗапомнитьИсточникПерехода() Экспорт
Если мИсторияПереходов = Неопределено Тогда
мИсторияПереходов = Новый Массив;
КонецЕсли;
АдресУхода = ПолеТекста.ВыделениеДвумерное();
Если Истина
И мИсторияПереходов.Количество() > 0
И ирОбщий.СравнитьЗначенияСвойствЛкс(мИсторияПереходов[0], АдресУхода)
Тогда
Возврат;
КонецЕсли;
мИсторияПереходов.Вставить(0, АдресУхода);
КонецПроцедуры
Процедура ВернутьсяИзПерехода() Экспорт
Пока Истина Цикл
Если мИсторияПереходов = Неопределено Или мИсторияПереходов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
АдресУхода = мИсторияПереходов[0];
Если ирОбщий.СравнитьЗначенияСвойствЛкс(ПолеТекста.ВыделениеДвумерное(), АдресУхода) Тогда
мИсторияПереходов.Удалить(0);
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
ПолеТекста.УстановитьВыделениеДвумерное(АдресУхода);
мИсторияПереходов.Удалить(0);
КонецПроцедуры
Функция ТаблицаСловВJSON(КлючНабораСлов = "") Экспорт
ИменаКолонок = "ТипСлова,Слово,ТипЗначения,Определение";
Если ЗначениеЗаполнено(КлючНабораСлов) Тогда
ВыгрузкаТаблицы = мНаборыСлов[КлючНабораСлов].Скопировать(, ИменаКолонок);
Иначе
ВыгрузкаТаблицы = ТаблицаСлов.Выгрузить(, ИменаКолонок);
КонецЕсли;
ВыгрузкаТаблицы.Колонки.Добавить("ЛиРез");
ВыгрузкаТаблицы.Колонки.Добавить("ЛиМетод");
ВыгрузкаТаблицы.Колонки.Добавить("ЛиТочный");
ВыгрузкаТаблицы.Колонки.Добавить("Тип");
//ВыгрузкаТаблицы.Колонки.Добавить("ЛиПар");
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого Строка Из ВыгрузкаТаблицы Цикл
Строка.ЛиРез = Строка.ТипЗначения <> "";
Строка.ЛиМетод = Строка.ТипСлова = "Метод";
Строка.ЛиТочный = Строка.Определение <> "Статистический";
Строка.Тип = Лев(Строка.ТипЗначения, 200);
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого Строка Из ВыгрузкаТаблицы Цикл   Строка.ЛиРез = Строка.ТипЗначения <> "";   Строка.ЛиМетод = Строка.ТипСлова = "Метод";   Строка.ЛиТочный = Строка.Определение <> "Статистический";   Строка.Тип = Лев(Строка.ТипЗначения, 200);   КонецЦикла;  
КонецЕсли;
ВыгрузкаТаблицы.Колонки.Удалить("ТипСлова");
ВыгрузкаТаблицы.Колонки.Удалить("ТипЗначения");
Возврат ирОбщий.ТаблицаЗначенийВJSONЛкс(ВыгрузкаТаблицы);
КонецФункции
// Добавляет слово локального контекста.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка - "Метод", "Свойство";
// *ТипЗначения - ОписаниеТипов, *Неопределено - ;
// *Метаданные - Произвольный, *Неопределено - используется, если ТипЗначения задан;
// *ТаблицаСтруктурТипа - ТаблицаЗначений, *Неопределено;
//
Функция ДобавитьСловоЛокальногоКонтекста(Слово, ТипСлова = "Свойство", Знач ТипЗначения = Неопределено,
пМетаданные = Неопределено, _Глобальное = Ложь, Значение = Неопределено, ТаблицаТипов = Неопределено, Знач ИмяОбщегоТипа = "") Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("нИмя", Нрег(Слово));
ТаблицаЛокальногоКонтекста = ТаблицаЛокальногоКонтекста(ТипСлова);
НайденныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = ТаблицаЛокальногоКонтекста.Добавить();
НоваяСтрока.Имя = Слово;
ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючСтроки);
Иначе
НоваяСтрока = НайденныеСтроки[0];
КонецЕсли;
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = мПлатформа.НоваяТаблицаТипов();
КонецЕсли;
НоваяСтрока.ТаблицаТипов = ТаблицаТипов;
Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда
СтруктураТипа = ТаблицаТипов.Добавить();
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
СтруктураТипа.Метаданные = пМетаданные;
КонецЕсли;
Если Значение <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы,
Новый Структура("СтрокаОписания, Метаданные", НоваяСтрока, пМетаданные)); // Циклическая ссылка СтрокаОписания
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
//Если Значение <> Неопределено Тогда
// Если ТипЗначения = Неопределено Тогда
// ТипЗначения = Новый ОписаниеТипов;
// КонецЕсли;
// ТипЗначения = Новый ОписаниеТипов(ТипЗначения, ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(Значение)));
//КонецЕсли;
Если ТипЗначения <> Неопределено Тогда
Для Каждого Тип Из ТипЗначения.Типы() Цикл
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы,
Новый Структура("СтрокаОписания, Метаданные", НоваяСтрока, пМетаданные)); // Циклическая ссылка СтрокаОписания
мПлатформа.ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
КонецЕсли;
НоваяСтрока.ТипЗначения = "??";
Возврат НоваяСтрока;
КонецФункции
Функция ТаблицаЛокальногоКонтекста(Знач ТипСлова = "Свойство")
Если мМодульМетаданных = Неопределено Тогда
ОбновитьМодульМетаданных("");
КонецЕсли;
Если ТипСлова = "Метод" Тогда
ТаблицаЛокальногоКонтекста = мМодульМетаданных.Методы;
Иначе
ТаблицаЛокальногоКонтекста = мМодульМетаданных.Переменные;
КонецЕсли;
Возврат ТаблицаЛокальногоКонтекста;
КонецФункции
Функция ЛиТекстЯзыкаЗапросовЛкс(Знач НачалоТекста) Экспорт
Результат = ирОбщий.ЛиТекстЯзыкаЗапросовЛкс(НачалоТекста);
Возврат Результат;
КонецФункции
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный ирПортативный.Открыть();
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ОбщийМодульЛкс("ирСервер");
//ирПортативный ирКлиент = ирПортативный.ОбщийМодульЛкс("ирКлиент");
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
мМодульМетаданных = мПлатформа.МодульМетаданных("");
ФормаВладелец = ОткрытьФорму();
мФормаАвтодополнение = ФормаАвтодополнение();
мФормаВызовМетода = ФормаВызовМетода();
#КонецЕсли
#Если Клиент Тогда
мПолеТекстаВременное = мПлатформа.СлужебноеПолеТекста;
#КонецЕсли
мПравилаВычисленияФункций = Новый ТаблицаЗначений;
мПравилаВычисленияФункций.Колонки.Добавить("Слово");
мПравилаВычисленияФункций.Колонки.Добавить("нСлово");
мПравилаВычисленияФункций.Колонки.Добавить("ТипКонтекста");
мПравилаВычисленияФункций.Колонки.Добавить("Правило");
мПравилаВычисленияФункций.Индексы.Добавить("Слово, ТипКонтекста");
НаКлиенте = Истина;
НаСервере = Истина;
мРазбиратьКонтекст = Истина;
мРасширенноеПолучениеМетаданныхADO = Ложь;
//мДоступныеТаблицыПолучены = Ложь;
мАвтоКонтекстнаяПомощь = Ложь;
мИменаОбщихТиповПоИменамКлассовCOM = Новый Соответствие;
мСтруктурыТиповПодсказкиУдержания = Новый Структура;
мДоступныеПоляТаблиц = Новый Соответствие;
мШиринаТабуляции = 4;
МаксСловНаходитьВТекстеПрограммы = 2000;
мРегВыражение = ирОбщий.НовоеРегВыражениеЛкс();
мРегВыражение.IgnoreCase = Истина;
мРегВыражение.MultiLine = Ложь;
шЛюбой = мПлатформа.шЛюбой;
шБуква = мПлатформа.шБуква;
шИмя = мПлатформа.шИмя;
шЧисло = мПлатформа.шЧисло;
шИндекс = мПлатформа.шИндекс;
шСкобки = мПлатформа.шСкобки;
шРазделитель = мПлатформа.шРазделитель;
шКомментарий = мПлатформа.шКомментарий;
шСтрокаПрограммы = мПлатформа.шСтрокаПрограммы;
шСтрокаЗапроса = мПлатформа.шСтрокаЗапроса;
шНачалоЧисла = "\d+(?:\.)?\d*";
шНачалоСкобок = "(\((?:[^\)\(]*?(?:(?:\([^\)]*?\)[^\)\(]*?)*)*\))?)";
шИмяСкобки = "(?:" + шИмя + "|\?|(?=\())" + шСкобки;
шИмяНачалоСкобок = "(?:" + шИмя + "|\?|(?=\())" + шНачалоСкобок;
шИмяСТочками = шИмя + "(?:\." + шИмя + ")*";
шПредИмя = "(?:^|[^" + шСимволыПрефиксаПараметра + шБуква + "\d\.])";
// Шаблоны программы
шСимволыПрефиксаПараметра = "&@~\?";
шДирективаПрепроцессора = "#[^\n]*\n";
шПрефиксПараметраНеобяз = "[" + шСимволыПрефиксаПараметра + "]?";
шНачалоСтрокиПрограммы = шСтрокаПрограммы + "?"; // опасно!
шОператорПрограммы = "(?:(?:=|>|<|<>|<=|>=|\*|\/|\+|\-)|" + шРазделитель + "(?:И|ИЛИ|НЕ|AND|OR|NOT)" + шРазделитель + ")+";
//шНазначениеТипа = "\s*см\.\s*([^\n]*)";
шФрагментСтрокиПрограммы = "(?:""|\|)(?:(?:"""")|[^""\n$])*(?:""|\n|$)";
шНачалоТокена = "([" + шБуква + "\d]" + шРазделитель + "+|(?:\]|\)|" + шФрагментСтрокиПрограммы + "|;|^)" + шРазделитель + "*)";
шКонецТокена = "(?=" + шРазделитель + "+[" + шБуква + "\d]|" + шРазделитель + "*(?:\[|\(|" + шФрагментСтрокиПрограммы + "|;|$))";
шЕсли = шНачалоТокена + "(?:Если|ИначеЕсли|If|ElseIf)"
+ шКонецТокена + "(?:" + шФрагментСтрокиПрограммы + "|\." + шРазделитель + "*Тогда|\r|\n|.)*?" + "[^" + шБуква + "\d\.]"
+ "(?:Тогда|Then)" + шКонецТокена;
шПока = шНачалоТокена + "Пока"
+ шКонецТокена + "(?:" + шФрагментСтрокиПрограммы + "|\r|\n|.)*?" + "[^" + шБуква + "\d\.]"
+ "Цикл" + шКонецТокена;
шВызватьИсключение = шНачалоТокена + "ВызватьИсключение"
+ шКонецТокена + "(?:" + шФрагментСтрокиПрограммы + "|\." + шРазделитель + "*;|\r|\n|.)*?;";
шВыражениеПрограммы1 = "(?:(?:новый|New)" + "(?:" + шРазделитель + "(?:" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(?:" + шИмя+ "(?:\." + шИмя + ")*)""\))?"
+ "|(?:(?:не|not)" + шРазделитель + "+)?(?:(?:(?:новый|New)" + шРазделитель + ")?" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")";
шВыражениеПрограммы = шРазделитель + "*" + шВыражениеПрограммы1 + "(?:" + шРазделитель + "*" + шОператорПрограммы + шРазделитель + "*"
+ шВыражениеПрограммы1 + ")*";
шНачалоВыраженияПрограммы = "(?:" + шРазделитель + "*(?:(?:"
+ шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + "*" + шОператорПрограммы + ")*"
+ шРазделитель + "*(?:(?:" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шНачалоЧисла + "|" + шНачалоСтрокиПрограммы + ")?";
шВызовМетодаПрограммы = "(?:" + шПредИмя + "(Новый|New)\s+)?(" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*?)"
+ "\(((?:(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*,)*)" + "(" + шНачалоВыраженияПрограммы + ")?" + шРазделитель + "*";
шПростоеВыражениеПрограммы = "((новый|New)(?=[\s\(])" // Изменение для поддержки ProgID типа Forms.TextBox.1
+ "(?:" + шРазделитель + "+(" + шИмя + "))?" + шРазделитель + "*(?:\(\s*(?:(" + шСтрокаПрограммы + ")|" + шСкобки + "|[^\(\)]+)*(?:\(|\)|$))?"
//+ "|(" + шИмяСкобки + "?" + шИндекс + "?(?:\." + шИмяСкобки + "?" + шИндекс + "?)*)"
+ "|(" + шИмяНачалоСкобок + "?" + шИндекс + "?(?:\." + шИмяНачалоСкобок + "?" + шИндекс + "?)*)" // Заменил на незаконченные скобки, т.к. вложенность их может быть иногда большой и тогда надо хотя бы часть параметров захватить
+ "|(" + шЧисло + ")"
+ "|(" + шСтрокаПрограммы + ")"
+ "|" // Пустая строка нужна чтобы посчитать количество присвоений
+ ")";
шПрисвоение = "(" + шРазделитель + "*=" + шРазделитель + "*" + шПростоеВыражениеПрограммы+ ")";
// Шаблоны запроса
шПараметрЗапроса = "[" + шСимволыПрефиксаПараметра + "][" + шБуква + "][" + шБуква + "\d]*";
шНачалоСтрокиЗапроса = шСтрокаЗапроса + "?"; // Опасно
шОператорЗапроса = "(?:(?:=|>|<|<>|<=|>=|\*|\/|\+|\-)|" + шРазделитель
+ "(?:И|AND|ИЛИ|OR|НЕ|NOT|МЕЖДУ|BETWEEN|ПОДОБНО|LIKE|ССЫЛКА|REFS|(?:ЕСТЬ|IS)" + шРазделитель + "+NULL|В|IN"
+ "|В" + шРазделитель + "+ИЕРАРХИИ|IN" + шРазделитель + "+HIERARCHY)" + шРазделитель + ")+";
ШаблонВыбора = "(?:ВЫБОР|CASE)" + шЛюбой + "+?(?:КОГДА|WHEN)" + шЛюбой + "+?(?:ТОГДА|THEN)" + шЛюбой + "+?(?:ИНАЧЕ|ELSE)" + шЛюбой + "+?(?:КОНЕЦ|END)";
ШаблонНачалаВыбора = "(?:ВЫБОР|CASE)" + шЛюбой + "+?(?:КОНЕЦ|END)?";
шИмяЗапроса = "(?:" + шИмя + "|\[[^\]]+\])";
шТаблицаЗапроса = "(" + шИмяЗапроса + "\.)*" + шИмяЗапроса + шСкобки + "?";
ШаблонСоединения = шРазделитель + "+((ПРАВОЕ|RIGHT|ЛЕВОЕ|LEFT|ВНУТРЕННЕЕ|INNER|ПОЛНОЕ|FULL|ВНЕШНЕЕ|OUTER)" + шРазделитель + "+)?(?:СОЕДИНЕНИЕ|JOIN)"
+ шРазделитель + "+";
шОписаниеТаблицы = "(" + шСкобки + "|" + шТаблицаЗапроса + "|&" + шИмя + ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+" + шИмяЗапроса;
шОписаниеТаблицыСЗахватом = "(" + шСкобки + "|" + шТаблицаЗапроса + "|&" + шИмя + ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+(" + шИмяЗапроса + ")";
шВыражениеЗапроса =
"(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
//+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*"
+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*?" // Сделал захват ленивым, чтобы избежать катастрофического шагания назад
+ шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)";
шНачалоВыраженияЗапроса =
"(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*?" // Сделал захват ленивым, чтобы избежать катастрофического шагания назад
+ шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шНачалоСтрокиЗапроса + "|" + ШаблонНачалаВыбора
+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)?";
шВызовМетодаЗапроса = "()?(" + шИмяЗапроса + шСкобки + "?" + "(?:(?:\.(?:" + шИмяЗапроса + ")" + шСкобки + "?)|" + шИндекс + ")*)"
+ "\(((?:(?:" + шВыражениеЗапроса + ")?" + шРазделитель + "*,)*)" + "(" + шНачалоВыраженияЗапроса + ")?" + шРазделитель + "*";
ШаблонОписанияПоля = шВыражениеЗапроса + шРазделитель + "+КАК" + шРазделитель + "+" + шИмяЗапроса;
ШаблонВЫБРАТЬ = "(?:ВЫБРАТЬ|SELECT)(" + шРазделитель + "+(?:РАЗРЕШЕННЫЕ|ALLOWED))?(" + ШаблонОписанияПоля + ",)*" + ШаблонОписанияПоля;
шИЗ = "(?:ИЗ|FROM)" + шРазделитель + "+" + шОписаниеТаблицы + "(" + ШаблонСоединения + шОписаниеТаблицы
+ шРазделитель + "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "*,"
+ шРазделитель + "*" + шОписаниеТаблицы + ")*";
шПоискОписанияТаблицы = "(" + ШаблонСоединения + ")?(" + шСкобки + "|" + шТаблицаЗапроса + "|&" + шИмя
+ ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+" + "#Идентификатор#(" + шРазделитель
+ "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "|,|;|\)|$)";
// К нему привязаны имена методов-трансляторов событий
ИмяКласса = "ПолеТекстаПрограммы";
мМаркерСлужебногоКомментария = "{: ";
мМаркерПорядкаОтладки = "ПорядокОтладки ";
мЭтоАвтоВызов = Ложь;
СброситьРезультатРазбораПозицииВТексте();
мАнглийский1С = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский;