private void WriteNotApplicableResult(ILWriter writer, ValidationKind kind)
        {
            var notApplicable = KnownMetadata.Methods.ValidationResult_NotApplicable;

            writer.LoadInt32((int)kind);
            writer.StaticMethodCall(notApplicable);
        }
Пример #2
0
        public static void Emit(RootNamespace root, SourceCodeBody body, string path)
        {
            var pgms           = Lookup.AllPrograms(body);
            var nss            = Lookup.AllNamespaces(body);
            var entrypoint     = Lookup.AllFunctionBodies(pgms).FindFirst(x => x.Name == "main");
            var structs        = Lookup.AllStructBodies(pgms).Concat(Lookup.AllStructBodies(root));
            var externs        = Lookup.AllExternFunctions(nss);
            var embedded       = Lookup.AllEmbeddedFunctions(nss);
            var extern_structs = Lookup.AllExternStructs(Lookup.GetRootNamespace(body));
            var extern_asms    = externs.Map(x => x.Assembly)
                                 .Concat(extern_structs.Map(x => x.Assembly))
                                 .By <Assembly>().Unique().ToArray();

            using var il = new ILWriter(path);
            AssemblyExternEmit(il, extern_asms);
            AssemblyNameEmit(il, path);

            var fss = new List <FunctionSpecialization>()
            {
                new FunctionSpecialization(entrypoint, new GenericsMapper())
            };

            structs.Each(x => AssemblyStructEmit(il, x, fss));
            AssemblyFunctionEmit(il, fss);
        }
Пример #3
0
        private void WriteTryCatchBlockBody(ILWriter writer, IImmutableQueue <Type> exceptionTypes)
        {
            var currentExecutionAttempt = writer.DeclareLocal <int>();
            var shouldRetry             = writer.DeclareLocal <bool>();

            var retryLabel = writer.DefineLabel();

            writer.MarkLabel(retryLabel);

            writer.WriteIncrement(currentExecutionAttempt, 1);

            writer.TryCatch(
                endOfTryCatch =>
            {
                writer.LoadFalse();
                writer.SetLocal(shouldRetry);

                var method = KnownMetadata.Methods.IExceptionAwareAction_Do;
                writer.LoadFirstParameter();
                writer.InstanceMethodCall(method);
            },
                WriteUnrolledCatchBlocks(writer, exceptionTypes, shouldRetry, currentExecutionAttempt)
                );

            writer.LoadLocal(shouldRetry);
            var shouldNotRetry = writer.IfTrueThen();

            writer.GoTo(retryLabel);

            writer.MarkLabel(shouldNotRetry);

            writer.Return();
        }
        private void WriteCustomValidation(ILWriter writer, PropertyInfo property, CustomValidationAttribute customValidationAttribute)
        {
            var validationKind = ValidationKind.Custom;

            var validatorType = typeof(ICustomValidator <>).MakeGenericType(property.PropertyType);

            if (!customValidationAttribute.ValidatorType.CanBe(validatorType))
            {
                var message = CommonErrors.CustomValidatorMustBeOfType.WithValues(property.ReflectedType.Name, property.Name, property.PropertyType.Name);
                throw new IncorrectValidationAttributeException(typeof(CustomValidationAttribute), message);
            }

            var localValidator = writer.DeclareLocal(validatorType);

            writer.New(customValidationAttribute.ValidatorType);
            writer.SetLocal(localValidator);

            var validate = KnownMetadata.Methods.ICustomValidator_OfType(property.PropertyType);

            writer.LoadLocal(localValidator);
            writer.LoadFirstParameter();
            writer.GetPropertyValue(property);
            writer.InstanceMethodCall(validate);

            var end = writer.IfFalseThen();

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

            writer.MarkLabel(end);
        }
        private void WriteStringLength(ILWriter writer, PropertyInfo property, StringLengthAttribute attribute)
        {
            var local = writer.DeclareLocal <string>();

            if (property.PropertyType == typeof(string))
            {
                writer.LoadFirstParameter();
                writer.GetPropertyValue(property);
                writer.SetLocal(local);

                writer.LoadLocal(local);
                writer.LoadNull();
                var notNullBlock = writer.IfEqualThen();

                var isNullMessage = CommonResults.PropertyCannotBeNull.WithValues(property.ReflectedType.Name, property.Name);
                WriteFailureResult(writer, ValidationKind.StringLength, isNullMessage);
                writer.Return();

                writer.MarkLabel(notNullBlock);

                var lengthValue = writer.DeclareLocal <int>();
                var length      = KnownMetadata.Properties.String_Length;
                writer.LoadLocal(local);
                writer.GetPropertyValue(length);
                writer.SetLocal(lengthValue);

                var minValue = attribute.Minimum;

                writer.LoadLocal(lengthValue);
                writer.LoadInt32((int)minValue);
                var longerThanMinBlock = writer.IfLessThan();

                var tooShortMessage = CommonResults.StringPropertyIsTooShort.WithValues(property.ReflectedType.Name, property.Name, minValue);
                WriteFailureResult(writer, ValidationKind.StringLength, tooShortMessage);
                writer.Return();

                writer.MarkLabel(longerThanMinBlock);

                var maxValue = attribute.Maximum;

                //The maximum value might not be set, if so then just ignore it
                if (maxValue > 0)
                {
                    writer.LoadLocal(lengthValue);
                    writer.LoadInt32((int)maxValue);
                    var shorterThanMaxBlock = writer.IfGreaterThan();

                    var tooLongMessage = CommonResults.StringPropertyIsTooLong.WithValues(property.ReflectedType.Name, property.Name, maxValue);
                    WriteFailureResult(writer, ValidationKind.StringLength, tooLongMessage);
                    writer.Return();

                    writer.MarkLabel(shorterThanMaxBlock);
                }
            }
            else
            {
                WriteNotApplicableResult(writer, ValidationKind.StringLength);
                writer.Return();
            }
        }
        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);
        }
