Skip to content

feat: add support for getLocFromIndex and getIndexFromLoc #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: main
Choose a base branch
from

Conversation

lumirlumir
Copy link
Member

@lumirlumir lumirlumir commented May 24, 2025

Prerequisites checklist

What is the purpose of this pull request?

Hello,

In this PR, I've completed implemention of getLocFromIndex() and getIndexFromLoc().

I based the implementation on the current JavaScript SourceCode class and incorporated the fast lookup algorithm discussed in eslint/eslint#19782.

The logic of getLocFromIndex() and getIndexFromLoc() is nearly identical to that in the JavaScript SourceCode class, with the key difference being that it accounts for the lineStart and columnStart values initialized in the constructor.


lineStart and columnStart

TextSourceCodeBase should accept lineStart and columnStart, as these can vary depending on the language, and both getLocFromIndex() and getIndexFromLoc() rely on them for accurate calculations. Here are some examples:

What changes did you make? (Give an overview)

I've completed implemention of getLocFromIndex() and getIndexFromLoc().

Related Issues

fixes: #166
refs: eslint/markdown#376, eslint/css#167, eslint/json#109, eslint/eslint#19782

Is there anything you'd like reviewers to focus on?

Prerequisites

@nzakas nzakas moved this from Needs Triage to Implementing in Triage Jun 5, 2025
Copy link
Member Author

@lumirlumir lumirlumir left a comment

Choose a reason for hiding this comment

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

It took a while, but I’ve finally finished implementing these two methods 😄

I’ve carefully reviewed the lazy calculation and addressed all the comments.

There might still be room for improvement—if so, I’d be happy to take a look.

(I didn’t go with the caching approach, as it turned out to be slightly slower in eslint/eslint#19782)

* @param {number} targetIndex The target index to find the line number for.
* @returns {number} The line number for the target index.
*/
function findLineNumberBinarySearch(lineStartIndices, targetIndex) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I’ve applied the binary‑search logic suggested in eslint/eslint#19782.

* Ensures `#lines` is lazily calculated from the source text.
* @returns {void}
*/
#ensureLines() {
Copy link
Member Author

@lumirlumir lumirlumir Jul 5, 2025

Choose a reason for hiding this comment

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

I’ve also applied lazy calculation to the lines getter method.

When I looked into the rules of the JavaScript, JSON, CSS, Markdown, HTML plugins (yeonjuan/html-eslint), and my custom plugins, I found that the lines getter is rarely used.

So, if we make the lines getter lazy, it would reduce unnecessary computation and memory usage.

);
}

const rootNodeLoc = this.getLoc(this.ast);
Copy link
Member Author

Choose a reason for hiding this comment

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

Now, we retrieve lineStart and columnStart information from the AST.

@lumirlumir lumirlumir requested a review from nzakas July 5, 2025 14:11
@lumirlumir lumirlumir marked this pull request as ready for review July 5, 2025 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Implementing
Development

Successfully merging this pull request may close these issues.

Change Request: Support getLocFromIndex() and getIndexFromLoc() methods for TextSourceCodeBase class
2 participants