Re[4]: Макрос изменяющий базовый тип класс - как? (если возм
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.05.07 19:06
Оценка: 6 (1)
Здравствуйте, 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.