Skip to content

Commit

Permalink
Revert "[JSC] Rebaseline Intl implementation based on lowest dependen…
Browse files Browse the repository at this point in the history
…cy ICU 70"

This reverts commit 0ea263d.
  • Loading branch information
mnutt committed Nov 22, 2024
1 parent fe781bc commit 68bf6dd
Show file tree
Hide file tree
Showing 16 changed files with 478 additions and 16 deletions.
27 changes: 27 additions & 0 deletions Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@
#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/icu/ICUHelpers.h>

#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
#include <unicode/uformattedvalue.h>
#ifdef U_HIDE_DRAFT_API
#undef U_HIDE_DRAFT_API
#endif
#endif // HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
#include <unicode/udateintervalformat.h>
#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
#define U_HIDE_DRAFT_API 1
#endif // HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)

WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN

Expand Down Expand Up @@ -1443,6 +1447,8 @@ UDateIntervalFormat* IntlDateTimeFormat::createDateIntervalFormatIfNecessary(JSG
return m_dateIntervalFormat.get();
}

#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)

static std::unique_ptr<UFormattedDateInterval, ICUDeleter<udtitvfmt_closeResult>> formattedValueFromDateRange(UDateIntervalFormat& dateIntervalFormat, UDateFormat& dateFormat, double startDate, double endDate, UErrorCode& status)
{
auto result = std::unique_ptr<UFormattedDateInterval, ICUDeleter<udtitvfmt_closeResult>>(udtitvfmt_openResult(&status));
Expand Down Expand Up @@ -1521,6 +1527,8 @@ static bool dateFieldsPracticallyEqual(const UFormattedValue* formattedValue, UE
return !hasSpan;
}

#endif // HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)

JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double startDate, double endDate)
{
ASSERT(m_dateFormat);
Expand All @@ -1539,6 +1547,7 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta
auto* dateIntervalFormat = createDateIntervalFormatIfNecessary(globalObject);
RETURN_IF_EXCEPTION(scope, { });

#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
UErrorCode status = U_ZERO_ERROR;
auto result = formattedValueFromDateRange(*dateIntervalFormat, *m_dateFormat, startDate, endDate, status);
if (U_FAILURE(status)) {
Expand Down Expand Up @@ -1576,6 +1585,17 @@ JSValue IntlDateTimeFormat::formatRange(JSGlobalObject* globalObject, double sta
replaceNarrowNoBreakSpaceOrThinSpaceWithNormalSpace(buffer);

return jsString(vm, String(WTFMove(buffer)));
#else
Vector<UChar, 32> buffer;
auto status = callBufferProducingFunction(udtitvfmt_format, dateIntervalFormat, startDate, endDate, buffer, nullptr);
if (U_FAILURE(status)) {
throwTypeError(globalObject, scope, "Failed to format date interval"_s);
return { };
}
replaceNarrowNoBreakSpaceOrThinSpaceWithNormalSpace(buffer);

return jsString(vm, String(WTFMove(buffer)));
#endif
}

JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, double startDate, double endDate)
Expand All @@ -1585,6 +1605,7 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
// http://tc39.es/proposal-intl-DateTimeFormat-formatRange/#sec-partitiondatetimerangepattern
startDate = timeClip(startDate);
endDate = timeClip(endDate);
Expand Down Expand Up @@ -1788,6 +1809,12 @@ JSValue IntlDateTimeFormat::formatRangeToParts(JSGlobalObject* globalObject, dou
}

return parts;
#else
UNUSED_PARAM(startDate);
UNUSED_PARAM(endDate);
throwTypeError(globalObject, scope, "Failed to format date interval"_s);
return { };
#endif
}


Expand Down
6 changes: 6 additions & 0 deletions Source/JavaScriptCore/runtime/IntlDateTimeFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@

struct UDateIntervalFormat;

#if !defined(HAVE_ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
#if U_ICU_VERSION_MAJOR_NUM >= 64
#define HAVE_ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS 1
#endif
#endif