Пример #7
0
        public void DeclareLocalOverloadDoesNotUnbalanceTheStack()
        {
            var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il = new ILWriter(generator);

            var localBuilder = il.DeclareLocal<object>();
            il.VerifyStack();
        }
Пример #8
0
        public void DeclareLocalOverloadDoesNotUnbalanceTheStack()
        {
            var method    = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il        = new ILWriter(generator);

            var localBuilder = il.DeclareLocal <object>();

            il.VerifyStack();
        }
Пример #9
0
        public void CatchBlockOverloadDoesNotUnbalanceTheStack()
        {
            var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il = new ILWriter(generator);

            var exceptionBlock = generator.BeginExceptionBlock();
            generator.Emit(OpCodes.Leave, exceptionBlock);
            il.CatchBlock<Exception>(exceptionBlock, () => { });
            il.VerifyStack();
        }
Пример #10
0
        public void CatchBlockOverloadDoesNotUnbalanceTheStack()
        {
            var method    = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il        = new ILWriter(generator);

            var exceptionBlock = generator.BeginExceptionBlock();

            generator.Emit(OpCodes.Leave, exceptionBlock);
            il.CatchBlock <Exception>(exceptionBlock, () => { });
            il.VerifyStack();
        }
Пример #11
0
        public static void AssemblyStructEmit(ILWriter il, StructBody body, List <FunctionSpecialization> fss)
        {
            var cache = new HashSet <string>();

            body.SpecializationMapper.Each(sp =>
            {
                var g      = sp.Key;
                var mapper = sp.Value;

                var name = GetStructName(body.Name, body, g);
                if (cache.Contains(name))
                {
                    return;
                }
                cache.Add(name);

                il.WriteLine($".class public {name}");
                il.WriteLine("{");
                il.Indent++;
                body.Members.Each(x => il.WriteLine($".field public {GetTypeName(mapper, x.Value, g)} {EscapeILName(x.Key)}"));
                il.WriteLine("");

                il.WriteLine($".method public void .ctor()");
                il.WriteLine("{");
                il.Indent++;
                var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList();
                local_vals.Each((x, i) => x.Index = i);
                if (local_vals.Count > 0)
                {
                    il.WriteLine(".locals(");
                    il.Indent++;
                    il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n"));
                    il.Indent--;
                    il.WriteLine(")");
                }
                var labels = Lookup.AllLabels(body.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}");
                body.Body.Each(x =>
                {
                    if (x is Call call)
                    {
                        CallToAddEmitFunctionList(mapper, call, fss);
                    }
                    AssemblyOperandEmit(il, x, body.Namespace, mapper, labels, g);
                });
                il.WriteLine("ret");
                il.Indent--;
                il.WriteLine("}");

                il.Indent--;
                il.WriteLine("}");
            });
        }
