<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;

namespace Jint.Native.Array
{
    /// <summary>
    /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4
    /// </summary>
    public sealed class ArrayPrototype : ArrayInstance
    {
        private ArrayPrototype(Engine engine) : base(engine)
        {
        }

        public static ArrayPrototype CreatePrototypeObject(Engine engine, ArrayConstructor arrayConstructor)
        {
            var obj = new ArrayPrototype(engine)
                {
                    Extensible = true, 
                    Prototype = engine.Object.PrototypeObject
                };

            obj.FastAddProperty("length", 0, true, false, false);
            obj.FastAddProperty("constructor", arrayConstructor, false, false, false);

            return obj;
        }

        public void Configure()
        {
            FastAddProperty("toString", new ClrFunctionInstance<object, object>(Engine, ToString, 0), true, false, true);
            FastAddProperty("toLocaleString", new ClrFunctionInstance<object, object>(Engine, ToLocaleString), true, false, true);
            FastAddProperty("concat", new ClrFunctionInstance<object, object>(Engine, Concat, 1), true, false, true);
            FastAddProperty("join", new ClrFunctionInstance<object, object>(Engine, Join, 1), true, false, true);
            FastAddProperty("pop", new ClrFunctionInstance<object, object>(Engine, Pop), true, false, true);
            FastAddProperty("push", new ClrFunctionInstance<object, object>(Engine, Push, 1), true, false, true);
            FastAddProperty("reverse", new ClrFunctionInstance<object, object>(Engine, Reverse), true, false, true);
            FastAddProperty("shift", new ClrFunctionInstance<object, object>(Engine, Shift), true, false, true);
            FastAddProperty("slice", new ClrFunctionInstance<object, object>(Engine, Slice, 2), true, false, true);
            FastAddProperty("sort", new ClrFunctionInstance<object, ObjectInstance>(Engine, Sort, 1), true, false, true);
            FastAddProperty("splice", new ClrFunctionInstance<object, ObjectInstance>(Engine, Splice, 2), true, false, true);
            FastAddProperty("unshift", new ClrFunctionInstance<object, uint>(Engine, Unshift, 1), true, false, true);
            FastAddProperty("indexOf", new ClrFunctionInstance<object, int>(Engine, IndexOf, 1), true, false, true);
            FastAddProperty("lastIndexOf", new ClrFunctionInstance<object, int>(Engine, LastIndexOf, 1), true, false, true);
            FastAddProperty("every", new ClrFunctionInstance<object, bool>(Engine, Every, 1), true, false, true);
            FastAddProperty("some", new ClrFunctionInstance<object, bool>(Engine, Some, 1), true, false, true);
            FastAddProperty("forEach", new ClrFunctionInstance<object, object>(Engine, ForEach, 1), true, false, true);
            FastAddProperty("map", new ClrFunctionInstance<object, object>(Engine, Map, 1), true, false, true);
            FastAddProperty("filter", new ClrFunctionInstance<ArrayInstance, object>(Engine, Filter), true, false, true);
            FastAddProperty("reduce", new ClrFunctionInstance<ArrayInstance, object>(Engine, Reduce), true, false, true);
            FastAddProperty("reduceRight", new ClrFunctionInstance<ArrayInstance, object>(Engine, ReduceRight), true, false, true);
        }

        private int LastIndexOf(object thisObj, object[] arguments)
        {
            var o = TypeConverter.ToObject(Engine, thisObj);
            var lenValue = o.Get("length");
            var len = TypeConverter.ToUint32(lenValue);
            if (len == 0)
            {
                return -1;
            }

            var n = arguments.Length > 1 ? (int)TypeConverter.ToInteger(arguments[1]) : (int)len - 1;
            int k;
            if (n >= 0)
            {
                k = System.Math.Min(n, (int)len - 1); // min
            }
            else
            {
                k = (int)len - System.Math.Abs(n);
            }
            var searchElement = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
            for (; k > 0; k--)
            {
                var kString = TypeConverter.ToString(k);
                var kPresent = o.HasProperty(kString);
                if (kPresent)
                {
                    var elementK = o.Get(kString);
                    var same = ExpressionInterpreter.StriclyEqual(elementK, searchElement);
                    if (same)
                    {
                        return k;
                    }
                }
            }
            return -1;
        }

        private object Reduce(object thisObj, object[] arguments)
        {
            throw new NotImplementedException();
        }

        private object Filter(object thisObj, object[] arguments)
        {
            throw new NotImplementedException();
        }

        private object Map(object thisObj, object[] arguments)
        {
            var callbackfn = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
            var thisArg = arguments.Length > 1 ? arguments[1] : Undefined.Instance;

            var o = TypeConverter.ToObject(Engine, thisObj);
            var lenValue = o.Get("length");<commit_msg>Implementing Array.prototype.filter<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;

namespace Jint.Native.Array
{
    /// <summary>
    /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4
    /// </summary>
    public sealed class ArrayPrototype : ArrayInstance
    {
        private ArrayPrototype(Engine engine) : base(engine)
        {
        }

        public static ArrayPrototype CreatePrototypeObject(Engine engine, ArrayConstructor arrayConstructor)
        {
            var obj = new ArrayPrototype(engine)
                {
                    Extensible = true, 
                    Prototype = engine.Object.PrototypeObject
                };

            obj.FastAddProperty("length", 0, true, false, false);
            obj.FastAddProperty("constructor", arrayConstructor, false, false, false);

            return obj;
        }

