-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Description
Environment
Node version: v19.3.0
npm version: v9.2.0
Local ESLint version: v8.31.0 (Currently used)
Global ESLint version: Not found
Operating System: darwin 22.1.0
What parser are you using?
Default (Espree)
What did you do?
While working on a custom rule I noticed an edge case where the filter
callback passed to sourceCode.getFirstToken()
and sourceCode.getLastToken()
was being called with an undefined
argument instead of a Token
object.
The following is a minimal example I created to illustrate the problem.
const { RuleTester } = require('eslint');
function isCommaToken(token) {
return token.type === 'Punctuator' && token.value === ',';
}
const rule = {
meta: {
docs: { description: 'Forbid commas' },
messages: { fail: 'commas not allowed' },
},
create(context) {
const sourceCode = context.getSourceCode();
return {
Program: node => {
if (sourceCode.getFirstToken(node, { filter: isCommaToken })) {
context.report({ node, messageId: 'fail' });
}
}
};
}
};
new RuleTester().run(
'no-commas',
rule,
{
valid:
[
'// comment',
],
invalid: [],
},
);
What did you expect to happen?
The sample test code should run without errors.
What actually happened?
An error occurs, because the filter
callback is called with undefined
:
TypeError: Cannot read properties of undefined (reading 'type') Occurred while linting :1 Rule: "no-commas" at isCommaToken (.../no-commas.js:4:18) at FilterCursor.moveNext (.../node_modules/eslint/lib/source-code/token-store/filter-cursor.js:37:17) at FilterCursor.getOneToken (.../node_modules/eslint/lib/source-code/token-store/cursor.js:49:21) at SourceCode.getFirstToken (.../node_modules/eslint/lib/source-code/token-store/index.js:264:11) at Program (.../no-commas.js:16:32) at ruleErrorHandler (.../node_modules/eslint/lib/linter/linter.js:1115:28) at .../node_modules/eslint/lib/linter/safe-emitter.js:45:58 at Array.forEach () at Object.emit (.../node_modules/eslint/lib/linter/safe-emitter.js:45:38) at NodeEventGenerator.applySelector (.../node_modules/eslint/lib/linter/node-event-generator.js:297:26) { ruleId: 'no-commas', currentNode: Node { type: 'Program', loc: SourceLocation { start: Position { line: 1, column: 0 }, end: Position { line: 1, column: 10 } }, range: [ 0, 10 ], body: [], sourceType: 'script', comments: [ { type: 'Line', value: ' comment', range: [ 0, 10 ], loc: { start: Position { line: 1, column: 0 }, end: Position { line: 1, column: 10 } } } ], tokens: [], parent: null } }
Participation
- I am willing to submit a pull request for this issue.
Additional comments
The problem occurs when a file being linted is empty or contains only comments, which is not extremely uncommon in practice.
I checked the usages of getFirstToken
and getLastToken
in the code base and it seems that none of the core rule is affected by this problem, but since these methods are part of the public API, I am wondering if this issue should be fixed. If not, it would be great to have it documented that the callback argument could be undefined sometimes, although this does not seem to be the intended behavior.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status