LibJS: Add StringIterator

This commit is contained in:
Matthew Olsson 2020-07-11 20:23:01 -07:00 committed by Andreas Kling
parent ac2470e66e
commit c831fb17bf
Notes: sideshowbarker 2024-07-19 04:51:49 +09:00
13 changed files with 252 additions and 3 deletions

View file

@ -46,6 +46,7 @@ public:
u32 operator*() const;
int codepoint_length_in_bytes() const;
bool done() const { return !m_length; }
private:
Utf8CodepointIterator(const unsigned char*, int);

View file

@ -63,6 +63,8 @@ set(SOURCES
Runtime/ScriptFunction.cpp
Runtime/Shape.cpp
Runtime/StringConstructor.cpp
Runtime/StringIterator.cpp
Runtime/StringIteratorPrototype.cpp
Runtime/StringObject.cpp
Runtime/StringPrototype.cpp
Runtime/Symbol.cpp

View file

@ -69,7 +69,8 @@
#define JS_ENUMERATE_ITERATOR_PROTOTYPES \
__JS_ENUMERATE(Iterator, iterator) \
__JS_ENUMERATE(ArrayIterator, array_iterator)
__JS_ENUMERATE(ArrayIterator, array_iterator) \
__JS_ENUMERATE(StringIterator, string_iterator)
#define JS_ENUMERATE_BUILTIN_TYPES \
JS_ENUMERATE_NATIVE_OBJECTS \

View file

@ -24,7 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <LibJS/Interpreter.h>
#include <LibJS/Runtime/ArrayIterator.h>
#include <LibJS/Runtime/GlobalObject.h>

View file

@ -41,8 +41,8 @@ ArrayIteratorPrototype::ArrayIteratorPrototype(GlobalObject& global_object)
void ArrayIteratorPrototype::initialize(Interpreter& interpreter, GlobalObject& global_object)
{
Object::initialize(interpreter, global_object);
define_native_function("next", next, 0, Attribute::Writable | Attribute::Configurable);
define_native_function("next", next, 0, Attribute::Configurable | Attribute::Writable);
define_property(interpreter.well_known_symbol_to_string_tag(), js_string(interpreter, "Array Iterator"), Attribute::Configurable);
}

View file

@ -58,6 +58,7 @@
#include <LibJS/Runtime/RegExpPrototype.h>
#include <LibJS/Runtime/Shape.h>
#include <LibJS/Runtime/StringConstructor.h>
#include <LibJS/Runtime/StringIteratorPrototype.h>
#include <LibJS/Runtime/StringPrototype.h>
#include <LibJS/Runtime/SymbolConstructor.h>
#include <LibJS/Runtime/SymbolPrototype.h>

View file

@ -123,6 +123,7 @@ public:
virtual bool is_number_object() const { return false; }
virtual bool is_symbol_object() const { return false; }
virtual bool is_bigint_object() const { return false; }
virtual bool is_string_iterator_object() const { return false; }
virtual bool is_array_iterator_object() const { return false; }
virtual const char* class_name() const override { return "Object"; }

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/Utf8View.h>
#include <LibJS/Runtime/StringIterator.h>
#include <LibJS/Runtime/GlobalObject.h>
namespace JS {
StringIterator* StringIterator::create(GlobalObject& global_object, String string)
{
return global_object.heap().allocate<StringIterator>(global_object, *global_object.string_iterator_prototype(), move(string));
}
StringIterator::StringIterator(Object& prototype, String string)
: Object(prototype)
, m_string(move(string))
, m_iterator(Utf8View(m_string).begin())
{
}
StringIterator::~StringIterator()
{
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/Utf8View.h>
#include <LibJS/Runtime/Object.h>
namespace JS {
class StringIterator final : public Object {
JS_OBJECT(StringIterator, Object);
public:
static StringIterator* create(GlobalObject&, String string);
explicit StringIterator(Object& prototype, String string);
virtual ~StringIterator() override;
Utf8CodepointIterator& iterator() { return m_iterator; }
bool done() const { return m_done; }
private:
friend class StringIteratorPrototype;
virtual bool is_string_iterator_object() const override { return true; }
String m_string;
Utf8CodepointIterator m_iterator;
bool m_done { false };
};
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/StringBuilder.h>
#include <LibJS/Runtime/StringIterator.h>
#include <LibJS/Runtime/StringIteratorPrototype.h>
#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/IteratorOperations.h>
namespace JS {
StringIteratorPrototype::StringIteratorPrototype(GlobalObject& global_object)
: Object(*global_object.iterator_prototype())
{
}
void StringIteratorPrototype::initialize(Interpreter& interpreter, GlobalObject& global_object)
{
Object::initialize(interpreter, global_object);
define_native_function("next", next, 0, Attribute::Configurable | Attribute::Writable);
define_property(interpreter.well_known_symbol_to_string_tag(), js_string(interpreter, "String Iterator"), Attribute::Configurable);
}
StringIteratorPrototype::~StringIteratorPrototype()
{
}
JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next)
{
auto this_value = interpreter.this_value(global_object);
if (!this_value.is_object() || !this_value.as_object().is_string_iterator_object())
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "String Iterator");
auto& this_object = this_value.as_object();
auto& iterator = static_cast<StringIterator&>(this_object);
if (iterator.done())
return create_iterator_result_object(interpreter, global_object, js_undefined(), true);
auto& utf8_iterator = iterator.iterator();
if (utf8_iterator.done()) {
iterator.m_done = true;
return create_iterator_result_object(interpreter, global_object, js_undefined(), true);
}
StringBuilder builder;
builder.append_codepoint(*utf8_iterator);
++utf8_iterator;
return create_iterator_result_object(interpreter, global_object, js_string(interpreter, builder.to_string()), false);
}
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <LibJS/Runtime/Object.h>
namespace JS {
class StringIteratorPrototype final : public Object {
JS_OBJECT(StringIteratorPrototype, Object)
public:
StringIteratorPrototype(GlobalObject&);
virtual void initialize(Interpreter&, GlobalObject&) override;
virtual ~StringIteratorPrototype() override;
private:
JS_DECLARE_NATIVE_FUNCTION(next);
};
}

View file

@ -33,6 +33,7 @@
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/PrimitiveString.h>
#include <LibJS/Runtime/StringObject.h>
#include <LibJS/Runtime/StringIterator.h>
#include <LibJS/Runtime/StringPrototype.h>
#include <LibJS/Runtime/Value.h>
#include <string.h>
@ -87,6 +88,7 @@ void StringPrototype::initialize(Interpreter& interpreter, GlobalObject& global_
define_native_function("includes", includes, 1, attr);
define_native_function("slice", slice, 2, attr);
define_native_function("lastIndexOf", last_index_of, 1, attr);
define_native_function(interpreter.well_known_symbol_iterator(), symbol_iterator, 0, attr);
}
StringPrototype::~StringPrototype()
@ -428,4 +430,16 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
return Value(-1);
}
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
{
auto this_object = interpreter.this_value(global_object);
if (this_object.is_undefined() || this_object.is_null())
return interpreter.throw_exception<TypeError>(ErrorType::ToObjectNullOrUndef);
auto string = this_object.to_string(interpreter);
if (interpreter.exception())
return {};
return StringIterator::create(global_object, string);
}
}

View file

@ -59,6 +59,8 @@ private:
JS_DECLARE_NATIVE_FUNCTION(includes);
JS_DECLARE_NATIVE_FUNCTION(slice);
JS_DECLARE_NATIVE_FUNCTION(last_index_of);
JS_DECLARE_NATIVE_FUNCTION(symbol_iterator);
};
}