Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packagedef
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Описание.Имя("annotations")
.Версия("1.6.0")
.Версия("1.7.0")
.Автор("Nikita Fedkin")
.АдресАвтора("nixel2007@gmail.com")
.Описание("Аннотации как объекты первого класса")
.ВерсияСреды("1.9.2")
.ВерсияСреды("2.0.0")
.ВключитьФайл("src")
.ВключитьФайл("docs")
.ВключитьФайл("tasks")
Expand Down
2 changes: 1 addition & 1 deletion src/Классы/КонтейнерАннотаций.os
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
);
КонецЕсли;

ОпределениеАннотации = Новый ОпределениеАннотации(ИмяАннотации, ИмяТипаАннотации, Параметры, Аннотации);
ОпределениеАннотации = Новый ОпределениеАннотации(ИмяАннотации, ИмяТипаАннотации, Параметры, Аннотации, ЭтотОбъект);

ОпределенияАннотаций.Вставить(НРег(ИмяАннотации), ОпределениеАннотации);

Expand Down
65 changes: 59 additions & 6 deletions src/Классы/ОпределениеАннотации.os
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
// Подчиненные аннотации
Перем Аннотации;

// Контейнер определений аннотаций, которому принадлежит данное определение.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нарушена типизация поля

// Используется для рекурсивной материализации вложенных аннотаций-значений.
Перем КонтейнерАннотаций;

#КонецОбласти

#Область ПрограммныйИнтерфейс
Expand Down Expand Up @@ -112,7 +116,11 @@
// * Имя - Строка - Имя аннотации.
// * Параметры - ТаблицаЗначений - Таблица параметров аннотации:
// ** Имя - Строка - Имя параметра аннотации.
// ** Значение - Строка - Значение параметра аннотации.
// ** Значение - Строка, Число, Булево, Дата, Неопределено, Null - литеральное значение параметра.
// - СтрокаТаблицыЗначений - вложенная аннотация (строка с колонками "Имя" и "Параметры",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Неверный формат описания строки тз. См https://v8std.ru/std/641/

// см. РаботаСАннотациями.ЭтоАннотация). Если её определение
// зарегистрировано в контейнере, рекурсивно превращается в объект
// соответствующей аннотации; иначе остаётся строкой таблицы значений.
//
// Возвращаемое значение:
// Произвольный - Объект аннотации с заданными параметрами.
Expand All @@ -123,18 +131,23 @@
Для Каждого Параметр Из Параметры() Цикл

