Skip to content

Commit d05be73

Browse files
New: no-deprecated-context-methods rule (fixes #40)
1 parent 221241f commit d05be73

File tree

4 files changed

+241
-0
lines changed

4 files changed

+241
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Name | ✔️ | 🛠 | Description
5050
----- | ----- | ----- | -----
5151
[consistent-output](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/consistent-output.md) | | | Enforces consistent use of output assertions in rule tests
5252
[fixer-return](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/fixer-return.md) | ✔️ | | Enforces always return from a fixer function
53+
[no-deprecated-context-methods](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-deprecated-context-methods.md) | | | Disallows usage of deprecated methods on rule context objects
5354
[no-deprecated-report-api](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-deprecated-report-api.md) | ✔️ | 🛠 | Prohibits the deprecated `context.report(node, message)` API
5455
[no-identical-tests](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-identical-tests.md) | ✔️ | 🛠 | Disallows identical tests
5556
[no-missing-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-missing-placeholders.md) | ✔️ | | Disallows missing placeholders in rule report messages
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Disallows usage of deprecated methods on rule context objects (no-deprecated-context-methods)
2+
3+
This rule disallows the use of deprecated methods on rule `context` objects.
4+
5+
The deprecated methods are:
6+
7+
* `getSource`
8+
* `getSourceLines`
9+
* `getAllComments`
10+
* `getNodeByRangeIndex`
11+
* `getComments`
12+
* `getCommentsBefore`
13+
* `getCommentsAfter`
14+
* `getCommentsInside`
15+
* `getJSDocComment`
16+
* `getFirstToken`
17+
* `getFirstTokens`
18+
* `getLastToken`
19+
* `getLastTokens`
20+
* `getTokenAfter`
21+
* `getTokenBefore`
22+
* `getTokenByRangeStart`
23+
* `getTokens`
24+
* `getTokensAfter`
25+
* `getTokensBefore`
26+
* `getTokensBetween`
27+
28+
Instead of using these methods, you should use the equivalent methods on [`SourceCode`](https://eslint.org/docs/developer-guide/working-with-rules#contextgetsourcecode), e.g. `context.getSourceCode().getText()` instead of `context.getSource()`.
29+
30+
## Rule Details
31+
32+
Examples of **incorrect** code for this rule:
33+
34+
```js
35+
module.exports = {
36+
create(context) {
37+
return {
38+
Program(node) {
39+
const firstToken = context.getFirstToken(node);
40+
}
41+
}
42+
}
43+
}
44+
```
45+
46+
Examples of **correct** code for this rule:
47+
48+
```js
49+
module.exports = {
50+
create(context) {
51+
const sourceCode = context.getSourceCode();
52+
53+
return {
54+
Program(node) {
55+
const firstToken = sourceCode.getFirstToken(node);
56+
}
57+
}
58+
}
59+
};
60+
```
61+
62+
## When Not To Use It
63+
64+
If you need to support very old versions of ESLint where `SourceCode` doesn't exist, you should not enable this rule.
65+
66+
## Further Reading
67+
68+
* [`SourceCode` API](https://eslint.org/docs/developer-guide/working-with-rules#contextgetsourcecode)
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @fileoverview Disallows usage of deprecated methods on rule context objects
3+
* @author Teddy Katz
4+
*/
5+
6+
'use strict';
7+
8+
const utils = require('../utils');
9+
10+
const DEPRECATED_PASSTHROUGHS = {
11+
getSource: 'getText',
12+
getSourceLines: 'getLines',
13+
getAllComments: 'getAllComments',
14+
getNodeByRangeIndex: 'getNodeByRangeIndex',
15+
getComments: 'getComments',
16+
getCommentsBefore: 'getCommentsBefore',
17+
getCommentsAfter: 'getCommentsAfter',
18+
getCommentsInside: 'getCommentsInside',
19+
getJSDocComment: 'getJSDocComment',
20+
getFirstToken: 'getFirstToken',
21+
getFirstTokens: 'getFirstTokens',
22+
getLastToken: 'getLastToken',
23+
getLastTokens: 'getLastTokens',
24+
getTokenAfter: 'getTokenAfter',
25+
getTokenBefore: 'getTokenBefore',
26+
getTokenByRangeStart: 'getTokenByRangeStart',
27+
getTokens: 'getTokens',
28+
getTokensAfter: 'getTokensAfter',
29+
getTokensBefore: 'getTokensBefore',
30+
getTokensBetween: 'getTokensBetween',
31+
};
32+
33+
// ------------------------------------------------------------------------------
34+
// Rule Definition
35+
// ------------------------------------------------------------------------------
36+
37+
module.exports = {
38+
meta: {
39+
docs: {
40+
description: 'Disallows usage of deprecated methods on rule context objects',
41+
category: 'Rules',
42+
recommended: false,
43+
},
44+
fixable: 'code',
45+
schema: [],
46+
},
47+
48+
create (context) {
49+
const sourceCode = context.getSourceCode();
50+
51+
// ----------------------------------------------------------------------
52+
// Public
53+
// ----------------------------------------------------------------------
54+
55+
return {
56+
'Program:exit' () {
57+
Array.from(utils.getContextIdentifiers(context, sourceCode.ast))
58+
.filter(
59+
contextId =>
60+
contextId.parent.type === 'MemberExpression' &&
61+
contextId === contextId.parent.object &&
62+
contextId.parent.property.type === 'Identifier' &&
63+
Object.prototype.hasOwnProperty.call(DEPRECATED_PASSTHROUGHS, contextId.parent.property.name)
64+
).forEach(
65+
contextId =>
66+
context.report({
67+
node: contextId.parent,
68+
message: 'Use `{{contextName}}.getSourceCode().{{replacement}}` instead of `{{contextName}}.{{original}}`.',
69+
data: {
70+
contextName: contextId.name,
71+
original: contextId.parent.property.name,
72+
replacement: DEPRECATED_PASSTHROUGHS[contextId.parent.property.name],
73+
},
74+
fix: fixer => [
75+
fixer.insertTextAfter(contextId, '.getSourceCode()'),
76+
fixer.replaceText(contextId.parent.property, DEPRECATED_PASSTHROUGHS[contextId.parent.property.name]),
77+
],
78+
})
79+
);
80+
},
81+
};
82+
},
83+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* @fileoverview Disallows usage of deprecated methods on rule context objects
3+
* @author Teddy Katz
4+
*/
5+
6+
'use strict';
7+
8+
// ------------------------------------------------------------------------------
9+
// Requirements
10+
// ------------------------------------------------------------------------------
11+
12+
const rule = require('../../../lib/rules/no-deprecated-context-methods');
13+
const RuleTester = require('eslint').RuleTester;
14+
15+
// ------------------------------------------------------------------------------
16+
// Tests
17+
// ------------------------------------------------------------------------------
18+
19+
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
20+
ruleTester.run('no-deprecated-context-methods', rule, {
21+
22+
valid: [
23+
`
24+
module.exports = {
25+
create(context) {
26+
context.getSourceCode();
27+
}
28+
}
29+
`,
30+
`
31+
module.exports = context => {
32+
const sourceCode = context.getSourceCode();
33+
34+
sourceCode.getFirstToken();
35+
}
36+
`,
37+
],
38+
39+
invalid: [
40+
{
41+
code: `
42+
module.exports = {
43+
create(context) {
44+
return {
45+
Program(node) {
46+
context.getSource(node);
47+
}
48+
}
49+
}
50+
}
51+
`,
52+
output: `
53+
module.exports = {
54+
create(context) {
55+
return {
56+
Program(node) {
57+
context.getSourceCode().getText(node);
58+
}
59+
}
60+
}
61+
}
62+
`,
63+
errors: [
64+
{
65+
message: 'Use `context.getSourceCode().getText` instead of `context.getSource`.',
66+
type: 'MemberExpression',
67+
},
68+
],
69+
},
70+
{
71+
code: `
72+
module.exports = myRuleContext => {
73+
myRuleContext.getFirstToken;
74+
}
75+
`,
76+
output: `
77+
module.exports = myRuleContext => {
78+
myRuleContext.getSourceCode().getFirstToken;
79+
}
80+
`,
81+
errors: [
82+
{
83+
message: 'Use `myRuleContext.getSourceCode().getFirstToken` instead of `myRuleContext.getFirstToken`.',
84+
type: 'MemberExpression',
85+
},
86+
],
87+
},
88+
],
89+
});

0 commit comments

Comments
 (0)