Перейти к основному содержимому
Версия: 5.x

Метапрограммирование

Метапрограммирование - это вид программирования, связанный с написанием программного кода, который в качестве результата порождает другой программный код. Метапрограммирование используется для повторной используемости кода и ускорения времени разработки.

Метакод

В языке lsFusion в качестве средства метапрограммирования используется метакод, который описывается инструкцией META. Метакод состоит из заголовка и блока кода на языке lsFusion, описывающего последовательность инструкций. Этот блок кода должен завершаться ключевым словом END. Рассмотрим пример метакода, который позволяет добавить на произвольную форму два действия:

META addActions(formName)
EXTEND FORM formName
PROPERTIES() showMessage, closeForm
;
END

В первой строке приведенного примера находится заголовок метакода. Он состоит из ключевого слова META, имени метакода и списка параметров. В данном примере метакод addActions имеет один параметр formName. Это имя формы, на которую будут добавлены действия. Рассмотрим возможные варианты использования этого метакода, которые описываются инструкцией @.

@addActions(documentForm);
@addActions(orderForm);

Инструкция использования метакода обозначается специальным символом @, затем идет имя метакода и передаваемые параметры. При генерации кода каждый параметр метакода будет заменен на значение, передаваемое в качестве параметра инструкции @, во всех местах использования параметра метакода. В данном примере параметр метакода formName будет заменяться на documentForm и на orderForm. Приведенные выше использования метакода порождают следующий блок кода:

EXTEND FORM documentForm
PROPERTIES() showMessage, closeForm
;

EXTEND FORM orderForm
PROPERTIES() showMessage, closeForm
;

Объединение лексем

Простой подстановки идентификатора вместо параметра метакода часто бывает недостаточно. Например, при создании большого количества новых элементов системы внутри метакода нужно иметь возможность задавать эти новые имена. Передавать все имена в качестве параметров метакода бывает неудобно. Поэтому в метакоде существует специальная операция ##, которая работает на уровне лексем. Эта операция может объединить две соседние лексемы в одну. Если же одна из объединяемых лексем является строковым литералом, то результатом объединения будет один строковый литерал.

META objectProperties(object, caption)
object##Name 'Имя '##caption = DATA BPSTRING[100](object);
object##Type 'Тип '##caption = DATA Type (object);
object##Value 'Стоимость '##caption = DATA INTEGER (object);
END

@objectProperties(Document, 'документа');

Результатом использования метакода objectProperties будет следующий код:

DocumentName 'Имя документа' = DATA BPSTRING[100](Document);
DocumentType 'Тип документа' = DATA Type (Document);
DocumentValue 'Стоимость документа' = DATA INTEGER (Document);

Также существует специальная операция ###, эквивалентная операции ##, за исключением того, что во втором из объединяемых литералов первый символ, если он является буквой, переводится в верхний регистр.

Примеры

META objectProperties(object, type, caption)
object##Name 'Имя'##caption = DATA BPSTRING[100](###object); // делаем заглавной первую букву
object##Type 'Тип'##caption = DATA type (###object);
object##Value 'Стоимость'##caption = DATA INTEGER (###object);
END

META objectProperties(object, type)
@objectProperties(object, type, '');
END