hermes icon indicating copy to clipboard operation
hermes copied to clipboard

Improve ICU4C-based Intl.DateTimeFormat implementation

Open robchu05 opened this issue 9 months ago • 4 comments

Summary

Improve and refactor ICU4C-based Intl.DateTimeFormat implementation for non-Android / non-Apple platforms.

  • Add a flag in top-level CMakeLists.txt for enabling Intl formatRange() and formatRangeToParts() APIs for non-Android and non-Apple platforms, i.e. Linux / ICU4C-backed Intl implementation.
  • Add the platform plumbing code for formatRange() and formatRangeToParts().
  • Remove PlatformIntlShared.h/.cpp as the remaining logic is only used in ICU4C-backed Intl.DateTimeFormat implementation and is now all inside impl_icu/DateTimeFormat.cpp.
  • Fix a bug in BCP47Parser isUnicodeVariantSubtag() so that the code accounts for the "digit" porition in the "digit alphanum{3}" syntax definition.
  • impl_icu/DateTimeFormat.h|.cpp is the implementation of Intl.DateTimeFormat using ICU4C C APIs. No ICU4C C++ APIs are used for ABI stability.
  • In PlatformIntlICU.cpp, remove DateTimeFormat implementation code and redirect DateTimeFormat platform implementation calls to impl_icu::DateTimeFormat.
  • Edit the order of Intl.DateTimeFormat options list in Intl.cpp so that they match the spec's option read ordering. A few test262 intl DateTimeFormat tests check for option read order and would fail if the options in this list are not ordered in the spec's option read ordering.
  • Add reading and validating formatMatcher option in PlatformIntlApple.mm.
  • Add new test files: date-time-format-additional.js, date-time-format-hour-cycle.js, date-time-format-format-range.js. They tests Intl.DateTimeFormat features that are not supported on Apple, and thus labeled with "UNSUPPORTED: apple". The test runner will skip these when running on Apple platform.
  • Rename date-time-format-apple.js to date-time-format.js, which have common test cases for both Apple and Linux / ICU4C-backed Intl.DateTimeFormat implementation. Edit a few test cases and expectations to account for differences in locale data and time zone id support (only use IANA time zone ids as they are the only ones that the spec allows). Add more negative test cases for invalid option values.
  • Enable running more test262 Intl test cases by editing testsuite.py to no longer skip tests that include testintl.js and tests that use 'const' declaration.
  • Update corresponding skip lists so to skip tests that are failing due to unsupported features for Hermes in general, for Linux only, or for Apple only.

Test Plan

Builds succeed on Ubuntu 20.04, 24.04, and Mac. Run the following JS tests on Ubuntu 20.04, 24.04, Mac, and all pass:

$ ./build/bin/hermes ./hermes/test/hermes/intl/intl.js
$ ./build/bin/hermes ./hermes/test/hermes/intl/get-canonical-locales.js | ./build/bin/FileCheck --match-full-lines ./hermes/test/hermes/intl/get-canonical-locales.js
$ ./build/bin/hermes ./hermes/test/hermes/intl/collator.js | ./build/bin/FileCheck --match-full-lines ./hermes/test/hermes/intl/collator.js
$ LC_ALL=fr_FR _HERMES_TEST_LOCALE=fr_FR ./build/bin/hermes ./hermes/test/hermes/intl/collator-resolved-options.js
$ TZ=GMT ./build/bin/hermes -O -target=HBC ./hermes/test/hermes/intl/date-time-format.js | ./build/bin/FileCheck --match-full-lines ./hermes/test/hermes/intl/date-time-format.js
$ TZ=US/Pacific ./build/bin/hermes -O -target=HBC hermes/test/hermes/intl/default-tz.js | ./build/bin/FileCheck --match-full-lines ./hermes/test/hermes/intl/default-tz.js

Run the following JS tests on Ubuntu 20.04, 24.04, and all pass:

$ ./build/bin/hermes hermes/test/hermes/intl/collator-resolved-options-validate-co-extension.js
$ TZ=GMT ./build/bin/hermes hermes/test/hermes/intl/date-time-format-additional.js | ./build/bin/FileCheck --match-full-lines ./hermes/test/hermes/intl/date-time-format-additional.js
$ TZ=GMT ./build/bin/hermes hermes/test/hermes/intl/date-time-format-hour-cycle.js
$ TZ=GMT ./build/bin/hermes hermes/test/hermes/intl/date-time-format-format-range.js

Run valgrind with above test runs and no memory leak detected.

Run Test262 test suite (pinned at commit hash 62626e083bd506124aac6c799464d76c2c42851b that the github workflow uses for test stablity). All non-skipped test cases pass.

$ ./hermes/utils/testsuite/run_testsuite.py -b ./build/bin --test-intl -a ~/Downloads/test262-62626e0/test262/test/

robchu05 avatar Mar 03 '25 19:03 robchu05

Hi @neildhar and @tmikov,