Если Параметр.Повторяемый Тогда
ЗначениеПараметра = РаботаСАннотациями.ПолучитьЗначенияПараметровАннотации(Аннотация, Параметр.Имя);
ЗначенияПараметра = РаботаСАннотациями.ПолучитьЗначенияПараметровАннотации(Аннотация, Параметр.Имя);
ЗначениеПараметра = Новый Массив;
Для Каждого Значение Из ЗначенияПараметра Цикл
ЗначениеПараметра.Добавить(МатериализоватьЗначение(Значение));
КонецЦикла;
Иначе
ЗначениеПараметра = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(
Значение = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(
Аннотация,
Параметр.Имя,
Параметр.ЗначениеПоУмолчанию,
Истина
);
ЗначениеПараметра = МатериализоватьЗначение(Значение);
КонецЕсли;
ПараметрыКонструктора.Добавить(ЗначениеПараметра);
КонецЦикла;

ОбъектАннотации = Новый(ИмяТипаАннотации(), ПараметрыКонструктора);

Возврат ОбъектАннотации;
Expand All @@ -145,6 +158,39 @@

#Область СлужебныеПроцедурыИФункции

// Материализовать значение параметра конструктора аннотации.
//
// Если значение является вложенной аннотацией (см. РаботаСАннотациями.ЭтоАннотация),
// а её определение зарегистрировано в контейнере данного определения, вложенная аннотация
// рекурсивно превращается в объект своей аннотации. В остальных случаях (литерал, отсутствие
// контейнера или незарегистрированная аннотация) значение возвращается как есть.
//
// Параметры:
// Значение - Произвольный - Значение параметра (литерал или вложенная аннотация).
//
// Возвращаемое значение:
// Произвольный - Материализованное значение (объект вложенной аннотации либо исходное значение).
//
Функция МатериализоватьЗначение(Значение)

Если КонтейнерАннотаций = Неопределено ИЛИ НЕ РаботаСАннотациями.ЭтоАннотация(Значение) Тогда

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В каком случае КонтейнерАннотаций может быть пустым?

Возврат Значение;
КонецЕсли;

ОпределениеВложеннойАннотации = КонтейнерАннотаций.ПолучитьОпределениеАннотации(Значение.Имя);
Если ОпределениеВложеннойАннотации = Неопределено Тогда
Возврат Значение;
КонецЕсли;

// Валидируем вложенную аннотацию так же, как верхнеуровневую: иначе неизвестные
// параметры молча игнорировались бы, а обязательные неявно получали бы Неопределено.
ПредставлениеВладельца = СтрШаблон("вложенная аннотация %1", Значение.Имя);
ОпределениеВложеннойАннотации.Проверить(Значение, ПредставлениеВладельца);

Возврат ОпределениеВложеннойАннотации.СоздатьОбъектАннотации(Значение);

Comment thread
coderabbitai[bot] marked this conversation as resolved.
КонецФункции

Процедура ПривестиИменаПараметров(Аннотация)

Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
Expand Down Expand Up @@ -263,12 +309,19 @@

#Область Инициализация

Процедура ПриСозданииОбъекта(Знач _Имя, Знач _ИмяТипаАннотации, Знач _Параметры, Знач _Аннотации)

Процедура ПриСозданииОбъекта(
Знач _Имя,
Знач _ИмяТипаАннотации,
Знач _Параметры,
Знач _Аннотации,
Знач _КонтейнерАннотаций = Неопределено
)

Имя = _Имя;
ИмяТипаАннотации = _ИмяТипаАннотации;
Аннотации = _Аннотации;
Параметры = _Параметры;
КонтейнерАннотаций = _КонтейнерАннотаций;

ОпределитьПовторяемостьПараметров();
ОпределитьПсевдонимыПараметров();
Expand Down
23 changes: 23 additions & 0 deletions src/Модули/РаботаСАннотациями.os
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,29 @@
Параметр.Значение = ЗначениеПараметра;
КонецПроцедуры

// Проверить, является ли значение вложенной аннотацией.
//
// Начиная с OneScript 2.0.0 значением параметра аннотации может быть другая
// аннотация. Рефлектор представляет её строкой таблицы значений с колонками
// "Имя" и "Параметры", как и строку таблицы аннотаций.
//
// Параметры:
// Значение - Произвольный - Проверяемое значение параметра аннотации.
//
// Возвращаемое значение:
// Булево - Истина, если значение является вложенной аннотацией.
//
Функция ЭтоАннотация(Значение) Экспорт

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Имя функции неудачное


Если ТипЗнч(Значение) <> Тип("СтрокаТаблицыЗначений") Тогда
Возврат Ложь;
КонецЕсли;

Колонки = Значение.Владелец().Колонки;
Возврат Колонки.Найти("Имя") <> Неопределено И Колонки.Найти("Параметры") <> Неопределено;

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции
Expand Down
73 changes: 73 additions & 0 deletions tests/ВложенныеАннотации.os
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#Использовать ".."
#Использовать "."
#Использовать asserts

&Тест
Процедура ЭтоАннотацияРаспознаетВложеннуюАннотацию() Экспорт

// Дано
Метод = НайтиМетод("МетодСВложеннойАннотацией");
ВнешняяАннотация = РаботаСАннотациями.НайтиАннотацию(Метод.Аннотации, "Внешняя");

// Когда
ЗначениеПараметра = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(ВнешняяАннотация, "Значение");

// Тогда
Ожидаем.Что(РаботаСАннотациями.ЭтоАннотация(ЗначениеПараметра)).Равно(Истина);
Ожидаем.Что(РаботаСАннотациями.ЭтоАннотация("просто строка")).Равно(Ложь);
Ожидаем.Что(РаботаСАннотациями.ЭтоАннотация(Неопределено)).Равно(Ложь);

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

&Тест
Процедура СоздатьОбъектАннотацииРекурсивноМатериализуетВложеннуюАннотацию() Экспорт

// Дано
Метод = НайтиМетод("МетодСВложеннойАннотацией");
ВнешняяАннотация = РаботаСАннотациями.НайтиАннотацию(Метод.Аннотации, "Внешняя");
КонтейнерАннотаций = ПодготовитьКонтейнер();

// Когда
ОпределениеВнешней = КонтейнерАннотаций.ПолучитьОпределениеАннотации("Внешняя");
ОбъектВнешней = ОпределениеВнешней.СоздатьОбъектАннотации(ВнешняяАннотация);

// Тогда
Ожидаем.Что(ОбъектВнешней.УстановленноеЗначение).ИмеетТип("АннотацияЦель");
Ожидаем.Что(ОбъектВнешней.УстановленноеЗначение.УстановленноеЗначение).Равно("вложенное значение");

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

&Тест
Процедура НезарегистрированнаяВложеннаяАннотацияОстаетсяСтрокойТаблицы() Экспорт

// Дано
Метод = НайтиМетод("МетодСВложеннойАннотацией");
ВнешняяАннотация = РаботаСАннотациями.НайтиАннотацию(Метод.Аннотации, "Внешняя");

// Внешняя зарегистрирована, а вложенная Цель не зарегистрирована.
КонтейнерАннотаций = Новый КонтейнерАннотаций();
КонтейнерАннотаций.ДобавитьАннотацию(Тип("АннотацияВнешняя"));

// Когда
ОпределениеВнешней = КонтейнерАннотаций.ПолучитьОпределениеАннотации("Внешняя");
ОбъектВнешней = ОпределениеВнешней.СоздатьОбъектАннотации(ВнешняяАннотация);

// Тогда
Ожидаем.Что(ОбъектВнешней.УстановленноеЗначение).ИмеетТип("СтрокаТаблицыЗначений");

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

Функция ПодготовитьКонтейнер()
КонтейнерАннотаций = Новый КонтейнерАннотаций();
КонтейнерАннотаций.ДобавитьАннотацию(Тип("АннотацияВнешняя"));
КонтейнерАннотаций.ДобавитьАннотацию(Тип("АннотацияЦель"));
Возврат КонтейнерАннотаций;
КонецФункции

Функция НайтиМетод(ИмяМетода)

Рефлектор = Новый Рефлектор();
ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Тип("ВладелецВложенныхАннотаций"));
Возврат ТаблицаМетодов.Найти(ИмяМетода, "Имя");

КонецФункции
6 changes: 6 additions & 0 deletions tests/Классы/АннотацияВнешняя.os
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Перем УстановленноеЗначение Экспорт; // BSLLS:ExportVariables-off

&Аннотация("Внешняя")
Процедура ПриСозданииОбъекта(Значение = Неопределено)
УстановленноеЗначение = Значение;
КонецПроцедуры
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Фикстура для проверки вложенных аннотаций как значений параметров аннотаций.
// Требует OneScript 2.0.0 и старше.

&Внешняя(&Цель("вложенное значение"))
Процедура МетодСВложеннойАннотацией() Экспорт
КонецПроцедуры
Loading