public static bool IsUndefined(object value) { Stats.Increment(StatsCounter.Dynamic_IsUndefinedInvoked); // NOTE: using Object.ReferenceEquals to avoid invoking PSBinaryOperation, // which does more work than necessary return(Object.ReferenceEquals(value, PlayScript.Undefined._undefined)); }
public static bool HasOwnProperty(object o, string name) { Stats.Increment(StatsCounter.Dynamic_HasOwnPropertyInvoked); if (o == null || o == PlayScript.Undefined._undefined) { return(false); } // handle dictionaries var dict = o as IDictionary <string, object>; if (dict != null) { return(dict.ContainsKey(name)); } var dc = o as IDynamicClass; if (dc != null) { return(dc.__HasDynamicValue(name)); } var otype = o.GetType(); var prop = otype.GetProperty(name); if (prop != null) { return(true); } var field = otype.GetField(name); if (field != null) { return(true); } var method = otype.GetMethod(name); if (method != null) { return(true); } // not found return(false); }
public static object InvokeStaticMethod(Type type, string methodName, IList args) { Stats.Increment(StatsCounter.Dynamic_InvokeStaticInvoked); var method = type.GetMethod(methodName); if (method == null) { throw new Exception("Method not found"); } var newargs = ConvertArgumentList(method, args); return(method.Invoke(null, newargs)); }
public static bool ObjectIsClass(object o, Type type) { Stats.Increment(StatsCounter.Dynamic_ObjectIsClassInvoked); if (o == null || type == null) { return(false); } if (type.IsAssignableFrom(o.GetType())) { return(true); } else { return(false); } }
public static bool SetStaticMember(Type type, string name, object v) { Stats.Increment(StatsCounter.Dynamic_SetStaticMemberInvoked); var property = type.GetProperty(name); if (property != null) { property.SetValue(null, v, null); return(true); } var field = type.GetField(name); if (field != null) { field.SetValue(null, v); return(true); } return(false); }
public static bool CanConvertValue(object value, Type targetType) { Stats.Increment(StatsCounter.Dynamic_CanConvertValueInvoked); if (value == null) { return(true); } Type valueType = value.GetType(); if (targetType == valueType) { return(true); } if (targetType == typeof(System.Object)) { return(true); } if (targetType.IsAssignableFrom(valueType)) { return(true); } else { if (targetType == typeof(String)) { return(true); } try { return(System.Convert.ChangeType(value, targetType) != null); } catch { return(false); } } }
public static MethodInfo FindPropertySetter(Type type, string propertyName) { Stats.Increment(StatsCounter.Dynamic_FindPropertySetterInvoked); do { var prop = type.GetProperty(propertyName); if (prop != null) { var propType = prop.PropertyType; var setter = prop.GetSetMethod(); if (setter != null) { return(setter); } } // walk up heirarchy type = type.BaseType; } while (type != null); return(null); }
public static bool ConvertMethodParameters(MethodBase m, object[] args, out object[] outArgs) { Stats.Increment(StatsCounter.Dynamic_ConvertMethodParametersInvoked); bool has_defaults = false; var parameters = m.GetParameters(); var args_len = args.Length; var par_len = parameters.Length; int paramsIndex = -1; int parameterCheckLength = par_len; if (hasVariadicParameter(m)) { paramsIndex = --parameterCheckLength; } // Note that this code does not check if the arguments passed for variadic parameters // matches the variadic type (we still convert later though). // This might not be important with PlayScript though (where it is just object[]). for (var i = 0; i < parameterCheckLength; i++) { var p = parameters[i]; if (i >= args.Length) { if ((p.Attributes & ParameterAttributes.HasDefault) != 0) { has_defaults = true; continue; } else { outArgs = null; return(false); } } else { if (!CanConvertValue(args[i], p.ParameterType)) { outArgs = null; return(false); } } } // default values and params are mutually exclusive in C# (they can't both be in the same signature) // TODO: Check that this is actually true... default, then variadic? // So it makes this code a bit simpler if (has_defaults) { var new_args = new object[par_len]; for (var j = 0; j < par_len; j++) { if (j < args.Length) { new_args[j] = ConvertValue(args[j], parameters[j].ParameterType); } else { new_args[j] = parameters[j].DefaultValue; } } outArgs = new_args; } else if (paramsIndex >= 0) { if ((paramsIndex == 0) && (args_len == 1)) { // For variadic, there is a special case that we handle here // In the case where there is only one argument, and it matches the type of the variadic // we assume we receive the variadic array as input directly and no conversion is necessary. // This can happen with all the various level of stacks that we have (would be good to investigate // and cover with unit-tests). // // Note that there could be an issue that the passed parameter happened to be of the variadic type, // but was actually the first parameter of the variadic array. In this case, the behavior will be incorrect. if (parameters[paramsIndex].ParameterType == args[0].GetType()) { // Exact same type, assume that we are done. // This is a good place to put a breakpoint if you think this is an incorrect assumption. outArgs = args; return(true); } } else { if (args_len < paramsIndex) { outArgs = null; return(false); } } var new_args = new object[par_len]; // We reserve the last parameter for special params handling // We verified earlier that there was enough args anyway to fill all the parameters (and optionally the parmsIndex) // Copy all the other parameters normally System.Type paramType = parameters[paramsIndex].ParameterType; Debug.Assert(paramType.IsArray, "Unexpected type"); // Because it is variadic the type is actually an array (like string[]) // Debug.Assert(paramType.BaseType.IsArray, "Unexpected type"); // Its base type is an array too (the generic kind this time - System.Array) paramType = paramType.BaseType.BaseType; // Get the type we are interested in (string) for each parameters Debug.Assert(paramType != null, "Unexpected type"); for (var j = 0; j < paramsIndex; j++) { new_args[j] = ConvertValue(args[j], parameters[j].ParameterType); } // Then copy the additional parameters to the last parameter (params) as an array // Array can be empty if we have just enough parameters up to the params one int numberOfAdditionalParameters = args_len - paramsIndex; object[] additionalParameters = new object[numberOfAdditionalParameters]; new_args[paramsIndex] = additionalParameters; for (var j = 0; j < numberOfAdditionalParameters; j++) { additionalParameters[j] = args[paramsIndex + j]; } System.Diagnostics.Debug.Assert(paramsIndex + numberOfAdditionalParameters == args_len, "Some arguments have not been handled properly"); outArgs = new_args; } else if (par_len == args_len) { outArgs = args; // Let's make sure all the parameters are converted for (var i = 0; i < par_len; i++) { outArgs[i] = ConvertValue(args[i], parameters[i].ParameterType); } } else { outArgs = null; return(false); } // success return(true); }
public static T ConvertValue <T>(object value) { Stats.Increment(StatsCounter.Dynamic_ConvertValueGenericInvoked); return(Convert <T> .FromObject(value)); }
public static bool HasOwnProperty(object o, string name) { name = FormatKeyForAs(name); Stats.Increment(StatsCounter.Dynamic_HasOwnPropertyInvoked); if (IsNullOrUndefined(o)) { return(false); } // handle dynamic objects var dynamicObject = o as IDynamicAccessorUntyped; if (dynamicObject != null) { return(dynamicObject.HasMember(name)); } // handle dictionaries var dict = o as IDictionary <string, object>; if (dict != null) { return(dict.ContainsKey(name)); } var dict2 = o as IDictionary; if (dict2 != null) { return(dict2.Contains((object)name)); } var dc = o as IDynamicClass; if (dc != null && dc.__HasDynamicValue(name)) { return(true); } var otype = o.GetType(); try { var prop = otype.GetProperty(name); if (prop != null) { return(true); } } catch (Exception) { } try { var field = otype.GetField(name); if (field != null) { return(true); } } catch (Exception) { } try { var method = otype.GetMethod(name); if (method != null) { return(true); } } catch (Exception) { } // not found return(false); }