Skip to content

Commit

Permalink
feat(eslint-plugin): [space-infix-ops] Add support for Union and inte…
Browse files Browse the repository at this point in the history
…rsection of type declarations (#3360)

* feat(space-infix-ops): Add support for Union and intersection of type declarations

* Simplify rules and refactor for more readability
  • Loading branch information
doumart committed May 28, 2021
1 parent cd0de65 commit 3d29323
Show file tree
Hide file tree
Showing 2 changed files with 613 additions and 32 deletions.
104 changes: 72 additions & 32 deletions packages/eslint-plugin/src/rules/space-infix-ops.ts
Expand Up @@ -8,6 +8,8 @@ import * as util from '../util';
export type Options = util.InferOptionsTypeFromRule<typeof baseRule>;
export type MessageIds = util.InferMessageIdsTypeFromRule<typeof baseRule>;

const UNIONS = ['|', '&'];

export default util.createRule<Options, MessageIds>({
name: 'space-infix-ops',
meta: {
Expand All @@ -34,6 +36,41 @@ export default util.createRule<Options, MessageIds>({
const rules = baseRule.create(context);
const sourceCode = context.getSourceCode();

const report = (
node: TSESTree.Node | TSESTree.Token,
operator: TSESTree.Token,
): void => {
context.report({
node: node,
loc: operator.loc,
messageId: 'missingSpace',
data: {
operator: operator.value,
},
fix(fixer) {
const previousToken = sourceCode.getTokenBefore(operator);
const afterToken = sourceCode.getTokenAfter(operator);
let fixString = '';

if (operator.range[0] - previousToken!.range[1] === 0) {
fixString = ' ';
}

fixString += operator.value;

if (afterToken!.range[0] - operator.range[1] === 0) {
fixString += ' ';
}

return fixer.replaceText(operator, fixString);
},
});
};

function isSpaceChar(token: TSESTree.Token): boolean {
return token.type === AST_TOKEN_TYPES.Punctuator && token.value === '=';
}

function checkAndReportAssignmentSpace(
node: TSESTree.Node,
leftNode: TSESTree.Token,
Expand All @@ -46,42 +83,17 @@ export default util.createRule<Options, MessageIds>({
const operator = sourceCode.getFirstTokenBetween(
leftNode,
rightNode,
token =>
token.type === AST_TOKEN_TYPES.Punctuator && token.value === '=',
isSpaceChar,
);

const prev = sourceCode.getTokenBefore(operator!);
const next = sourceCode.getTokenAfter(operator!);

if (
operator &&
(!sourceCode.isSpaceBetweenTokens(prev!, operator) ||
!sourceCode.isSpaceBetweenTokens(operator, next!))
!sourceCode.isSpaceBetween!(prev!, operator!) ||
!sourceCode.isSpaceBetween!(operator!, next!)
) {
context.report({
node: node,
loc: operator.loc,
messageId: 'missingSpace',
data: {
operator: operator.value,
},
fix(fixer) {
const previousToken = sourceCode.getTokenBefore(operator);
const afterToken = sourceCode.getTokenAfter(operator);
let fixString = '';

if (operator.range[0] - previousToken!.range[1] === 0) {
fixString = ' ';
}

fixString += operator.value;

if (afterToken!.range[0] - operator.range[1] === 0) {
fixString += ' ';
}

return fixer.replaceText(operator, fixString);
},
});
report(node, operator!);
}
}

Expand Down Expand Up @@ -119,11 +131,37 @@ export default util.createRule<Options, MessageIds>({
checkAndReportAssignmentSpace(node, leftNode, rightNode);
}

/**
* Check if it is missing spaces between type annotations chaining
* @param typeAnnotation TypeAnnotations list
*/
function checkForTypeAnnotationSpace(
typeAnnotation: TSESTree.TSIntersectionType | TSESTree.TSUnionType,
): void {
const types = typeAnnotation.types;

types.forEach(type => {
const operator = sourceCode.getTokenBefore(type);

if (operator != null && UNIONS.includes(operator.value)) {
const prev = sourceCode.getTokenBefore(operator);
const next = sourceCode.getTokenAfter(operator);

if (
!sourceCode.isSpaceBetween!(prev!, operator) ||
!sourceCode.isSpaceBetween!(operator, next!)
) {
report(typeAnnotation, operator);
}
}
});
}

/**
* Check if it has an assignment char and report if it's faulty
* @param node The node to report
*/
function checkForTypeAliasAssignmentSpace(
function checkForTypeAliasAssignment(
node: TSESTree.TSTypeAliasDeclaration,
): void {
const leftNode = sourceCode.getTokenByRangeStart(node.id.range[0])!;
Expand All @@ -138,7 +176,9 @@ export default util.createRule<Options, MessageIds>({
...rules,
TSEnumMember: checkForEnumAssignmentSpace,
ClassProperty: checkForClassPropertyAssignmentSpace,
TSTypeAliasDeclaration: checkForTypeAliasAssignmentSpace,
TSTypeAliasDeclaration: checkForTypeAliasAssignment,
TSUnionType: checkForTypeAnnotationSpace,
TSIntersectionType: checkForTypeAnnotationSpace,
};
},
});

0 comments on commit 3d29323

Please sign in to comment.