From 579975fd1e47953ac71753c014442190ba4a2506 Mon Sep 17 00:00:00 2001 From: Kesse Jones Date: Sun, 19 Apr 2020 20:07:22 -0300 Subject: [PATCH] LibJS: Add Array.prototype.indexOf --- Libraries/LibJS/Runtime/ArrayPrototype.cpp | 34 +++++++++++++++++++ Libraries/LibJS/Runtime/ArrayPrototype.h | 2 +- .../LibJS/Tests/Array.prototype.indexOf.js | 24 +++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 Libraries/LibJS/Tests/Array.prototype.indexOf.js diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index fc38b71acb..d3e881d81d 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -53,6 +53,7 @@ ArrayPrototype::ArrayPrototype() put_native_function("join", join, 1); put_native_function("concat", concat, 1); put_native_function("slice", slice, 2); + put_native_function("indexOf", index_of, 1); put("length", Value(0)); } @@ -309,4 +310,37 @@ Value ArrayPrototype::slice(Interpreter& interpreter) return new_array; } +Value ArrayPrototype::index_of(Interpreter& interpreter) +{ + auto* array = array_from(interpreter); + if (!array) + return {}; + + i32 array_size = static_cast(array->elements().size()); + if (interpreter.argument_count() == 0 || array_size == 0) + return Value(-1); + + i32 from_index = 0; + if (interpreter.argument_count() >= 2) { + from_index = interpreter.argument(1).to_number().to_i32(); + + if (from_index >= array_size) + return Value(-1); + + auto negative_min_index = ((array_size - 1) * -1); + if (from_index < negative_min_index) + from_index = 0; + else if (from_index < 0) + from_index = (array_size - 1) + from_index; + } + + auto search_element = interpreter.argument(0); + for (i32 i = from_index; i < array_size; ++i) { + auto& element = array->elements().at(i); + if (typed_eq(interpreter, element, search_element).as_bool()) + return Value(i); + } + + return Value(-1); +} } diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.h b/Libraries/LibJS/Runtime/ArrayPrototype.h index 5c27d3c9c7..50afdced8b 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -50,6 +50,6 @@ private: static Value join(Interpreter&); static Value concat(Interpreter&); static Value slice(Interpreter&); + static Value index_of(Interpreter&); }; - } diff --git a/Libraries/LibJS/Tests/Array.prototype.indexOf.js b/Libraries/LibJS/Tests/Array.prototype.indexOf.js new file mode 100644 index 0000000000..40e1f72440 --- /dev/null +++ b/Libraries/LibJS/Tests/Array.prototype.indexOf.js @@ -0,0 +1,24 @@ +load("test-common.js"); + +try { + assert(Array.prototype.indexOf.length === 1); + + var array = ['hello', 'friends', 1, 2, false]; + + assert(array.indexOf('hello') === 0); + assert(array.indexOf('friends') === 1); + assert(array.indexOf(false) === 4); + assert(array.indexOf(false, 2) === 4); + assert(array.indexOf(false, -2) === 4); + assert(array.indexOf(1) === 2); + assert(array.indexOf(1, 1000) === -1); + assert(array.indexOf(1, -1000) === 2); + assert(array.indexOf('serenity') === -1); + assert([].indexOf('serenity') === -1); + assert([].indexOf('serenity', 10) === -1); + assert([].indexOf('serenity', -10) === -1); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}