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, Вы писали:
VD>Буков много, а понять что ты хочешь не удается. Можно в двух словах описать проблему? VD>Тебе нужно создать тип в определенном пространстве имен?
Вообщем:
Макрос генерирует N классов.
Часть классов содержат свойства ссылающиеся на другие, свежие типы.
При задании полей/вызове конструторов компилятор жалуется, что не удалось про резолвить тип по имени.
Чтобы решыть проблеммы с типами полей/свойств пихаю тип не PExpr.Red a PExpr.TypedType(так как он содержит ссылку на TypeBuilder)
при вызове конструктора такое рещение не проканало, так как компилятор сказал, что PExpr.TypedType должен использоваться в патерн матчинге а не при вызове метода.
Пришлось делать очень жосткий финт, создать марос уровня выражения для вызова конструтора.... который создает типизированое выражение.... )
Собственно ошибка в том, что тайпер как то не правильно ищет в NamespaceTree (ф отладчике видно, что класс туда добавился)
Re[3]: использование в TypeBuilder'e типов созданых в этом
Здравствуйте, BogdanMart, Вы писали:
BM>Вообщем: BM> Макрос генерирует N классов. BM> Часть классов содержат свойства ссылающиеся на другие, свежие типы. BM> При задании полей/вызове конструторов компилятор жалуется, что не удалось про резолвить тип по имени. BM> Чтобы решыть проблеммы с типами полей/свойств пихаю тип не PExpr.Red a PExpr.TypedType(так как он содержит ссылку на TypeBuilder) BM> при вызове конструктора такое рещение не проканало, так как компилятор сказал, что PExpr.TypedType должен использоваться в патерн матчинге а не при вызове метода.
А зачем типы строками задавать?
У тебя скорее всего что-то не так с цветами. Попробуй вместо usesite использовать dyn.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: использование в TypeBuilder'e типов созданых в этом
Здравствуйте, 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 типов созданых в этом
Здравствуйте, 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 типов созданых в этом
Здравствуйте, 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, Вы писали:
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). Так что ты не сможешь к ним обратиться. На более поздней стадии код будет примерно таким:
Здравствуйте, VladD2, Вы писали:
VD>В usesite и dyn ожидается простое имя (не квалифицированное). Если тебе нужно задать квалифицированное имя, то нужно использовать функцию PExpr.FromQualifiedIdentifier().
Спасибо!!!
VD>Типизированный вызов конструктора на этой стадии невозможен, так как до WithTypedMembers компилятор еще не создает MemberBuilder-ы (MethodBuilder, PropertyBuilder). Так что ты не сможешь к ним обратиться. На более поздней стадии код будет примерно таким: VD>