Re[5]: использование в TypeBuilder'e типов созданых в этом
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.06.11 16:16
Оценка: 9 (2)
Здравствуйте, BogdanMart, Вы писали:

VD>>У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.

BM>$(ommClass.FullName : dyn)(value)

BM>Error 5 unbound name `DynamicOmmControls.OMMs.CPU' D:\Projects\SUF\SUF3\source\Client\Dynamic Controls\DynamicOmmControlsCore\NamespaceProvider.n 16 17 DynamicOmmControlsCore


В usesite и dyn ожидается простое имя (не квалифицированное). Если тебе нужно задать квалифицированное имя, то нужно использовать функцию PExpr.FromQualifiedIdentifier(). При этом, твой код будет выглядеть примерно так:
def fc = FixedType.Class(ch_class,[]);
def ty = PExpr.TypedType(fc);
def fullName = PExpr.FromQualifiedIdentifier(env.Manager, ch_class.FullName);

def decl=
<[decl: 
        public $(tl.Head: usesite) : $ty //$(ch_class.FullName : dyn)
        {
          get
          {
            #if (bug)
              $fullName()  // Здесь!!!!
            #else
              null
            #endif
          }
        }
        ]>;


Типизированный вызов конструктора на этой стадии невозможен, так как до WithTypedMembers компилятор еще не создает MemberBuilder-ы (MethodBuilder, PropertyBuilder). Так что ты не сможешь к ним обратиться. На более поздней стадии код будет примерно таким:
assert(ch_class.LookupMemberAvailable);
def ctor = ch_class.LookupMember(".ctor").Head;
def tCtor = TExpr.StaticRef(fc, fc, ctor, []);
...
$(tCtor : typed)();

Но для твоей задачи — это оверкил. Так что просто используй PExpr.FromQualifiedIdentifier().
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
использование в TypeBuilder'e типов созданых в этом макросе
От: BogdanMart Украина  
Дата: 02.06.11 19:37
Оценка:
Собсвенно проблема:
Классы создаються рекурсивно.

    GetOmmClass(templ : Template, env : GlobalEnv) : TypeBuilder
    {      
      def pareseTemplate(templ : Template) : TypeBuilder
      {
      mutable ommClassDef =
        <[decl:
          public class $(DecorateName(templ.Name) : usesite) : System.ComponentModel.INotifyPropertyChanged
          {
            public this([Assertions.NotNull] omm : OMM)
            {
              when (omm.ID_Template != Guid($(templ.ID.ToString() : string)))
                throw ExceptionHelper.Throw.[ArgumentException]("OMM must be of type: {0}", $(templ.Name : string));
              
              _omm = omm;
              _omm.PropertyChanged += OnOMMChanged;
              _ = _omm.Parameters;
            }
            
.............
          }
        ]>;
      
      def c = env.Define(ommClassDef);
      

.........................
        def parseChildren()
        {
          foreach(ch in templ.Children)
          {
            def ch_class = GetOmmClass(ch, env);
            def gc = env.LookupType(["SUF","Client","GUICollections","IGUICollection"]);
            
            def fc = FixedType.Class(gc.Value, [FixedType.Class(ch_class,[])]);
            def ty = PExpr.TypedType(fc);

            def decl=
            <[decl: 
                    public $(ch.Name : usesite) : IGUICollection[$(ch_class.FullName : usesite)]  // Говрит что не ужалось найти класс 
                    {
                      get
                      {
                        CollectionMapper(
                          FilteredCollection(
                          LazyCollection( fun() { GUICollection(_omm.Children) }),
                            om => om.ID_Template == Guid($(ch.ID.ToString() : string))))
                      }
                    }
                    ]>;
            c.Define(decl);
          }
        }


            def ch_class = GetOmmClass(ch, env);
            def gc = env.LookupType(["SUF","Client","GUICollections","IGUICollection"]);
            
            def fc = FixedType.Class(gc.Value, [FixedType.Class(ch_class,[])]);
            def ty = PExpr.TypedType(fc);

            def decl=
            <[decl: 
                    public $(ch.Name : usesite) : $ty
                    {
                      get
                      {
                        CollectionMapper(
                          FilteredCollection(
                          LazyCollection( fun() { GUICollection(_omm.Children) }),
                            om => om.ID_Template == Guid($(ch.ID.ToString() : string))))
                      }
                    }
                    ]>;
            c.Define(decl);
          }
        }
так работает, но выглядит довольно коряво... и до этого еще допереть было крайне сложно.....


но в этом случае еще нормально а вот здесь:

    CreateControl(templ : Template, env : GlobalEnv) : void
    {
      def ommClass = GetOmmClass(templ, env);

      def c = env.Define(
        <[decl:
          [SUF.Client.OMMControl($(templ.ID.ToString() : string))]
          public class $(DecorateName(templ.Name) + "Control" : usesite) : DynamicOmmControls.BaseControl
          {
            public this(){}

            public override set_SufOmm(value : SUF.Common.SUFMonitoringClasses.OMM) : void
            {
              base.set_SufOmm(value);
              this.Omm = null;
              when (value : object != null)
                _ = ClientThread.Create(null, ()=> $(ommClass.FullName : usesite)(value), om => this.Omm = om, "Loading OMM: " + $(ommClass.Name : string));              
            }
            
            protected virtual OnOmmChanged() : void {};
          }
        ]>);
Совсем никак не хочет работать, тоже пишет что не удаеться найти тип (Если сгенерированый тип в текущем пространстве имен то работает, но это не вариант, зы предыдущий пример не работает и в одном пространстве имен). Здесь использование PExpr.TypedType не помогло, так как компилятор говрит что его можно использовать только при патернматчинге а не при выове метода.

Помогло обходное решение(но ОЧЕНЬ ЖУТКО!!!)
      def ommClass = GetOmmClass(templ, env);
      
      def c = env.Define(
        <[decl:
          [SUF.Client.OMMControl($(templ.ID.ToString() : string))]
          public class $(DecorateName(templ.Name) + "Control" : usesite) : DynamicOmmControls.BaseControl
          {
            public this(){}

            public override set_SufOmm(value : SUF.Common.SUFMonitoringClasses.OMM) : void
            {
              base.set_SufOmm(value);
              this.Omm = null;
              when (value : object != null)
                _ = ClientThread.Create(null, ()=> CallCtor($(ommClass.FullName : usesite),value), om => this.Omm = om, "Loading OMM: " + $(ommClass.Name : string));              
            }
            
            protected virtual OnOmmChanged() : void {};
          }
        ]>);
========================================
  public macro CallCtor(type, param )
  {
    CCTImpl.Impl(type, param, Nemerle.Macros.ImplicitCTX())
  }
  
  internal module CCTImpl
  {
    public Impl(type : PExpr , param: PExpr, typer : Typer) : PExpr
    {
      | (PExpr.Ref(n), PExpr.Ref as prm, _) =>
        def nnn = n.Id.SplitToList('.');
        match(typer.Env.LookupType(nnn))
        {
          | Some(typ) =>
            def ft = FixedType.Class(typ, []);
            PExpr.Call(PExpr.Typed(TExpr.StaticRef(ft, typ.GetMembers().OfType.[IMethod]().First(m=> m.Name==".ctor"),[])), [prm])


Если первый случай и фитча, то второе очень смахивает на баг...  Как можно с таким бороться по хорошему?
        }
    }
  }
Но это жутко криво!

По идеи Тайпер не может найти класс в NamespaceTree по какой-то причине, хотя он там присутствует(смотрел в вотчах)
Re: использование в TypeBuilder'e типов созданых в этом мак
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.11 15:52
Оценка:
Здравствуйте, BogdanMart, Вы писали:

Буков много, а понять что ты хочешь не удается. Можно в двух словах описать проблему?

Тебе нужно создать тип в определенном пространстве имен?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: использование в TypeBuilder'e типов созданых в этом
От: BogdanMart Украина  
Дата: 03.06.11 18:34
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Буков много, а понять что ты хочешь не удается. Можно в двух словах описать проблему?

VD>Тебе нужно создать тип в определенном пространстве имен?

Вообщем:
  • Макрос генерирует N классов.
  • Часть классов содержат свойства ссылающиеся на другие, свежие типы.
  • При задании полей/вызове конструторов компилятор жалуется, что не удалось про резолвить тип по имени.
    Чтобы решыть проблеммы с типами полей/свойств пихаю тип не PExpr.Red a PExpr.TypedType(так как он содержит ссылку на TypeBuilder)
    при вызове конструктора такое рещение не проканало, так как компилятор сказал, что PExpr.TypedType должен использоваться в патерн матчинге а не при вызове метода.
    Пришлось делать очень жосткий финт, создать марос уровня выражения для вызова конструтора.... который создает типизированое выражение.... )

    Собственно ошибка в том, что тайпер как то не правильно ищет в NamespaceTree (ф отладчике видно, что класс туда добавился)
  • Re[3]: использование в TypeBuilder'e типов созданых в этом
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 03.06.11 19:43
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

    BM>Вообщем:

    BM>
  • Макрос генерирует N классов.
    BM>
  • Часть классов содержат свойства ссылающиеся на другие, свежие типы.
    BM>
  • При задании полей/вызове конструторов компилятор жалуется, что не удалось про резолвить тип по имени.
    BM> Чтобы решыть проблеммы с типами полей/свойств пихаю тип не PExpr.Red a PExpr.TypedType(так как он содержит ссылку на TypeBuilder)
    BM> при вызове конструктора такое рещение не проканало, так как компилятор сказал, что PExpr.TypedType должен использоваться в патерн матчинге а не при вызове метода.

    А зачем типы строками задавать?

    У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.
  • Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[4]: использование в TypeBuilder'e типов созданых в этом
    От: BogdanMart Украина  
    Дата: 03.06.11 20:06
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>А зачем типы строками задавать?

    Хм ? ну у меня есть TypeBuilder, там где мог, использовал FixedType, но получить IMethod конструтора не могу(для TExpr.StaticRef), так как нахожусь в фазе BeforeInheritence. (Заменял на WithTyped Memeber -- не хотело объявлять свойства)

    VD>У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.

    $(ommClass.FullName : dyn)(value)

    Error 5 unbound name `DynamicOmmControls.OMMs.CPU' D:\Projects\SUF\SUF3\source\Client\Dynamic Controls\DynamicOmmControlsCore\NamespaceProvider.n 16 17 DynamicOmmControlsCore
    Re[5]: использование в TypeBuilder'e типов созданых в этом
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 03.06.11 20:11
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

    VD>>У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.

    BM>$(ommClass.FullName : dyn)(value)

    BM>Error 5 unbound name `DynamicOmmControls.OMMs.CPU' D:\Projects\SUF\SUF3\source\Client\Dynamic Controls\DynamicOmmControlsCore\NamespaceProvider.n 16 17 DynamicOmmControlsCore


    Приведи полный пример. Так чтобы можно было его скомпилить. А то я что-то не понимаю что у тебя там травится.
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[6]: использование в TypeBuilder'e типов созданых в этом
    От: BogdanMart Украина  
    Дата: 03.06.11 20:27
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Здравствуйте, BogdanMart, Вы писали:


    VD>>>У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.

    BM>>$(ommClass.FullName : dyn)(value)

    BM>>Error 5 unbound name `DynamicOmmControls.OMMs.CPU' D:\Projects\SUF\SUF3\source\Client\Dynamic Controls\DynamicOmmControlsCore\NamespaceProvider.n 16 17 DynamicOmmControlsCore


    VD>Приведи полный пример. Так чтобы можно было его скомпилить. А то я что-то не понимаю что у тебя там травится.

    Попробую... проблемно выкусить от туда логику...
    Re[6]: использование в TypeBuilder'e типов созданых в этом
    От: BogdanMart Украина  
    Дата: 04.06.11 21:20
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Приведи полный пример. Так чтобы можно было его скомпилить. А то я что-то не понимаю что у тебя там травится.


    Вот

    Вырезал от туда все свое, чисто пример...

    Просьба за
    | _ :: ((_ :: _) as tl) =>

    По голове не бить, просто в спешке переписывал чтобы компилилось, раньше там было
              foreach(ch in templ.Children)
              {
                def ch_class = GetOmmClass(ch);


    Но урезал все, оставил только общий принцип (разбирается древовидная структура, по которой генеряться классы)
    Re[6]: использование в TypeBuilder'e типов созданых в этом
    От: BogdanMart Украина  
    Дата: 12.06.11 17:03
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>В usesite и dyn ожидается простое имя (не квалифицированное). Если тебе нужно задать квалифицированное имя, то нужно использовать функцию PExpr.FromQualifiedIdentifier().

    Спасибо!!!

    VD>Типизированный вызов конструктора на этой стадии невозможен, так как до WithTypedMembers компилятор еще не создает MemberBuilder-ы (MethodBuilder, PropertyBuilder). Так что ты не сможешь к ним обратиться. На более поздней стадии код будет примерно таким:

    VD>
    VD>assert(ch_class.LookupMemberAvailable);
    VD>def ctor = ch_class.LookupMember(".ctor").Head;
    VD>def tCtor = TExpr.StaticRef(fc, fc, ctor, []);
    VD>...
    VD>$(tCtor : typed)();
    VD>

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