Как искать и сравнивать типы?
От: STDray http://stdray.livejournal.com
Дата: 25.11.15 18:14
Оценка:
Здравствуйте!


1. Допустим у меня есть алаис для неймспейса
using A = Some.Very.Very.Long.Namespace;

и есть упоминание типа из этого неймпейса
A.SomeType

Мне надо по строке "A.SomeType" (или по выражению A.SomeType) получить соответствующий тип (TypeInfo). Вызов LookupType ничего не находит.
      match(typer.Env.LookupType(name.SplitToList(array['.']), typer.CurrentTypeBuilder, 0))
      {
        | Some(t) => t
        | None => Message.FatalError(expr.Location, $"Type $name not found");
      }

Как в данном случае можно получить TypeInfo?


2. У меня есть результат типизации выражения exprType (FixedType, а в нем есть TypeInfo) и есть информация о типе someTypeInfo (TypeInfo).
Мне надо узнать, что тип моего exprType равен someTypeInfo или является его потомком.
По сути мне надо как-то сравнить два объекта TypeInfo.
Сейчас это сделано следующим образом
    public IsSubtype(ty : TypeInfo, super : TypeInfo) : bool
    {
      if(ty.Equals(super) || ty.HasSuperType(super))
        true
      else if(GetTypeAlias(ty) is Some(alias))
        IsSubtype(alias, super)
      else if(GetTypeAlias(super) is Some(alias))
        IsSubtype(ty, alias)
      else 
        false;
    }
    
    public GetTypeAlias(t1 : TypeInfo) : option[TypeInfo]
    {
      if(t1.SystemType != null && t1.SystemType.IsDefined(SystemTypeCache.TypeAliasAttribute, false))
      {
        def attr = t1.SystemType.GetCustomAttributes(SystemTypeCache.TypeAliasAttribute, false)[0];
        def type = late(attr.AliasedType) :> string;
        Some(Manager.Lookup(type.TrimEnd('(', ')')));
      }
      else 
        None()
    }

Я подозреваю, что руками проверять наличие TypeAliasAttribute и потом через рефлексию вытаскивать из него тип, на который он ссылается неправильно.
Как это должно делаться по-хорошему?
Отредактировано 25.11.2015 18:20 STDray . Предыдущая версия .
Re: Как искать и сравнивать типы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.11.15 19:42
Оценка: 4 (1)
Здравствуйте, STDray, Вы писали:

STD>Как в данном случае можно получить TypeInfo?


Проще всего типизировать выражение с помощью typer.TypeExpr(), а потом взять тип (свойство Type у результата типизации).

STD>2. У меня есть результат типизации выражения exprType (FixedType, а в нем есть TypeInfo) и есть информация о типе someTypeInfo (TypeInfo).

STD>Мне надо узнать, что тип моего exprType равен someTypeInfo или является его потомком.
STD>По сути мне надо как-то сравнить два объекта TypeInfo.

STD>Как это должно делаться по-хорошему?


Создать из someTypeInfo FixedType и пользоваться его метод TryRequire или Require, если точно установлено, что такая зависимость между типами должна существовать (если это не так будет выдано сообщение об ошибке).
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Как искать и сравнивать типы?
От: STDray http://stdray.livejournal.com
Дата: 25.11.15 21:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Проще всего типизировать выражение с помощью typer.TypeExpr(), а потом взять тип (свойство Type у результата типизации).

У меня, грубо говоря, такое выражение на входе в макрос
@my_macro(A.SomeType)

Разве типизатор сможет найти его типизировать?

VD>Создать из someTypeInfo FixedType и пользоваться его метод TryRequire или Require, если точно установлено, что такая зависимость между типами должна существовать (если это не так будет выдано сообщение об ошибке).

По-моему, я изначально так и пытался делать, но споткнулся на том, что TryRequire для Nemerle.int (алиас) и System.Int32 всегда возвращал ложь.
Re[3]: Как искать и сравнивать типы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.11.15 01:11
Оценка:
Здравствуйте, STDray, Вы писали:

STD>У меня, грубо говоря, такое выражение на входе в макрос

STD>
STD>@my_macro(A.SomeType)
STD>

STD>Разве типизатор сможет найти его типизировать?

Смотря что такое SomeType. Если имя не перегружено, сможет. А там смотреть надо.

STD>По-моему, я изначально так и пытался делать, но споткнулся на том, что TryRequire для Nemerle.int (алиас) и System.Int32 всегда возвращал ложь.


Это вряд ли. Иначе нечего бы на работало.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Как искать и сравнивать типы?
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.11.15 04:32
Оценка:
Здравствуйте, VladD2, Вы писали:

STD>>По-моему, я изначально так и пытался делать, но споткнулся на том, что TryRequire для Nemerle.int (алиас) и System.Int32 всегда возвращал ложь.


Откуда у тебя появляется Nemerle.int?

В общем, лучше покажи код. Разберемся.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Как искать и сравнивать типы?
От: STDray http://stdray.livejournal.com
Дата: 30.11.15 15:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Откуда у тебя появляется Nemerle.int?

Приходил в результате вызова (при name = "int")
typer.Env.LookupType(name.SplitToList(array['.']), typer.CurrentTypeBuilder, 0)



VD>В общем, лучше покажи код. Разберемся.

А я разобрался. Сделал финт ушами, отправив на типизацию не само переданное выражение, а вот такую его производную
          def varExpr = <[ mutable x : $t; x ]>;
          def varType = typer.TypeExpr(varExpr);

И потом уже через TryRequire сопоставляю типы. Всё заработало отлично. Ручное сравнение типов и работу с алиасами удалил.

Спасибо, за совет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.