Ejemplo n.º 1
0
        public override JSValue Evaluate(Context context)
        {
            var length = elements.Length;
            var res    = new BaseLibrary.Array(length);

            if (length > 0)
            {
                for (int sourceIndex = 0, targetIndex = 0; sourceIndex < length; sourceIndex++, targetIndex++)
                {
                    if (elements[sourceIndex] != null)
                    {
                        var e = elements[sourceIndex].Evaluate(context);
                        if (e._valueType == JSValueType.SpreadOperatorResult)
                        {
                            var spreadArray = e._oValue as IList <JSValue>;
                            for (var i = 0; i < spreadArray.Count; i++, targetIndex++)
                            {
                                res._data[targetIndex] = spreadArray[i].CloneImpl(false);
                            }
                            targetIndex--;
                        }
                        else
                        {
                            e                      = e.CloneImpl(true);
                            e._attributes          = 0;
                            res._data[targetIndex] = e;
                        }
                    }
                    else
                    {
                        if (writableNotExists == null)
                        {
                            writableNotExists = new JSValue()
                            {
                                _valueType = JSValueType.NotExistsInObject, _attributes = JSValueAttributesInternal.SystemObject
                            }
                        }
                        ;
                        res._data[targetIndex] = writableNotExists;
                    }
                }
            }
            return(res);
        }
Ejemplo n.º 2
0
        protected internal override JSValue Invoke(bool construct, JSValue targetObject, Arguments arguments)
        {
            var objc = targetObject as ObjectWrapper;

            if (construct) // new
            {
            }
            else
            {
                if (_staticProxy._hostedType == typeof(Date))
                {
                    return(new Date().ToString());
                }
            }

            try
            {
                object obj;
                if (_staticProxy._hostedType == typeof(BaseLibrary.Array))
                {
                    if (arguments == null)
                    {
                        obj = new BaseLibrary.Array();
                    }
                    else
                    {
                        switch (arguments._iValue)
                        {
                        case 0:
                            obj = new BaseLibrary.Array();
                            break;

                        case 1:
                        {
                            var a0 = arguments[0];
                            switch (a0._valueType)
                            {
                            case JSValueType.Integer:
                                obj = new BaseLibrary.Array(a0._iValue);
                                break;

                            case JSValueType.Double:
                                obj = new BaseLibrary.Array(a0._dValue);
                                break;

                            default:
                                obj = new BaseLibrary.Array(arguments);
                                break;
                            }
                            break;
                        }

                        default:
                            obj = new BaseLibrary.Array(arguments);
                            break;
                        }
                    }
                }
                else
                {
                    if ((arguments == null || arguments._iValue == 0)
#if (PORTABLE || NETCORE)
                        && _staticProxy._hostedType.GetTypeInfo().IsValueType)
#else
                        && _staticProxy._hostedType.IsValueType)
#endif
                    {
                        obj = Activator.CreateInstance(_staticProxy._hostedType);
                    }
                    else
                    {
                        object[] args        = null;
                        var      constructor = findConstructor(arguments, ref args);

                        if (constructor == null)
                        {
                            ExceptionHelper.ThrowTypeError(_staticProxy._hostedType.Name + " can't be created.");
                        }

                        if (args == null)
                        {
                            args = new object[] { arguments }
                        }
                        ;

                        var target = constructor.GetTargetObject(targetObject, null);
                        if (target != null)
                        {
                            obj = constructor._method.Invoke(target, args);
                        }
                        else
                        {
                            obj = (constructor._method as ConstructorInfo).Invoke(args);
                        }
                    }
                }

                JSValue res = obj as JSValue;

                if (construct)
                {
                    if (res != null)
                    {
                        // Для Number, Boolean и String
                        if (res._valueType < JSValueType.Object)
                        {
                            objc.instance = obj;
                            if (objc._objectPrototype == null)
                            {
                                objc._objectPrototype = res.__proto__;
                            }
                            res = objc;
                        }
                        else if (res._oValue is JSValue)
                        {
                            res._oValue = res;
                            // На той стороне понять, по new или нет вызван конструктор не получится,
                            // поэтому по соглашению такие типы себя настраивают так, как будто они по new,
                            // а в oValue пишут экземпляр аргумента на тот случай, если вызван конструктор типа как функция
                            // с передачей в качестве аргумента существующего экземпляра
                        }
                    }
                    else
                    {
                        objc.instance = obj;

                        objc._attributes |= _staticProxy._hostedType.GetTypeInfo().IsDefined(typeof(ImmutableAttribute), false) ? JSValueAttributesInternal.Immutable : JSValueAttributesInternal.None;
                        if (obj.GetType() == typeof(Date))
                        {
                            objc._valueType = JSValueType.Date;
                        }
                        else if (res != null)
                        {
                            objc._valueType = (JSValueType)System.Math.Max((int)objc._valueType, (int)res._valueType);
                        }

                        res = objc;
                    }
                }
                else
                {
                    if (_staticProxy._hostedType == typeof(JSValue))
                    {
                        if ((res._oValue is JSValue) && (res._oValue as JSValue)._valueType >= JSValueType.Object)
                        {
                            return(res._oValue as JSValue);
                        }
                    }

                    res = res ?? new ObjectWrapper(obj)
                    {
                        _attributes = JSValueAttributesInternal.SystemObject | (_staticProxy._hostedType.GetTypeInfo().IsDefined(typeof(ImmutableAttribute), false) ? JSValueAttributesInternal.Immutable : JSValueAttributesInternal.None)
                    };
                }

                return(res);
            }