This pull request refactors and completes the ICU4C-based Intl.DateTimeFormat implementation. Support for formatToParts, formatRange, formatRangeToParts, as well as offset time zone string inputs, e.g. +0200, -07:00, etc, is added.

Please have a look. Thank you!

robchu05 avatar Mar 03 '25 19:03 robchu05

Thanks for submitting this PR! Before we start reviewing it, could you make the changes to the static_h branch instead? All new features/improvements should happen on that branch now. Thanks!

lavenzg avatar Mar 03 '25 21:03 lavenzg

Hi @lavenzg,

Thank you for letting me know about static_h branch. I see that Hermes team is working on getting React Native main branch and releases to switch over to the static_h branch: https://github.com/facebook/react-native/pull/48531.

Our team tracks RN main branch and releases as upstreams and Hermes is part of that. So we get upstream Hermes changes from Hermes main branch, until RN main branch and releases switch over to Hermes static_h branch. We would thus like to see this PR to be included in both Hermes main branch and static_h branch as we don't yet know when RN will switch over.

What do you think about keeping this PR targeting main branch, and have it reviewed, comments addressed, and merged first, then subseqeuntly I'll work on a new PR for the static_h branch?

thanks,

Robert

P.S. I took a look at the relevant code files on static_h branch, and bringing the changes in this PR to static_h should be straightforward as the relevant code is the pretty much the same between static_h and main branch, except for some details to be worked out in the automated testing configuration because that setup has some differences between the two branches.

robchu05 avatar Mar 05 '25 19:03 robchu05

@robchu05 Sounds good. We'll start reviewing this. Thanks!

lavenzg avatar Mar 06 '25 00:03 lavenzg

Hi @lavenzg,

Just want to see if you had a chance to start reviewing this yet.

Regards,

Robert

robchu05 avatar Mar 17 '25 18:03 robchu05

Hi @lavenzg, @neildhar, @tmikov,

Friendly reminder to review this PR.

Regards,

Robert

robchu05 avatar Mar 27 '25 20:03 robchu05

Hi @lavenzg, @neildhar, @tmikov,

Friendly reminder to review this PR.

Regards,

Robert

Hi Robert, I'm reviewing it. Will get back to you soon.

lavenzg avatar Mar 27 '25 20:03 lavenzg

Hi @lavenzg,

Do you have any initial feedback to share?

Best,

Robert

robchu05 avatar Apr 11 '25 17:04 robchu05

Hi @lavenzg,

Hope you are doing well. Any update on the review for this PR?

Regards,

Robert

robchu05 avatar Apr 25 '25 17:04 robchu05

Hi @lavenzg, @neildhar, @tmikov,

Hope things are going fine. Please help review this PR as it's been opened for quite some time.

Regards,

Robert

robchu05 avatar Apr 29 '25 17:04 robchu05

@robchu05 Sorry for the delay! I'll get it done this week.

lavenzg avatar May 06 '25 20:05 lavenzg

@lavenzg, thanks for the review and feedback. I plan to address them next week.

robchu05 avatar May 19 '25 17:05 robchu05

@lavenzg, please have a look at my replies to your feedback and the new revision I posted.

I'm going to be on vacation between June 7 - 29. If there are additional feedback while I'm away, I'll address them after I'm back. I will also work on porting this to the static_h branch after my break.

robchu05 avatar Jun 02 '25 18:06 robchu05

@lavenzg, I'm back in office. Have you had a chance to review rev 2? Thanks!

robchu05 avatar Jul 02 '25 21:07 robchu05

@lavenzg, I'm back in office. Have you had a chance to review rev 2? Thanks!

LGTM. I will import it to our internal repository and run some extra tests. If no failure we will merge them.

Thanks for your work on this (and your patience as my response sometimes are slow)!

lavenzg avatar Jul 02 '25 21:07 lavenzg

@lavenzg has imported this pull request. If you are a Meta employee, you can view this in D77691166.

facebook-github-bot avatar Jul 02 '25 21:07 facebook-github-bot

@lavenzg has imported this pull request. If you are a Meta employee, you can view this in D77691166.

facebook-github-bot avatar Jul 07 '25 20:07 facebook-github-bot

@lavenzg, update on the import status of this change? Thanks.

robchu05 avatar Jul 22 '25 20:07 robchu05

@lavenzg, any update on merging this PR? Thank you.

robchu05 avatar Aug 11 '25 19:08 robchu05

@lavenzg, are you able to merge this PR? Let me know if you need anything form me.

robchu05 avatar Sep 02 '25 18:09 robchu05

Hi, unfortunately it seems like we won't be able to merge this PR. I apologize, Meta, for better or worse, has decided that it cannot dedicate the resources to maintain a Intl implementation, and we can't merge something that we can't maintain. This is not an ideal situation, but it is out the hands of the Hermes team.

Instead, we are adding 1st class (and maintained) support for NodeAPI, which is well defined and ABI stable. This make it possible for Intl implementations to exist outside of the Hermes repository, while being guaranteed compatibility with Hermes by NodeAPI.

tmikov avatar Sep 03 '25 00:09 tmikov