Как процитировать имя класса, не работает FullName
От: Ilya10k Россия  
Дата: 13.02.10 20:37
Оценка:
Добрый день.
В очередной раз пытаюсь использовать Nemerle. Nemerle — это вещь! Удалось заменить кучу C# кода макросом.
Но столкнулся с рядом сложностей и багов. Некоторые баги уже есть в багтрекере (например, довольно неприятным оказался http://nemerle.rsdn.ru/bugs/view.php?id=818 : Cannot implement an interface twice with different type parameters). А вот эту проблему не нашел:

Вопрос в том как правильно процитировать имя класса, пространство которого неоткрыто в месте использования. Привожу упрощенный пример, как я реально пытался это использовать:
Нижеприведенный код выдает ошибку при компиляции сборки:
ItemsCollection.n:6:3:6:23: <[01;31merror<[0m: unbound name `Project.Items.SimpleItem'

Если же в классе, где используется макрос указать using и использовать вместо FullName — Name (закоментаренные строки), то все работает.

IItem.n
namespace Project.Items
{
    public interface IItem
    {
    }
}

SimpleItem.n
namespace Project.Items
{
    public class SimpleItem : IItem
    {
        public static GetTypeName() : string
        {
            "SimpleItem"
        }
    }
}

ItemsCollection.n
using ProjectMacro;
//using Project.Items;

namespace Project
{
    [ItemsCollectionMacro]
    public class ItemsCollection
    {        
    }
}

ItemsCollectionMacro.n
using System;
using System.Collections.Generic;
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;

namespace ProjectMacro
{
    [Nemerle.MacroUsage (Nemerle.MacroPhase.WithTypedMembers, Nemerle.MacroTargets.Class)]
    macro ItemsCollectionMacro(builder : TypeBuilder)
    {
        def typer = Macros.ImplicitCTX();
        def typeBuilders = typer.Env.NameTree.NamespaceTree.GetTypeBuilders();
        def types = typeBuilders.Filter(tb => !tb.IsInterface && tb.GetMemType().TryRequire(<[ ttype : Project.Items.IItem ]>));

        def items = types.Map(tb => <[ $(tb.FullName : usesite).GetTypeName() ]>);
        //def items = types.Map(tb => <[ $(tb.Name : usesite).GetTypeName() ]>);

        builder.Define(
        <[
            decl: public GetTypes() : IEnumerable[string]
            {
                array[.. $items]
            }
        ]>);
    }
}

build.cmd
ncc -target:library -r Nemerle.Macros.dll -out:ItemsCollectionMacro.dll ItemsCollectionMacro.n
ncc -target:library -r ItemsCollectionMacro.dll -out:Items.dll IItem.n ItemsCollection.n SimpleItem.n
... << RSDN@Home 1.2.0 alpha 4 rev. 1238>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.