public Method GetMethod(BuilderType builderType) { if (this.ParameterTypes == null || this.ParameterTypes.Length == 0) { return(builderType.GetMethod(this.Name, this.ParameterCount, true).Import()); } return(builderType.GetMethod(this.Name, true, this.ParameterTypes).Import()); }
static GetAssemblyWeaver() { if (Builder.Current.IsUWP) { introspectionExtensions = Builder.Current.GetType("System.Reflection.IntrospectionExtensions")?.Import(); typeInfo = Builder.Current.GetType("System.Reflection.TypeInfo")?.Import(); getTypeInfo = introspectionExtensions.GetMethod("GetTypeInfo", 1).Import(); getAssembly = typeInfo.GetMethod("get_Assembly").Import(); } else { type = Builder.Current.GetType("System.Type")?.Import(); getAssembly = type.GetMethod("get_Assembly").Import(); } }
private static void CreateSetterDelegate(Builder builder, Method setterDelegateMethod, BuilderType propertyType, Func <ICode, ICode> loadValue, Func <ICode, Func <object>, ICode> setValue) { var extensions = new __Extensions(); var iList = new __IList(); var setterCode = setterDelegateMethod.NewCode(); if (propertyType.ParameterlessContructor != null && propertyType.ParameterlessContructor.IsPublic) { loadValue(setterCode).IsNull().Then(y => setValue(y, () => setterCode.NewCode().NewObj(propertyType.ParameterlessContructor))); } // Only this if the property implements idisposable if (propertyType.Implements(typeof(IDisposable))) { setterCode.Call(extensions.TryDisposeInternal, loadValue(setterCode.NewCode())); } setterCode.Load(Crumb.GetParameter(0)).IsNull().Then(x => { // Just clear if its clearable if (propertyType.Implements(__IList.Type.Fullname)) { loadValue(x).Callvirt(iList.Clear).Return(); } // Otherwise if the property is not a value type and nullable else if (!propertyType.IsValueType || propertyType.IsNullable || propertyType.IsArray) { setValue(x, () => null).Return(); } else // otherwise... throw an exception { x.ThrowNew(typeof(NotSupportedException), "Value types does not accept null values."); } }); if (propertyType.IsArray) { setterCode.Load(Crumb.GetParameter(0)).Is(typeof(IEnumerable)) .Then(x => setValue(x, () => Crumb.GetParameter(0)).Return()) .ThrowNew(typeof(NotSupportedException), "Value does not inherits from IEnumerable"); } else if (propertyType.Implements(__IList.Type.Fullname) && propertyType.ParameterlessContructor != null) { var addRange = propertyType.GetMethod("AddRange", 1, false); if (addRange == null) { var add = propertyType.GetMethod("Add", 1); var array = setterCode.CreateVariable(propertyType.ChildType.MakeArray()); setterCode.Assign(array).Set(Crumb.GetParameter(0)); setterCode.For(array, (x, item) => loadValue(x).Callvirt(add, item)); if (!add.ReturnType.IsVoid) { setterCode.Pop(); } } else { loadValue(setterCode).Callvirt(addRange, Crumb.GetParameter(0)); } } else if (propertyType.IsEnum) { // Enums requires special threatment setterCode.Load(Crumb.GetParameter(0)).Is(typeof(string)).Then(x => { var stringVariable = setterCode.CreateVariable(typeof(string)); setterCode.Assign(stringVariable).Set(Crumb.GetParameter(0)); setValue(setterCode, () => stringVariable).Return(); }); setValue(setterCode, () => Crumb.GetParameter(0)); } else { setValue(setterCode, () => Crumb.GetParameter(0)); } setterCode.Return().Replace(); }
private static void CreateSetterDelegate(Builder builder, Method setterDelegateMethod, BuilderType propertyType, object value) { var setterCode = setterDelegateMethod.NewCoder(); T CodeMe <T>(Func <Field, T> fieldCode, Func <Property, T> propertyCode) where T : class { switch (value) { case Field field: return(fieldCode(field)); case Property property: return(propertyCode(property)); default: return(null); } } if (propertyType.ParameterlessContructor != null && propertyType.ParameterlessContructor.IsPublic) { CodeMe( field => setterCode.If(x => x.Load(field).IsNull(), then => then.SetValue(field, x => x.NewObj(propertyType.ParameterlessContructor))), property => setterCode.If(x => x.Call(property.Getter).IsNull(), then => then.Call(property.Setter, x => x.NewObj(propertyType.ParameterlessContructor)))); } // Only this if the property implements idisposable if (propertyType.Implements(typeof(IDisposable))) { CodeMe( field => setterCode.Call(BuilderTypes.Extensions.GetMethod_TryDisposeInternal(), x => x.Load(field)), property => setterCode.Call(BuilderTypes.Extensions.GetMethod_TryDisposeInternal(), x => x.Call(property.Getter))); } setterCode.If(x => x.Load(CodeBlocks.GetParameter(0)).IsNull(), then => { // Just clear if its clearable if (propertyType.Implements(BuilderTypes.IList)) { CodeMe( field => setterCode.Load(field).Call(BuilderTypes.IList.GetMethod_Clear()).Return(), property => setterCode.Call(property.Getter).Call(BuilderTypes.IList.GetMethod_Clear()).Return()); } // Otherwise if the property is not a value type and nullable else if (!propertyType.IsValueType || propertyType.IsNullable || propertyType.IsArray) { CodeMe <CoderBase>( field => setterCode.SetValue(field, null), property => setterCode.Call(property.Setter, null)); } else // otherwise... throw an exception { then.ThrowNew(typeof(NotSupportedException), "Value types does not accept null values."); } return(then); }); setterCode.If(x => CodeMe( field => x.Load(CodeBlocks.GetParameter(0)).Is(field.FieldType), property => x.Load(CodeBlocks.GetParameter(0)).Is(property.ReturnType)), then => CodeMe( field => then.SetValue(field, CodeBlocks.GetParameter(0)).Return(), property => then.Call(property.Setter, CodeBlocks.GetParameter(0)).Return())); if (propertyType.Implements(BuilderTypes.IList)) { var add = propertyType.GetMethod("Add", 1); var array = setterDelegateMethod.GetOrCreateVariable(propertyType.ChildType.MakeArray()); setterCode.SetValue(array, CodeBlocks.GetParameter(0)); setterCode.For(array, (x, item, indexer) => CodeMe( field => x.Load(field).Call(add, item()), property => x.Call(property.Getter).Call(add, item()))); if (!add.ReturnType.IsVoid) { setterCode.Pop(); } } else if (propertyType.Implements(typeof(IEnumerable)) || propertyType.IsArray) { setterCode.If(x => x.Load(CodeBlocks.GetParameter(0)).Is(typeof(IEnumerable)), then => CodeMe( field => then.SetValue(field, CodeBlocks.GetParameter(0)).Return(), property => then.Call(property.Setter, CodeBlocks.GetParameter(0)).Return())) .ThrowNew(typeof(NotSupportedException), "Value does not inherits from IEnumerable"); } else if (propertyType.IsEnum) { // Enums requires special threatment setterCode.If(x => x.Load(CodeBlocks.GetParameter(0)).Is(typeof(string)), then => { var stringVariable = setterDelegateMethod.GetOrCreateVariable(typeof(string)); then.SetValue(stringVariable, CodeBlocks.GetParameter(0)); CodeMe( // Cecilator automagically implements a convertion for this field => then.SetValue(field, stringVariable).Return(), property => then.Call(property.Setter, stringVariable).Return()); return(then); }); CodeMe <CoderBase>( field => setterCode.SetValue(field, CodeBlocks.GetParameter(0)), property => setterCode.Call(property.Setter, CodeBlocks.GetParameter(0))); } else { CodeMe <CoderBase>( field => setterCode.SetValue(field, CodeBlocks.GetParameter(0)), property => setterCode.Call(property.Setter, CodeBlocks.GetParameter(0))); } setterCode.Return().Replace(); }