private void WriteFailureResult(ILWriter writer, ValidationKind kind, string message)
        {
            var failure = KnownMetadata.Methods.ValidationResult_Failure;

            writer.LoadInt32((int)kind);
            writer.LoadString(message);
            writer.StaticMethodCall(failure);
        }
        private void WriteIsMatch(ILWriter writer, PropertyInfo property, IsMatchForAttribute isMatchAttribute)
        {
            var validationKind = ValidationKind.RegularExpressionMatch;
            var local          = writer.DeclareLocal <string>();

            if (property.PropertyType == typeof(string))
            {
                writer.LoadFirstParameter();
                writer.GetPropertyValue(property);
                writer.SetLocal(local);
            }
            else
            {
                var temp = writer.DeclareLocal(property.PropertyType);
                writer.LoadFirstParameter();
                writer.GetPropertyValue(property);
                writer.SetLocal(temp);

                writer.LoadLocal(temp);
                var notNull = writer.IsNotNull();

                WriteFailureResult(writer, validationKind, CommonResults.CannotValidateNullProperty.WithValues(property.ReflectedType.Name, property.Name));
                writer.Return();

                writer.MarkLabel(notNull);

                writer.LoadLocal(temp);
                writer.InstanceMethodCall(KnownMetadata.Methods.Object_ToString);
                writer.SetLocal(local);
            }

            writer.LoadLocal(local);
            writer.LoadString(isMatchAttribute.RegularExpression);
            writer.StaticMethodCall(KnownMetadata.Methods.Regex_IsMatch);
            var end = writer.IfFalseThen();

            WriteFailureResult(writer, validationKind, CommonResults.RegularExpressionWasNotMatch.WithValues(property.ReflectedType.Name, property.Name));
            writer.Return();

            writer.MarkLabel(end);
        }
        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();
        }