From b2305cb67db98bc658a4eaca7f3d97f5ecdcd2ed Mon Sep 17 00:00:00 2001 From: Kesse Jones Date: Tue, 21 Apr 2020 20:17:16 -0300 Subject: [PATCH] LibJS: Add Array.prototype.lastIndexOf --- Libraries/LibJS/Runtime/ArrayPrototype.cpp | 35 +++++++++++++++++++ Libraries/LibJS/Runtime/ArrayPrototype.h | 1 + .../Tests/Array.prototype.lastIndexOf.js | 22 ++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 Libraries/LibJS/Tests/Array.prototype.lastIndexOf.js diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index c063085419..67a5630bca 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -55,6 +55,7 @@ ArrayPrototype::ArrayPrototype() put_native_function("slice", slice, 2); put_native_function("indexOf", index_of, 1); put_native_function("reverse", reverse, 0); + put_native_function("lastIndexOf", last_index_of, 1); put("length", Value(0)); } @@ -365,4 +366,38 @@ Value ArrayPrototype::reverse(Interpreter& interpreter) return array; } +Value ArrayPrototype::last_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 + from_index; + } + + auto search_element = interpreter.argument(0); + for (i32 i = array_size - 1; i >= from_index; --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 168827dcb5..e7c5dd833c 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -52,5 +52,6 @@ private: static Value slice(Interpreter&); static Value index_of(Interpreter&); static Value reverse(Interpreter&); + static Value last_index_of(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/Array.prototype.lastIndexOf.js b/Libraries/LibJS/Tests/Array.prototype.lastIndexOf.js new file mode 100644 index 0000000000..642c897292 --- /dev/null +++ b/Libraries/LibJS/Tests/Array.prototype.lastIndexOf.js @@ -0,0 +1,22 @@ +load("test-common.js"); + +try { + assert(Array.prototype.lastIndexOf.length === 1); + + var array = [1, 2, 3, 1, "hello"]; + + assert(array.lastIndexOf("hello") === 4); + assert(array.lastIndexOf(1) === 3); + assert(array.lastIndexOf(1, -1) === -1); + assert(array.lastIndexOf(1, -2) === 3); + assert(array.lastIndexOf(2) === 1); + assert(array.lastIndexOf(2, -3) === -1); + assert(array.lastIndexOf(2, -4) === 1); + assert([].lastIndexOf('hello') === -1); + assert([].lastIndexOf('hello', 10) === -1); + assert([].lastIndexOf('hello', -10) === -1); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}