예제 #1
0
        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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        public static T ConvertValue <T>(object value)
        {
            Stats.Increment(StatsCounter.Dynamic_ConvertValueGenericInvoked);

            return(Convert <T> .FromObject(value));
        }
예제 #10
0
        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);
        }