Пример #12
0
        /// <summary>
        /// The core method for creating a new proxy type
        /// </summary>
        /// <param name="interfaceType"> The interface type. </param>
        /// <param name="implementationTypeName"> The implementation type name. </param>
        /// <returns> The created type </returns>
        private static Type CreateProxyCore(Type interfaceType, string implementationTypeName)
        {
            TypeBuilder classBuilder = CreateImplementationType(moduleBuilder, interfaceType, implementationTypeName);

            ILWriter.CreateConstructor(classBuilder, typeof(ServiceClient));

            foreach (MethodInfo method in interfaceType.GetMethods())
            {
                GenerateMethod(classBuilder, method);
            }

            return(classBuilder.CreateType());
        }
Пример #13
0
        public static void AssemblyFunctionEmit(ILWriter il, List <FunctionSpecialization> fss)
        {
            for (var i = 0; i < fss.Count; i++)
            {
                var f      = fss[i].Body.Cast <IFunctionBody>();
                var g      = fss[i].GenericsMapper;
                var mapper = Lookup.GetTypemapper(f.SpecializationMapper, g);

                il.WriteLine($".method public static {GetTypeName(mapper, f.Return, g)} {EscapeILName(f.Name)}({f.Arguments.Map(a => GetTypeName(mapper[a.Name], g)).Join(", ")})");
                il.WriteLine("{");
                il.Indent++;
                if (i == 0)
                {
                    il.WriteLine(".entrypoint");
                }
                il.WriteLine(".maxstack 8");
                var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList();
                local_vals.Each((x, i) => x.Index = i);
                if (local_vals.Count > 0)
                {
                    il.WriteLine(".locals(");
                    il.Indent++;
                    local_vals.Map(x => x.Struct).By <AnonymousFunctionBody>().Each(x => CallToAddEmitFunctionList(mapper, x, fss));
                    il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n"));
                    il.Indent--;
                    il.WriteLine(")");
                }
                var labels = Lookup.AllLabels(f.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}");
                f.Body.Each(x =>
                {
                    if (x is Call call)
                    {
                        CallToAddEmitFunctionList(mapper, call, fss);
                    }
                    AssemblyOperandEmit(il, x, f, mapper, labels, g);
                });
                il.WriteLine("ret");
                il.Indent--;
                il.WriteLine("}");
            }
        }
        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);
        }
Пример #15
0
        /// <summary>
        /// Populates the high level metadata properties
        /// </summary>
        /// <param name="il">The IL Generator</param>
        /// <param name="metadataLocal"> The metadata local. </param>
        /// <param name="interfaceMethod"> The interface method. </param>
        private static void PopulateMetadata(ILGenerator il, LocalBuilder metadataLocal, MethodInfo interfaceMethod)
        {
            HttpVerb verb = ReflectionUtils.DetermineHttpVerb(interfaceMethod);

            string consumeMediaType  = ReflectionUtils.DetermineConsumesMediaType(interfaceMethod, MediaType.TextXml);
            string producesMediaType = ReflectionUtils.DetermineProducesMediaType(interfaceMethod, MediaType.TextXml);

            PathAttribute methodPathAttr  = ReflectionUtils.GetAttribute <PathAttribute>(interfaceMethod);
            PathAttribute servicePathAttr = ReflectionUtils.GetAttribute <PathAttribute>(interfaceMethod.DeclaringType);

            string methodPath  = methodPathAttr == null ? "/" : methodPathAttr.Path;
            string servicePath = servicePathAttr == null ? string.Empty : servicePathAttr.Path;

            Type methodMetaType = typeof(MethodMetadata);

            ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "ServicePath", servicePath);
            ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "MethodPath", methodPath);
            ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "Consumes", consumeMediaType);
            ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "Produces", producesMediaType);
            ILWriter.WritePropertyInt(il, metadataLocal, methodMetaType, "Verb", (int)verb);
        }
