Skip to content

Sync upstream commit 91a479d#117

Merged
simbo1905 merged 4 commits intomainfrom
sync-91a479d
Jan 26, 2026
Merged

Sync upstream commit 91a479d#117
simbo1905 merged 4 commits intomainfrom
sync-91a479d

Conversation

@simbo1905
Copy link
Owner

Summary

  • Syncs upstream commit 91a479d "Reduce StringBuilder allocation in toDisplayString"
  • Updates all modules to use new upstream API
  • Adds Java 21 polyfills for LazyConstant and Math.powExact

Upstream API Changes

Old New
JsonString.value() JsonString.string()
JsonNumber.toNumber() JsonNumber.toLong() / toDouble()
JsonBoolean.value() JsonBoolean.bool()
JsonArray.values() JsonArray.elements()
Json.fromUntyped() Removed
Json.toUntyped() Removed

New APIs

  • JsonValue.get(String) - navigate to object member
  • JsonValue.element(int) - navigate to array element
  • JsonValue.getOrAbsent(String) - safe navigation

Backporting

  • Added LazyConstant.java polyfill (upstream switched from StableValue)
  • Added Utils.powExact() polyfill for Math.powExact(long, int)
  • Replaced unnamed variables _ with ignored (Java 21 compat)

Tests

All 390 tests pass (mvnd verify)

…splayString

Upstream API changes:
- JsonString.value() -> JsonString.string()
- JsonNumber.toNumber() -> JsonNumber.toLong()/toDouble()
- JsonBoolean.value() -> JsonBoolean.bool()
- JsonArray.values() -> JsonArray.elements()
- Json.fromUntyped()/toUntyped() removed
- New navigation: JsonValue.get(String), element(int), getOrAbsent()

Backporting:
- Added LazyConstant.java polyfill (upstream switched from StableValue)
- Added Utils.powExact() polyfill for Math.powExact(long, int)
- Replaced unnamed variables _ with ignored (Java 21 compat)
- Updated all modules to use new API

Verify: mvnd verify (390 tests pass)
@gemini-code-assist
Copy link

Summary of Changes

Hello @simbo1905, 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 updates the project's JSON API to align with recent developments in the OpenJDK jdk-sandbox JSON branch. The core changes involve significant API method renames, the removal of untyped conversion utilities, and the introduction of new, more explicit accessor methods on the JsonValue interface for enhanced type safety and ease of use. Additionally, the update includes necessary polyfills and code modernizations to maintain full compatibility with Java 21.

Highlights

  • Upstream API Sync: Synchronized the JSON API with the latest changes from the OpenJDK jdk-sandbox JSON branch (commit 91a479d), incorporating updates to method signatures and behavior.
  • API Method Renames: Key accessor methods across JsonString, JsonNumber, JsonArray, and JsonBoolean have been renamed for improved clarity and consistency (e.g., value() to string(), toNumber() to toLong()/toDouble(), values() to elements(), value() to bool()).
  • Removal of Untyped Conversion: The Json.fromUntyped() and Json.toUntyped() methods have been removed from the public API, promoting a more type-safe and explicit approach to JSON manipulation.
  • New Accessor Methods on JsonValue: Introduced new default methods on the JsonValue sealed interface, such as get(String), element(int), getOrAbsent(String), and valueOrNull(), to simplify navigation and access within JSON structures.
  • Java 21 Polyfills and Compatibility: Added polyfills for LazyConstant (replacing StableValue) and Math.powExact(long, int) to ensure full compatibility with Java 21. Unnamed variables (_) were also replaced with ignored for modern Java syntax.
  • Performance Optimization: The Json.toDisplayString method has been refactored to reduce StringBuilder allocations, leading to improved performance when formatting JSON for display.
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.

The upstream API removed fromUntyped/toUntyped methods, so we deleted
the test file that tested those methods (12 tests removed: 509 -> 497).
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 syncs the project with a significant upstream API update. Key changes include renaming accessor methods (e.g., .value() to .string(), .bool()), replacing .toNumber() with .toLong()/.toDouble(), and removing the fromUntyped/toUntyped methods in favor of typed factories. New navigation methods on JsonValue have been added, along with polyfills for LazyConstant and Math.powExact to ensure Java 21 compatibility. My review confirms that most of these changes are correctly implemented across the codebase. However, I've identified a critical bug in JsonNumber.of(double) where it fails to correctly initialize offsets, potentially causing runtime failures. A code suggestion to resolve this is provided. Overall, this is a substantial and well-executed update.

Comment on lines 112 to 118
static JsonNumber of(double num) {
// non-integral types
return new JsonNumberImpl(num);
if (!Double.isFinite(num)) {
throw new IllegalArgumentException("Not a valid JSON number");
}
var str = Double.toString(num);
return new JsonNumberImpl(str.toCharArray(), 0, str.length(), 0, 0);
}

Choose a reason for hiding this comment

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

critical

The implementation of JsonNumber.of(double) incorrectly hardcodes the decimal and exponent offsets to 0 when creating a JsonNumberImpl. This will cause issues in methods like toLong(), which rely on these offsets to parse the number correctly from its string representation. For example, for a number like 123.45, the decimal offset is not 0, and this will lead to a NumberFormatException or incorrect parsing.

To fix this, we can reuse the JsonNumber.of(String) factory, which correctly parses the number string and sets the offsets via Json.parse().

    static JsonNumber of(double num) {
        if (!Double.isFinite(num)) {
            throw new IllegalArgumentException(

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26c47212e1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +125 to +129
var shiftedFractionPart = new String(doc, decimalOffset + 1, Math.min(exp, exponentOffset - decimalOffset - 1));
exp = exp - shiftedFractionPart.length();
sig = Long.parseLong(new String(doc, startOffset, decimalOffset - startOffset) + shiftedFractionPart);
}
scale = Utils.powExact(10L, exp);

Choose a reason for hiding this comment

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

P1 Badge Fix toLong handling of negative exponents with decimals

The exponent+decimal path always shifts fractional digits into sig before the sign check, which is correct for positive exponents but wrong for negative exponents because the decimal point should move left, not right. With this logic, inputs like "1.0e-1" or "120.0e-1" end up as 10/1200 instead of throwing or returning 0/12, so toLong() can return an incorrect integer for non-integral values. The negative‑exponent branch needs to avoid this right‑shift (or include the fractional length in the divisor) so toLong() only succeeds when the post‑exponent value is actually integral.

Useful? React with 👍 / 👎.

Added 10 tests for LazyConstant.java polyfill covering:
- Lazy initialization behavior
- Thread safety with concurrent access
- Caching/memoization
- Exception propagation
- Usage in JSON parsing context

Test count: 509 -> 507 (removed 12 fromUntyped/toUntyped tests, added 10 LazyConstant tests)
@simbo1905 simbo1905 merged commit 85389ba into main Jan 26, 2026
4 checks passed
@simbo1905 simbo1905 deleted the sync-91a479d branch January 26, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant