Skip to content
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

Reports incorrect node locations for files with comments containing single quote #163

Open
nwalters512 opened this issue Aug 10, 2021 · 0 comments

Comments

@nwalters512
Copy link
Contributor

nwalters512 commented Aug 10, 2021

I originally reported this problem in stylelint (stylelint/stylelint#5438), but eventually determined it was caused by postcss-less.

  • Node Version: 14.17.0
  • NPM Version: 6.14.13
  • postcss Version: 8.3.5
  • postcss-less Version: master

LESS

This example may look kind of contrived, but it's based on many real-world examples in our code (long, rambling explanations that happen to single quotes). This is as simplified as I could get it.

a {
  // '
  color: pink;
}

/** ' */

JavaScript

Here is the test I added to test/parser/comments.test.js to reproduce the problem:

test('handles single quotes in comments', (t) => {
  const less = `a {\n  // '\n  color: pink;\n}\n\n/** ' */`;

  const root = parse(less);

  const [ruleNode, commentNode] = root.nodes;

  t.is(ruleNode.type, 'rule');
  t.is(commentNode.type, 'comment');

  const [innerCommentNode, declarationNode] = ruleNode.nodes;

  t.is(innerCommentNode.type, 'comment');
  t.is(declarationNode.type, 'decl');

  t.is(declarationNode.source.start.line, 3);
  t.is(declarationNode.source.start.column, 3);
  t.is(declarationNode.source.end.line, 3);
  t.is(declarationNode.source.end.column, 14);

  t.is(nodeToString(root), less);
});

All assertions about declarationNode.source.*.line fail.

Expected Behavior

I would expect that the declaration node for color: pink to be marked as starting and ending on line 3.

Actual Behavior

The declaration node for color: pink is marked as starting and ending on line 2. As you can see from the original LESS document, this is incorrect; line 2 is a comment.

How can we reproduce the behavior?

If you add the above test to test/parser/comments.test.js and run npm run test -- test/parser/comments.test.js, you can observe the test failing:

> ava "test/parser/comments.test.js"


  handles single quotes in comments

  test/parser/comments.test.js:198

   197:                                                
   198:   t.is(declarationNode.source.start.line, 3);  
   199:   t.is(declarationNode.source.start.column, 3);

  Difference:

  - 2
  + 3

  › test/parser/comments.test.js:198:5

  ─

  1 test failed

Potential fix

I spent a good deal of time trying to develop a fix for this, but I haven't yet figured out a way to work around the fact that the inline-comment node creates a new tokenizer in the middle of parsing (source). My current thinking is to try to do some kind of post-processing on the tree in the parse function - does that seem like a reasonable approach to you?

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

No branches or pull requests

1 participant