Докомпиляция интерфейсов |
Докомпиляция интерфейсов целиком основана на механизме наследования vip-интерфейсов. Основное отличие состоит в том, что в новом интерфейсе невозможно добавление новых public-функций, разрешается только перегрузка существующих, а также расширение логических таблиц и обработчиков событий.
Для докомпиляции интерфейса необходимо наличие в ресурсе символьной информации (так же как и для наследования). Включение необходимой информации в ресурс управляется параметром Compilers.InhSaveLevel.
По умолчанию в ресурс включается символьная информация из интерфейсов, для которых имеется оператор vipInterface.
Если задать Compilers.InhSaveLevel = 3, то символьная информация будет генерироваться для всех интерфейсов. Однако надо помнить, что запись символьной информации для каждого интерфейса сильно увеличит размер ресурсного файла.
Докомпилировать можно только те элементы интерфейса (методы, потоки и т.д.), для которых указан квалификатор public и есть символьная информация в ресурсе.
Описание докомпиляции похоже на описание интерфейса, но добавляются ключевые слова alter и fix:
<докомпиляция-интерфейса> = alter interface <имя-интерфейса> [ ( [ fix ] <служебная-информация> ) ] <элемент-докомпиляции> { <элемент-докомпиляции> } end.
Ключевое слово fix означает исправление ошибки и смысловой нагрузки не несёт.
<элемент-докомпиляции> - перегрузка методов или потоков данных, а также расширение логических таблиц и обработчиков событий. Перегружаемые методы описываются в секции overload, которая должна быть описана сразу после параметров интерфейса.
<элемент-докомпиляции> = overload <перекрытый-элемент> { <перекрытый-элемент> } end; | <расширение-логической-таблицы> | <расширение-обработчика-событий>
<перекрытый-элемент> - объявление перекрытых потока данных, функции или процедуры. Соответствующая реализация приводится в теле интерфейса, за пределами секции overload.
<перекрытый-элемент> = datastream <имя-потока-данных> ; | <перегрузка-функции> | <перегрузка-процедуры>
Конструкция datastream <имя-потока-данных> объявляет расширяемый поток данных. Реализация расширяемого потока в основном описывается так же, как и реализация исходного потока (см. "Реализация потока данных. "). Но в описании элемента потока добавляется ключевое слово inherited:
<элемент-потока> = [ [ <имя-поля> ] ] <выражение> ; | table <имя-таблицы> [ onClick ( <ключевое-поле> ) ] ( <элемент-потока> {, <элемент-потока> } ) ; | table inherited::<имя-таблицы-предка> ( <элемент-потока> {, <элемент-потока> } ) ; | dataset <имя-датасета> [ onClick (<ключевое-поле>) ] ( <элемент-потока> {, <элемент-потока> } ) ; | dataset inherited::<имя-датасета-предка> ( <элемент-потока> {, <элемент-потока> } ) ;
<имя-поля> - уникальное для элемента потока имя поля, доступное в генераторе отчётов и т.д. Хотя указание имени поля необязательно, рекомендуется всегда указывать его. В случае, если имя не указано - полю будет автоматически присвоено сгенерированное имя и компилятор выдаст предупреждение.
<выражение> - вычисляемое выражение в текущем контексте.
<имя-таблицы> - уникальное в пределах потока данных имя элемента потока. Должно соответствовать имени одной из таблиц интерфейса. Не должно совпадать ни с одним из имён потока данных-предка. Для использования в генераторе отчётов и т.д.
<имя-датасета> - уникальное в пределах потока данных имя элемента потока. Не должно совпадать ни с одним из имён потока данных-предка. Для использования в генераторе отчётов и т.д.
<ключевое-поле> - поле элемента потока, значение которого используется для навигации. При обработке событий номер поля можно взять из переменной Target, а значение ключевого поля - из переменной ExprFieldValue. По значению ключевого поля можно выяснить текущую запись элемента потока. Ключевое поле должно быть соответствующим образом описано.
<имя-таблицы-предка> - уникальное в пределах потока данных имя элемента потока. Должно соответствовать имени одной из таблиц интерфейса и совпадать с именем расширяемого элемента потока данных-предка.
<имя-датасета-предка> - уникальное в пределах потока данных имя элемента потока. Должно совпадать с именем расширяемого элемента потока данных-предка.
<перегрузка-функции> - объявление перекрываемой функции. Синтаксис описания такой же, как и при наследовании.
<перегрузка-процедуры> - объявление перекрываемой процедуры. Синтаксис описания такой же, как и при наследовании.
<расширение-логической-таблицы> - см. "Расширение логических таблиц. ".
<расширение-обработчика-событий> - см. "Расширение обработчиков событий. ".
Ограничение Докомпиляция интерфейса должна проводится в ресурс, отличный от того, откуда загружается докомпилируемый интерфейс.
Пример 1. Перегрузка функции и расширение обработчика событий.
alter interface vTest (fix 'исправление грамматической ошибки') 'Проверка'; overload function iTest.Func1 ( var vUglUskR : integer ) : boolean; end; function iTest.Func1 ( var vUglUskR : integer ) : boolean; { result := false; if (inherited :: Func1 (vUglUskR)) then ... } handleEvent cmValue19: { ... inherited :: handleEvent (cmValue18); ... } end; end.
Пример 2. Расширение потока данных.
Создадим файл dstream2.vip (докомпилируемый интерфейс должен находиться в другом исходном файле, относительно оригинального):
// -- dstream2.vip -- #include dstream.vih alter interface SampleInterface2; create view as select * from x$files; dataStream SampleStream ( // Изменение существующего элемента потока table inherited::x$files ( [ SMPLTXT2 ] "Поле xf$name: " + xf$name; ); // Добавление в поток данных нового элемента table x$users ( [ SMPLNAME ] xu$loginname; ); ) end; end.
Атлантис 5.0.
Расширение потоков данных введено начиная с Атлантис 5.1.2x.