Информация об изменениях

Сообщение Как искать и сравнивать типы? от 25.11.2015 18:14

Изменено 25.11.2015 18:20 STDray

Здравствуйте!


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 и потом через рефлексию вытаскивать из него тип, на который он ссылается неправильно.
Как это должно делаться по-хорошему?
Как искать и сравнивать типы?
Здравствуйте!


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 и потом через рефлексию вытаскивать из него тип, на который он ссылается неправильно.
Как это должно делаться по-хорошему?