Skip to content

Commit 2e16e1d

Browse files
authored
Merge pull request #2 from sfaqer/feature/annotationSupport
Поддержка аннотаций в лямбда выражении
2 parents 3d89d28 + ee081d0 commit 2e16e1d

File tree

8 files changed

+340
-15
lines changed

8 files changed

+340
-15
lines changed

.github/workflows/testing.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
16-
oscript_version: ['1.8.3', 'stable']
16+
oscript_version: ['1.8.3', 'stable', 'dev']
1717

1818
steps:
1919
# Загрузка проекта
@@ -22,7 +22,7 @@ jobs:
2222

2323
# Установка OneScript конкретной версии
2424
- name: Установка OneScript
25-
uses: otymko/setup-onescript@v1.1
25+
uses: otymko/setup-onescript@v1.4
2626
with:
2727
version: ${{ matrix.oscript_version }}
2828

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,47 @@
271271

272272
Как мы видим, в выражении возможно обратиться к полям и методам переданного объекта
273273

274+
### Аннотации
275+
276+
Есть возможность указать Аннотации как для параметров метода так и для самого метода, создаваемого из лямбда-выражения, например:
277+
278+
```bsl
279+
"&АннотацияМетода (Первый, Второй) -> Возврат Первый + Второй"
280+
```
281+
282+
Будет преобразовано в:
283+
284+
```bsl
285+
&АннотацияМетода
286+
Функция Принять(Первый, Второй)
287+
Возврат Первый + Второй;
288+
КонецФункции
289+
```
290+
291+
Так же и для параметров:
292+
293+
```bsl
294+
"(&АннотацияПараметра(1) Первый, &АннотацияПараметра(2) Второй) -> Возврат Первый + Второй"
295+
```
296+
297+
Будет преобразовано в:
298+
299+
```bsl
300+
Функция Принять(&АннотацияПараметра(1) Первый, &АннотацияПараметра(2) Второй)
301+
Возврат Первый + Второй;
302+
КонецФункции
303+
```
304+
305+
> Важно
306+
При использовании аннотаций требуется использовать полную форму указания параметров т.е. со скобками `(Параметр1, Параметр2)`.
307+
В такой форме аннотации, оставшиеся за скобками параметров, будут принадлежать методу, а внутри скобок - параметрам, перед которым они идут.
308+
Так же блок параметров должен быть отделён пробелом от самой аннотации, в ином случае они будут прочитаны как параметры аннотации:
309+
```bsl
310+
&Аннотация (Парам1, Парам2) // <- Метод с двумя параметрами и аннотацией
311+
312+
&Аннотация(Парам1, Парам2) // <- Метод без параметров с аннотацией с двумя параметрами
313+
```
314+
274315
## Программный интерфейс
275316

276317
### Лямбда

packagedef

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Описание.Имя("lambdas")
2-
.Версия("0.1.3")
2+
.Версия("0.2.0")
33
.Автор("Кирилл Черненко")
44
.АдресАвтора("https://github.com/sfaqer")
55
.Описание("API для реализации функциональных интерфейсов для OneScript")
@@ -9,7 +9,7 @@
99
.ВключитьФайл("LICENSE.md")
1010
.ВключитьФайл("package-loader.os")
1111
.ЗависитОт("reflector", "0.7.1")
12-
.ЗависитОт("decorator", "1.5.0")
12+
.ЗависитОт("decorator", "1.7.1")
1313
.РазработкаЗависитОт("1testrunner")
1414
.РазработкаЗависитОт("coverage")
1515
.РазработкаЗависитОт("asserts")

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: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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+
Процедура ДобавитьПараметрАннотации(Параметры, ПараметрАннотации)
135+
136+
ПараметрАннотации.Значение = СтрЗаменить(ПараметрАннотации.Значение, """", "");
137+
138+
Если ЭтоЦифра(Лев(ПараметрАннотации.Значение, 1)) Тогда
139+
ПараметрАннотации.Значение = Число(ПараметрАннотации.Значение);
140+
ИначеЕсли СтрНачинаетсяС(ПараметрАннотации.Значение, "'") Тогда
141+
ПараметрАннотации.Значение = Дата(СтрЗаменить(ПараметрАннотации.Значение, "'", ""));
142+
ИначеЕсли ПараметрАннотации.Значение = "Ложь" Или ПараметрАннотации.Значение = "False"
143+
Или ПараметрАннотации.Значение = "Истина" Или ПараметрАннотации.Значение = "True" Тогда
144+
ПараметрАннотации.Значение = Булево(ПараметрАннотации.Значение);
145+
КонецЕсли;
146+
147+
Параметры.Добавить(ПараметрАннотации);
148+
149+
КонецПроцедуры
150+
151+
Цифры = Новый Массив;
152+
Цифры.Добавить("0");
153+
Цифры.Добавить("1");
154+
Цифры.Добавить("2");
155+
Цифры.Добавить("3");
156+
Цифры.Добавить("4");
157+
Цифры.Добавить("5");
158+
Цифры.Добавить("6");
159+
Цифры.Добавить("7");
160+
Цифры.Добавить("8");
161+
Цифры.Добавить("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
мВыражение = Выражение;

tasks/oscript.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
lib.additional=../oscript_modules
1+
lib.system=../oscript_modules

0 commit comments

Comments
 (0)