mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:37:34 +00:00
LibJS: Add String.raw
This commit is contained in:
parent
b5f1df57ed
commit
ab652fa1ee
3 changed files with 67 additions and 1 deletions
|
@ -24,12 +24,13 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/StringConstructor.h>
|
#include <LibJS/Runtime/StringConstructor.h>
|
||||||
#include <LibJS/Runtime/StringObject.h>
|
#include <LibJS/Runtime/StringObject.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ StringConstructor::StringConstructor()
|
||||||
{
|
{
|
||||||
put("prototype", interpreter().global_object().string_prototype(), 0);
|
put("prototype", interpreter().global_object().string_prototype(), 0);
|
||||||
put("length", Value(1), Attribute::Configurable);
|
put("length", Value(1), Attribute::Configurable);
|
||||||
|
|
||||||
|
put_native_function("raw", raw, 0, Attribute::Writable | Attribute::Configurable);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringConstructor::~StringConstructor()
|
StringConstructor::~StringConstructor()
|
||||||
|
@ -63,4 +66,30 @@ Value StringConstructor::construct(Interpreter& interpreter)
|
||||||
return StringObject::create(interpreter.global_object(), *primitive_string);
|
return StringObject::create(interpreter.global_object(), *primitive_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value StringConstructor::raw(Interpreter& interpreter)
|
||||||
|
{
|
||||||
|
auto* template_object = interpreter.argument(0).to_object(interpreter.heap());
|
||||||
|
if (interpreter.exception())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto raw = template_object->get("raw");
|
||||||
|
if (raw.is_empty() || raw.is_undefined() || raw.is_null()) {
|
||||||
|
interpreter.throw_exception<TypeError>(String::format("Cannot convert property 'raw' to object from %s", raw.is_null() ? "null" : "undefined"));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (!raw.is_array())
|
||||||
|
return js_string(interpreter, "");
|
||||||
|
|
||||||
|
auto& raw_array_elements = static_cast<Array*>(raw.to_object(interpreter.heap()))->elements();
|
||||||
|
StringBuilder builder;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < raw_array_elements.size(); ++i) {
|
||||||
|
builder.append(raw_array_elements.at(i).to_string());
|
||||||
|
if (i + 1 < interpreter.argument_count() && i < raw_array_elements.size() - 1)
|
||||||
|
builder.append(interpreter.argument(i + 1).to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
return js_string(interpreter, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual bool has_constructor() const override { return true; }
|
virtual bool has_constructor() const override { return true; }
|
||||||
virtual const char* class_name() const override { return "StringConstructor"; }
|
virtual const char* class_name() const override { return "StringConstructor"; }
|
||||||
|
|
||||||
|
static Value raw(Interpreter&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
35
Libraries/LibJS/Tests/String.raw.js
Normal file
35
Libraries/LibJS/Tests/String.raw.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
load("test-common.js")
|
||||||
|
|
||||||
|
try {
|
||||||
|
let str = String.raw`foo\nbar`;
|
||||||
|
assert(str.length === 8 && str === "foo\\nbar");
|
||||||
|
|
||||||
|
str = String.raw`foo ${1 + 9}\nbar${"hf!"}`;
|
||||||
|
assert(str === "foo 10\\nbarhf!");
|
||||||
|
|
||||||
|
str = String.raw`${10}${20}${30}`;
|
||||||
|
assert(str === "102030");
|
||||||
|
|
||||||
|
str = String.raw({ raw: ["foo ", "\\nbar"] }, 10, "hf!");
|
||||||
|
assert(str === "foo 10\\nbar");
|
||||||
|
|
||||||
|
str = String.raw({ raw: ["foo ", "\\nbar"] });
|
||||||
|
assert(str === "foo \\nbar");
|
||||||
|
|
||||||
|
str = String.raw({ raw: [] }, 10, "hf!");
|
||||||
|
assert(str === "");
|
||||||
|
|
||||||
|
str = String.raw({ raw: 1 });
|
||||||
|
assert(str === "");
|
||||||
|
|
||||||
|
assertThrowsError(() => {
|
||||||
|
String.raw({});
|
||||||
|
}, {
|
||||||
|
error: TypeError,
|
||||||
|
message: "Cannot convert property 'raw' to object from undefined",
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("PASS");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("FAIL: " + e);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue