Здравствуйте, ie, Вы писали:
А>>Необходимо для подготовки типа представления (view type — из MVC) базовый тип хотелось менять динамически (на этапе компиляции) чтобы была возможность исходя из контекста использовать, скажем: System.Windows.Forms.Form или System.Windows.Forms.UserControl
ie>Хммм... Похоже что нельзя задать в макросе базовый класс, даже если он не был указан ранее. Покопаю еще, но пока мне не представляется это возможным.
Вы плохого мнения о макросах Немерле

.
Все можно. Даже можно старый класс убрать, а новый добавить. Вот только делать это нужно иключительно на стадии MacroPhase.BeforeInheritance. Вот за 5 минут набросал тестик...
Код макро-сборки:
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
namespace Test
{
[Nemerle.MacroUsage (Nemerle.MacroPhase.BeforeInheritance, Nemerle.MacroTargets.Class, Inherited = true)]
public macro View(tb : TypeBuilder, classname)
syntax("view", classname)
{
def ast = tb.Ast :> TopDeclaration.Class;
ast.t_extends ::= classname;
}
}
Код тестового приложения:
using System.Console;
using Test;
class A { public Method1() : void { WriteLine("A.Method1()") } }
class B view A { }
module Program
{
Main() : void
{
def b = B();
b.Method1();
_ = ReadLine();
}
}
Вся суть заключается в том, что на стадии BeforeInheritance код из AST еще не прошел этап типизации и типизированное описание не было добавлено в структуры TypeBuilder-а. AST доступно через свойство Ast (только в современной версии компилятора), так что мы можем его изменять (в том числе анализировать и выбрасывать ненужное наследовние или выдавать сообщения об ошибках если таковое присутствует).
ЗЫ
Небольшой хинт. Создание макросов радикально упрощается если использовать интеграцию. Проблема только в том, что комплит пока что не работает внутри самих макросов. Но из макроса можно вызвать метод-помошник в котором комплит будет пработать как надо. Именно так я и сделал, а потом перенес код мароса непосредственно в его тело (для краткости).
... << RSDN@Home 1.2.0 alpha rev. 637>>