        public void Configure()
        {
            FastAddProperty("toString", new ClrFunctionInstance<object, object>(Engine, ToString, 0), true, false, true);
            FastAddProperty("toLocaleString", new ClrFunctionInstance<object, object>(Engine, ToLocaleString), true, false, true);
            FastAddProperty("concat", new ClrFunctionInstance<object, object>(Engine, Concat, 1), true, false, true);
            FastAddProperty("join", new ClrFunctionInstance<object, object>(Engine, Join, 1), true, false, true);
            FastAddProperty("pop", new ClrFunctionInstance<object, object>(Engine, Pop), true, false, true);
            FastAddProperty("push", new ClrFunctionInstance<object, object>(Engine, Push, 1), true, false, true);
            FastAddProperty("reverse", new ClrFunctionInstance<object, object>(Engine, Reverse), true, false, true);
            FastAddProperty("shift", new ClrFunctionInstance<object, object>(Engine, Shift), true, false, true);
            FastAddProperty("slice", new ClrFunctionInstance<object, object>(Engine, Slice, 2), true, false, true);
            FastAddProperty("sort", new ClrFunctionInstance<object, ObjectInstance>(Engine, Sort, 1), true, false, true);
            FastAddProperty("splice", new ClrFunctionInstance<object, ObjectInstance>(Engine, Splice, 2), true, false, true);
            FastAddProperty("unshift", new ClrFunctionInstance<object, uint>(Engine, Unshift, 1), true, false, true);
            FastAddProperty("indexOf", new ClrFunctionInstance<object, int>(Engine, IndexOf, 1), true, false, true);
            FastAddProperty("lastIndexOf", new ClrFunctionInstance<object, int>(Engine, LastIndexOf, 1), true, false, true);
            FastAddProperty("every", new ClrFunctionInstance<object, bool>(Engine, Every, 1), true, false, true);
            FastAddProperty("some", new ClrFunctionInstance<object, bool>(Engine, Some, 1), true, false, true);
            FastAddProperty("forEach", new ClrFunctionInstance<object, object>(Engine, ForEach, 1), true, false, true);
            FastAddProperty("map", new ClrFunctionInstance<object, object>(Engine, Map, 1), true, false, true);
            FastAddProperty("filter", new ClrFunctionInstance<object, object>(Engine, Filter, 1), true, false, true);
            FastAddProperty("reduce", new ClrFunctionInstance<ArrayInstance, object>(Engine, Reduce), true, false, true);
            FastAddProperty("reduceRight", new ClrFunctionInstance<ArrayInstance, object>(Engine, ReduceRight), true, false, true);
        }

        private int LastIndexOf(object thisObj, object[] arguments)
        {
            var o = TypeConverter.ToObject(Engine, thisObj);
            var lenValue = o.Get("length");
            var len = TypeConverter.ToUint32(lenValue);
            if (len == 0)
            {
                return -1;
            }

            var n = arguments.Length > 1 ? (int)TypeConverter.ToInteger(arguments[1]) : (int)len - 1;
            int k;
            if (n >= 0)
            {
                k = System.Math.Min(n, (int)len - 1); // min
            }
            else
            {
                k = (int)len - System.Math.Abs(n);
            }
            var searchElement = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
            for (; k > 0; k--)
            {
                var kString = TypeConverter.ToString(k);
                var kPresent = o.HasProperty(kString);
                if (kPresent)
                {
                    var elementK = o.Get(kString);
                    var same = ExpressionInterpreter.StriclyEqual(elementK, searchElement);
                    if (same)
                    {
                        return k;
                    }
                }
            }
            return -1;
        }

        private object Reduce(object thisObj, object[] arguments)
        {
            throw new NotImplementedException();
        }

        private object Filter(object thisObj, object[] arguments)
        {
            var callbackfn = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
            var thisArg = arguments.Length > 1 ? arguments[1] : Undefined.Instance;

            var o = TypeConverter.ToObject(Engine, thisObj);
            var lenValue = o.Get("length");
            var len = TypeConverter.ToUint32(lenValue);

            var callable = callbackfn as ICallable;
            if (callable == null)
            {
                throw new JavaScriptException(Engine.TypeError, "Argument must be callable");
            }

            var a = Engine.Array.Construct(Arguments.Empty);

            var to = 0;
            for (var k = 0; k < len; k++)
            {
                var pk = k.ToString();
                var kpresent = o.HasProperty(pk);
                if (kpresent)
                {
                    var kvalue = o.Get(pk);
                    var selected = callable.Call(thisArg, new object[] { kvalue, k, o });
                    if (TypeConverter.ToBoolean(selected) == true)
                    {
                        a.DefineOwnProperty(to.ToString(), new DataDescriptor(kvalue) { Writable = true, Enumerable = true, Configurable = true }, false);
                        to++;
                    }
                }
            }

            return a;
        }

        private object Map(object thisObj, object[] arguments)
        {
            var callbackfn = arguments.Length > 0 ? arguments[0] : Undefined.Instance;
            var thisArg = arguments.Length > 1 ? arguments[1] : Undefined.Instance;

            var o = TypeConverter.ToObject(Engine, thisObj);
            var lenValue = o.Get("length");
{'fraction_non_alphanumeric': 0.11311394079708946, 'fraction_numerical': 0.0075243922606251035, 'mean_word_length': 2.197197991012424, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3204572', 'n_tokens_mistral': 3206, 'n_tokens_neox': 3073, 'n_words': 795}