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"

Still need to support ICU 66 for the short term.

This reverts commit 0ea263d.
  • Loading branch information
mnutt committed Nov 24, 2024
1 parent 32a9ddb commit fa97b2d
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 fa97b2d

Please sign in to comment.