Пример #16
0
        private IEnumerable <Action <Label> > WriteUnrolledCatchBlocks(ILWriter writer, IImmutableQueue <Type> exceptionTypes, LocalBuilder shouldRetry, LocalBuilder currentExecutionAttempt)
        {
            var handleException = KnownMetadata.Methods.IExceptionAwareAction_HandleException;

            foreach (var exceptionType in exceptionTypes)
            {
                yield return(endOfTryCatch =>
                {
                    var handleSpecificException = handleException.MakeGenericMethod(exceptionType);

                    Action catchBlockBody = () =>
                    {
                        var endOfCatch = writer.DefineLabel();
                        var localException = writer.DeclareLocal(exceptionType);
                        writer.SetLocal(localException);

                        writer.LoadFirstParameter(); //Exception-aware instance
                        writer.LoadLocal(localException);
                        writer.LoadLocal(currentExecutionAttempt);
                        writer.InstanceMethodCall(handleSpecificException);

                        //The handler refusing to handle it indicates that we should perform a retry.
                        var wasHandled = writer.IfFalseThen();

                        writer.LoadTrue();
                        writer.SetLocal(shouldRetry);
                        writer.GoTo(endOfCatch);

                        writer.MarkLabel(wasHandled);

                        writer.LoadFalse();
                        writer.SetLocal(shouldRetry);

                        writer.MarkLabel(endOfCatch);
                    };

                    writer.CatchBlock(exceptionType, endOfTryCatch, catchBlockBody);
                });
            }
        }
        private void WriteRequireNotNull(ILWriter writer, PropertyInfo property, NotNullAttribute notNullAttribute)
        {
            if (property.PropertyType.IsClass || property.PropertyType.IsInterface)
            {
                writer.LoadFirstParameter();
                writer.GetPropertyValue(property);
                writer.LoadNull();
                var elseLabel = writer.IfEqualThen();

                var message = CommonResults.PropertyCannotBeNull.WithValues(property.ReflectedType.Name, property.Name);
                WriteFailureResult(writer, ValidationKind.RequireNotNull, message);
                writer.Return();

                writer.MarkLabel(elseLabel);
            }
            else
            {
                //Value types, pointers, everything that can't be null is here
                WriteNotApplicableResult(writer, ValidationKind.RequireNotNull);
                writer.Return();
            }
        }
        private void WritePropertyValidation <T>(ILWriter writer)
        {
            var properties = typeof(T).GetProperties();

            foreach (var property in properties)
            {
                var validationAttributes = property.GetAttributesOf <IValidationAttribute>();

                foreach (var attribute in validationAttributes)
                {
                    if (attribute.CanBe <NotNullAttribute>())
                    {
                        WriteRequireNotNull(writer, property, (NotNullAttribute)attribute);
                    }
                    else if (attribute.CanBe <StringLengthAttribute>())
                    {
                        WriteStringLength(writer, property, (StringLengthAttribute)attribute);
                    }
                    else if (attribute.CanBe <IntegerRangeAttribute>())
                    {
                        WriteIntegerRange(writer, property, (IntegerRangeAttribute)attribute);
                    }
                    else if (attribute.CanBe <IsMatchForAttribute>())
                    {
                        WriteIsMatch(writer, property, (IsMatchForAttribute)attribute);
                    }
                    else if (attribute.CanBe <CustomValidationAttribute>())
                    {
                        WriteCustomValidation(writer, property, (CustomValidationAttribute)attribute);
                    }
                    else
                    {
                        Debug.Fail("Encountered unhandled validation attribute");
                    }
                }
            }
        }
        void WriteValidatorBody <T>(ILWriter writer)
        {
            if (typeof(T).IsValueType)
            {
                WritePropertyValidation <T>(writer);

                WriteSuccessResult(writer);

                writer.Return();
            }
            else
            {
                writer.LoadFirstParameter(); //Load the parameter we're validating
                var isNull = writer.IsNotNull();

                WritePropertyValidation <T>(writer);

                writer.MarkLabel(isNull); //Ending mark for initial parameter null check

                WriteSuccessResult(writer);

                writer.Return();
            }
        }
