Skip to content

Conversation

@mosuem
Copy link
Member

@mosuem mosuem commented Nov 6, 2025

General API refactorings.

  • Getting rid of the Intl object, as it only served as a wrapper of Locale. So the ...Format objects are now the top-level things.
  • Remove most ...Options objects from the public API, as they make it more verbose. Users now directly input the options to the top-level ...Format constructor.
  • Use => instead of block bodies for methods where possible.
  • Fix some imports
  • Add documentation to some classes (more to follow!)
  • Remove some methods which are not implemented in ICU4X
  • Add conformance testing between ICU4X and ECMA for DateTime formatting. This shows many discrepancies for now, which need to be resolved before this PR can be merged - or we need to decide they are fine and remove the conformance testing.

Fixes #1027


  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:

Many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.

Note: The Dart team is trialing Gemini Code Assist. Don't take its comments as final Dart team feedback. Use the suggestions if they're helpful; otherwise, wait for a human reviewer.

@gemini-code-assist
Copy link

Summary of Changes

Hello @mosuem, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the intl4x package's API by removing the overarching Intl class. The change aims to simplify the usage of internationalization features by allowing direct instantiation of specific formatters and rules. This makes the API more modular and intuitive, reducing boilerplate and improving clarity for developers. The refactoring also includes updates to locale handling and option enums to enhance consistency and usability across the package.

Highlights

  • API Refactoring: The central Intl class has been removed, streamlining the API. Internationalization functionalities like DateTimeFormat, Collation, NumberFormat, etc., are now instantiated directly.
  • Locale System Access: A new static getter Locale.system has been introduced, providing a direct way to access the system's current locale.
  • Enum Renaming and Relocation: Several enums have been renamed for clarity (e.g., Type to ListType and PluralType) and the NumberingSystem enum has been moved to a more general options.dart file. Calendar enum values have also been updated for consistency.
  • Modular Imports and Exports: The Locale class is now explicitly exported from individual feature modules, improving modularity and reducing reliance on a single top-level intl4x.dart file.
  • Test and Example Updates: All example and test files have been updated to reflect the new API structure, ensuring compatibility and demonstrating correct usage of the refactored classes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great simplification of the intl4x API. Removing the central Intl class and promoting the individual formatting classes to be top-level makes the library more modular and easier to understand and use. The renames of Type to ListType and PluralType are also excellent changes that prevent name collisions.

While the refactoring is a positive change, it introduces several breaking changes that should be clearly documented for users of the library, for example in the PR description and the package's changelog. These include:

  • The removal of the Intl class.
  • The removal of ofDateTime, ofScript, ofCurrency, and ofCalendar methods from DisplayNames.
  • Renaming and removal of some Calendar enum values.

I've added a few comments with suggestions for improvements, mostly related to code style, consistency, and documentation, following the repository's contribution guidelines.

final CaseMappingImpl _caseMappingImpl;

const CaseMapping._(this._caseMappingImpl);
CaseMapping({Locale? locale})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository's style guide requires documentation for all public members.1 Please add a doc comment for the CaseMapping constructor explaining what it does. If locale is not provided, it defaults to the system locale.

For example:

  /// Constructs a [CaseMapping] instance for the given [locale].
  ///
  /// If [locale] is not provided, the system's locale is used.

This also applies to the new public constructors in Collation, DateTimeFormat, DisplayNames, ListFormat, NumberFormat, and PluralRules.

Style Guide References

Footnotes

  1. The style guide mandates that all public members should have documentation.

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

PR Health

License Headers ✔️
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

This check can be disabled by tagging the PR with skip-license-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
intl4x Breaking 0.14.0 0.15.0 0.15.0 ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

