question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: deprecate `sourceCode.getComments()` in favor of `sourceCode.getCommentsBefore|After|Inside`.

See original GitHub issue

Now that we’re preparing for v4 in earnest and https://github.com/eslint/eslint/pull/7516 is about to land, I’d like to discuss officially deprecating sourceCode.getComments(), as mentioned in this comment.

Now that we’re no longer relying on parsers to attach comments to nodes, I think it makes much more sense to think of comments in terms of token lists rather than the AST. The concept of attaching comments to nodes is confusing (it would be perfectly acceptable if comments could only occur between Nodes, but unfortunately comments can occur anywhere), and now that we have alternatives to this behavior (with our new token iterator methods and comment calculation moving to core), I think it would make sense to move away from that paradigm. An example of why I think thinking of comments in the context of nodes is problematic (taken from this comment):

/* 1 */ function /* 2 */ foo(/* 3 */) /* 4 */ { /* 5 */ } /* 6 */

Are comments, 2, 3, 4, and 5 leading comments or trailing comments? I would argue that 4 is a leading comment for the BlockStatement, but otherwise I don’t really think the rest fit into either category. In Espree, because it collected all comments as it parsed and would attach them as it was finishing up nodes, it would end up attaching a number of inner comments as trailing comments. And since we didn’t have the token iterator methods we do now, it ended up allowing us to access comments inside “empty” nodes (such as the BlockStatement above), since those comments didn’t have a node right before or after. Given the weirdness that ensues (and now that we don’t have to be beholden to it!), I’d like to start moving towards thinking of comments in the context of tokens.

I’d like to propose landing https://github.com/eslint/eslint/pull/7516 and then deprecating sourceCode.getComments() in favor of three other methods:

  • sourceCode.getCommentsBefore()
  • sourceCode.getCommentsAfter()
  • sourceCode.getCommentsInside()

It seems to be a pretty rare case where rules would need to access comments in both directions, so I think it makes sense to think of them separately. I’m envisioning that they would be purely token based (not attempting to “dedupe” based on whether they could be attached to a parent node as getComments() currently does) with the following behavior:

// Collect comments before the node until it hits a non-comment token (the current behavior of
// getComments() minus the parent's range check)
sourceCode.getCommentsBefore(node) {
    const comments = [];
    let currentToken = this.getTokenBefore(node, { includeComments: true });
    
    while (currentToken && astUtils.isCommentToken(currentToken)) {
        comments.leading.unshift(currentToken);
        currentToken = this.getTokenBefore(currentToken, { includeComments: true });
    }

    return comments;
}

// Collect comments after the node until it hits a non-comment token (the current behavior of 
// getComments() minus the parent's range check)
sourceCode.getCommentsAfter(node) {
    const comments = [];
    let currentToken = this.getTokenAfter(node, { includeComments: true });

    while (currentToken && astUtils.isCommentToken(currentToken)) {
        comments.trailing.push(currentToken);
        currentToken = this.getTokenAfter(currentToken, { includeComments: true });
    }

    return comments;
}

// Return all comment tokens inside the current Node (regardless of whether they are inside children nodes)
sourceCode.getCommentsInside(node) {
    return this.getTokens(node, {
        includeComments: true,
        filter: astUtils.isCommentToken
    });
}

Again, we would only deprecate getComments right now - we would still leave it for backwards compatibility (as much as we have been able to approximate given the constraints of not being able to do it at parse time) and remove it in a future major version.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
kaicataldocommented, Apr 6, 2017

That’s fair! I’ll make a PR this weekend.

0reactions
btmillscommented, Apr 13, 2017

This was accepted in the 2017-04-13 TSC meeting.

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found