Пример #20
0
        /// <summary>
        /// The populate metadata.
        /// </summary>
        /// <param name="il">The IL Generator</param>
        /// <param name="metadataLocal"> The metadata local. </param>
        /// <param name="interfaceMethod"> The interface method. </param>
        private static void PopulateMetadataParameters(ILGenerator il, LocalBuilder metadataLocal, MethodInfo interfaceMethod)
        {
            ParameterInfo[] parameters = interfaceMethod.GetParameters();

            Type methodMetaType = typeof(MethodMetadata);

            foreach (ParameterInfo parameter in parameters)
            {
                if (parameter.IsOut)
                {
                    throw new NotSupportedException(Resources.OutAndOptionalParamsNotSupported);
                }

                bool attributeFound = false;

                HeaderParamAttribute headerAttribute = ReflectionUtils.GetAttribute <HeaderParamAttribute>(parameter);
                if (headerAttribute != null)
                {
                    attributeFound = true;
                    ILWriter.AddParameter(
                        il,
                        "AddHeaderParameter",
                        metadataLocal,
                        methodMetaType,
                        headerAttribute.HeaderName,
                        parameter);
                }

                QueryParamAttribute queryAttribute = ReflectionUtils.GetAttribute <QueryParamAttribute>(parameter);
                if (queryAttribute != null)
                {
                    attributeFound = true;
                    ILWriter.AddParameter(
                        il,
                        "AddQueryParameter",
                        metadataLocal,
                        methodMetaType,
                        queryAttribute.ParameterName,
                        parameter);
                }

                FormParamAttribute formAttribute = ReflectionUtils.GetAttribute <FormParamAttribute>(parameter);
                if (formAttribute != null)
                {
                    attributeFound = true;
                    ILWriter.AddParameter(
                        il,
                        "AddFormParameter",
                        metadataLocal,
                        methodMetaType,
                        formAttribute.ParameterName,
                        parameter);
                }

                PathParamAttribute pathAttribute = ReflectionUtils.GetAttribute <PathParamAttribute>(parameter);
                if (pathAttribute != null)
                {
                    attributeFound = true;
                    ILWriter.AddParameter(
                        il,
                        "AddPathParameter",
                        metadataLocal,
                        methodMetaType,
                        pathAttribute.ParameterName,
                        parameter);
                }

                if (!attributeFound)
                {
                    MethodInfo bodySetter = methodMetaType.GetProperty("RequestBody").GetSetMethod();

                    il.Emit(OpCodes.Ldloc, metadataLocal);
                    il.Emit(OpCodes.Ldarg, parameter.Position + 1);
                    if (parameter.ParameterType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, parameter.ParameterType);
                    }

                    il.Emit(OpCodes.Call, bodySetter);
                }
            }
        }
        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();
        }
Пример #22
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();
        }
        private void WriteSuccessResult(ILWriter writer)
        {
            var success = KnownMetadata.Methods.ValidationResult_Success;

            writer.StaticMethodCall(success);
        }
Пример #24
0
 public static void AssemblyNameEmit(ILWriter il, string path) => il.WriteLine($".assembly {Path.GetFileNameWithoutExtension(path)} {{}}");
Пример #25
0
 public static void AssemblyOperandEmit(ILWriter il, IOperand op, INamespace ns, TypeMapper m, Dictionary <LabelCode, string> labels, GenericsMapper g)
 {
     il.WriteLine();
     if (op is IReturnBind prop && prop.Return is { } && m[prop.Return].Type == VariableType.Property)
Пример #26
0
 public static void AssemblyExternEmit(ILWriter il, Assembly[] extern_asms) => extern_asms.Each(x => il.WriteLine($".assembly extern {x.GetName().Name} {{}}"));
        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);
            }
        }