использование в 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 по какой-то причине, хотя он там присутствует(смотрел в вотчах)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.