MemberInfo GetSetter()
        {
            Debug.Assert(Context.CurrentProperty != null, "Context.CurrentProperty != null");

            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            var propertyType = Context.CurrentProperty.PropertyType;
            var fields       = InstanceType.GetFields(bindingFlags);

            foreach (var field in fields)
            {
                var attrs = field.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && field.FieldType.IsSameOrParentOf(propertyType))
                {
                    return(field);
                }
            }

            var props = InstanceType.GetProperties(bindingFlags);

            foreach (var prop in props)
            {
                var attrs = prop.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && prop.PropertyType.IsSameOrParentOf(propertyType))
                {
                    return(prop);
                }
            }

            foreach (var field in fields)
            {
                if (field.Name == "Value" && field.FieldType.IsSameOrParentOf(propertyType))
                {
                    return(field);
                }
            }

            foreach (var prop in props)
            {
                if (prop.Name == "Value" && prop.PropertyType.IsSameOrParentOf(propertyType))
                {
                    return(prop);
                }
            }

            var method = InstanceType.GetMethod(false, "SetValue", bindingFlags);

            if (method != null && method.ReturnType == typeof(void))
            {
                return(method);
            }

            throw new TypeBuilderException(string.Format(
                                               "The '{0}' type does not have appropriate setter. See '{1}' member '{2}' of '{3}' type.",
                                               InstanceType.FullName, propertyType.FullName, Context.CurrentProperty.Name, Context.Type.FullName));
        }
        public override void Emit(ILRunner pRunner)
        {
            MethodDefinition def = MetadataCache.GetMethod(this);

            foreach (var a in Arguments)
            {
                a.Emit(pRunner);
            }

            if (def.Name == "ToString")
            {
                Type[] types = new Type[Arguments.Count];
                for (int i = 0; i < Arguments.Count; i++)
                {
                    types[i] = Arguments[i].Type.ToSystemType();
                }
                var m = InstanceType.GetMethod(Value, types);
                pRunner.Emitter.Emit(OpCodes.Callvirt, m);
            }
            else
            {
                if (TypeParameters.Count == 0)
                {
                    pRunner.Emitter.Emit(OpCodes.Call, def.CallSite);
                }
                else
                {
                    Type[] types = new Type[TypeParameters.Count];
                    for (int i = 0; i < TypeParameters.Count; i++)
                    {
                        types[i] = SmallType.FromString("", TypeParameters[i]).ToSystemType();
                        if (types[i] == null)
                        {
                            var t = pRunner.CurrentMethod.TypeHints;
                            for (int j = 0; j < t.Count; j++)
                            {
                                if (TypeParameters[i].Equals(t[j].Name, StringComparison.OrdinalIgnoreCase))
                                {
                                    types[i] = t[j].ToSystemType();
                                }
                            }
                        }
                    }
                    var cs = def.CallSite.MakeGenericMethod(types);
                    pRunner.Emitter.Emit(OpCodes.Call, cs);
                }
            }

            if (def.ReturnTypes.Length > 0)
            {
                //TODO Should move to some sort of visitor? This will fail eventually if I allow struct functions
                if (Parent.GetType() == typeof(BlockSyntax) || !string.IsNullOrEmpty(Namespace) && Parent.Parent.GetType() == typeof(BlockSyntax))
                {
                    pRunner.Emitter.Emit(OpCodes.Pop);
                }
            }
        }
Beispiel #3
0
            public void Invoke(string methodName, params string[] parameters)
            {
                MethodInfo method;

                if (!Methods.TryGetValue(methodName, out method))
                {
                    try
                    {
                        method = InstanceType.GetMethod(methodName);
                    }
                    catch (AmbiguousMatchException ex)
                    {
                        throw new Exception("Invoked methods can't have multiple overloads: " + methodName, ex);
                    }
                    Methods[methodName] = method;
                }
                var methodParametersInfo = method.GetParameters();

                if (methodParametersInfo.Length != parameters.Length)
                {
                    throw new Exception(string.Format("Wrong number of parameters. Method: {0}, Expected: {1}, Received: {2}", methodName, methodParametersInfo.Length, parameters.Length));
                }
                var parameterValues = new List <object>();

                for (int index = 0; index < parameters.Length; index++)
                {
                    try
                    {
                        parameterValues.Add(JsonConvert.DeserializeObject(parameters[index], methodParametersInfo[index].ParameterType));
                    }
                    catch (Exception ex)
                    {
                        RoqueTrace.Source.Trace(TraceEventType.Error, "Error deserializing parameter: {0}. Method: {1}, Parameter: {2}, Expected Type: {3}",
                                                ex.Message, method.Name, methodParametersInfo[index].Name, methodParametersInfo[index].ParameterType.FullName, ex);
                        throw;
                    }
                }
                try
                {
                    method.Invoke(Instance, parameterValues.ToArray());
                }
                catch (TargetInvocationException ex)
                {
                    var jobException = ex.InnerException;
                    RoqueTrace.Source.Trace(TraceEventType.Error, "Error invoking job target: {0}\n\n{1}", jobException.Message, jobException);
                    var jobExceptionType = jobException.GetType();
                    if (jobException is ShouldRetryException)
                    {
                        throw jobException;
                    }
                    var invokedMethod = (Instance == null ? method : Instance.GetType().GetMethod(methodName));
                    var retryOn       = invokedMethod.GetCustomAttributes(typeof(RetryOnAttribute), true)
                                        .OfType <RetryOnAttribute>()
                                        .FirstOrDefault(attr => attr.ExceptionType.IsAssignableFrom(jobExceptionType));
                    if (retryOn == null)
                    {
                        retryOn = invokedMethod.DeclaringType.GetCustomAttributes(typeof(RetryOnAttribute), true)
                                  .OfType <RetryOnAttribute>()
                                  .FirstOrDefault(attr => attr.ExceptionType.IsAssignableFrom(jobExceptionType));
                    }
                    if (retryOn != null && !(retryOn is DontRetryOnAttribute))
                    {
                        throw retryOn.CreateException(jobException);
                    }
                    throw;
                }
            }