Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(eslint-plugin): [space-infix-ops] extention rule
- Loading branch information
1 parent
1329294
commit 7df3395
Showing
7 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# This rule is aimed at ensuring there are spaces around infix operators. (`space-infix-ops`) | ||
|
||
This rule extends the base [`eslint/space-infix-ops`](https://eslint.org/docs/rules/space-infix-ops) rule. | ||
|
||
## How to use | ||
|
||
```jsonc | ||
{ | ||
"space-infix-ops": "off", | ||
"@typescript-eslint/space-infix-ops": ["error", { "int32Hint": false }] | ||
} | ||
``` | ||
|
||
## Options | ||
|
||
See [`eslint/space-infix-ops` options](https://eslint.org/docs/rules/space-infix-ops#options). | ||
|
||
<sup>Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/semi.md)</sup> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import { | ||
AST_NODE_TYPES, | ||
TSESLint, | ||
TSESTree, | ||
} from '@typescript-eslint/experimental-utils'; | ||
import baseRule from 'eslint/lib/rules/space-infix-ops'; | ||
import { TSEnumMember } from '../../../parser/node_modules/@typescript-eslint/types/dist/ts-estree'; | ||
import * as util from '../util'; | ||
|
||
export type Options = util.InferOptionsTypeFromRule<typeof baseRule>; | ||
export type MessageIds = util.InferMessageIdsTypeFromRule<typeof baseRule>; | ||
|
||
export default util.createRule<Options, MessageIds>({ | ||
name: 'space-infix-ops', | ||
meta: { | ||
type: 'layout', | ||
docs: { | ||
description: | ||
'This rule is aimed at ensuring there are spaces around infix operators.', | ||
category: 'Stylistic Issues', | ||
recommended: false, | ||
extendsBaseRule: true, | ||
}, | ||
fixable: baseRule.meta.fixable, | ||
schema: baseRule.meta.schema, | ||
messages: baseRule.meta.messages, | ||
}, | ||
defaultOptions: [ | ||
{ | ||
int32Hint: false, | ||
}, | ||
], | ||
create(context) { | ||
const rules = baseRule.create(context); | ||
const sourceCode = context.getSourceCode(); | ||
|
||
/** | ||
* Find the first non space specified char | ||
* @param {TSESTree.token} left The token to the left | ||
* @param {TSESTree.Token} right The token to the right | ||
* @param {string} op The token to find | ||
* @returns {TSESTree.Token|null} | ||
* @private | ||
*/ | ||
function getFirstNonSpacedToken( | ||
left: TSESTree.Token, | ||
right: TSESTree.Token, | ||
op: string, | ||
): TSESTree.Token | null { | ||
const operator = sourceCode.getFirstTokenBetween( | ||
left, | ||
right, | ||
token => token.value === op, | ||
); | ||
const prev = sourceCode.getTokenBefore(operator!); | ||
const next = sourceCode.getTokenAfter(operator!); | ||
|
||
if ( | ||
!sourceCode.isSpaceBetweenTokens(prev!, operator!) || | ||
!sourceCode.isSpaceBetweenTokens(operator!, next!) | ||
) { | ||
return operator; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Reports an AST node as a rule violation | ||
* @param {TSESTree.Node} mainNode The node to report | ||
* @param {TSESTree.Token} culpritToken The token which has a problem | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function report( | ||
mainNode: TSESTree.Node, | ||
culpritToken: TSESTree.Token, | ||
): void { | ||
context.report({ | ||
node: mainNode, | ||
loc: culpritToken.loc, | ||
messageId: 'missingSpace', | ||
data: { | ||
operator: culpritToken.value, | ||
}, | ||
fix(fixer) { | ||
const previousToken = sourceCode.getTokenBefore(culpritToken); | ||
const afterToken = sourceCode.getTokenAfter(culpritToken); | ||
let fixString = ''; | ||
|
||
if (culpritToken.range[0] - previousToken!.range[1] === 0) { | ||
fixString = ' '; | ||
} | ||
|
||
fixString += culpritToken.value; | ||
|
||
if (afterToken!.range[0] - culpritToken.range[1] === 0) { | ||
fixString += ' '; | ||
} | ||
|
||
return fixer.replaceText(culpritToken, fixString); | ||
}, | ||
}); | ||
} | ||
|
||
/** | ||
* Check if it has an assignment char and report if it's faulty | ||
* @param {TSESTree.Node} node The node to report | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function checkForAssignmentSpace(node: TSEnumMember): void { | ||
if (!node.initializer) { | ||
return; | ||
} | ||
|
||
const leftNode = sourceCode.getTokenByRangeStart( | ||
sourceCode.getIndexFromLoc(node.id.loc.start), | ||
)!; | ||
const rightNode = sourceCode.getTokenByRangeStart( | ||
sourceCode.getIndexFromLoc(node.initializer.loc.start), | ||
)!; | ||
|
||
if (!rightNode) { | ||
return; | ||
} | ||
|
||
const operator = '='; | ||
|
||
const nonSpacedNode = getFirstNonSpacedToken( | ||
leftNode, | ||
rightNode, | ||
operator, | ||
); | ||
|
||
if (nonSpacedNode) { | ||
report(node, nonSpacedNode); | ||
} | ||
} | ||
|
||
const nodesToCheck = [AST_NODE_TYPES.TSEnumMember].reduce< | ||
TSESLint.RuleListener | ||
>((acc, node) => { | ||
acc[node as string] = checkForAssignmentSpace; | ||
return acc; | ||
}, {}); | ||
|
||
return { | ||
...rules, | ||
...nodesToCheck, | ||
}; | ||
}, | ||
}); |
98 changes: 98 additions & 0 deletions
98
packages/eslint-plugin/tests/rules/space-infix-ops.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* eslint-disable @typescript-eslint/internal/plugin-test-formatting */ | ||
import rule from '../../src/rules/space-infix-ops'; | ||
import { RuleTester } from '../RuleTester'; | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: '@typescript-eslint/parser', | ||
}); | ||
|
||
ruleTester.run('space-infix-ops', rule, { | ||
valid: [ | ||
{ | ||
code: ` | ||
enum Test { | ||
KEY1 = 2, | ||
} | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
enum Test { | ||
KEY1 = "value", | ||
} | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
enum Test { | ||
KEY1, | ||
} | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
enum Test { | ||
A= 2, | ||
B = 1, | ||
} | ||
`, | ||
output: ` | ||
enum Test { | ||
A = 2, | ||
B = 1, | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'missingSpace', | ||
column: 12, | ||
line: 3, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
enum Test { | ||
KEY1= "value1", | ||
KEY2 = "value2", | ||
} | ||
`, | ||
output: ` | ||
enum Test { | ||
KEY1 = "value1", | ||
KEY2 = "value2", | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'missingSpace', | ||
column: 15, | ||
line: 3, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
enum Test { | ||
A =2, | ||
B = 1, | ||
} | ||
`, | ||
output: ` | ||
enum Test { | ||
A = 2, | ||
B = 1, | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'missingSpace', | ||
column: 13, | ||
line: 3, | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters