Skip to content

Commit 03c6348

Browse files
committed
Поддержка аннотаций в лямбда выражении
1 parent 3d89d28 commit 03c6348

File tree

4 files changed

+290
-10
lines changed

4 files changed

+290
-10
lines changed

src/internal/Модули/ЛямбдыКешируемыеЗначения.os

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Если ЭтоЛямбдаВыражение = Неопределено Тогда
77

88
ЭтоЛямбдаВыражение = Новый РегулярноеВыражение(
9-
"\(?\s*([^)]*)\s*\)?\s*->\s*\{?([^\}]+)\}?"
9+
"(.*)->\s*\{?([^\}]+)\}?"
1010
);
1111

1212
КонецЕсли;
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
Перем Цифры;
2+
3+
Функция РазобратьСтрокуПараметров(СтрокаПараметров) Экспорт
4+
5+
Результат = Новый Структура(
6+
"Аннотации, Параметры",
7+
Новый Массив,
8+
Новый Массив
9+
);
10+
11+
Этап = "";
12+
МетаЭтап = "АннотацииМетода";
13+
14+
РазбираемыеАннотации = Новый Массив;
15+
16+
Для Индекс = 1 По СтрДлина(СтрокаПараметров) Цикл
17+
18+
Токен = Сред(СтрокаПараметров, Индекс, 1);
19+
20+
Если Этап = "" Тогда
21+
22+
Если Токен = "&" Тогда
23+
Этап = "Аннотация";
24+
Аннотация = Новый Структура("Имя, Параметры", "", Новый Массив);
25+
Продолжить;
26+
КонецЕсли;
27+
28+
Если Токен = "(" И МетаЭтап = "АннотацииМетода" Тогда
29+
Этап = "";
30+
МетаЭтап = "ПараметрыМетода";
31+
Результат.Аннотации = РазбираемыеАннотации;
32+
РазбираемыеАннотации = Новый Массив;
33+
Продолжить;
34+
КонецЕсли;
35+
36+
Если Не ПустаяСтрока(Токен) Тогда
37+
38+
Этап = "ПараметрМетода";
39+
МетаЭтап = "ПараметрыМетода";
40+
41+
ПараметрМетода = Новый Структура("Имя, Аннотации", "");
42+
ПараметрМетода.Аннотации = РазбираемыеАннотации;
43+
РазбираемыеАннотации = Новый Массив;
44+
45+
КонецЕсли;
46+
47+
КонецЕсли;
48+
49+
Если Этап = "Аннотация" Тогда
50+
51+
Если Токен = "(" Тогда
52+
Этап = "ПараметрАннотации";
53+
ЭтапПараметрАннотации = "Имя";
54+
ПараметрАннотации = Новый Структура("Имя, Значение", "", "");
55+
Продолжить;
56+
КонецЕсли;
57+
58+
Если Токен = " " Тогда
59+
Этап = "";
60+
РазбираемыеАннотации.Добавить(Аннотация);
61+
Продолжить;
62+
КонецЕсли;
63+
64+
Аннотация.Имя = Аннотация.Имя + Токен;
65+
66+
КонецЕсли;
67+
68+
Если Этап = "ПараметрАннотации" Тогда
69+
70+
Если Токен = ")" Тогда
71+
Этап = "Аннотация";
72+
ДобавитьПараметрАннотации(Аннотация.Параметры, ПараметрАннотации);
73+
Продолжить;
74+
КонецЕсли;
75+
76+
Если Токен = "," Тогда
77+
ДобавитьПараметрАннотации(Аннотация.Параметры, ПараметрАннотации);
78+
ЭтапПараметрАннотации = "Имя";
79+
ПараметрАннотации = Новый Структура("Имя, Значение", "", "");
80+
Продолжить;
81+
КонецЕсли;
82+
83+
Если Токен = """"
84+
Или Токен = "'"
85+
Или ЭтоЦифра(Токен) Тогда
86+
ЭтапПараметрАннотации = "ЗначениеНачало";
87+
КонецЕсли;
88+
89+
Если Токен = "=" Тогда
90+
ЭтапПараметрАннотации = "Значение";
91+
Продолжить;
92+
КонецЕсли;
93+
94+
Если ЭтапПараметрАннотации = "Имя" Тогда
95+
96+
Если ПустаяСтрока(Токен) Тогда
97+
Продолжить;
98+
КонецЕсли;
99+
100+
ПараметрАннотации.Имя = ПараметрАннотации.Имя + Токен;
101+
ИначеЕсли ЭтапПараметрАннотации = "ЗначениеНачало" Тогда
102+
ПараметрАннотации.Значение = ПараметрАннотации.Значение + Токен;
103+
КонецЕсли;
104+
105+
КонецЕсли;
106+
107+
Если Этап = "ПараметрМетода" Тогда
108+
109+
Если Токен = ")" Или Токен = "," Или Индекс = СтрДлина(СтрокаПараметров) Тогда
110+
Этап = "";
111+
Результат.Параметры.Добавить(ПараметрМетода);
112+
ПараметрМетода = Новый Структура("Имя, Аннотации", "");
113+
Продолжить;
114+
КонецЕсли;
115+
116+
ПараметрМетода.Имя = ПараметрМетода.Имя + Токен;
117+
118+
КонецЕсли;
119+
120+
КонецЦикла;
121+
122+
Возврат Результат;
123+
124+
КонецФункции
125+
126+
Функция ЭтоЦифра(Символ)
127+
Возврат Цифры.Найти(Символ) <> Неопределено;
128+
КонецФункции
129+
130+
Процедура ДобавитьПараметрАннотации(Параметры, ПараметрАннотации)
131+
132+
ПараметрАннотации.Значение = СтрЗаменить(ПараметрАннотации.Значение, """", "");
133+
134+
Если ЭтоЦифра(Лев(ПараметрАннотации.Значение, 1)) Тогда
135+
ПараметрАннотации.Значение = Число(ПараметрАннотации.Значение);
136+
ИначеЕсли СтрНачинаетсяС(ПараметрАннотации.Значение, "'") Тогда
137+
ПараметрАннотации.Значение = Дата(ПараметрАннотации.Значение);
138+
ИначеЕсли ПараметрАннотации.Значение = "Ложь" Или ПараметрАннотации.Значение = "False"
139+
Или ПараметрАннотации.Значение = "Истина" Или ПараметрАннотации.Значение = "True" Тогда
140+
ПараметрАннотации.Значение = Булево(ПараметрАннотации.Значение);
141+
КонецЕсли;
142+
143+
Параметры.Добавить(ПараметрАннотации);
144+
145+
КонецПроцедуры
146+
147+
Цифры = Новый Массив;
148+
Цифры.Добавить("0");
149+
Цифры.Добавить("1");
150+
Цифры.Добавить("2");
151+
Цифры.Добавить("3");
152+
Цифры.Добавить("4");
153+
Цифры.Добавить("5");
154+
Цифры.Добавить("6");
155+
Цифры.Добавить("7");
156+
Цифры.Добавить("8");
157+
Цифры.Добавить("9");

src/Классы/ЛямбдаВыражение.os

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,36 @@
155155
Метод.ЭтоПроцедура();
156156
КонецЕсли;
157157

158-
Для каждого ИмяПараметра Из РазобранноеВыражение.Параметры Цикл
159-
Метод.Параметр(Новый ПараметрМетода(ИмяПараметра));
158+
Для Каждого Аннотация Из РазобранноеВыражение.Аннотации Цикл
159+
160+
АннотацияМетода = Новый Аннотация(Аннотация.Имя);
161+
162+
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
163+
АннотацияМетода.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
164+
КонецЦикла;
165+
166+
Метод.Аннотация(АннотацияМетода);
167+
168+
КонецЦикла;
169+
170+
Для каждого Параметр Из РазобранноеВыражение.Параметры Цикл
171+
172+
ПараметрМетода = Новый ПараметрМетода(Параметр.Имя);
173+
174+
Для Каждого Аннотация Из Параметр.Аннотации Цикл
175+
176+
АннотацияПараметра = Новый Аннотация(Аннотация.Имя);
177+
178+
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
179+
АннотацияПараметра.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
180+
КонецЦикла;
181+
182+
ПараметрМетода.Аннотация(АннотацияПараметра);
183+
184+
КонецЦикла;
185+
186+
Метод.Параметр(ПараметрМетода);
187+
160188
КонецЦикла;
161189

162190
Построитель = Новый ПостроительДекоратора(мОбъект)
@@ -190,11 +218,10 @@
190218

191219
Совпадения = ЭтоЛямбдаВыражение.НайтиСовпадения(Выражение);
192220

193-
РазобранноеВыражение.Параметры = СтрРазделить(
194-
Совпадения[0].Группы[1].Значение,
195-
",",
196-
Ложь
197-
);
221+
РезультатРазбора = Парсер.РазобратьСтрокуПараметров(Совпадения[0].Группы[1].Значение);
222+
223+
РазобранноеВыражение.Параметры = РезультатРазбора.Параметры;
224+
РазобранноеВыражение.Аннотации = РезультатРазбора.Аннотации;
198225

199226
РазобранноеВыражение.Тело = Совпадения[0].Группы[2].Значение;
200227

@@ -252,7 +279,7 @@
252279
Процедура ПриСозданииОбъекта(Выражение)
253280

254281
РазобранноеВыражение = Новый Структура(
255-
"Параметры, Тело"
282+
"Аннотации, Параметры, Тело"
256283
);
257284

258285
мВыражение = Выражение;

tests/ЛямбдаВыражение.os

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,104 @@
441441

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

444+
&Тест
445+
Процедура АннотированныеПараметры() Экспорт
446+
447+
// Дано
448+
ЛямбдаВыражение = Новый ЛямбдаВыражение(
449+
"&АннотацияБезПараметра &Аннотация(""с одним параметром"") &Аннотация(Значение = ""С двумя"", Параметра = ""ми"") " +
450+
"(&АннотацияБезПараметра x, &Аннотация(Значение = ""С двумя"", Параметра = ""ми"") y, " +
451+
"&АннотацияБезПараметра &Аннотация(""с одним параметром"") " +
452+
"&Аннотация(Значение = ""С двумя"", Параметра = ""ми"") z) " +
453+
"-> a = x+y+z"
454+
);
455+
456+
// Когда
457+
Объект = ЛямбдаВыражение.Отладка().ВОбъект();
458+
459+
// Тогда
460+
461+
Методы = Рефлектор.ПолучитьТаблицуМетодов(Объект);
462+
463+
Метод = Методы.Найти("Принять", "Имя");
464+
465+
Ожидаем.Что(Метод).Существует();
466+
467+
Ожидаем.Что(Метод.КоличествоПараметров).Равно(3);
468+
Ожидаем.Что(Метод.Аннотации.Количество()).Равно(3);
469+
470+
Аннотация = Метод.Аннотации[0];
471+
472+
Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра");
473+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0);
474+
475+
Аннотация = Метод.Аннотации[1];
476+
477+
Ожидаем.Что(Аннотация.Имя).Равно("Аннотация");
478+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(1);
479+
Ожидаем.Что(Аннотация.Параметры[0].Имя).ЭтоНеопределено();
480+
Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("с одним параметром");
481+
482+
Аннотация = Метод.Аннотации[2];
483+
484+
Ожидаем.Что(Аннотация.Имя).Равно("Аннотация");
485+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2);
486+
Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение");
487+
Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("С двумя");
488+
Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра");
489+
Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно("ми");
490+
491+
Параметр = Метод.Параметры[0];
492+
493+
Ожидаем.Что(Параметр.Имя).Равно("x");
494+
495+
Аннотация = Параметр.Аннотации[0];
496+
497+
Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра");
498+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0);
499+
500+
Параметр = Метод.Параметры[1];
501+
502+
Ожидаем.Что(Параметр.Имя).Равно("y");
503+
504+
Аннотация = Параметр.Аннотации[0];
505+
506+
Ожидаем.Что(Аннотация.Имя).Равно("Аннотация");
507+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2);
508+
Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение");
509+
Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("С двумя");
510+
Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра");
511+
Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно("ми");
512+
513+
Параметр = Метод.Параметры[2];
514+
515+
Ожидаем.Что(Параметр.Имя).Равно("z");
516+
517+
Аннотация = Параметр.Аннотации[0];
518+
519+
Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра");
520+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0);
521+
522+
Аннотация = Параметр.Аннотации[1];
523+
524+
Ожидаем.Что(Аннотация.Имя).Равно("Аннотация");
525+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(1);
526+
Ожидаем.Что(Аннотация.Параметры[0].Имя).ЭтоНеопределено();
527+
Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("с одним параметром");
528+
529+
Аннотация = Параметр.Аннотации[2];
530+
531+
Ожидаем.Что(Аннотация.Имя).Равно("Аннотация");
532+
Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2);
533+
Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение");
534+
Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("С двумя");
535+
Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра");
536+
Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно("ми");
537+
538+
КонецПроцедуры
539+
444540
Функция ЗахватываемыйОбъект()
445-
541+
446542
Возврат Новый ПостроительДекоратора()
447543
.Метод(
448544
Новый Метод("Тест")

0 commit comments

Comments
 (0)