Coverage ⚠️
File Coverage
pkgs/intl4x/example/bin/example.dart 💔 Not covered
pkgs/intl4x/lib/case_mapping.dart 💚 100 %
pkgs/intl4x/lib/collation.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/datetime_format.dart 💔 Not covered
pkgs/intl4x/lib/display_names.dart 💔 Not covered
pkgs/intl4x/lib/list_format.dart 💚 100 %
pkgs/intl4x/lib/number_format.dart 💔 Not covered
pkgs/intl4x/lib/plural_rules.dart 💔 Not covered
pkgs/intl4x/lib/src/case_mapping/case_mapping.dart 💚 100 %
pkgs/intl4x/lib/src/collation/collation.dart 💔 88 % ⬇️ 13 %
pkgs/intl4x/lib/src/collation/collation_4x.dart 💚 85 % ⬆️ 9 %
pkgs/intl4x/lib/src/collation/collation_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/collation/collation_options.dart 💚 9 %
pkgs/intl4x/lib/src/collation/collation_stub.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/src/collation/collation_stub_4x.dart 💔 Not covered
pkgs/intl4x/lib/src/datetime_format/datetime_format.dart 💔 78 % ⬇️ 5 %
pkgs/intl4x/lib/src/datetime_format/datetime_format_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/datetime_format/datetime_format_impl.dart 💔 83 % ⬇️ 2 %
pkgs/intl4x/lib/src/datetime_format/datetime_format_options.dart 💚 40 % ⬆️ 28 %
pkgs/intl4x/lib/src/datetime_format/datetime_format_stub.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/src/datetime_format/datetime_format_stub_4x.dart 💔 Not covered
pkgs/intl4x/lib/src/datetime_format/icu4x/date_formatter.dart 💚 100 % ⬆️ 5 %
pkgs/intl4x/lib/src/datetime_format/icu4x/date_time_formatter.dart 💚 100 % ⬆️ 5 %
pkgs/intl4x/lib/src/datetime_format/icu4x/datetime_format_4x.dart 💚 98 % ⬆️ 7 %
pkgs/intl4x/lib/src/datetime_format/icu4x/time_formatter.dart 💚 9 %
pkgs/intl4x/lib/src/display_names/display_names.dart 💚 80 % ⬆️ 37 %
pkgs/intl4x/lib/src/display_names/display_names_4x.dart 💚 95 % ⬆️ 38 %
pkgs/intl4x/lib/src/display_names/display_names_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/display_names/display_names_impl.dart 💚 100 %
pkgs/intl4x/lib/src/display_names/display_names_options.dart 💚 17 %
pkgs/intl4x/lib/src/display_names/display_names_stub.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/src/display_names/display_names_stub_4x.dart 💔 Not covered
pkgs/intl4x/lib/src/list_format/list_format.dart 💔 75 % ⬇️ 10 %
pkgs/intl4x/lib/src/list_format/list_format_4x.dart 💚 100 %
pkgs/intl4x/lib/src/list_format/list_format_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/list_format/list_format_options.dart 💚 50 % ⬆️ 200 %
pkgs/intl4x/lib/src/list_format/list_format_stub.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/src/list_format/list_format_stub_4x.dart 💔 Not covered
pkgs/intl4x/lib/src/locale/locale.dart 💔 25 % ⬇️ 25 %
pkgs/intl4x/lib/src/locale/locale_4x.dart 💚 73 % ⬆️ 71 %
pkgs/intl4x/lib/src/locale/locale_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/number_format/number_format.dart 💔 30 % ⬇️ 64 %
pkgs/intl4x/lib/src/number_format/number_format_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/number_format/number_format_options.dart 💚 31 %
pkgs/intl4x/lib/src/options.dart 💚 100 %
pkgs/intl4x/lib/src/plural_rules/plural_rules.dart 💔 86 % ⬇️ 14 %
pkgs/intl4x/lib/src/plural_rules/plural_rules_4x.dart 💚 100 %
pkgs/intl4x/lib/src/plural_rules/plural_rules_ecma.dart 💔 Not covered
pkgs/intl4x/lib/src/plural_rules/plural_rules_options.dart 💚 22 %
pkgs/intl4x/lib/src/plural_rules/plural_rules_stub.dart 💔 0 % ⬇️ NaN %
pkgs/intl4x/lib/src/plural_rules/plural_rules_stub_4x.dart 💔 Not covered
pkgs/intl4x/lib/src/utils.dart 💚 100 % ⬆️ 50 %

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

Copy link
Collaborator

@robertbastian robertbastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of the gemini comments are actionable as well

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also test the string extension method

@mosuem mosuem requested a review from robertbastian November 18, 2025 09:14
@mosuem
Copy link
Member Author

mosuem commented Nov 19, 2025

/gemini review

@github-actions
Copy link

Package publishing

Package Version Status Publish tag (post-merge)
package:intl 0.20.3-wip WIP (no publish necessary)
package:intl4x 0.15.0 ready to publish intl4x-v0.15.0
package:intl_translation 0.21.0 already published at pub.dev
package:messages_shrinker 0.2.2-wip WIP (no publish necessary)

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and welcome refactoring of the intl4x API. The removal of the Intl object and the direct integration of options into the formatters' constructors greatly simplifies the API and improves usability. The added documentation, examples, and conformance tests are valuable additions that enhance the package's quality and maintainability. The changes align well with modern Dart practices, such as using expression bodies (=>) and extension types. I've found a few minor issues, mostly related to documentation typos and a small error in an example, which are detailed in the comments.

Comment on lines +29 to +30
/// DisplayNames(locale: Locale.parse('es-419'))
/// .ofLanguage(Locale.parse('de')); // Alemania

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This example seems to have a copy-paste error. To get the name of the region 'Germany' in Spanish, you should use ofRegion('DE'). The current code ofLanguage(Locale.parse('de')) would return the name of the German language ('alemán'), not the region name ('Alemania').

/// DisplayNames(locale: Locale.parse('es-419'))
///   .ofRegion('DE'); // Alemania

///
library;

import 'display_names.dart';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This self-import is unnecessary and can be removed.

/// The comparison rules are configured using the provided parameters:
///
/// * [locale]: The specific locale to use for comparison. If `null`, the
/// system's current locale is determined used.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a small typo here. determined used should probably be determined and used or simply used for conciseness.

Suggested change
/// system's current locale is determined used.
/// system's current locale is used.

/// for a string, or sorting a list of strings. The
/// [CollationOptions.sensitivity] regulates how exact the comparison should
/// be. Setting [CollationOptions.numeric] means that numbers are not sorted
/// alphbetically, but by their value. The

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Typo: alphbetically should be alphabetically.

Suggested change
/// alphbetically, but by their value. The
/// alphabetically, but by their value. The

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Numeric Collation option does not work.

2 participants