Skip to content

Conversation

@amannn
Copy link
Owner

@amannn amannn commented Dec 29, 2025

Change notes for consumers

  • There might be a minor change to sorting of messages in case you have multiple messages within a file. Previously these messages were sorted by ID, now they are sorted by line number (which matches the remaining sort order by file reference path).
  • Your diff will contain added line numbers.

Implementation

The Reference struct now includes a line field alongside path, enabling consumers to know exactly where each message was found in the source file.

Before:

{
  "id": "+YJVTi",
  "message": "Hey!",
  "references": [{ "path": "src/Component.tsx" }]
}

After:

{
  "id": "+YJVTi",
  "message": "Hey!",
  "references": [{ "path": "src/Component.tsx", "line": 5 }]
}

Approach

Used SWC's PluginSourceMapProxy to look up line numbers from AST span positions. This is SWC's internal position tracking (always available during parsing), not the optional output source maps (.map files).

let line = self
    .source_map
    .as_ref()
    .map_or(0, |sm| sm.lookup_char_pos(call.span.lo).line);

Considerations

  1. Performance: lookup_char_pos uses O(log n) binary search on pre-computed line offsets. Only called once per extracted message, not on every AST node visit.

  2. Source map availability: PluginSourceMapProxy is only constructible in the plugin environment. Used Option<PluginSourceMapProxy> to allow tests to pass None (tests validate AST output, not emitted results).

  3. Line numbering: SWC's lookup_char_pos returns 1-indexed line numbers (first line is 1).

  4. Column numbers: Deliberately excluded—line numbers provide sufficient granularity for the use case without adding noise to the output.

  5. Input vs output source maps: The position tracking we use is always available (SWC needs it for error reporting). This is independent of whether output source maps are configured.


Note

Introduces precise source locations for extracted messages and aligns sorting with reference path and line.

  • SWC extractor now records line for each reference, aggregates duplicate usages, and exposes results; new JSON fixtures validate output
  • Update types to include ExtractorMessageReference.line; add compareReferences and sort messages by path then line in utils
  • CatalogManager merges per-file references, preserves other-file refs, sorts with compareReferences, and ignores refs in equality checks; .po outputs include line numbers
  • Tests adjusted to expect line numbers and new ordering; example .po catalogs updated
  • Dependencies: bump po-parser to ^2.1.1; add indexmap to SWC plugin

Written by Cursor Bugbot for commit 9ca7057. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Dec 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
next-intl-docs Ready Ready Preview, Comment Jan 1, 2026 9:51am
next-intl-example-app-router Ready Ready Preview, Comment Jan 1, 2026 9:51am
next-intl-example-app-router-without-i18n-routing Ready Ready Preview, Comment Jan 1, 2026 9:51am

@amannn amannn marked this pull request as ready for review December 31, 2025 08:49
@amannn amannn changed the title fix: Include line numbers for file references fix: Include line numbers for file references & incorporate for sorting of messages Dec 31, 2025
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

cursoragent and others added 2 commits December 31, 2025 09:46
Make StrictExtractedMessage and its fields public. Add a test for merging duplicate messages while preserving descriptions.

Co-authored-by: jan <[email protected]>
relativeFilePath,
message.references
);
}
Copy link

Choose a reason for hiding this comment

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

Description merging uses last file instead of first

The PR discussion states that "a description is picked up as soon as any message has one and then kept for all entries" (first description wins). However, the merging logic at lines 315-319 only copies from prevMessage to message if message[key] is null. This means if a later file has a description, it overwrites the earlier one. The test expects "Description from FileZ" but FileY.tsx is processed first (alphabetically) and has a description, so it should be "Description from FileY" per the stated requirement.

Additional Locations (1)

Fix in Cursor Fix in Web

@amannn amannn changed the title fix: Include line numbers for file references & incorporate for sorting of messages feat: Include line numbers for file references & incorporate for sorting of messages Jan 1, 2026
@amannn amannn changed the title feat: Include line numbers for file references & incorporate for sorting of messages feat: Include line numbers for file references in .po files from useExtracted & incorporate for sorting of messages Jan 1, 2026
@amannn amannn merged commit 0303294 into canary Jan 1, 2026
10 checks passed
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.

3 participants