├── .github └── workflows │ ├── release.yml │ └── testing.yml ├── .gitignore ├── LICENCE.md ├── README.md ├── packagedef ├── src ├── internal │ ├── Классы │ │ ├── БиПроцедура.os │ │ ├── БиФункция.os │ │ ├── Вызываемый.os │ │ ├── Запускаемый.os │ │ ├── ТриПроцедура.os │ │ ├── ТриФункция.os │ │ ├── УниПроцедура.os │ │ └── УниФункция.os │ └── Модули │ │ ├── ЛямбдыКешируемыеЗначения.os │ │ └── ПарсерЛямбдаВыражений.os ├── Классы │ └── ЛямбдаВыражение.os └── Модули │ ├── Лямбда.os │ └── ФункциональныеИнтерфейсы.os ├── tasks ├── coverage.os ├── oscript.cfg └── test.os └── tests ├── Лямбда.os ├── ЛямбдаВыражение.os └── ФункциональныеИнтерфейсы.os /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Публикация релиза 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | workflow_dispatch: 8 | 9 | jobs: 10 | release: 11 | uses: autumn-library/workflows/.github/workflows/release.yml@main 12 | with: 13 | package_mask: "lambdas-*.ospx" 14 | secrets: 15 | PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/testing.yml: -------------------------------------------------------------------------------- 1 | name: Тестирование 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | oscript_version: ['dev', 'lts-dev', 'default'] 14 | uses: autumn-library/workflows/.github/workflows/test.yml@main 15 | with: 16 | oscript_version: ${{ matrix.oscript_version }} 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .vscode/ 3 | oscript_modules/ -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © `2023` `Kirill Chernenko ` 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lambdas 2 | 3 | Лямбдас это библиотека для реализации функциональных интерфейсов в ваших библиотеках 4 | 5 | ## How to 6 | 7 | ### Синтаксис лямбда выражения: 8 | 9 | Поддерживаются следующие варианты синтаксиса лямбда выражений: 10 | 11 | ```bsl 12 | // 1 13 | "(ПараметрПервый, ПараметрВторой) -> { Возврат ПараметрПервый + ПараметрВторой }" 14 | 15 | // 2 16 | "(ПараметрПервый, ПараметрВторой) -> Возврат ПараметрПервый + ПараметрВторой" 17 | 18 | // 3 19 | "ПараметрПервый, ПараметрВторой -> { Возврат ПараметрПервый + ПараметрВторой }" 20 | 21 | // 4 22 | "ПараметрПервый, ПараметрВторой -> Возврат ПараметрПервый + ПараметрВторой" 23 | 24 | ``` 25 | 26 | ### Простой пример 27 | 28 | Допустим, у вас есть библиотека, в рамках которой вы хотите позволить потребителю удалять элементы из массива по некоторому условию. 29 | 30 | Вы добавляете метод: 31 | 32 | ```bsl 33 | // МояКласснаяБиблиотека.os 34 | 35 | Процедура УдалитьПоУсловию(Условие) Экспорт 36 | 37 | Действие = Лямбда.Выражение(Условие) 38 | .ВДействие(); 39 | 40 | Для каждого Элемент из Коллекция Цикл 41 | 42 | Если Действие.Выполнить() Тогда 43 | Коллекция.Удалить(Элемент); 44 | КонецЕсли; 45 | 46 | КонецЦикла; 47 | 48 | КонецПроцедуры 49 | ``` 50 | 51 | В данном примере вы получаете [Действие](https://oscript.io/syntax/page/Действие) на метод, который был создан по переданному выражению, и вызов вашего метода теперь может выглядеть вот так: 52 | 53 | ```bsl 54 | // ПотребительМоейКласснойБиблиотеки.os 55 | 56 | Процедура Удалить() 57 | 58 | // Удалим из коллекции все элементы которые больше или равны двум 59 | МояКласснаяБиблиотека.УдалитьПоУсловию("Элемент -> Возврат Элемент >= 2"); 60 | 61 | КонецПроцедуры 62 | ``` 63 | 64 | ### Интерфейсы 65 | 66 | Для лямбда выражения можно указать функциональный интерфейс который она будет реализовывать, эта возможность преследует две цели 67 | 1. Проверить что переданное выражение соответствует вашим ожиданиям, Функция это или Процедура, и количество параметров 68 | 1. Предоставить возможность не писать возврат в однострочных лямбда выражениях вашим потребителям, если это функция 69 | 70 | В составе библиотеки поставляет ряд функциональных интерфейсов (в модуле `ФункциональныеИнтерфейсы`): 71 | 1. Вызываемый - Функция `Вызвать` без параметров 72 | 1. УниФункция - Функция `Применить` с одним параметром 73 | 1. БиФункция - Функция `Применить` с двумя параметром 74 | 1. ТриФункция - Функция `Применить` с тремя параметром 75 | 1. Запускаемый - Процедура `Запустить` без параметров 76 | 1. УниПроцедура - Процедура `Принять` с одним параметром 77 | 1. БиПроцедура - Процедура `Принять` с двумя параметрами 78 | 1. ТриПроцедура - Процедура `Принять` с тремя параметрами 79 | 80 | Так же можно установить произвольный `ИнтерфейсОбъекта` для создания метода по нему 81 | 82 | Если интерфейс не был передан явно, то будет предпринята попытка автоматически подобрать один из интерфейсов из списка выше, в зависимости от количества параметров лямбда выражения и наличия возврата значения в его тексте 83 | 84 | Например: 85 | 86 | ```bsl 87 | // МояКласснаяБиблиотека.os 88 | 89 | Процедура Сортировать(СравнениеЗначений) Экспорт 90 | 91 | Интерфейс = Новый ИнтерфейсОбъекта(); 92 | Интерфейс.ФункцияИнтерфейса("Сравнить", 2); 93 | 94 | Компаратор = Лямбда.Выражение(СравнениеЗначений) 95 | .Интерфейс(Интерфейс) 96 | .ВОбъект(); 97 | 98 | Для каждого Элемент Из Коллекция Цикл 99 | 100 | РезультатСравнения = Компаратор.Сравнить(Элемент, СледующийЭлемент); 101 | 102 | Если РезультатСравнения > 0 Тогда 103 | // ... 104 | ИначеЕсли РезультатСравнения < 0 Тогда 105 | // ... 106 | Иначе 107 | // ... 108 | КонецЕсли; 109 | 110 | // Алгоритм сортировки 111 | 112 | КонецЦикла; 113 | 114 | КонецПроцедуры 115 | ``` 116 | Тут мы использовали метод `ВОбъект` для получения сценария, который реализует наш переданный интерфейс, и обратились по имени метода, который мы отразили в интерфейсе. 117 | 118 | Вызов метода: 119 | 120 | ```bsl 121 | // ПотребительМоейКласснойБиблиотеки.os 122 | 123 | МояКласснаяБиблиотека.Сортировать("Первый, Второй -> 124 | | Если Первый > Второй Тогда 125 | | Возврат 1; 126 | | ИначеЕсли Второй > Первый Тогда 127 | | Возврат -1; 128 | | Иначе 129 | | Возврат 0; 130 | | КонецЕсли;" 131 | ); 132 | ``` 133 | 134 | Пример необязательного возврата: 135 | 136 | ```bsl 137 | // МояКласснаяБиблиотека.os 138 | 139 | Процедура Заменить(Массив, Выражение) Экспорт 140 | 141 | Действие = Лямбда.Выражение(Выражение) 142 | .Интерфейс(ФункциональныеИнтерфейсы.УниФункция()) 143 | .ВДействие(); 144 | 145 | Счетчик = 0; 146 | 147 | Для Счетчик = 0 По Массив.ВГраница() Цикл 148 | Массив.Установить(Счетчик, Действие.Выполнить(Массив[Счетчик])); 149 | КонецЦикла; 150 | 151 | КонецПроцедуры 152 | ``` 153 | 154 | ```bsl 155 | // ПотребительМоейКласснойБиблиотеки.os 156 | 157 | Массив = Новый Массив(); 158 | Массив.Добавить(1); 159 | Массив.Добавить(2); 160 | Массив.Добавить(3); 161 | 162 | Заменить(Массив, "Элемент -> Элемент + 1"); 163 | 164 | Сообщить(Массив[0]); 165 | Сообщить(Массив[1]); 166 | Сообщить(Массив[2]); 167 | ``` 168 | 169 | Результат: 170 | ``` 171 | // 2 172 | // 3 173 | // 4 174 | ``` 175 | 176 | #### Контекст 177 | 178 | Лямбда-выражению можно установить `Контекст`, это позволит использовать поля контекста прямо в выражении, контекстом может выступать только структура 179 | 180 | Например: 181 | 182 | ```bsl 183 | // МояКласснаяБиблиотека.os 184 | 185 | Процедура СделайДело(ЧтоСделать) Экспорт 186 | 187 | ДелоПервое = Новый Структура("Состояние", "НеСделано"); 188 | ДелоВторое = Новый Структура("Состояние", "НеСделано"); 189 | 190 | Контекст = Новый Структура( 191 | "ДелоПервое, ДелоВторое", 192 | ДелоПервое, 193 | ДелоВторое 194 | ); 195 | 196 | Делатель = Лямбда.Выражение(ЧтоСделать) 197 | .Контекст(Контекст) 198 | .ВДействие(); 199 | 200 | Делатель.Выполнить(1); 201 | 202 | Сообщить("ДелоПервое = " + ДелоПервое.Состояние); 203 | Сообщить("ДелоВторое = " + ДелоВторое.Состояние); 204 | 205 | КонецПроцедуры 206 | ``` 207 | 208 | Вызов метода: 209 | 210 | ```bsl 211 | // ПотребительМоейКласснойБиблиотеки.os 212 | 213 | МояКласснаяБиблиотека.СделайДело("(НомерДела) -> 214 | | Если НомерДела = 1 Тогда 215 | | ДелоПервое.Состояние = ""Сделано"" 216 | | ИначеЕсли НомерДела = 2 Тогда 217 | | ДелоВторое.Состояние = ""Сделано"" 218 | | КонецЕсли;" 219 | ); 220 | 221 | ``` 222 | 223 | Результат: 224 | 225 | ``` 226 | ДелоПервое = Сделано 227 | ДелоВторое = НеСделано 228 | ``` 229 | Как мы видим, поля контекста доступны в лямбда выражении по именам ключей структуры контекста 230 | 231 | #### Захват объекта 232 | 233 | В лямбда выражение можно захватить какой-то объект, чтобы в тексте лямбда выражения можно было использовать публичные и приватные поля объекта, а также публичные методы 234 | 235 | Например: 236 | 237 | ```bsl 238 | // МояКласснаяБиблиотека.os 239 | 240 | Функция Единичка(Алгоритм, Объект) Экспорт 241 | 242 | Действие = Лямбда.Выражение(Алгоритм) 243 | .ЗахватитьОбъект(Объект) 244 | .ВДействие(); 245 | 246 | Возврат Действие.Выполнить(1); 247 | 248 | КонецФункции 249 | ``` 250 | 251 | Вызов метода: 252 | 253 | ```bsl 254 | // ПотребительМоейКласснойБиблиотеки.os 255 | 256 | Перем Двойка; 257 | Перем Тройка Экспорт; 258 | 259 | Функция Четверка() Экспорт 260 | Возврат 4; 261 | КонецФункции 262 | 263 | Результат = МояКласснаяБиблиотека.Единичка( 264 | "(Единица) -> Возврат Единица + Двойка + Тройка + Четверка()", 265 | ЭтотОбъект 266 | ); 267 | 268 | // Результат = 10 269 | 270 | ``` 271 | 272 | Как мы видим, в выражении возможно обратиться к полям и методам переданного объекта 273 | 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 | 315 | ## Программный интерфейс 316 | 317 | ### Лямбда 318 | 319 | #### Выражение 320 | 321 | ```bsl 322 | // Создаёт лямбда-выражение из переданного выражения 323 | // 324 | // Параметры: 325 | // Выражение - Строка - Выражение, из которого будет создано лямбда-выражение 326 | // 327 | // Возвращаемое значение: 328 | // ЛямбдаВыражение - Созданное лямбда-выражение 329 | // 330 | Функция Выражение(Выражение) 331 | ``` 332 | --- 333 | 334 | ### ЛямбдаВыражение 335 | 336 | #### ПриСозданииОбъекта 337 | 338 | ```bsl 339 | 340 | Процедура ПриСозданииОбъекта(Выражение) 341 | ``` 342 | 343 | #### Интерфейс 344 | 345 | ```bsl 346 | // Устанавливает функциональный интерфейс для лямбда выражения. 347 | // В случае если метод интерфейса это функция: 348 | // 1. Добавляет "Возврат" в лямбда выражение если оно однострочное и не содержит возврат 349 | // 2. Проверяет что многострочное выражение содержит возврат значения 350 | // В случае В случае если метод интерфейса это процедура: 351 | // 1. Проверяет что выражение не содержит возврат значения 352 | // 353 | // Параметры: 354 | // Интерфейс - ИнтерфейсОбъекта - Устанавливаемый функциональный интерфейс 355 | // 356 | // Возвращаемое значение: 357 | // ЛямбдаВыражение - Инстанс текущего выражения 358 | // 359 | Функция Интерфейс(Интерфейс) 360 | ``` 361 | 362 | #### Контекст 363 | 364 | ```bsl 365 | // Устанавливает контекст для лямбда выражения. 366 | // При исполнении лямбда выражения все значения контекста будут доступны для использования в лямбда выражении 367 | // 368 | // Параметры: 369 | // Контекст - Структура, ФиксированныйСтруктура - Устанавливаемый контекст 370 | // 371 | // Возвращаемое значение: 372 | // ЛямбдаВыражение - Инстанс текущего выражения 373 | // 374 | Функция Контекст(Контекст) 375 | ``` 376 | 377 | #### ЗахватитьОбъект 378 | 379 | ```bsl 380 | // Захватывает переданный объект для использования его в качестве контекста лямбда выражения. 381 | // При исполнении лямбда выражения в нём будут доступны публичные и приватные поля переданного объекта 382 | // а так же публичные методы. 383 | // 384 | // Параметры: 385 | // Объект - Сценарий - Захватываемый объект 386 | // 387 | // Возвращаемое значение: 388 | // ЛямбдаВыражение - Инстанс текущего выражения 389 | // 390 | Функция ЗахватитьОбъект(Объект) 391 | ``` 392 | 393 | #### ВДействие 394 | 395 | ```bsl 396 | // Возвращает действие (делегат) на метод созданный по лямбда выражению 397 | // 398 | // Возвращаемое значение: 399 | // Действие - Действие на метод лямбда выражения 400 | // 401 | Функция ВДействие() 402 | ``` 403 | 404 | #### ВОбъект 405 | 406 | ```bsl 407 | // Возвращает сценарий созданный по лямбда выражению, который содержит метод согласно интерфейса 408 | // 409 | // Возвращаемое значение: 410 | // Сценарий - Созданный сценарий 411 | // 412 | Функция ВОбъект() 413 | ``` 414 | --- 415 | 416 | ### ФункциональныеИнтерфейсы 417 | 418 | #### Вызываемый 419 | 420 | ```bsl 421 | // Возвращает интерфейс объекта содержащий функцию без параметров 422 | // 423 | // Возвращаемое значение: 424 | // ИнтерфейсОбъекта - Искомый интерфейс 425 | // 426 | Функция Вызываемый() Экспорт 427 | ``` 428 | 429 | #### УниФункция 430 | 431 | ```bsl 432 | // Возвращает интерфейс объекта содержащий функцию с одним параметром 433 | // 434 | // Возвращаемое значение: 435 | // ИнтерфейсОбъекта - Искомый интерфейс 436 | // 437 | Функция УниФункция() 438 | ``` 439 | 440 | #### БиФункция 441 | 442 | ```bsl 443 | // Возвращает интерфейс объекта содержащий функцию с двумя параметрами 444 | // 445 | // Возвращаемое значение: 446 | // ИнтерфейсОбъекта - Искомый интерфейс 447 | // 448 | Функция БиФункция() 449 | ``` 450 | 451 | #### ТриФункция 452 | 453 | ```bsl 454 | // Возвращает интерфейс объекта содержащий функцию с тремя параметрами 455 | // 456 | // Возвращаемое значение: 457 | // ИнтерфейсОбъекта - Искомый интерфейс 458 | // 459 | Функция ТриФункция() 460 | ``` 461 | #### Запускаемый 462 | 463 | ```bsl 464 | // Возвращает интерфейс объекта содержащий процедуру без параметров 465 | // 466 | // Возвращаемое значение: 467 | // ИнтерфейсОбъекта - Искомый интерфейс 468 | // 469 | Функция Запускаемый() Экспорт 470 | ``` 471 | 472 | #### УниПроцедура 473 | 474 | ```bsl 475 | // Возвращает интерфейс объекта содержащий процедуру с одним параметром 476 | // 477 | // Возвращаемое значение: 478 | // ИнтерфейсОбъекта - Искомый интерфейс 479 | // 480 | Функция УниПроцедура() 481 | ``` 482 | 483 | #### БиПроцедура 484 | 485 | ```bsl 486 | // Возвращает интерфейс объекта содержащий процедуру с двумя параметрами 487 | // 488 | // Возвращаемое значение: 489 | // ИнтерфейсОбъекта - Искомый интерфейс 490 | // 491 | Функция БиПроцедура() 492 | ``` 493 | 494 | #### ТриПроцедура 495 | 496 | ```bsl 497 | // Возвращает интерфейс объекта содержащий процедуру с тремя параметрами 498 | // 499 | // Возвращаемое значение: 500 | // ИнтерфейсОбъекта - Искомый интерфейс 501 | // 502 | Функция ТриПроцедура() 503 | ``` 504 | 505 | -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 | Описание.Имя("lambdas") 2 | .Версия("0.3.2") 3 | .Автор("Кирилл Черненко") 4 | .АдресАвтора("https://github.com/sfaqer") 5 | .Описание("API для реализации функциональных интерфейсов для OneScript") 6 | .ВерсияСреды("1.9.2") 7 | .ВключитьФайл("src") 8 | .ВключитьФайл("README.md") 9 | .ВключитьФайл("LICENSE.md") 10 | .ВключитьФайл("package-loader.os") 11 | .ЗависитОт("reflector", "0.7.1") 12 | .ЗависитОт("decorator", "2.0.0") 13 | .РазработкаЗависитОт("1testrunner") 14 | .РазработкаЗависитОт("coverage") 15 | .РазработкаЗависитОт("asserts") 16 | ; 17 | -------------------------------------------------------------------------------- /src/internal/Классы/БиПроцедура.os: -------------------------------------------------------------------------------- 1 | Процедура Принять(Параметр1, Параметр2) Экспорт 2 | КонецПроцедуры 3 | -------------------------------------------------------------------------------- /src/internal/Классы/БиФункция.os: -------------------------------------------------------------------------------- 1 | Функция Применить(Параметр1, Параметр2) Экспорт // BSLLS:FunctionShouldHaveReturn-off 2 | КонецФункции 3 | -------------------------------------------------------------------------------- /src/internal/Классы/Вызываемый.os: -------------------------------------------------------------------------------- 1 | Функция Вызвать() Экспорт // BSLLS:FunctionShouldHaveReturn-off 2 | КонецФункции 3 | -------------------------------------------------------------------------------- /src/internal/Классы/Запускаемый.os: -------------------------------------------------------------------------------- 1 | Процедура Запустить() Экспорт 2 | КонецПроцедуры 3 | -------------------------------------------------------------------------------- /src/internal/Классы/ТриПроцедура.os: -------------------------------------------------------------------------------- 1 | Процедура Принять(Параметр1, Параметр2, Параметр3) Экспорт 2 | КонецПроцедуры 3 | -------------------------------------------------------------------------------- /src/internal/Классы/ТриФункция.os: -------------------------------------------------------------------------------- 1 | Функция Применить(Параметр1, Параметр2, Параметр3) Экспорт // BSLLS:FunctionShouldHaveReturn-off 2 | КонецФункции 3 | -------------------------------------------------------------------------------- /src/internal/Классы/УниПроцедура.os: -------------------------------------------------------------------------------- 1 | Процедура Принять(Параметр1) Экспорт 2 | КонецПроцедуры 3 | -------------------------------------------------------------------------------- /src/internal/Классы/УниФункция.os: -------------------------------------------------------------------------------- 1 | Функция Применить(Параметр1) Экспорт // BSLLS:FunctionShouldHaveReturn-off 2 | КонецФункции 3 | -------------------------------------------------------------------------------- /src/internal/Модули/ЛямбдыКешируемыеЗначения.os: -------------------------------------------------------------------------------- 1 | Перем ЭтоЛямбдаВыражение; // Кеш регулярного выражения лямбда выражения 2 | Перем СодержитВозвратЗначения; // Кеш регулярного выражения содержит возврат значения 3 | 4 | Перем КешСозданныхЛямбд; // LRU кеш созданных лямбд 5 | 6 | Функция РегулярноеВыражениеЭтоЛямбдаВыражение() Экспорт 7 | 8 | Если ЭтоЛямбдаВыражение = Неопределено Тогда 9 | 10 | ЭтоЛямбдаВыражение = Новый РегулярноеВыражение( 11 | "((?:\s|\S)*?)->\s*([\s\S]*)" 12 | ); 13 | 14 | КонецЕсли; 15 | 16 | Возврат ЭтоЛямбдаВыражение; 17 | 18 | КонецФункции 19 | 20 | Функция РегулярноеВыражениеСодержитВозвратЗначения() Экспорт 21 | 22 | Если СодержитВозвратЗначения = Неопределено Тогда 23 | СодержитВозвратЗначения = Новый РегулярноеВыражение("(?>[^\S]+|^)(Возврат)\s+[^;\s]+\s*;?"); 24 | КонецЕсли; 25 | 26 | Возврат СодержитВозвратЗначения; 27 | 28 | КонецФункции 29 | 30 | Функция ДостатьИзКеша(Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект) Экспорт 31 | 32 | Строки = КешСозданныхЛямбд.НайтиСтроки( 33 | Новый Структура( 34 | "Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект", 35 | Выражение, 36 | Интерфейс, 37 | Контекст, 38 | ЗахватываемыйОбъект 39 | ) 40 | ); 41 | 42 | Если Строки.Количество() = 0 Тогда 43 | Возврат Неопределено; 44 | КонецЕсли; 45 | 46 | КешСозданныхЛямбд.Сдвинуть(Строки[0], -КешСозданныхЛямбд.Индекс(Строки[0])); 47 | Возврат Строки[0].Объект; 48 | 49 | КонецФункции 50 | 51 | Процедура ПоложитьВКеш(Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект, Объект) Экспорт 52 | 53 | Строка = КешСозданныхЛямбд.Вставить(0); 54 | Строка.Выражение = Выражение; 55 | Строка.Интерфейс = Интерфейс; 56 | Строка.Контекст = Контекст; 57 | Строка.ЗахватываемыйОбъект = ЗахватываемыйОбъект; 58 | Строка.Объект = Объект; 59 | 60 | Если КешСозданныхЛямбд.Количество() > 20 Тогда 61 | КешСозданныхЛямбд.Удалить(КешСозданныхЛямбд.Количество() - 1); 62 | КонецЕсли; 63 | 64 | КонецПроцедуры 65 | 66 | КешСозданныхЛямбд = Новый ТаблицаЗначений(); 67 | КешСозданныхЛямбд.Колонки.Добавить("Выражение"); 68 | КешСозданныхЛямбд.Колонки.Добавить("Интерфейс"); 69 | КешСозданныхЛямбд.Колонки.Добавить("Контекст"); 70 | КешСозданныхЛямбд.Колонки.Добавить("ЗахватываемыйОбъект"); 71 | КешСозданныхЛямбд.Колонки.Добавить("Объект"); 72 | -------------------------------------------------------------------------------- /src/internal/Модули/ПарсерЛямбдаВыражений.os: -------------------------------------------------------------------------------- 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 | ПараметрАннотации.Значение = СтрЗаменить(ПараметрАннотации.Значение, """", ""); 139 | 140 | Если ЭтоЦифра(Лев(ПараметрАннотации.Значение, 1)) Тогда 141 | ПараметрАннотации.Значение = Число(ПараметрАннотации.Значение); 142 | ИначеЕсли СтрНачинаетсяС(ПараметрАннотации.Значение, "'") Тогда 143 | ПараметрАннотации.Значение = Дата(СтрЗаменить(ПараметрАннотации.Значение, "'", "")); 144 | ИначеЕсли ПараметрАннотации.Значение = "Ложь" Или ПараметрАннотации.Значение = "False" 145 | Или ПараметрАннотации.Значение = "Истина" Или ПараметрАннотации.Значение = "True" Тогда 146 | ПараметрАннотации.Значение = Булево(ПараметрАннотации.Значение); 147 | КонецЕсли; 148 | 149 | Параметры.Добавить(ПараметрАннотации); 150 | 151 | КонецПроцедуры 152 | 153 | Цифры = Новый Массив; 154 | Цифры.Добавить("0"); 155 | Цифры.Добавить("1"); 156 | Цифры.Добавить("2"); 157 | Цифры.Добавить("3"); 158 | Цифры.Добавить("4"); 159 | Цифры.Добавить("5"); 160 | Цифры.Добавить("6"); 161 | Цифры.Добавить("7"); 162 | Цифры.Добавить("8"); 163 | Цифры.Добавить("9"); 164 | -------------------------------------------------------------------------------- /src/Классы/ЛямбдаВыражение.os: -------------------------------------------------------------------------------- 1 | #Использовать decorator 2 | 3 | Перем РазобранноеВыражение; // Структура разобранного лямбда выражения 4 | 5 | Перем мВыражение; // Лямбда выражение 6 | Перем мИнтерфейс; // Функциональный интерфейс для лямбда выражения 7 | Перем мКонтекст; // Структура с контекстом для лямбда выражения 8 | Перем мОбъект; // Объект который будет захвачен в лямбда выражение 9 | Перем Отладка; // Отладочное сохранение текста сценария в файл 10 | 11 | Перем СодержитВозвратЗначения; // Регулярное выражение проверяющее наличие возврата значения 12 | Перем ЭтоЛямбдаВыражение; // Регулярное выражение проверяющее лямбда выражение 13 | 14 | // Устанавливает функциональный интерфейс для лямбда выражения. 15 | // В случае если метод интерфейса это функция: 16 | // 1. Добавляет "Возврат" в лямбда выражение если оно однострочное и не содержит возврат 17 | // 2. Проверяет что многострочное выражение содержит возврат значения 18 | // В случае В случае если метод интерфейса это процедура: 19 | // 1. Проверяет что выражение не содержит возврат значения 20 | // 21 | // Параметры: 22 | // Интерфейс - ИнтерфейсОбъекта - Устанавливаемый функциональный интерфейс 23 | // 24 | // Возвращаемое значение: 25 | // ЛямбдаВыражение - Инстанс текущего выражения 26 | // 27 | Функция Интерфейс(Интерфейс) Экспорт 28 | 29 | ЭтоФункция = Интерфейс.ПолучитьКартуИнтерфейса()[0].ЭтоФункция; 30 | ВозвратыЗначений = СодержитВозвратЗначения.НайтиСовпадения(РазобранноеВыражение.Тело); 31 | 32 | Если ЭтоФункция Тогда 33 | 34 | Если СтрЧислоСтрок(РазобранноеВыражение.Тело) > 1 35 | И ВозвратыЗначений.Количество() = 0 Тогда 36 | 37 | ВызватьИсключение Новый ИнформацияОбОшибке( 38 | "Лямбда выражение должно возвращать значение", 39 | мВыражение 40 | ); 41 | 42 | КонецЕсли; 43 | 44 | Если СтрЧислоСтрок(РазобранноеВыражение.Тело) = 1 45 | И ВозвратыЗначений.Количество() = 0 Тогда 46 | 47 | РазобранноеВыражение.Тело = "Возврат " + РазобранноеВыражение.Тело; 48 | 49 | КонецЕсли; 50 | 51 | ИначеЕсли ВозвратыЗначений.Количество() <> 0 Тогда 52 | 53 | ВызватьИсключение Новый ИнформацияОбОшибке( 54 | "Лямбда выражение не должно возвращать значение", 55 | мВыражение 56 | ); 57 | 58 | КонецЕсли; // BSLLS:IfElseIfEndsWithElse-off 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 | мИнтерфейс.ПолучитьКартуИнтерфейса()[0].Имя 134 | ); 135 | 136 | КонецФункции 137 | 138 | // Возвращает сценарий созданный по лямбда выражению, который содержит метод согласно интерфейса 139 | // 140 | // Возвращаемое значение: 141 | // Сценарий - Созданный сценарий 142 | // 143 | Функция ВОбъект() Экспорт 144 | 145 | Если Не ЗначениеЗаполнено(мИнтерфейс) Тогда 146 | ОпределитьИнтерфейс(); 147 | КонецЕсли; 148 | 149 | Объект = ЛямбдыКешируемыеЗначения.ДостатьИзКеша(мВыражение, мИнтерфейс, мКонтекст, мОбъект); 150 | ОбработкаДекоратора.СинхронизироватьПоля(мОбъект, Объект); 151 | 152 | Если Не ЗначениеЗаполнено(Объект) Тогда 153 | Объект = СоздатьОбъект(); 154 | ЛямбдыКешируемыеЗначения.ПоложитьВКеш(мВыражение, мИнтерфейс, мКонтекст, мОбъект, Объект); 155 | КонецЕсли; 156 | 157 | Возврат Объект; 158 | 159 | КонецФункции 160 | 161 | Процедура РазобратьВыражение(Выражение) 162 | 163 | Если Не ЭтоЛямбдаВыражение.Совпадает(Выражение) Тогда 164 | ВызватьИсключение Новый ИнформацияОбОшибке("Переданное выражение не является лямбда выражением", Выражение); 165 | КонецЕсли; 166 | 167 | Совпадения = ЭтоЛямбдаВыражение.НайтиСовпадения(Выражение); 168 | 169 | РезультатРазбора = ПарсерЛямбдаВыражений.РазобратьСтрокуПараметров(Совпадения[0].Группы[1].Значение); 170 | 171 | РазобранноеВыражение.Параметры = РезультатРазбора.Параметры; 172 | РазобранноеВыражение.Аннотации = РезультатРазбора.Аннотации; 173 | 174 | Тело = Совпадения[0].Группы[2].Значение; 175 | 176 | Если СтрНачинаетсяС(Тело, "{") Тогда 177 | Тело = Прав(Тело, СтрДлина(Тело) - 1); 178 | КонецЕсли; 179 | 180 | Если СтрЗаканчиваетсяНа(Тело, "}") Тогда 181 | Тело = Лев(Тело, СтрДлина(Тело) - 1); 182 | КонецЕсли; 183 | 184 | РазобранноеВыражение.Тело = Тело; 185 | 186 | КонецПроцедуры 187 | 188 | Процедура ОпределитьИнтерфейс() 189 | 190 | ЭтоФункция = СодержитВозвратЗначения.НайтиСовпадения(РазобранноеВыражение.Тело).Количество() <> 0; 191 | КоличествоПараметров = РазобранноеВыражение.Параметры.Количество(); 192 | 193 | Если ЭтоФункция Тогда 194 | 195 | Если КоличествоПараметров = 0 Тогда 196 | мИнтерфейс = ФункциональныеИнтерфейсы.Вызываемый(); 197 | ИначеЕсли КоличествоПараметров = 1 Тогда 198 | мИнтерфейс = ФункциональныеИнтерфейсы.УниФункция(); 199 | ИначеЕсли КоличествоПараметров = 2 Тогда // BSLLS:MagicNumber-off 200 | мИнтерфейс = ФункциональныеИнтерфейсы.БиФункция(); 201 | ИначеЕсли КоличествоПараметров = 3 Тогда // BSLLS:MagicNumber-off 202 | мИнтерфейс = ФункциональныеИнтерфейсы.ТриФункция(); 203 | КонецЕсли; // BSLLS:IfElseIfEndsWithElse-off 204 | 205 | Иначе 206 | 207 | Если КоличествоПараметров = 0 Тогда 208 | мИнтерфейс = ФункциональныеИнтерфейсы.Запускаемый(); 209 | ИначеЕсли КоличествоПараметров = 1 Тогда 210 | мИнтерфейс = ФункциональныеИнтерфейсы.УниПроцедура(); 211 | ИначеЕсли КоличествоПараметров = 2 Тогда // BSLLS:MagicNumber-off 212 | мИнтерфейс = ФункциональныеИнтерфейсы.БиПроцедура(); 213 | ИначеЕсли КоличествоПараметров = 3 Тогда // BSLLS:MagicNumber-off 214 | мИнтерфейс = ФункциональныеИнтерфейсы.ТриПроцедура(); 215 | КонецЕсли; // BSLLS:IfElseIfEndsWithElse-off 216 | 217 | КонецЕсли; 218 | 219 | Если Не ЗначениеЗаполнено(мИнтерфейс) Тогда 220 | 221 | Параметры = Новый Структура( 222 | "Выражение, ЭтоФункция, КоличествоПараметров", 223 | мВыражение, 224 | ЭтоФункция, 225 | КоличествоПараметров 226 | ); 227 | 228 | ВызватьИсключение Новый ИнформацияОбОшибке( 229 | "Невозможно определить функциональный интерфейс для лямбда выражения", 230 | Параметры 231 | ); 232 | 233 | КонецЕсли; 234 | 235 | КонецПроцедуры 236 | 237 | Функция СоздатьОбъект() 238 | 239 | МетодИнтерфейса = мИнтерфейс.ПолучитьКартуИнтерфейса()[0]; 240 | 241 | Метод = Новый Метод(МетодИнтерфейса.Имя) 242 | .Публичный() 243 | .ТелоМетода(РазобранноеВыражение.Тело); 244 | 245 | Если Не МетодИнтерфейса.ЭтоФункция Тогда 246 | Метод.ЭтоПроцедура(); 247 | КонецЕсли; 248 | 249 | Для Каждого Аннотация Из РазобранноеВыражение.Аннотации Цикл 250 | 251 | АннотацияМетода = Новый Аннотация(Аннотация.Имя); 252 | 253 | Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл 254 | АннотацияМетода.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя); 255 | КонецЦикла; 256 | 257 | Метод.Аннотация(АннотацияМетода); 258 | 259 | КонецЦикла; 260 | 261 | Для каждого Параметр Из РазобранноеВыражение.Параметры Цикл 262 | 263 | ПараметрМетода = Новый ПараметрМетода(Параметр.Имя); 264 | 265 | Для Каждого Аннотация Из Параметр.Аннотации Цикл 266 | 267 | АннотацияПараметра = Новый Аннотация(Аннотация.Имя); 268 | 269 | Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл 270 | АннотацияПараметра.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя); 271 | КонецЦикла; 272 | 273 | ПараметрМетода.Аннотация(АннотацияПараметра); 274 | 275 | КонецЦикла; 276 | 277 | Метод.Параметр(ПараметрМетода); 278 | 279 | КонецЦикла; 280 | 281 | Построитель = Новый ПостроительДекоратора(мОбъект) 282 | .Отладка(Отладка) 283 | .Поле(Новый Поле("Выражение").ЗначениеПоУмолчанию(мВыражение)) 284 | .Метод(Метод) 285 | .Метод( 286 | Новый Метод("ОбработкаПолученияПредставления") 287 | .ЭтоПроцедура() 288 | .Параметр(Новый ПараметрМетода("Представление")) 289 | .Параметр(Новый ПараметрМетода("СтандартнаяОбработка")) 290 | .ТелоМетода("СтандартнаяОбработка = Ложь; Представление = Выражение;") 291 | ); 292 | 293 | Контекст = ?(ЗначениеЗаполнено(мКонтекст), мКонтекст, Новый Структура()); 294 | 295 | Для каждого ПеременнаяИЗначение Из Контекст Цикл 296 | 297 | Построитель.Поле( 298 | Новый Поле(ПеременнаяИЗначение.Ключ) 299 | .ЗначениеПоУмолчанию(ПеременнаяИЗначение.Значение) 300 | ); 301 | 302 | КонецЦикла; 303 | 304 | Объект = Построитель.Построить(); 305 | 306 | Рефлектор = Новый РефлекторОбъекта(Объект); 307 | 308 | Рефлектор.РеализуетИнтерфейс(мИнтерфейс, Истина); 309 | 310 | Возврат Объект; 311 | 312 | КонецФункции 313 | 314 | Процедура ПриСозданииОбъекта(Выражение) 315 | 316 | РазобранноеВыражение = Новый Структура( 317 | "Аннотации, Параметры, Тело" 318 | ); 319 | 320 | мВыражение = Выражение; 321 | Отладка = Ложь; 322 | 323 | РазобратьВыражение(Выражение); 324 | 325 | КонецПроцедуры 326 | 327 | ЭтоЛямбдаВыражение = ЛямбдыКешируемыеЗначения.РегулярноеВыражениеЭтоЛямбдаВыражение(); 328 | СодержитВозвратЗначения = ЛямбдыКешируемыеЗначения.РегулярноеВыражениеСодержитВозвратЗначения(); 329 | -------------------------------------------------------------------------------- /src/Модули/Лямбда.os: -------------------------------------------------------------------------------- 1 | // Создаёт лямбда выражение из переданного выражения 2 | // 3 | // Параметры: 4 | // Выражение - Строка - Выражение из которого будет создано лямбда выражение 5 | // 6 | // Возвращаемое значение: 7 | // ЛямбдаВыражение - Созданное лямбда выражение 8 | // 9 | Функция Выражение(Выражение) Экспорт 10 | Возврат Новый ЛямбдаВыражение(Выражение); 11 | КонецФункции 12 | -------------------------------------------------------------------------------- /src/Модули/ФункциональныеИнтерфейсы.os: -------------------------------------------------------------------------------- 1 | #Использовать reflector 2 | #Использовать "../internal" 3 | 4 | Перем Вызываемый; // Кеш интерфейса Вызываемый 5 | Перем УниФункция; // Кеш интерфейса УниФункция 6 | Перем БиФункция; // Кеш интерфейса БиФункция 7 | Перем ТриФункция; // Кеш интерфейса ТриФункция 8 | Перем Запускаемый; // Кеш интерфейса Запускаемый 9 | Перем УниПроцедура; // Кеш интерфейса УниПроцедура 10 | Перем БиПроцедура; // Кеш интерфейса БиПроцедура 11 | Перем ТриПроцедура; // Кеш интерфейса ТриПроцедура 12 | 13 | // Возвращает интерфейс объекта содержащий функцию без параметров 14 | // 15 | // Возвращаемое значение: 16 | // ИнтерфейсОбъекта - Искомый интерфейс 17 | // 18 | Функция Вызываемый() Экспорт 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 | 139 | КонецФункции 140 | -------------------------------------------------------------------------------- /tasks/coverage.os: -------------------------------------------------------------------------------- 1 | #Использовать coverage 2 | #Использовать 1commands 3 | #Использовать fs 4 | 5 | СистемнаяИнформация = Новый СистемнаяИнформация; 6 | ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0; 7 | 8 | ФС.ОбеспечитьПустойКаталог(ОбъединитьПути("build", "coverage")); 9 | ПутьКСтат = "build/coverage/stat.json"; 10 | 11 | Команда = Новый Команда; 12 | Команда.УстановитьКоманду("oscript"); 13 | Если НЕ ЭтоWindows Тогда 14 | Команда.ДобавитьПараметр("-encoding=utf-8"); 15 | КонецЕсли; 16 | Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); 17 | Команда.ДобавитьПараметр("tasks/test.os"); 18 | Команда.ПоказыватьВыводНемедленно(Истина); 19 | 20 | КодВозврата = Команда.Исполнить(); 21 | 22 | ФайлСтатистики = Новый Файл(ПутьКСтат); 23 | 24 | ПроцессорГенерации = Новый ГенераторОтчетаПокрытия(); 25 | 26 | ПроцессорГенерации.ОтносительныеПути() 27 | .РабочийКаталог("build/coverage") 28 | .КаталогИсходников(ТекущийКаталог()) 29 | .ФайлСтатистики(ФайлСтатистики.ПолноеИмя) 30 | .GenericCoverage() 31 | .Cobertura() 32 | .Сформировать(); 33 | 34 | ЗавершитьРаботу(КодВозврата); 35 | -------------------------------------------------------------------------------- /tasks/oscript.cfg: -------------------------------------------------------------------------------- 1 | lib.system=../oscript_modules 2 | -------------------------------------------------------------------------------- /tasks/test.os: -------------------------------------------------------------------------------- 1 | #Использовать 1testrunner 2 | #Использовать fs 3 | 4 | Функция ПрогнатьТесты() 5 | 6 | Тестер = Новый Тестер; 7 | Тестер.УстановитьФорматЛогФайла(Тестер.ФорматыЛогФайла().GenericExec); 8 | Тестер.ПодробныеОписанияОшибок(Истина); 9 | 10 | ПутьКТестам = "tests"; 11 | ПутьКОтчетуJUnit = ОбъединитьПути("build", "testsResults"); 12 | 13 | ФС.ОбеспечитьПустойКаталог(ПутьКОтчетуJUnit); 14 | 15 | РезультатТестирования = Тестер.ТестироватьКаталог( 16 | Новый Файл(ПутьКТестам), 17 | Новый Файл(ПутьКОтчетуJUnit) 18 | ); 19 | 20 | Успешно = РезультатТестирования = 0; 21 | 22 | Возврат Успешно; 23 | 24 | КонецФункции // ПрогнатьТесты() 25 | 26 | // основной код 27 | 28 | ТекКаталог = ТекущийКаталог(); 29 | 30 | Попытка 31 | ТестыПрошли = ПрогнатьТесты(); 32 | Исключение 33 | ТестыПрошли = Ложь; 34 | Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно 35 | |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 36 | КонецПопытки; 37 | 38 | УстановитьТекущийКаталог(ТекКаталог); 39 | 40 | Если Не ТестыПрошли Тогда 41 | ВызватьИсключение "Тестирование завершилось неудачно!"; 42 | Иначе 43 | Сообщить(СтрШаблон("Результат прогона тестов <%1> 44 | |", ТестыПрошли)); 45 | КонецЕсли; 46 | -------------------------------------------------------------------------------- /tests/Лямбда.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | 3 | &Тест 4 | Процедура Выражение() Экспорт 5 | 6 | Ожидаем.Что(Лямбда.Выражение("(х) -> Сообщить(х)")) 7 | .ИмеетТип("ЛямбдаВыражение"); 8 | 9 | КонецПроцедуры 10 | 11 | &Тест 12 | Процедура НекорректноеВыражение() Экспорт 13 | 14 | Параметры = Новый Массив; 15 | Параметры.Добавить("Я не лямбда выражение"); 16 | 17 | Ожидаем.Что(Лямбда) 18 | .Метод("Выражение", Параметры) 19 | .ВыбрасываетИсключение("Переданное выражение не является лямбда выражением"); 20 | 21 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/ЛямбдаВыражение.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | #Использовать reflector 3 | 4 | Перем Рефлектор; // Рефлектор 5 | 6 | &Тест 7 | Процедура УстанавливаетсяИнтерфейс() Экспорт 8 | 9 | // Дано 10 | 11 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х"); 12 | 13 | // Когда 14 | 15 | ЛямбдаВыражение.Интерфейс( 16 | ФункциональныеИнтерфейсы.УниФункция() 17 | ); 18 | 19 | // Тогда 20 | 21 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 22 | .Равно(ФункциональныеИнтерфейсы.УниФункция()); 23 | 24 | КонецПроцедуры 25 | 26 | &Тест 27 | Процедура УстанавливаетсяПроизвольныйИнтерфейс() Экспорт 28 | 29 | // Дано 30 | 31 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х"); 32 | 33 | Интерфейс = Новый ИнтерфейсОбъекта(); 34 | Интерфейс.ФункцияИнтерфейса("Тест", 1); 35 | 36 | // Когда 37 | 38 | ЛямбдаВыражение.Интерфейс( 39 | Интерфейс 40 | ); 41 | 42 | // Тогда 43 | 44 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 45 | .Равно(Интерфейс); 46 | 47 | КонецПроцедуры 48 | 49 | &Тест 50 | Процедура ПриУстановкеИнтерфейсаПроверяетсяЧтоМногострочнаяФункцияДолжнаСодержатьВозврат() Экспорт 51 | 52 | // Дано 53 | 54 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> 55 | | х = х + 1; 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 | Контекст = Новый Структура("А", 1); 117 | 118 | // Когда 119 | 120 | ЛямбдаВыражение.Контекст(Контекст); 121 | 122 | // Тогда 123 | 124 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мКонтекст")) 125 | .Равно(Контекст); 126 | 127 | КонецПроцедуры 128 | 129 | &Тест 130 | Процедура ПроверкаТипаКонтекста() Экспорт 131 | 132 | // Дано 133 | 134 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х"); 135 | 136 | Параметры = Новый Массив; 137 | Параметры.Добавить(Новый Массив); 138 | 139 | // Тогда 140 | 141 | Ожидаем.Что(ЛямбдаВыражение) 142 | .Метод("Контекст", Параметры) 143 | .ВыбрасываетИсключение("Контекстом для лямбда выражения может выступать только структура"); 144 | 145 | КонецПроцедуры 146 | 147 | &Тест 148 | Процедура ОбъектЗахватывается() Экспорт 149 | 150 | // Дано 151 | 152 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х"); 153 | 154 | // Когда 155 | 156 | ЛямбдаВыражение.ЗахватитьОбъект(ЭтотОбъект); 157 | 158 | // Тогда 159 | 160 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мОбъект")) 161 | .Равно(ЭтотОбъект); 162 | 163 | КонецПроцедуры 164 | 165 | &Тест 166 | Процедура ОбъектСФункциейСоздаётся() Экспорт 167 | 168 | // Дано 169 | 170 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х") 171 | .Интерфейс(ФункциональныеИнтерфейсы.УниФункция()); 172 | 173 | // Когда 174 | 175 | Объект = ЛямбдаВыражение.ВОбъект(); 176 | 177 | // Тогда 178 | 179 | Ожидаем.Что(Объект.Применить(1)).Равно(1); 180 | 181 | КонецПроцедуры 182 | 183 | &Тест 184 | Процедура ОбъектСПроцедуройСоздаётся() Экспорт 185 | 186 | // Дано 187 | 188 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1") 189 | .Интерфейс(ФункциональныеИнтерфейсы.УниПроцедура()); 190 | 191 | // Когда 192 | 193 | Объект = ЛямбдаВыражение.ВОбъект(); 194 | 195 | // Тогда 196 | 197 | Проверка = 1; 198 | Объект.Принять(Проверка); 199 | 200 | Ожидаем.Что(Проверка).Равно(2); 201 | 202 | КонецПроцедуры 203 | 204 | &Тест 205 | Процедура ОбъектСКонтекстомСоздаётся() Экспорт 206 | 207 | // Дано 208 | 209 | Контекст = Новый Структура("А", 1); 210 | 211 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х + а") 212 | .Интерфейс(ФункциональныеИнтерфейсы.УниФункция()) 213 | .Контекст(Контекст); 214 | 215 | // Когда 216 | 217 | Объект = ЛямбдаВыражение.ВОбъект(); 218 | 219 | // Тогда 220 | 221 | Ожидаем.Что(Объект.Применить(2)).Равно(3); 222 | 223 | КонецПроцедуры 224 | 225 | &Тест 226 | Процедура ОбъектСЗахваченнымОбъектомСоздаётся() Экспорт 227 | 228 | // Дано 229 | 230 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х + ПубличноеПоле + ПриватноеПоле + Тест(4)") 231 | .Интерфейс(ФункциональныеИнтерфейсы.УниФункция()) 232 | .ЗахватитьОбъект(ЗахватываемыйОбъект()); 233 | 234 | // Когда 235 | 236 | Объект = ЛямбдаВыражение.ВОбъект(); 237 | 238 | // Тогда 239 | 240 | Ожидаем.Что(Объект.Применить(1)).Равно(10); 241 | 242 | КонецПроцедуры 243 | 244 | &Тест 245 | Процедура ОбъектСПроизвольнымИнтерфейсомСоздаётся() Экспорт 246 | 247 | // Дано 248 | 249 | Интерфейс = Новый ИнтерфейсОбъекта(); 250 | Интерфейс.ФункцияИнтерфейса("Тест", 1); 251 | 252 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х") 253 | .Интерфейс(Интерфейс); 254 | 255 | // Когда 256 | 257 | Объект = ЛямбдаВыражение.ВОбъект(); 258 | 259 | // Тогда 260 | 261 | Ожидаем.Что(Объект.Тест(2)).Равно(2); 262 | 263 | КонецПроцедуры 264 | 265 | &Тест 266 | Процедура ДействиеСоздаётся() Экспорт 267 | 268 | // Дано 269 | 270 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х") 271 | .Интерфейс(ФункциональныеИнтерфейсы.УниФункция()); 272 | 273 | // Когда 274 | 275 | Действие = ЛямбдаВыражение.ВДействие(); 276 | 277 | // Тогда 278 | 279 | Ожидаем.Что(Действие.Выполнить(1)).Равно(1); 280 | 281 | КонецПроцедуры 282 | 283 | &Тест 284 | Процедура ОпределяетсяИнтерфейсДляФункцииБезПараметров() Экспорт 285 | 286 | // Дано 287 | 288 | ЛямбдаВыражение = Новый ЛямбдаВыражение(" -> Возврат 1"); 289 | 290 | // Когда 291 | 292 | ЛямбдаВыражение.ВОбъект(); 293 | 294 | // Тогда 295 | 296 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 297 | .Равно(ФункциональныеИнтерфейсы.Вызываемый()); 298 | 299 | КонецПроцедуры 300 | 301 | &Тест 302 | Процедура ОпределяетсяИнтерфейсДляФункцииСОднимПараметром() Экспорт 303 | 304 | // Дано 305 | 306 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат х"); 307 | 308 | // Когда 309 | 310 | ЛямбдаВыражение.ВОбъект(); 311 | 312 | // Тогда 313 | 314 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 315 | .Равно(ФункциональныеИнтерфейсы.УниФункция()); 316 | 317 | КонецПроцедуры 318 | 319 | &Тест 320 | Процедура ОпределяетсяИнтерфейсДляФункцииСДвумяПараметрами() Экспорт 321 | 322 | // Дано 323 | 324 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х, у -> Возврат х"); 325 | 326 | // Когда 327 | 328 | ЛямбдаВыражение.ВОбъект(); 329 | 330 | // Тогда 331 | 332 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 333 | .Равно(ФункциональныеИнтерфейсы.БиФункция()); 334 | 335 | КонецПроцедуры 336 | 337 | &Тест 338 | Процедура ОпределяетсяИнтерфейсДляФункцииСТремяПараметрами() Экспорт 339 | 340 | // Дано 341 | 342 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х, у, а -> Возврат х"); 343 | 344 | // Когда 345 | 346 | ЛямбдаВыражение.ВОбъект(); 347 | 348 | // Тогда 349 | 350 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 351 | .Равно(ФункциональныеИнтерфейсы.ТриФункция()); 352 | 353 | КонецПроцедуры 354 | 355 | &Тест 356 | Процедура ОпределяетсяИнтерфейсДляПроцедурыБезПараметров() Экспорт 357 | 358 | // Дано 359 | 360 | ЛямбдаВыражение = Новый ЛямбдаВыражение(" -> X = 1 = 1"); 361 | 362 | // Когда 363 | 364 | ЛямбдаВыражение.ВОбъект(); 365 | 366 | // Тогда 367 | 368 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 369 | .Равно(ФункциональныеИнтерфейсы.Запускаемый()); 370 | 371 | КонецПроцедуры 372 | 373 | &Тест 374 | Процедура ОпределяетсяИнтерфейсДляПроцедурыСОднимПараметром() Экспорт 375 | 376 | // Дано 377 | 378 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х"); 379 | 380 | // Когда 381 | 382 | ЛямбдаВыражение.ВОбъект(); 383 | 384 | // Тогда 385 | 386 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 387 | .Равно(ФункциональныеИнтерфейсы.УниПроцедура()); 388 | 389 | КонецПроцедуры 390 | 391 | &Тест 392 | Процедура ОпределяетсяИнтерфейсДляПроцедурыСДвумяПараметрами() Экспорт 393 | 394 | // Дано 395 | 396 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х, у -> х = х + у"); 397 | 398 | // Когда 399 | 400 | ЛямбдаВыражение.ВОбъект(); 401 | 402 | // Тогда 403 | 404 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 405 | .Равно(ФункциональныеИнтерфейсы.БиПроцедура()); 406 | 407 | КонецПроцедуры 408 | 409 | &Тест 410 | Процедура ОпределяетсяИнтерфейсДляПроцедурыСТремяПараметрами() Экспорт 411 | 412 | // Дано 413 | 414 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х, у, а -> х = х + у + а"); 415 | 416 | // Когда 417 | 418 | ЛямбдаВыражение.ВОбъект(); 419 | 420 | // Тогда 421 | 422 | Ожидаем.Что(Рефлектор.ПолучитьСвойство(ЛямбдаВыражение, "мИнтерфейс")) 423 | .Равно(ФункциональныеИнтерфейсы.ТриПроцедура()); 424 | 425 | КонецПроцедуры 426 | 427 | &Тест 428 | Процедура ИсключениеПриНевозможностиПодобратьИнтерфейс() Экспорт 429 | 430 | // Дано 431 | 432 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х, у, а, б -> х = х + у + а + б"); 433 | 434 | // Когда 435 | 436 | // Тогда 437 | 438 | Ожидаем.Что(ЛямбдаВыражение) 439 | .Метод("ВОбъект") 440 | .ВыбрасываетИсключение("Невозможно определить функциональный интерфейс для лямбда выражения"); 441 | 442 | КонецПроцедуры 443 | 444 | &Тест 445 | Процедура АннотированныеПараметры() Экспорт 446 | 447 | // Дано 448 | ЛямбдаВыражение = Новый ЛямбдаВыражение( 449 | "&АннотацияБезПараметра 450 | |&Аннотация('20200101') 451 | |&Аннотация(Значение = Истина, Параметра = 1) 452 | |( 453 | | &АннотацияБезПараметра x, 454 | | &Аннотация(Значение = ""С двумя"", Параметра = ""ми"") y, 455 | | &АннотацияБезПараметра &Аннотация(""с одним параметром"") 456 | | &Аннотация(Значение = ""С двумя"", Параметра = ""ми"") 457 | | z 458 | |) -> 459 | | Возврат x+y+z" 460 | ); 461 | 462 | // Когда 463 | Объект = ЛямбдаВыражение.ВОбъект(); 464 | 465 | // Тогда 466 | 467 | Методы = Рефлектор.ПолучитьТаблицуМетодов(Объект); 468 | 469 | Метод = Методы.Найти("Применить", "Имя"); 470 | 471 | Ожидаем.Что(Метод).Существует(); 472 | 473 | Ожидаем.Что(Метод.КоличествоПараметров).Равно(3); 474 | Ожидаем.Что(Метод.Аннотации.Количество()).Равно(3); 475 | 476 | Аннотация = Метод.Аннотации[0]; 477 | 478 | Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра"); 479 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0); 480 | 481 | Аннотация = Метод.Аннотации[1]; 482 | 483 | Ожидаем.Что(Аннотация.Имя).Равно("Аннотация"); 484 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(1); 485 | Ожидаем.Что(Аннотация.Параметры[0].Имя).ЭтоНеопределено(); 486 | Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно('20200101'); 487 | 488 | Аннотация = Метод.Аннотации[2]; 489 | 490 | Ожидаем.Что(Аннотация.Имя).Равно("Аннотация"); 491 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2); 492 | Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение"); 493 | Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно(Истина); 494 | Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра"); 495 | Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно(1); 496 | 497 | Параметр = Метод.Параметры[0]; 498 | 499 | Ожидаем.Что(Параметр.Имя).Равно("x"); 500 | 501 | Аннотация = Параметр.Аннотации[0]; 502 | 503 | Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра"); 504 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0); 505 | 506 | Параметр = Метод.Параметры[1]; 507 | 508 | Ожидаем.Что(Параметр.Имя).Равно("y"); 509 | 510 | Аннотация = Параметр.Аннотации[0]; 511 | 512 | Ожидаем.Что(Аннотация.Имя).Равно("Аннотация"); 513 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2); 514 | Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение"); 515 | Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("С двумя"); 516 | Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра"); 517 | Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно("ми"); 518 | 519 | Параметр = Метод.Параметры[2]; 520 | 521 | Ожидаем.Что(Параметр.Имя).Равно("z"); 522 | 523 | Аннотация = Параметр.Аннотации[0]; 524 | 525 | Ожидаем.Что(Аннотация.Имя).Равно("АннотацияБезПараметра"); 526 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(0); 527 | 528 | Аннотация = Параметр.Аннотации[1]; 529 | 530 | Ожидаем.Что(Аннотация.Имя).Равно("Аннотация"); 531 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(1); 532 | Ожидаем.Что(Аннотация.Параметры[0].Имя).ЭтоНеопределено(); 533 | Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("с одним параметром"); 534 | 535 | Аннотация = Параметр.Аннотации[2]; 536 | 537 | Ожидаем.Что(Аннотация.Имя).Равно("Аннотация"); 538 | Ожидаем.Что(Аннотация.Параметры.Количество()).Равно(2); 539 | Ожидаем.Что(Аннотация.Параметры[0].Имя).Равно("Значение"); 540 | Ожидаем.Что(Аннотация.Параметры[0].Значение).Равно("С двумя"); 541 | Ожидаем.Что(Аннотация.Параметры[1].Имя).Равно("Параметра"); 542 | Ожидаем.Что(Аннотация.Параметры[1].Значение).Равно("ми"); 543 | 544 | Ожидаем.Что(Объект.Применить(1, 2, 3)).Равно(6); 545 | 546 | КонецПроцедуры 547 | 548 | &Тест 549 | Процедура ФигурнаяСкобкаВнутриВыраженияНеЛомаетЛямбду() Экспорт 550 | 551 | // Дано 552 | 553 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> Возврат ""{"" + х + ""}"" }"); 554 | 555 | // Когда 556 | 557 | Результат = ЛямбдаВыражение.ВОбъект().Применить("1"); 558 | 559 | // Тогда 560 | 561 | Ожидаем.Что(Результат).Равно("{1}"); 562 | 563 | КонецПроцедуры 564 | 565 | &Тест 566 | Процедура ПредставлениеПереопределяется() Экспорт 567 | 568 | // Дано 569 | 570 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1"); 571 | 572 | // Когда 573 | 574 | Результат = Строка(ЛямбдаВыражение.ВОбъект()); 575 | 576 | // Тогда 577 | 578 | Ожидаем.Что(Результат).Равно("х -> х = х + 1"); 579 | 580 | КонецПроцедуры 581 | 582 | &Тест 583 | Процедура ОбъектыЛямбдаВыраженийКешируются() Экспорт 584 | 585 | // Дано 586 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1"); 587 | Объект = ЛямбдаВыражение.ВОбъект(); 588 | 589 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1"); 590 | 591 | // Когда 592 | Результат = ЛямбдаВыражение.ВОбъект(); 593 | 594 | // Тогда 595 | Ожидаем.Что(Результат).Равно(Объект); 596 | 597 | КонецПроцедуры 598 | 599 | &Тест 600 | Процедура ОбъектыЛямбдаВыраженийВытесняютсяИзКеша() Экспорт 601 | 602 | // Дано 603 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1"); 604 | Объект = ЛямбдаВыражение.ВОбъект(); 605 | 606 | Для Сч = 2 По 22 Цикл // Вытесним из кеша 607 | _ = Новый ЛямбдаВыражение("х -> х = х + " + Сч) 608 | .ВОбъект(); 609 | КонецЦикла; 610 | 611 | ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1"); 612 | 613 | // Когда 614 | Результат = ЛямбдаВыражение.ВОбъект(); 615 | 616 | // Тогда 617 | Ожидаем.Что(Результат).Не_().Равно(Объект); 618 | 619 | КонецПроцедуры 620 | 621 | Функция ЗахватываемыйОбъект() 622 | 623 | Возврат Новый ПостроительДекоратора() 624 | .Метод( 625 | Новый Метод("Тест") 626 | .Публичный() 627 | .Параметр(Новый ПараметрМетода("Тест")) 628 | .ТелоМетода("Возврат Тест") 629 | ).Поле( 630 | Новый Поле("ПубличноеПоле") 631 | .Публичное() 632 | .ЗначениеПоУмолчанию(2) 633 | ).Поле( 634 | Новый Поле("ПриватноеПоле") 635 | .ЗначениеПоУмолчанию(3) 636 | ).Построить(); 637 | 638 | КонецФункции 639 | 640 | Рефлектор = Новый Рефлектор; 641 | -------------------------------------------------------------------------------- /tests/ФункциональныеИнтерфейсы.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | 3 | &Тест 4 | Процедура Вызываемый() Экспорт 5 | 6 | Ожидаем.Что(ФункциональныеИнтерфейсы.Вызываемый()) 7 | .ИмеетТип("ИнтерфейсОбъекта") 8 | .Равно(ФункциональныеИнтерфейсы.Вызываемый()); 9 | 10 | КонецПроцедуры 11 | 12 | &Тест 13 | Процедура УниФункция() Экспорт 14 | 15 | Ожидаем.Что(ФункциональныеИнтерфейсы.УниФункция()) 16 | .ИмеетТип("ИнтерфейсОбъекта") 17 | .Равно(ФункциональныеИнтерфейсы.УниФункция()); 18 | 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 | --------------------------------------------------------------------------------