Собсвенно проблема:
Классы создаються рекурсивно.
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 по какой-то причине, хотя он там присутствует(смотрел в вотчах)