mirror of
https://github.com/bia-technologies/bsl-parser.git
synced 2024-11-27 08:20:55 +02:00
df39d1f593
Исправлена ошибка использования библиотеки из пакета
277 lines
16 KiB
Plaintext
277 lines
16 KiB
Plaintext
// Пояснения по переменным даны в конце модуля
|
|
Перем ПоказатьСообщенияЗагрузки;
|
|
Перем ВыдаватьОшибкуПриЗагрузкеУжеСуществующихКлассовМодулей;
|
|
|
|
Перем КэшМодулей;
|
|
|
|
Процедура ПриЗагрузкеБиблиотеки(Путь, СтандартнаяОбработка, Отказ)
|
|
Вывести("
|
|
|ПриЗагрузкеБиблиотеки " + Путь);
|
|
|
|
ФайлМанифеста = Новый Файл(ОбъединитьПути(Путь, "lib.config"));
|
|
|
|
Если ФайлМанифеста.Существует() Тогда
|
|
Вывести("Обрабатываем по манифесту");
|
|
|
|
СтандартнаяОбработка = Ложь;
|
|
ОбработатьМанифест(ФайлМанифеста.ПолноеИмя, Путь, Отказ);
|
|
Иначе
|
|
Вывести("Обрабатываем структуру каталогов по произвольному алгоритму");
|
|
ЗагрузитьМодулиБиблиотеки(ОбъединитьПути(Путь, "src"), СтандартнаяОбработка, Отказ);
|
|
КонецЕсли;
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ОбработатьМанифест(Знач Файл, Знач Путь, Отказ)
|
|
|
|
Чтение = Новый ЧтениеXML;
|
|
Чтение.ОткрытьФайл(Файл);
|
|
Чтение.ПерейтиКСодержимому();
|
|
|
|
Если Чтение.ЛокальноеИмя <> "package-def" Тогда
|
|
Отказ = Истина;
|
|
Чтение.Закрыть();
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
Пока Чтение.Прочитать() Цикл
|
|
|
|
Если Чтение.ТипУзла = ТипУзлаXML.Комментарий Тогда
|
|
|
|
Продолжить;
|
|
|
|
КонецЕсли;
|
|
|
|
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
|
|
|
Если Чтение.ЛокальноеИмя = "class" Тогда
|
|
ФайлКласса = Новый Файл(Путь + "/" + Чтение.ЗначениеАтрибута("file"));
|
|
Если ФайлКласса.Существует() и ФайлКласса.ЭтоФайл() Тогда
|
|
Идентификатор = Чтение.ЗначениеАтрибута("name");
|
|
Если Не ПустаяСтрока(Идентификатор) Тогда
|
|
Вывести(СтрШаблон(" класс %1, файл %2", Идентификатор, ФайлКласса.ПолноеИмя));
|
|
|
|
// ДобавитьКласс(ФайлКласса.ПолноеИмя, Идентификатор);
|
|
ДобавитьКлассЕслиРанееНеДобавляли(ФайлКласса.ПолноеИмя, Идентификатор);
|
|
КонецЕсли;
|
|
Иначе
|
|
ВызватьИсключение "Не найден файл " + ФайлКласса.ПолноеИмя + ", указанный в манифесте";
|
|
КонецЕсли;
|
|
|
|
Чтение.Прочитать(); // в конец элемента
|
|
КонецЕсли;
|
|
|
|
Если Чтение.ЛокальноеИмя = "module" Тогда
|
|
ФайлКласса = Новый Файл(Путь + "/" + Чтение.ЗначениеАтрибута("file"));
|
|
Если ФайлКласса.Существует() и ФайлКласса.ЭтоФайл() Тогда
|
|
Идентификатор = Чтение.ЗначениеАтрибута("name");
|
|
Если Не ПустаяСтрока(Идентификатор) Тогда
|
|
Вывести(СтрШаблон(" модуль %1, файл %2", Идентификатор, ФайлКласса.ПолноеИмя));
|
|
Попытка
|
|
ДобавитьМодульЕслиРанееНеДобавляли(ФайлКласса.ПолноеИмя, Идентификатор);
|
|
Исключение
|
|
Если ВыдаватьОшибкуПриЗагрузкеУжеСуществующихКлассовМодулей Тогда
|
|
ВызватьИсключение;
|
|
КонецЕсли;
|
|
Вывести("Предупреждение:
|
|
| " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
|
КонецПопытки;
|
|
КонецЕсли;
|
|
Иначе
|
|
ВызватьИсключение "Не найден файл " + ФайлКласса.ПолноеИмя + ", указанный в манифесте";
|
|
КонецЕсли;
|
|
|
|
Чтение.Прочитать(); // в конец элемента
|
|
КонецЕсли;
|
|
|
|
КонецЕсли;
|
|
|
|
КонецЦикла;
|
|
|
|
Чтение.Закрыть();
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ЗагрузитьМодулиБиблиотеки(КорневойКаталог, СтандартнаяОбработка, Отказ)
|
|
|
|
// Загрузим служебные глобальные модули
|
|
ДобавитьМодульЕслиРанееНеДобавляли(ОбъединитьПути(КорневойКаталог, "Модули", "ПараметрыПродукта.os"), "ПараметрыПродукта");
|
|
|
|
КаталогПеречисления = ОбъединитьПути(КорневойКаталог, "Перечисления");
|
|
КаталогРеализации = ОбъединитьПути(КорневойКаталог, "Внутренние");
|
|
|
|
// Загрузим общие служебные модули
|
|
ОбработатьСтруктуруКаталоговПоСоглашению(ОбъединитьПути(КаталогРеализации, "Служебные"), СтандартнаяОбработка, Отказ);
|
|
|
|
// Загрузим перечисления
|
|
ОбработатьСтруктуруКаталоговПоСоглашению(КаталогПеречисления, СтандартнаяОбработка, Отказ);
|
|
|
|
// Загрузим внутренние модули реализации
|
|
Для Каждого Файл Из НайтиФайлы(КаталогРеализации, "*", Ложь) Цикл
|
|
|
|
Если Файл.ЭтоКаталог() Тогда
|
|
|
|
ОбработатьСтруктуруКаталоговПоСоглашению(Файл.ПолноеИмя, СтандартнаяОбработка, Отказ);
|
|
|
|
КонецЕсли;
|
|
|
|
КонецЦикла;
|
|
|
|
// Загрузим модули API
|
|
ОбработатьСтруктуруКаталоговПоСоглашению(КорневойКаталог, СтандартнаяОбработка, Отказ);
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ОбработатьСтруктуруКаталоговПоСоглашению(Путь, СтандартнаяОбработка, Отказ)
|
|
|
|
КаталогиКлассов = Новый Массив;
|
|
КаталогиКлассов.Добавить(ОбъединитьПути(Путь, "Классы"));
|
|
КаталогиКлассов.Добавить(ОбъединитьПути(Путь, "Classes"));
|
|
КаталогиКлассов.Добавить(ОбъединитьПути(Путь, "src", "Классы"));
|
|
КаталогиКлассов.Добавить(ОбъединитьПути(Путь, "src", "Classes"));
|
|
|
|
КаталогиМодулей = Новый Массив;
|
|
КаталогиМодулей.Добавить(ОбъединитьПути(Путь, "Модули"));
|
|
КаталогиМодулей.Добавить(ОбъединитьПути(Путь, "Modules"));
|
|
КаталогиМодулей.Добавить(ОбъединитьПути(Путь, "src", "Модули"));
|
|
КаталогиМодулей.Добавить(ОбъединитьПути(Путь, "src", "Modules"));
|
|
|
|
Для Каждого мКаталог Из КаталогиКлассов Цикл
|
|
|
|
ОбработатьКаталогКлассов(мКаталог, СтандартнаяОбработка, Отказ);
|
|
|
|
КонецЦикла;
|
|
|
|
Для Каждого мКаталог Из КаталогиМодулей Цикл
|
|
|
|
ОбработатьКаталогМодулей(мКаталог, СтандартнаяОбработка, Отказ);
|
|
|
|
КонецЦикла;
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ОбработатьКаталогКлассов(Знач Путь, СтандартнаяОбработка, Отказ)
|
|
|
|
КаталогКлассов = Новый Файл(Путь);
|
|
|
|
Если КаталогКлассов.Существует() Тогда
|
|
Файлы = НайтиФайлы(КаталогКлассов.ПолноеИмя, "*.os");
|
|
Для Каждого Файл Из Файлы Цикл
|
|
Вывести(СтрШаблон(" класс (по соглашению) %1, файл %2", Файл.ИмяБезРасширения, Файл.ПолноеИмя));
|
|
СтандартнаяОбработка = Ложь;
|
|
// ДобавитьКласс(Файл.ПолноеИмя, Файл.ИмяБезРасширения);
|
|
ДобавитьКлассЕслиРанееНеДобавляли(Файл.ПолноеИмя, Файл.ИмяБезРасширения);
|
|
КонецЦикла;
|
|
КонецЕсли;
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ОбработатьКаталогМодулей(Знач Путь, СтандартнаяОбработка, Отказ)
|
|
|
|
КаталогМодулей = Новый Файл(Путь);
|
|
|
|
Если КаталогМодулей.Существует() Тогда
|
|
Файлы = НайтиФайлы(КаталогМодулей.ПолноеИмя, "*.os");
|
|
Для Каждого Файл Из Файлы Цикл
|
|
Вывести(СтрШаблон(" модуль (по соглашению) %1, файл %2", Файл.ИмяБезРасширения, Файл.ПолноеИмя));
|
|
СтандартнаяОбработка = Ложь;
|
|
Попытка
|
|
ДобавитьМодульЕслиРанееНеДобавляли(Файл.ПолноеИмя, Файл.ИмяБезРасширения);
|
|
Исключение
|
|
Если ВыдаватьОшибкуПриЗагрузкеУжеСуществующихКлассовМодулей Тогда
|
|
ВызватьИсключение;
|
|
КонецЕсли;
|
|
СтандартнаяОбработка = Истина;
|
|
Вывести("Предупреждение:
|
|
|" + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
|
КонецПопытки;
|
|
КонецЦикла;
|
|
КонецЕсли;
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ДобавитьКлассЕслиРанееНеДобавляли(ПутьФайла, ИмяКласса)
|
|
Вывести("Добавляю класс, если ранее не добавляли " + ИмяКласса);
|
|
Если ВыдаватьОшибкуПриЗагрузкеУжеСуществующихКлассовМодулей Тогда
|
|
Вывести("Добавляю класс " + ИмяКласса);
|
|
ДобавитьКласс(ПутьФайла, ИмяКласса);
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
КлассУжеЕсть = Ложь;
|
|
Попытка
|
|
Объект = Новый(ИмяКласса);
|
|
КлассУжеЕсть = Истина;
|
|
Исключение
|
|
СообщениеОшибки = ОписаниеОшибки();
|
|
ИскомаяОшибка = СтрШаблон("Конструктор не найден (%1)", ИмяКласса);
|
|
КлассУжеЕсть = СтрНайти(СообщениеОшибки, ИскомаяОшибка) = 0;
|
|
КонецПопытки;
|
|
Если Не КлассУжеЕсть Тогда
|
|
|
|
Вывести("Добавляю класс, т.к. он не найден - " + ИмяКласса);
|
|
ДобавитьКласс(ПутьФайла, ИмяКласса);
|
|
|
|
Иначе
|
|
Вывести("Пропускаю загрузку класса " + ИмяКласса);
|
|
|
|
КонецЕсли;
|
|
КонецПроцедуры
|
|
|
|
Процедура ДобавитьМодульЕслиРанееНеДобавляли(ПутьФайла, ИмяМодуля)
|
|
Вывести("Добавляю модуль, если ранее не добавляли " + ИмяМодуля);
|
|
|
|
МодульУжеЕсть = КэшМодулей.Найти(ИмяМодуля) <> Неопределено;
|
|
Если Не МодульУжеЕсть Тогда
|
|
|
|
Вывести("Добавляю модуль, т.к. он не найден - " + ИмяМодуля);
|
|
ДобавитьМодуль(ПутьФайла, ИмяМодуля);
|
|
КэшМодулей.Добавить(ИмяМодуля);
|
|
Иначе
|
|
Вывести("Пропускаю загрузку модуля " + ИмяМодуля);
|
|
|
|
КонецЕсли;
|
|
КонецПроцедуры
|
|
|
|
Процедура Вывести(Знач Сообщение)
|
|
Если ПоказатьСообщенияЗагрузки Тогда
|
|
Сообщить(Сообщение);
|
|
КонецЕсли;
|
|
КонецПроцедуры
|
|
|
|
Функция ПолучитьБулевоИзПеременнойСреды(Знач ИмяПеременнойСреды, Знач ЗначениеПоУмолчанию)
|
|
Рез = ЗначениеПоУмолчанию;
|
|
РезИзСреды = ПолучитьПеременнуюСреды(ИмяПеременнойСреды);
|
|
Если ЗначениеЗаполнено(РезИзСреды) Тогда
|
|
РезИзСреды = СокрЛП(РезИзСреды);
|
|
Попытка
|
|
Рез = Число(РезИзСреды) <> 0 ;
|
|
Исключение
|
|
Рез = ЗначениеПоУмолчанию;
|
|
Сообщить(СтрШаблон("Неверный формат переменной среды %1. Ожидали 1 или 0, а получили %2", ИмяПеременнойСреды, РезИзСреды));
|
|
КонецПопытки;
|
|
КонецЕсли;
|
|
|
|
Возврат Рез;
|
|
КонецФункции
|
|
|
|
// Если Истина, то выдаются подробные сообщения о порядке загрузке пакетов, классов, модулей, что помогает при анализе проблем
|
|
// очень полезно при анализе ошибок загрузки
|
|
// Переменная среды может принимать значение 0 (выключено) или 1 (включено)
|
|
// Значение флага по умолчанию - Ложь
|
|
ПоказатьСообщенияЗагрузки = ПолучитьБулевоИзПеременнойСреды(
|
|
"OSLIB_LOADER_TRACE", Ложь);
|
|
|
|
// Если Ложь, то пропускаются ошибки повторной загрузки классов/модулей,
|
|
//что важно при разработке/тестировании стандартных библиотек
|
|
// Если Истина, то выдается ошибка при повторной загрузке классов библиотек из движка
|
|
// Переменная среды может принимать значение 0 (выключено) или 1 (включено)
|
|
// Значение флага по умолчанию - Истина
|
|
ВыдаватьОшибкуПриЗагрузкеУжеСуществующихКлассовМодулей = ПолучитьБулевоИзПеременнойСреды(
|
|
"OSLIB_LOADER_DUPLICATES", Ложь);
|
|
|
|
// для установки других значений переменных среды и запуска скриптов можно юзать следующую командную строку
|
|
// (set OSLIB_LOADER_TRACE=1) && (oscript .\tasks\test.os)
|
|
|
|
КэшМодулей = Новый Массив;
|