namespace JSC {

enum class RelevantExtensionKey : uint8_t;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const ClassInfo IntlDateTimeFormatPrototype::s_info = { "Intl.DateTimeFormat"_s,
@begin dateTimeFormatPrototypeTable
format intlDateTimeFormatPrototypeGetterFormat DontEnum|ReadOnly|CustomAccessor
formatRange intlDateTimeFormatPrototypeFuncFormatRange DontEnum|Function 2
formatRangeToParts intlDateTimeFormatPrototypeFuncFormatRangeToParts DontEnum|Function 2
formatToParts intlDateTimeFormatPrototypeFuncFormatToParts DontEnum|Function 1
resolvedOptions intlDateTimeFormatPrototypeFuncResolvedOptions DontEnum|Function 0
@end
Expand All @@ -83,7 +82,12 @@ void IntlDateTimeFormatPrototype::finishCreation(VM& vm, JSGlobalObject* globalO
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
#if HAVE(ICU_U_DATE_INTERVAL_FORMAT_FORMAT_RANGE_TO_PARTS)
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("formatRangeToParts"_s, intlDateTimeFormatPrototypeFuncFormatRangeToParts, static_cast<unsigned>(PropertyAttribute::DontEnum), 2, ImplementationVisibility::Public);
#else
UNUSED_PARAM(globalObject);
UNUSED_PARAM(&intlDateTimeFormatPrototypeFuncFormatRangeToParts);
#endif
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}

Expand Down
27 changes: 27 additions & 0 deletions Source/JavaScriptCore/runtime/IntlDurationFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,21 @@
// While UListFormatter APIs are draft in ICU 67, they are stable in ICU 68 with the same function signatures.
// So we can assume that these signatures of draft APIs are stable.
// If UListFormatter is available, UNumberFormatter is also available.
#if HAVE(ICU_U_LIST_FORMATTER)
#ifdef U_HIDE_DRAFT_API
#undef U_HIDE_DRAFT_API
#endif
#endif
#include <unicode/ulistformatter.h>
#include <unicode/unumberformatter.h>
#include <unicode/ures.h>
#if HAVE(ICU_U_LIST_FORMATTER)
#define U_HIDE_DRAFT_API 1
#endif

#if HAVE(ICU_U_LIST_FORMATTER)
#include <unicode/uformattedvalue.h>
#endif

WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN

Expand Down Expand Up @@ -240,6 +247,7 @@ void IntlDurationFormat::initializeDurationFormat(JSGlobalObject* globalObject,
m_fractionalDigits = intlNumberOption(globalObject, options, vm.propertyNames->fractionalDigits, 0, 9, fractionalDigitsUndefinedValue);
RETURN_IF_EXCEPTION(scope, void());

#if HAVE(ICU_U_LIST_FORMATTER)
{
auto toUListFormatterWidth = [](Style style) {
// 6. Let listStyle be durationFormat.[[Style]].
Expand All @@ -266,8 +274,15 @@ void IntlDurationFormat::initializeDurationFormat(JSGlobalObject* globalObject,
return;
}
}
#else
UNUSED_PARAM(IntlDurationFormatInternal::verbose);
throwTypeError(globalObject, scope, "Failed to initialize Intl.DurationFormat since this feature is not supported in the linked ICU version"_s);
return;
#endif
}

#if HAVE(ICU_U_LIST_FORMATTER)

static String retrieveSeparator(const CString& locale, const String& numberingSystem)
{
ASCIILiteral fallbackTimeSeparator = ":"_s;
Expand Down Expand Up @@ -624,12 +639,15 @@ static Vector<Element> collectElements(JSGlobalObject* globalObject, const IntlD
return elements;
}

#endif

// https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.format
JSValue IntlDurationFormat::format(JSGlobalObject* globalObject, ISO8601::Duration duration) const
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

#if HAVE(ICU_U_LIST_FORMATTER)
auto elements = collectElements(globalObject, this, WTFMove(duration));
RETURN_IF_EXCEPTION(scope, { });

Expand Down Expand Up @@ -665,6 +683,10 @@ JSValue IntlDurationFormat::format(JSGlobalObject* globalObject, ISO8601::Durati
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);

return jsString(vm, String(WTFMove(result)));
#else
UNUSED_PARAM(duration);
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);
#endif
}

// https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.formatToParts
Expand All @@ -673,6 +695,7 @@ JSValue IntlDurationFormat::formatToParts(JSGlobalObject* globalObject, ISO8601:
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

#if HAVE(ICU_U_LIST_FORMATTER)
auto elements = collectElements(globalObject, this, WTFMove(duration));
RETURN_IF_EXCEPTION(scope, { });

Expand Down Expand Up @@ -825,6 +848,10 @@ JSValue IntlDurationFormat::formatToParts(JSGlobalObject* globalObject, ISO8601:
}

return parts;
#else
UNUSED_PARAM(duration);
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);
#endif
}

// https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.resolvedOptions
Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/runtime/IntlDurationFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ class IntlDurationFormat final : public JSNonFinalObject {
static ASCIILiteral unitStyleString(UnitStyle);
static ASCIILiteral displayString(Display);

#if HAVE(ICU_U_LIST_FORMATTER)
std::unique_ptr<UListFormatter, UListFormatterDeleter> m_listFormat;
#endif
String m_locale;
String m_numberingSystem;
CString m_dataLocaleWithExtensions;
Expand Down
24 changes: 24 additions & 0 deletions Source/JavaScriptCore/runtime/IntlListFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@

// While UListFormatter APIs are draft in ICU 67, they are stable in ICU 68 with the same function signatures.
// So we can assume that these signatures of draft APIs are stable.
#if HAVE(ICU_U_LIST_FORMATTER)
#ifdef U_HIDE_DRAFT_API
#undef U_HIDE_DRAFT_API
#endif
#endif
#include <unicode/ulistformatter.h>
#if HAVE(ICU_U_LIST_FORMATTER)
#define U_HIDE_DRAFT_API 1
#endif

#if HAVE(ICU_U_LIST_FORMATTER)
#include <unicode/uformattedvalue.h>
#endif

WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN

Expand Down Expand Up @@ -107,6 +114,7 @@ void IntlListFormat::initializeListFormat(JSGlobalObject* globalObject, JSValue
m_style = intlOption<Style>(globalObject, options, vm.propertyNames->style, { { "long"_s, Style::Long }, { "short"_s, Style::Short }, { "narrow"_s, Style::Narrow } }, "style must be either \"long\", \"short\", or \"narrow\""_s, Style::Long);
RETURN_IF_EXCEPTION(scope, void());

#if HAVE(ICU_U_LIST_FORMATTER)
auto toUListFormatterType = [](Type type) {
switch (type) {
case Type::Conjunction:
Expand Down Expand Up @@ -137,8 +145,13 @@ void IntlListFormat::initializeListFormat(JSGlobalObject* globalObject, JSValue
throwTypeError(globalObject, scope, "failed to initialize ListFormat"_s);
return;
}
#else
throwTypeError(globalObject, scope, "Failed to initialize Intl.ListFormat since this feature is not supported in the linked ICU version"_s);
return;
#endif
}

#if HAVE(ICU_U_LIST_FORMATTER)
static Vector<String, 4> stringListFromIterable(JSGlobalObject* globalObject, JSValue iterable)
{
Vector<String, 4> result;
Expand All @@ -158,13 +171,15 @@ static Vector<String, 4> stringListFromIterable(JSGlobalObject* globalObject, JS
});
return result;
}
#endif

// https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat.prototype.format
JSValue IntlListFormat::format(JSGlobalObject* globalObject, JSValue list) const
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

#if HAVE(ICU_U_LIST_FORMATTER)
auto stringList = stringListFromIterable(globalObject, list);
RETURN_IF_EXCEPTION(scope, { });

Expand All @@ -176,6 +191,10 @@ JSValue IntlListFormat::format(JSGlobalObject* globalObject, JSValue list) const
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);

return jsString(vm, String(WTFMove(result)));
#else
UNUSED_PARAM(list);
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);
#endif
}

// https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat.prototype.formatToParts
Expand All @@ -184,6 +203,7 @@ JSValue IntlListFormat::formatToParts(JSGlobalObject* globalObject, JSValue list
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

#if HAVE(ICU_U_LIST_FORMATTER)
auto stringList = stringListFromIterable(globalObject, list);
RETURN_IF_EXCEPTION(scope, { });

Expand Down Expand Up @@ -269,6 +289,10 @@ JSValue IntlListFormat::formatToParts(JSGlobalObject* globalObject, JSValue list
}

return parts;
#else
UNUSED_PARAM(list);
return throwTypeError(globalObject, scope, "failed to format list of strings"_s);
#endif
}

// https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat.prototype.resolvedOptions
Expand Down
6 changes: 6 additions & 0 deletions Source/JavaScriptCore/runtime/IntlListFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
#include "JSObject.h"
#include <wtf/unicode/icu/ICUHelpers.h>

#if !defined(HAVE_ICU_U_LIST_FORMATTER)
#if U_ICU_VERSION_MAJOR_NUM >= 67 || (U_ICU_VERSION_MAJOR_NUM >= 66 && USE(APPLE_INTERNAL_SDK))
#define HAVE_ICU_U_LIST_FORMATTER 1
#endif
#endif

struct UListFormatter;

namespace JSC {
Expand Down
Loading

0 comments on commit 68bf6dd

Please sign in to comment.