Пример #1
0
        private void WriteLogBody(ILWriter writer, Type type, MemberInfo[] loggableMembers)
        {
            var localTypedInstance = writer.DeclareLocal(type);

            writer.LoadFirstParameter();
            writer.Cast(typeof(object), type);
            writer.SetLocal(localTypedInstance);

            //TODO: Recurse into loggable members
            foreach (var member in loggableMembers)
            {
                var logAttributes = member.GetCustomAttributes <LogAttribute>().ToArray();

                if (logAttributes.Length == 0)
                {
                    continue;
                }

                //TODO: Support multiple attributes per member
                var attribute = logAttributes[0];

                if (attribute.Ignore)
                {
                    continue;
                }

                if (CanWriteToLog(attribute.Visibility))
                {
                    LocalBuilder localValue;
                    LocalBuilder localLogItem = writer.DeclareLocal <CustomLoggableMember>();

                    switch (member.MemberType)
                    {
                    case MemberTypes.Field:
                        var field = (FieldInfo)member;
                        localValue = writer.DeclareLocal(field.FieldType);

                        writer.LoadLocal(localTypedInstance);
                        writer.LoadField(field);
                        writer.SetLocal(localValue);
                        break;

                    case MemberTypes.Property:
                        var property = (PropertyInfo)member;
                        localValue = writer.DeclareLocal(property.PropertyType);

                        writer.LoadLocal(localTypedInstance);
                        writer.GetPropertyValue(property);
                        writer.SetLocal(localValue);
                        break;

                    default:
                        var message = String.Format("Encountered loggable member '{0}' that was not supported in IL generation", member.Name);
                        System.Diagnostics.Debug.Fail(message);
                        throw new ILGenerationException(message);
                    }

                    writer.New <CustomLoggableMember>();
                    writer.SetLocal(localLogItem);

                    writer.LoadLocal(localLogItem);
                    writer.LoadInt32((int)attribute.Visibility);
                    writer.SetPropertyValue(typeof(CustomLoggableMember).GetProperty("MemberVisibility"));

                    writer.LoadLocal(localLogItem);
                    writer.TypeOf(type);
                    writer.Cast(localValue.LocalType, typeof(Type));
                    writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_OwningType);

                    writer.LoadLocal(localLogItem);
                    writer.LoadString(member.Name);
                    writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberName);

                    writer.LoadLocal(localLogItem);
                    writer.TypeOf(localValue.LocalType);
                    writer.Cast(localValue.LocalType, typeof(Type));
                    writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberType);

                    writer.LoadLocal(localLogItem);
                    writer.LoadLocal(localValue);
                    writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberValue);

                    writer.LoadSecondParameter();
                    writer.LoadLocal(localLogItem);
                    writer.ActionDelegateMethodCall <CustomLoggableMember>();
                }
            }

            writer.Return();
        }
        void WriteTranslatorBody <TFrom, TTo>(ILWriter writer)
        {
            var sourceProperties         = typeof(TFrom).GetPublicPropertiesWithGetter();
            var targetProperties         = typeof(TTo).GetPublicPropertiesWithSetter().ToDictionary(p => p.Name);
            var targetedSourceProperties = sourceProperties.GetTranslatableProperties <TTo>();

            if (targetProperties.Count == 0)
            {
                writer.ReturnNull();
                return;
            }

            var localTargetInstance = writer.DeclareLocal <TTo>();

            writer.New <TTo>();
            writer.SetLocal(localTargetInstance);

            foreach (var sourceProperty in sourceProperties)
            {
                var explicitMapping = GetExplicitMappingIfPresent <TTo>(sourceProperty);

                var targetName = (explicitMapping == null) ? sourceProperty.Name : explicitMapping.PropertyName;

                if (!targetProperties.ContainsKey(targetName))
                {
                    if (this.shouldThrowExceptions)
                    {
                        throw new PropertyIsMissingException();
                    }
                    continue;
                }

                var targetProperty = targetProperties[targetName];

                var propertiesAreSameType = sourceProperty.PropertyType == targetProperty.PropertyType;

                if (!propertiesAreSameType && !sourceProperty.PropertyType.HasConversionTo(targetProperty.PropertyType))
                {
                    if (this.shouldThrowExceptions)
                    {
                        throw new PropertyTypeMismatchException();
                    }
                    continue;
                }

                var localSourceValue = writer.DeclareLocal(sourceProperty.PropertyType);

                writer.LoadFirstParameter();
                writer.GetPropertyValue(sourceProperty);
                writer.SetLocal(localSourceValue);

                writer.LoadLocal(localTargetInstance);
                writer.LoadLocal(localSourceValue);

                if (!propertiesAreSameType)
                {
                    writer.Cast(sourceProperty.PropertyType, targetProperty.PropertyType);
                }

                writer.SetPropertyValue(targetProperty);
            }

            writer.LoadLocal(localTargetInstance);
            writer.Return();
            writer.VerifyStack();
        }
        private void WriteIntegerRange(ILWriter writer, PropertyInfo property, IntegerRangeAttribute integerRangeAttribute)
        {
            var validationKind = ValidationKind.IntegerRange;

            var signedSet = new HashSet <Type>()
            {
                typeof(sbyte),
                typeof(short),
                typeof(int),
                typeof(long)
            };

            var unsignedSet = new HashSet <Type>()
            {
                typeof(byte),
                typeof(ushort),
                typeof(uint),
                typeof(ulong)
            };

            LocalBuilder local;

            if (signedSet.Contains(property.PropertyType))
            {
                local = writer.DeclareLocal <long>();
            }
            else if (unsignedSet.Contains(property.PropertyType))
            {
                local = writer.DeclareLocal <ulong>();
            }
            else
            {
                WriteNotApplicableResult(writer, validationKind);
                writer.Return();
                return;
            }

            writer.LoadFirstParameter();
            writer.GetPropertyValue(property);
            writer.Cast(property.PropertyType, local.LocalType);
            writer.SetLocal(local);

            if (integerRangeAttribute.HasMinimum && integerRangeAttribute.HasMaximum)
            {
                if (integerRangeAttribute.Minimum > integerRangeAttribute.Maximum)
                {
                    var message = CommonErrors.IntegerRangeValidationHasMinGreaterThanMax.WithValues(property.ReflectedType.Name, property.Name);
                    throw new IncorrectValidationAttributeException(typeof(IntegerRangeAttribute), message);
                }
            }

            if (integerRangeAttribute.HasMinimum)
            {
                writer.LoadLocal(local);
                writer.LoadInt64(integerRangeAttribute.Minimum);

                var isGreaterThanOrEqual = writer.IfLessThan();

                WriteFailureResult(writer, validationKind, CommonResults.IntegerPropertyIsTooLow.WithValues(property.ReflectedType.Name, property.Name, integerRangeAttribute.Minimum));
                writer.Return();

                writer.MarkLabel(isGreaterThanOrEqual);
            }

            if (integerRangeAttribute.HasMaximum)
            {
                writer.LoadLocal(local);
                writer.LoadInt64(integerRangeAttribute.Maximum);

                var isLessThanOrEqual = writer.IfGreaterThan();

                WriteFailureResult(writer, validationKind, CommonResults.IntegerPropertyIsTooHigh.WithValues(property.ReflectedType.Name, property.Name, integerRangeAttribute.Maximum));
                writer.Return();

                writer.MarkLabel(isLessThanOrEqual);
            }
        }