Реализация дерева интерфейсов макросом
От: Saidai no  
Дата: 19.11.11 08:20
Оценка:
Добрый день!

Я пытаюсь написать (точнее, пока что — представить :) макрос, который генерирует набор прокси-объектов, реализующих требуемый интерфейс.
Чтобы это не выглядело слишком абстрактно, собственно задача: есть обертка WebKit для Mac (Monobjc.WebKit) и для Gtk (webkit-sharp, с шаманством для работы на последних версиях), которые, понятное дело, несовместимы. И есть сгенерированный мной по idl набор интерфейсов DOM (спасибо за парсер C#; наверное, генерить макросами было бы круче, но пока и так хватает работы :). Нужно получить в каждой из сборок прокси-объекты, реализующие эти интерфейсы насколько это возможно автоматически. Проблема осложняется тем, что для Mac используются обертки нативных типов для всего (строк, в частности). Некоторые вещи, наверняка, придется дописывать руками (например, работу с callback-ами), потому что там слишком уж принципиальная разница.

Пока что я представляю себе реализацию себе так:
1. Макрос уровня сборки ImplementInterface, который принимает исходный тип, тип интерфейса и куски реализации, прописанные руками. Создает тип-прокси, делает в нем конструктор от исходного типа, записывает куски реализации и каким-то образом (?) дописывает автоматически методы, которые не были предоставлены пользователем.
2. Макрос для метода ImplementInterface, который пытается с помощью изменения регистра и добавления/удаления префиксов найти подходящий метод в исходном классе и подключить его. Если метод не найден, выводит warning и подставляет throw NotImplementedException.
3. Макрос уровня выражения proxy, который подставляет конструктор нужного типа в тех местах, где нужно вернуть DOM-интерфейсы в другую сборку.

Соответственно, у меня такие вопросы:
1. Правильно ли я понимаю, что создавать тип, который может использоваться в пользовательском коде, и добавлять в него методы можно только на этапе BeforeInheritance?
2. Если это так, то каким образом вообще можно получить информацию о том, какие интерфейсы требует реализовать заданный, какие у них требуемые методы и как предоставленные пользователем реализации, например, свойств сопоставлять интерфейсу, чтобы сообразить, какие методы дописывать?
3. В Monobjc вместо строк используются обертки нативных NSString, для которых определен implicit-оператор для string в обе стороны. Можно ли как-то опознать наличие такого оператора (видимо, информация в наличии — возвращаемый тип метода, название которого подходит для интерфейса и требуемый интерфейсом возвращаемый тип)?
4. Некоторые методы интерфейсов требуют возвращать другие интерфейсы, для которых хорошо бы уметь автоматически подставлять proxy. Как можно это реализовать? Все интерфейсы лежать в отдельной от прокси-объектов сборке в своем неймспейсе.
5. Откуда proxy может знать кому какой прокси сопоставлен? Можно ли в макро-сборке держать какую-то информацию в статических переменных, которая будет использоваться как разделяемая между макросами? Может ли макрос уровня выражения выполняться на последней стадии, когда вся информация уже есть?

Ну и главный вопрос — насколько это реально и сложно? Не стоит ли пока забить на это и воспользоваться пока что для разработки "планом Б" — макрос для типа "ForceNotImplemented", который для всех нереализованных методов интерфейсов выводит warning и подставляет заглушку? Потому что главное, все-таки, это код, который дальше будет работать с DOM, и ему пока очень небольшая часть методов нужна.

Спасибо за внимание! :)

P.S. Кстати, на тему моего предыдущего вопроса: компилятор собирается Mono с патчем, который был предложен в моновской багзилле еще давно, но дальше, уже при работе компилятора, mono начинает падать в каких-то странных местах. Так что если у кого-то есть необходимость собирать компилятор с mono, можно держать отдельно локальную версию mono "для сборки" :)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.