private static void CreatePropertySetterDelegate(Builder builder, PropertyBuilderInfo member, Method propertySetter) { // If we don't have a backing field and we don't have a setter and getter // don't bother creating a setter delegate if (member.Property.BackingField == null && propertySetter == null) { return; } if (member.Property.BackingField == null && member.Property.Getter != null && member.Property.Setter != null) { var getter = member.Property.Getter.Copy(); var setter = member.Property.Setter.Copy(); CreateSetterDelegate(builder, propertySetter, member.Property.ReturnType, x => x.Call(getter.IsStatic ? null : Crumb.This, getter), (coder, value) => coder.Call(setter.IsStatic ? null : Crumb.This, setter, value())); } else if (member.Property.BackingField != null && !member.Property.BackingField.FieldType.IsGenericType) { CreateSetterDelegate(builder, propertySetter, member.Property.BackingField.FieldType, x => x.Load(member.Property.BackingField) as ICode, (coder, value) => coder.Assign(member.Property.BackingField).Set(value())); } else if (member.Property.BackingField == null && member.Property.Setter != null) { var methodSetter = member.Property.Setter.Copy(); propertySetter.NewCode().Call(methodSetter.IsStatic ? null : Crumb.This, methodSetter, Crumb.GetParameter(0)).Return().Replace(); } else if (member.Property.BackingField == null && member.Property.Getter != null) { // This shouldn't be a thing } else { propertySetter.NewCode().Assign(member.Property.BackingField).Set(Crumb.GetParameter(0)).Return().Replace(); } }
private static void AddPropertySetterInterception(Builder builder, __PropertyInterceptionInfo propertyInterceptionInfo, PropertyBuilderInfo member, Field propertyField, Method actionObjectCtor, Method propertySetter, Dictionary <string, Field> interceptorFields) { var syncRoot = new __ISyncRoot(builder); var legalSetterInterceptors = member.InterceptorInfos.Where(x => x.InterfaceSetter != null).ToArray(); member.Property.Setter .NewCode() .Context(x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).IsNull().Then(y => { y.Assign(field).NewObj(item.Attribute); if (item.HasSyncRootInterface) { y.Load(field).As(syncRoot.Type.Import()).Call(syncRoot.SyncRoot, member.SyncRoot); } }); item.Attribute.Remove(); } x.Load(propertyField).IsNull().Then(y => y.Assign(propertyField) .NewObj(propertyInterceptionInfo.Ctor, member.Property.Getter, member.Property.Setter, member.Property.Name, member.Property.ReturnType, y.This, member.Property.ReturnType.IsArray || member.Property.ReturnType.Implements(typeof(IEnumerable)) ? member.Property.ReturnType.ChildType : null, y.NewCode().NewObj(actionObjectCtor, propertySetter))); }) .Try(x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.Type).Call(item.InterfaceSetter.OnSet, propertyField, member.Property.BackingField, member.Property.Setter.NewCode().GetParameter(0)); x.IsFalse().Then(y => y.Assign(member.Property.BackingField).Set(member.Property.Setter.NewCode().GetParameter(0))); } }) .Catch(typeof(Exception), x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.Type).Call(legalSetterInterceptors[i].InterfaceSetter.OnException, x.Exception); } x.Rethrow(); }) .Finally(x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.Type).Call(legalSetterInterceptors[i].InterfaceSetter.OnExit); } }) .EndTry() .Return() .Replace(); }
private static void CreatePropertySetterDelegate(Builder builder, PropertyBuilderInfo member, Method propertySetter) { var iList = new __IList(builder); var setterCode = propertySetter.NewCode(); if (!member.Property.BackingField.FieldType.IsGenericType) { var extensions = new __Extensions(builder); if (member.Property.BackingField.FieldType.ParameterlessContructor != null && member.Property.BackingField.FieldType.ParameterlessContructor.IsPublic) { setterCode.Load(member.Property.BackingField).IsNull().Then(y => y.Assign(member.Property.BackingField).Set(propertySetter.NewCode() .NewObj(member.Property.BackingField.FieldType.ParameterlessContructor))); } // Only this if the property implements idisposable if (member.Property.BackingField.FieldType.Implements(typeof(IDisposable))) { setterCode.Call(extensions.TryDisposeInternal, member.Property.BackingField); } setterCode.Load(propertySetter.NewCode().GetParameter(0)).IsNull().Then(x => { // Just clear if its clearable if (member.Property.BackingField.FieldType.Implements(iList.Type.Fullname)) { x.Load(member.Property.BackingField).Callvirt(iList.Clear).Return(); } // Otherwise if the property is not a value type and nullable else if (!member.Property.BackingField.FieldType.IsValueType || member.Property.BackingField.FieldType.IsNullable || member.Property.BackingField.FieldType.IsArray) { x.Assign(member.Property.BackingField).Set(null).Return(); } else // otherwise... throw an exception { x.ThrowNew(typeof(NotSupportedException), "Value types does not accept null values."); } }); if (member.Property.BackingField.FieldType.IsArray) { setterCode.Load(propertySetter.NewCode().GetParameter(0)).Is(typeof(IEnumerable)) .Then(x => x.Assign(member.Property.BackingField).Set(propertySetter.NewCode().GetParameter(0)).Return()) .ThrowNew(typeof(NotSupportedException), "Value does not inherits from IEnumerable"); } else if (member.Property.BackingField.FieldType.Implements(iList.Type.Fullname) && member.Property.BackingField.FieldType.ParameterlessContructor != null) { var addRange = member.Property.BackingField.FieldType.GetMethod("AddRange", 1, false); if (addRange == null) { var add = member.Property.BackingField.FieldType.GetMethod("Add", 1); var array = setterCode.CreateVariable(member.Property.BackingField.FieldType.ChildType.MakeArray()); setterCode.Assign(array).Set(propertySetter.NewCode().GetParameter(0)); setterCode.For(array, (x, item) => x.Load(member.Property.BackingField).Callvirt(add, item)); if (!add.ReturnType.IsVoid) { setterCode.Pop(); } } else { setterCode.Load(member.Property.BackingField).Callvirt(addRange, propertySetter.NewCode().GetParameter(0)); } } else if (member.Property.BackingField.FieldType.IsEnum) { // Enums requires special threatment setterCode.Load(propertySetter.NewCode().GetParameter(0)).Is(typeof(string)).Then(x => { var stringVariable = setterCode.CreateVariable(typeof(string)); setterCode.Assign(stringVariable).Set(x.NewCode().GetParameter(0)); setterCode.Assign(member.Property.BackingField).Set(stringVariable).Return(); }); setterCode.Assign(member.Property.BackingField).Set(propertySetter.NewCode().GetParameter(0)); } else { setterCode.Assign(member.Property.BackingField).Set(propertySetter.NewCode().GetParameter(0)); } } else { setterCode.Assign(member.Property.BackingField).Set(propertySetter.NewCode().GetParameter(0)); } setterCode.Return().Replace(); }
private static void AddPropertySetterInterception(Builder builder, __PropertyInterceptionInfo propertyInterceptionInfo, PropertyBuilderInfo member, Field propertyField, Method actionObjectCtor, Method propertySetter, Dictionary <string, Field> interceptorFields) { var syncRoot = new __ISyncRoot(); var legalSetterInterceptors = member.InterceptorInfos.Where(x => x.InterfaceSetter != null).ToArray(); member.Property.Setter .NewCode() .Context(x => { if (member.HasInitializer) { return; } for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).IsNull().Then(y => { y.Assign(field).NewObj(item.Attribute); if (item.HasSyncRootInterface) { y.Load(field).As(syncRoot.ToBuilderType.Import()).Call(syncRoot.SyncRoot, member.SyncRoot); } ImplementAssignMethodAttribute(builder, legalSetterInterceptors[i].AssignMethodAttributeInfos, field, y, false); }); item.Attribute.Remove(); } x.Load(propertyField).IsNull().Then(y => y.Assign(propertyField) .NewObj(propertyInterceptionInfo.Ctor, member.Property.Getter, member.Property.Setter, member.Property.Name, member.Property.ReturnType, Crumb.This, member.Property.ReturnType.IsArray || member.Property.ReturnType.Implements(typeof(IEnumerable)) ? member.Property.ReturnType.ChildType : null, propertySetter == null ? null : y.NewCode().NewObj(actionObjectCtor, propertySetter))); }) .Try(x => { if (member.Property.BackingField == null) { var oldvalue = member.Property.Getter == null ? null : x.CreateVariable(member.Property.ReturnType); if (oldvalue != null) { var getter = member.Property.Getter.Copy(); x.Call(getter.IsStatic ? null : Crumb.This, getter).StoreLocal(oldvalue); } for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.ToBuilderType).Call(item.InterfaceSetter.OnSet, propertyField, oldvalue, Crumb.GetParameter(0)); x.IsFalse().Then(y => y.OriginalBodyNewMethod()); } } else { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.ToBuilderType).Call(item.InterfaceSetter.OnSet, propertyField, member.Property.BackingField, Crumb.GetParameter(0)); x.IsFalse().Then(y => y.OriginalBody()); } } }) .Catch(typeof(Exception), x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.ToBuilderType).Call(legalSetterInterceptors[i].InterfaceSetter.OnException, x.Exception); } x.Rethrow(); }) .Finally(x => { for (int i = 0; i < legalSetterInterceptors.Length; i++) { var item = legalSetterInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Load(field).As(legalSetterInterceptors[i].InterfaceSetter.ToBuilderType).Call(legalSetterInterceptors[i].InterfaceSetter.OnExit); } }) .EndTry() .Return() .Replace(); }
private static void AddPropertyInitializeInterception(Builder builder, __PropertyInterceptionInfo propertyInterceptionInfo, PropertyBuilderInfo member, Field propertyField, Method actionObjectCtor, Method propertySetter, Dictionary <string, Field> interceptorFields) { var declaringType = member.Property.OriginType; var syncRoot = new __ISyncRoot(); var legalInitInterceptors = member.InterceptorInfos.Where(x => x.InterfaceInitializer != null).ToArray(); var relevantCtors = member.Property.IsStatic ? new Method[] { declaringType.StaticConstructor } : declaringType.GetRelevantConstructors().Where(x => x.Name != ".cctor"); foreach (var ctor in relevantCtors) { ctor.NewCode() .Context(x => { for (int i = 0; i < legalInitInterceptors.Length; i++) { var item = legalInitInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Assign(field).NewObj(item.Attribute); if (item.HasSyncRootInterface) { x.Load(field).As(__ISyncRoot.Type.Import()).Call(syncRoot.SyncRoot, member.SyncRoot); } ImplementAssignMethodAttribute(builder, legalInitInterceptors[i].AssignMethodAttributeInfos, field, x, false); } x.Assign(propertyField) .NewObj(propertyInterceptionInfo.Ctor, member.Property.Getter, member.Property.Setter, member.Property.Name, member.Property.ReturnType, Crumb.This, member.Property.ReturnType.IsArray || member.Property.ReturnType.Implements(typeof(IEnumerable)) ? member.Property.ReturnType.ChildType : null, propertySetter == null ? null : x.NewCode().NewObj(actionObjectCtor, propertySetter)); for (int i = 0; i < legalInitInterceptors.Length; i++) { var item = legalInitInterceptors[i]; var field = interceptorFields[item.Attribute.Identification]; x.Call(field, item.InterfaceInitializer.OnInitialize, propertyField, member.Property.BackingField); } }) .Insert(InsertionPosition.Beginning); } }