mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Implement Intl.Segmenter.prototype.segment method
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
39be7b7d97
commit
a526fc2ad8
12 changed files with 411 additions and 28 deletions
|
|
@ -1412,6 +1412,39 @@ static Value builtinIntlSegmenterSupportedLocalesOf(ExecutionState& state, Value
|
|||
return Intl::supportedLocales(state, availableLocales, requestedLocales, options);
|
||||
}
|
||||
|
||||
static Value builtinIntlSegmenterSegment(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
{
|
||||
if (!thisValue.isObject() || !thisValue.asObject()->isIntlSegmenterObject()) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Method called on incompatible receiver");
|
||||
}
|
||||
return thisValue.asObject()->asIntlSegmenterObject()->segment(state, argv[0].toString(state));
|
||||
}
|
||||
|
||||
static Value builtinIntlSegmentsIterator(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
{
|
||||
if (!thisValue.isObject() || !thisValue.asObject()->isIntlSegmentsObject()) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Method called on incompatible receiver");
|
||||
}
|
||||
|
||||
return thisValue.asObject()->asIntlSegmentsObject()->createIteratorObject(state);
|
||||
}
|
||||
|
||||
static Value builtinIntlSegmentsContaining(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
{
|
||||
if (!thisValue.isObject() || !thisValue.asObject()->isIntlSegmentsObject()) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Method called on incompatible receiver");
|
||||
}
|
||||
return thisValue.asObject()->asIntlSegmentsObject()->containing(state, argv[0]);
|
||||
}
|
||||
|
||||
static Value builtinIntlSegmentsIteratorNext(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
{
|
||||
if (!thisValue.isObject() || !thisValue.asObject()->isIntlSegmentsIteratorObject()) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Method called on incompatible receiver");
|
||||
}
|
||||
return thisValue.asObject()->asIntlSegmentsIteratorObject()->next(state);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static Value builtinIntlGetCanonicalLocales(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
|
||||
|
|
@ -1994,8 +2027,27 @@ void GlobalObject::installIntl(ExecutionState& state)
|
|||
m_intlSegmenterPrototype->directDefineOwnProperty(state, strings->lazyResolvedOptions(),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyResolvedOptions(), builtinIntlSegmenterResolvedOptions, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::WritablePresent)));
|
||||
|
||||
m_intlSegmenterPrototype->directDefineOwnProperty(state, strings->lazySegment(),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySegment(), builtinIntlSegmenterSegment, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::WritablePresent)));
|
||||
|
||||
m_intlSegmenterPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
|
||||
ObjectPropertyDescriptor(Value(strings->lazyIntlDotSegmenter().string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
||||
m_intlSegmentsPrototype = new PrototypeObject(state, m_objectPrototype);
|
||||
m_intlSegmentsPrototype->setGlobalIntrinsicObject(state, true);
|
||||
|
||||
m_intlSegmentsPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->symbolIterator, builtinIntlSegmentsIterator, 0, NativeFunctionInfo::Strict)),
|
||||
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
||||
m_intlSegmentsPrototype->directDefineOwnProperty(state, strings->lazyContaining(),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyContaining(), builtinIntlSegmentsContaining, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::WritablePresent)));
|
||||
|
||||
m_intlSegmentsIteratorPrototype = new PrototypeObject(state, m_iteratorPrototype);
|
||||
m_intlSegmentsIteratorPrototype->setGlobalIntrinsicObject(state, true);
|
||||
|
||||
m_intlSegmentsIteratorPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().next),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().next, builtinIntlSegmentsIteratorNext, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
#endif
|
||||
|
||||
m_intl->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
|
||||
|
|
|
|||
|
|
@ -884,14 +884,14 @@ void GlobalObject::installIterator(ExecutionState& state)
|
|||
m_asyncIteratorPrototype->setGlobalIntrinsicObject(state, true);
|
||||
// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-asynciteratorprototype-asynciterator
|
||||
m_asyncIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().asyncIterator),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.asyncIterator]")), builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->symbolAsyncIterator, builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)),
|
||||
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
||||
m_iteratorPrototype = new PrototypeObject(state);
|
||||
m_iteratorPrototype->setGlobalIntrinsicObject(state, true);
|
||||
// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-%iteratorprototype%-@@iterator
|
||||
m_iteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.iterator]")), builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->symbolIterator, builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)),
|
||||
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
m_iteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(state.context()->vmInstance()->globalSymbols().toStringTag)),
|
||||
ObjectPropertyDescriptor(Value(strings->Iterator.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
|
|
|||
|
|
@ -1773,7 +1773,7 @@ void GlobalObject::installString(ExecutionState& state)
|
|||
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
||||
m_stringPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.iterator]")), builtinStringIterator, 0, NativeFunctionInfo::Strict)),
|
||||
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->symbolIterator, builtinStringIterator, 0, NativeFunctionInfo::Strict)),
|
||||
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
||||
|
||||
m_stringPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->at),
|
||||
|
|
|
|||
207
src/intl/IntlSegmenter.cpp
Normal file
207
src/intl/IntlSegmenter.cpp
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
#if defined(ENABLE_ICU) && defined(ENABLE_INTL)
|
||||
/*
|
||||
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include "Escargot.h"
|
||||
#include "runtime/Context.h"
|
||||
#include "runtime/ExecutionState.h"
|
||||
#include "runtime/VMInstance.h"
|
||||
#include "Intl.h"
|
||||
#include "IntlSegmenter.h"
|
||||
|
||||
#if defined(ENABLE_INTL_SEGMENTER)
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
IntlSegmenterObject::IntlSegmenterObject(ExecutionState& state, Value locales, Value options)
|
||||
: IntlSegmenterObject(state, state.context()->globalObject()->intlSegmenterPrototype(), locales, options)
|
||||
{
|
||||
}
|
||||
|
||||
IntlSegmenterObject::IntlSegmenterObject(ExecutionState& state, Object* proto, Value locales, Value optionsInput)
|
||||
: DerivedObject(state, proto)
|
||||
{
|
||||
#if defined(ENABLE_RUNTIME_ICU_BINDER)
|
||||
UVersionInfo versionArray;
|
||||
u_getVersion(versionArray);
|
||||
if (versionArray[0] < 69) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Intl.NumberFormat needs 69+ version of ICU");
|
||||
}
|
||||
#endif
|
||||
ValueVector requestedLocales = Intl::canonicalizeLocaleList(state, locales);
|
||||
|
||||
Optional<Object*> options;
|
||||
if (!optionsInput.isUndefined()) {
|
||||
options = optionsInput.toObject(state);
|
||||
}
|
||||
|
||||
StringMap opt;
|
||||
Value localeMatcherValues[2] = { state.context()->staticStrings().lazyLookup().string(), state.context()->staticStrings().lazyBestFit().string() };
|
||||
String* matcher = localeMatcherValues[1].asString();
|
||||
if (options) {
|
||||
matcher = Intl::getOption(state, options.value(), state.context()->staticStrings().lazyLocaleMatcher().string(), Intl::StringValue, localeMatcherValues, 2, localeMatcherValues[1]).asString();
|
||||
}
|
||||
opt.insert(std::make_pair("matcher", matcher));
|
||||
|
||||
StringMap r = Intl::resolveLocale(state, state.context()->vmInstance()->intlDurationFormatAvailableLocales(), requestedLocales, opt, nullptr, 0, nullptr);
|
||||
String* locale = r.at("locale");
|
||||
m_locale = locale;
|
||||
|
||||
Value granularityValues[3] = { state.context()->staticStrings().lazyGrapheme().string(), state.context()->staticStrings().lazyWord().string(), state.context()->staticStrings().lazySentence().string() };
|
||||
m_granularity = granularityValues[0].asString();
|
||||
if (options) {
|
||||
m_granularity = Intl::getOption(state, options.value(), state.context()->staticStrings().lazyGranularity().string(), Intl::StringValue, granularityValues, 3, granularityValues[0]).asString();
|
||||
}
|
||||
|
||||
UBreakIteratorType type = UBRK_CHARACTER;
|
||||
if (m_granularity->equals("grapheme")) {
|
||||
type = UBRK_CHARACTER;
|
||||
} else if (m_granularity->equals("word")) {
|
||||
type = UBRK_WORD;
|
||||
} else if (m_granularity->equals("sentence")) {
|
||||
type = UBRK_SENTENCE;
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
m_icuSegmenter = ubrk_open(type, m_locale->toNonGCUTF8StringData().data(), nullptr, 0, &status);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to initialize Segmenter");
|
||||
}
|
||||
|
||||
addFinalizer([](PointerValue* obj, void* data) {
|
||||
IntlSegmenterObject* self = (IntlSegmenterObject*)obj;
|
||||
ubrk_close(self->m_icuSegmenter);
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
Object* IntlSegmenterObject::resolvedOptions(ExecutionState& state)
|
||||
{
|
||||
Object* options = new Object(state);
|
||||
auto& ss = state.context()->staticStrings();
|
||||
options->directDefineOwnProperty(state, ObjectPropertyName(ss.lazySmallLetterLocale()), ObjectPropertyDescriptor(m_locale, ObjectPropertyDescriptor::AllPresent));
|
||||
options->directDefineOwnProperty(state, ObjectPropertyName(ss.lazyGranularity()), ObjectPropertyDescriptor(m_granularity, ObjectPropertyDescriptor::AllPresent));
|
||||
return options;
|
||||
}
|
||||
|
||||
IntlSegmentsObject* IntlSegmenterObject::segment(ExecutionState& state, String* string)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
auto newIterator = ubrk_clone(m_icuSegmenter, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to clone ICU break iterator");
|
||||
}
|
||||
String* u16String = new UTF16String(string->toUTF16StringData());
|
||||
ubrk_setText(newIterator, u16String->bufferAccessData().bufferAs16Bit, string->length(), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to init ICU break iterator");
|
||||
}
|
||||
return new IntlSegmentsObject(state, string, u16String, m_granularity, newIterator);
|
||||
}
|
||||
|
||||
static Object* createSegmentDataObject(ExecutionState& state, String* string, int32_t startIndex, int32_t endIndex, UBreakIterator* segmenter, String* granularity)
|
||||
{
|
||||
Object* result = new Object(state);
|
||||
result->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazySegment()),
|
||||
ObjectPropertyDescriptor(string->substring(startIndex, endIndex), ObjectPropertyDescriptor::AllPresent));
|
||||
result->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().index),
|
||||
ObjectPropertyDescriptor(Value(startIndex), ObjectPropertyDescriptor::AllPresent));
|
||||
result->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().input),
|
||||
ObjectPropertyDescriptor(string, ObjectPropertyDescriptor::AllPresent));
|
||||
if (granularity->equals("word")) {
|
||||
int32_t ruleStatus = ubrk_getRuleStatus(segmenter);
|
||||
result->directDefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyIsWordLike()),
|
||||
ObjectPropertyDescriptor(Value(!(ruleStatus >= UBRK_WORD_NONE && ruleStatus <= UBRK_WORD_NONE_LIMIT)), ObjectPropertyDescriptor::AllPresent));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
IntlSegmentsObject::IntlSegmentsObject(ExecutionState& state, String* string, String* u16String, String* granularity, UBreakIterator* icuSegmenter)
|
||||
: DerivedObject(state, state.context()->globalObject()->intlSegmentsPrototype())
|
||||
, m_string(string)
|
||||
, m_u16String(u16String)
|
||||
, m_granularity(granularity)
|
||||
, m_icuSegmenter(icuSegmenter)
|
||||
{
|
||||
addFinalizer([](PointerValue* obj, void* data) {
|
||||
IntlSegmentsObject* self = (IntlSegmentsObject*)obj;
|
||||
ubrk_close(self->m_icuSegmenter);
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
Value IntlSegmentsObject::containing(ExecutionState& state, const Value& indexInput)
|
||||
{
|
||||
double value = indexInput.toInteger(state);
|
||||
|
||||
if (value < 0 || value >= m_string->length()) {
|
||||
return Value();
|
||||
}
|
||||
int32_t index = Value(Value::DoubleToIntConvertibleTestNeeds, value).toInt32(state);
|
||||
|
||||
int32_t startIndex = ubrk_preceding(m_icuSegmenter, index + 1);
|
||||
if (startIndex == UBRK_DONE) {
|
||||
startIndex = 0;
|
||||
}
|
||||
int32_t endIndex = ubrk_following(m_icuSegmenter, index);
|
||||
if (endIndex == UBRK_DONE) {
|
||||
endIndex = m_string->length();
|
||||
}
|
||||
|
||||
return createSegmentDataObject(state, m_string, startIndex, endIndex, m_icuSegmenter, m_granularity);
|
||||
}
|
||||
|
||||
IntlSegmentsIteratorObject* IntlSegmentsObject::createIteratorObject(ExecutionState& state)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
auto newIterator = ubrk_clone(m_icuSegmenter, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to clone ICU break iterator");
|
||||
}
|
||||
ubrk_first(newIterator);
|
||||
return new IntlSegmentsIteratorObject(state, this, newIterator);
|
||||
}
|
||||
|
||||
IntlSegmentsIteratorObject::IntlSegmentsIteratorObject(ExecutionState& state, IntlSegmentsObject* segments, UBreakIterator* icuSegmenter)
|
||||
: IteratorObject(state, state.context()->globalObject()->intlSegmentsIteratorPrototype())
|
||||
, m_segments(segments)
|
||||
, m_icuSegmenter(icuSegmenter)
|
||||
{
|
||||
addFinalizer([](PointerValue* obj, void* data) {
|
||||
IntlSegmentsIteratorObject* self = (IntlSegmentsIteratorObject*)obj;
|
||||
ubrk_close(self->m_icuSegmenter);
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
std::pair<Value, bool> IntlSegmentsIteratorObject::advance(ExecutionState& state)
|
||||
{
|
||||
int32_t startIndex = ubrk_current(m_icuSegmenter);
|
||||
int32_t endIndex = ubrk_next(m_icuSegmenter);
|
||||
if (endIndex == UBRK_DONE) {
|
||||
return std::make_pair(Value(), true);
|
||||
}
|
||||
|
||||
return std::make_pair(Value(createSegmentDataObject(state, m_segments->string(), startIndex, endIndex, m_icuSegmenter, m_segments->granularity())), false);
|
||||
}
|
||||
|
||||
} // namespace Escargot
|
||||
#endif
|
||||
#endif
|
||||
104
src/intl/IntlSegmenter.h
Normal file
104
src/intl/IntlSegmenter.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#if defined(ENABLE_ICU) && defined(ENABLE_INTL) && defined(ENABLE_INTL_SEGMENTER)
|
||||
/*
|
||||
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __EscargotIntlSegmenter__
|
||||
#define __EscargotIntlSegmenter__
|
||||
|
||||
#include "runtime/Object.h"
|
||||
#include "runtime/IteratorObject.h"
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
class IntlSegmentsIteratorObject;
|
||||
|
||||
class IntlSegmenterObject : public DerivedObject {
|
||||
public:
|
||||
IntlSegmenterObject(ExecutionState& state, Value locales, Value options);
|
||||
IntlSegmenterObject(ExecutionState& state, Object* proto, Value locales, Value options);
|
||||
|
||||
virtual bool isIntlSegmenterObject() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Object* resolvedOptions(ExecutionState& state);
|
||||
IntlSegmentsObject* segment(ExecutionState& state, String* string);
|
||||
|
||||
protected:
|
||||
String* m_locale;
|
||||
String* m_granularity;
|
||||
|
||||
UBreakIterator* m_icuSegmenter;
|
||||
};
|
||||
|
||||
class IntlSegmentsObject : public DerivedObject {
|
||||
public:
|
||||
IntlSegmentsObject(ExecutionState& state, String* string, String* u16String, String* granularity, UBreakIterator* icuSegmenter);
|
||||
|
||||
virtual bool isIntlSegmentsObject() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Value containing(ExecutionState& state, const Value& index);
|
||||
IntlSegmentsIteratorObject* createIteratorObject(ExecutionState& state);
|
||||
|
||||
String* string() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
String* u16String() const
|
||||
{
|
||||
return m_u16String;
|
||||
}
|
||||
|
||||
String* granularity() const
|
||||
{
|
||||
return m_granularity;
|
||||
}
|
||||
|
||||
protected:
|
||||
String* m_string;
|
||||
String* m_u16String;
|
||||
String* m_granularity;
|
||||
UBreakIterator* m_icuSegmenter;
|
||||
};
|
||||
|
||||
class IntlSegmentsIteratorObject : public IteratorObject {
|
||||
public:
|
||||
IntlSegmentsIteratorObject(ExecutionState& state, IntlSegmentsObject* segments, UBreakIterator* icuSegmenter);
|
||||
|
||||
virtual bool isIntlSegmentsIteratorObject() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual std::pair<Value, bool> advance(ExecutionState& state) override;
|
||||
|
||||
private:
|
||||
IntlSegmentsObject* m_segments;
|
||||
UBreakIterator* m_icuSegmenter;
|
||||
};
|
||||
|
||||
} // namespace Escargot
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -130,7 +130,9 @@ class FunctionObject;
|
|||
#if defined(ENABLE_INTL_SEGMENTER)
|
||||
#define GLOBALOBJECT_BUILTIN_INTL_SEGMENTER(F, objName) \
|
||||
F(intlSegmenter, FunctionObject, objName) \
|
||||
F(intlSegmenterPrototype, Object, objName)
|
||||
F(intlSegmenterPrototype, Object, objName) \
|
||||
F(intlSegmentsPrototype, Object, objName) \
|
||||
F(intlSegmentsIteratorPrototype, Object, objName)
|
||||
#else
|
||||
#define GLOBALOBJECT_BUILTIN_INTL_SEGMENTER(F, objName)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ class IntlDisplayNamesObject;
|
|||
class IntlListFormatObject;
|
||||
class IntlDurationFormatObject;
|
||||
class IntlSegmenterObject;
|
||||
class IntlSegmentsObject;
|
||||
class IntlSegmentsIteratorObject;
|
||||
#endif
|
||||
#if defined(ENABLE_WASM)
|
||||
class WASMModuleObject;
|
||||
|
|
@ -542,6 +544,16 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isIntlSegmentsObject() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isIntlSegmentsIteratorObject() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_TEMPORAL)
|
||||
|
|
@ -962,6 +974,18 @@ public:
|
|||
ASSERT(isIntlSegmenterObject());
|
||||
return (IntlSegmenterObject*)this;
|
||||
}
|
||||
|
||||
IntlSegmentsObject* asIntlSegmentsObject()
|
||||
{
|
||||
ASSERT(isIntlSegmentsObject());
|
||||
return (IntlSegmentsObject*)this;
|
||||
}
|
||||
|
||||
IntlSegmentsIteratorObject* asIntlSegmentsIteratorObject()
|
||||
{
|
||||
ASSERT(isIntlSegmentsIteratorObject());
|
||||
return (IntlSegmentsIteratorObject*)this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_TEMPORAL)
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ void StaticStrings::initStaticStrings()
|
|||
INIT_STATIC_STRING(symbolReplace, "[Symbol.replace]");
|
||||
INIT_STATIC_STRING(symbolSearch, "[Symbol.search]");
|
||||
INIT_STATIC_STRING(symbolSplit, "[Symbol.split]");
|
||||
INIT_STATIC_STRING(symbolAsyncIterator, "[Symbol.asyncIterator]");
|
||||
INIT_STATIC_STRING(symbolIterator, "[Symbol.iterator]");
|
||||
|
||||
#if defined(ENABLE_WASM)
|
||||
INIT_STATIC_STRING(getExports, "get exports");
|
||||
|
|
|
|||
|
|
@ -728,6 +728,7 @@ namespace Escargot {
|
|||
F(CompactDisplay, "compactDisplay") \
|
||||
F(Compare, "compare") \
|
||||
F(CompareFunction, "compareFunction") \
|
||||
F(Containing, "containing") \
|
||||
F(Conjunction, "conjunction") \
|
||||
F(Constrain, "constrain") \
|
||||
F(Currency, "currency") \
|
||||
|
|
@ -826,6 +827,7 @@ namespace Escargot {
|
|||
F(IntlDotDurationFormat, "Intl.DurationFormat") \
|
||||
F(IntlDotRelativeTimeFormat, "Intl.RelativeTimeFormat") \
|
||||
F(IntlDotSegmenter, "Intl.Segmenter") \
|
||||
F(IsWordLike, "isWordLike") \
|
||||
F(Kf, "kf") \
|
||||
F(Kn, "kn") \
|
||||
F(Language, "language") \
|
||||
|
|
@ -879,6 +881,8 @@ namespace Escargot {
|
|||
F(Script, "script") \
|
||||
F(Second, "second") \
|
||||
F(Seconds, "seconds") \
|
||||
F(Segment, "segment") \
|
||||
F(Segments, "segments") \
|
||||
F(Sentence, "sentence") \
|
||||
F(Sensitivity, "sensitivity") \
|
||||
F(Select, "select") \
|
||||
|
|
@ -1057,6 +1061,8 @@ public:
|
|||
AtomicString getmaxByteLength;
|
||||
AtomicString getresizable;
|
||||
AtomicString set__proto__;
|
||||
AtomicString symbolAsyncIterator;
|
||||
AtomicString symbolIterator;
|
||||
AtomicString symbolMatch;
|
||||
AtomicString symbolMatchAll;
|
||||
AtomicString symbolReplace;
|
||||
|
|
|
|||
5
third_party/runtime_icu_binder/ICUPolyfill.h
vendored
5
third_party/runtime_icu_binder/ICUPolyfill.h
vendored
|
|
@ -148,6 +148,11 @@
|
|||
#define ubrk_setUText RuntimeICUBinder::ICU::instance().ubrk_setUText
|
||||
#define ubrk_close RuntimeICUBinder::ICU::instance().ubrk_close
|
||||
#define ubrk_clone RuntimeICUBinder::ICU::instance().ubrk_clone
|
||||
#define ubrk_preceding RuntimeICUBinder::ICU::instance().ubrk_preceding
|
||||
#define ubrk_following RuntimeICUBinder::ICU::instance().ubrk_following
|
||||
#define ubrk_getRuleStatus RuntimeICUBinder::ICU::instance().ubrk_getRuleStatus
|
||||
#define ubrk_first RuntimeICUBinder::ICU::instance().ubrk_first
|
||||
#define ubrk_current RuntimeICUBinder::ICU::instance().ubrk_current
|
||||
|
||||
#define ucnv_open RuntimeICUBinder::ICU::instance().ucnv_open
|
||||
#define ucnv_compareNames RuntimeICUBinder::ICU::instance().ucnv_compareNames
|
||||
|
|
|
|||
|
|
@ -162,6 +162,11 @@ namespace RuntimeICUBinder {
|
|||
F(ubrk_openRules, UBreakIterator*(CALLCONV*)(const UChar* rules, int32_t rulesLength, const UChar* text, int32_t textLength, UParseError* parseErr, UErrorCode* status), UBreakIterator*) \
|
||||
F(ubrk_next, int32_t(CALLCONV*)(UBreakIterator * bi), int32_t) \
|
||||
F(ubrk_clone, UBreakIterator*(CALLCONV*)(const UBreakIterator* format, UErrorCode* status), UBreakIterator*) \
|
||||
F(ubrk_preceding, int32_t(CALLCONV*)(UBreakIterator *bi, int32_t offset), int32_t) \
|
||||
F(ubrk_following, int32_t(CALLCONV*)(UBreakIterator *bi, int32_t offset), int32_t) \
|
||||
F(ubrk_getRuleStatus, int32_t(CALLCONV*)(UBreakIterator *bi), int32_t) \
|
||||
F(ubrk_first, int32_t(CALLCONV*)(UBreakIterator *bi), int32_t) \
|
||||
F(ubrk_current, int32_t(CALLCONV*)(const UBreakIterator *bi), int32_t) \
|
||||
F(ucsdet_open, UCharsetDetector*(CALLCONV*)(UErrorCode * status), UCharsetDetector*) \
|
||||
F(ucsdet_detectAll, const UCharsetMatch**(CALLCONV*)(UCharsetDetector * ucsd, int32_t* matchesFound, UErrorCode* status), const UCharsetMatch**) \
|
||||
F(ucsdet_detect, const UCharsetMatch*(CALLCONV*)(UCharsetDetector * ucsd, UErrorCode * status), const UCharsetMatch*) \
|
||||
|
|
|
|||
|
|
@ -4658,30 +4658,6 @@
|
|||
<test id="intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-long"><reason>TODO</reason></test>
|
||||
<test id="intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow"><reason>TODO</reason></test>
|
||||
<test id="intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-short"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/constructor/constructor/subclassing"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/branding"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/branding"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/breakable-input"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/index-throws"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/iswordlike"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/length"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/name"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/one-index"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/out-of-bound-index"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/prop-desc"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/unbreakable-input"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/word-iswordlike"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/containing/zero-index"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/length"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/name"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/nested-next"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/next-inside-next"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/next-mix-with-containing"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/prop-desc"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/segment-grapheme-iterable"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/segment-sentence-iterable"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/segment-tostring"><reason>TODO</reason></test>
|
||||
<test id="intl402/Segmenter/prototype/segment/segment-word-iterable"><reason>TODO</reason></test>
|
||||
<test id="intl402/Temporal/Duration/compare/relativeto-hour"><reason>TODO</reason></test>
|
||||
<test id="intl402/Temporal/Duration/compare/relativeto-sub-minute-offset"><reason>TODO</reason></test>
|
||||
<test id="intl402/Temporal/Duration/compare/twenty-five-hour-day"><reason>TODO</reason></test>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue