first commit
This commit is contained in:
224
node_modules/eslint-plugin-import-x/lib/rules/newline-after-import.js
generated
vendored
Normal file
224
node_modules/eslint-plugin-import-x/lib/rules/newline-after-import.js
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
import debug from 'debug';
|
||||
import { isStaticRequire, createRule } from '../utils/index.js';
|
||||
const log = debug('eslint-plugin-import-x:rules:newline-after-import');
|
||||
function containsNodeOrEqual(outerNode, innerNode) {
|
||||
return (outerNode.range[0] <= innerNode.range[0] &&
|
||||
outerNode.range[1] >= innerNode.range[1]);
|
||||
}
|
||||
function getScopeBody(scope) {
|
||||
if (scope.block.type === 'SwitchStatement') {
|
||||
log('SwitchStatement scopes not supported');
|
||||
return [];
|
||||
}
|
||||
const body = 'body' in scope.block ? scope.block.body : null;
|
||||
if (body && 'type' in body && body.type === 'BlockStatement') {
|
||||
return body.body;
|
||||
}
|
||||
return Array.isArray(body) ? body : [];
|
||||
}
|
||||
function findNodeIndexInScopeBody(body, nodeToFind) {
|
||||
return body.findIndex(node => containsNodeOrEqual(node, nodeToFind));
|
||||
}
|
||||
function getLineDifference(node, nextNode) {
|
||||
return nextNode.loc.start.line - node.loc.end.line;
|
||||
}
|
||||
function isClassWithDecorator(node) {
|
||||
return node.type === 'ClassDeclaration' && !!node.decorators?.length;
|
||||
}
|
||||
function isExportDefaultClass(node) {
|
||||
return (node.type === 'ExportDefaultDeclaration' &&
|
||||
node.declaration.type === 'ClassDeclaration');
|
||||
}
|
||||
function isExportNameClass(node) {
|
||||
return (node.type === 'ExportNamedDeclaration' &&
|
||||
node.declaration?.type === 'ClassDeclaration');
|
||||
}
|
||||
export default createRule({
|
||||
name: 'newline-after-import',
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
category: 'Style guide',
|
||||
description: 'Enforce a newline after import statements.',
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
count: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
},
|
||||
exactCount: { type: 'boolean' },
|
||||
considerComments: { type: 'boolean' },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
newline: 'Expected {{count}} empty line{{lineSuffix}} after {{type}} statement not followed by another {{type}}.',
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
let level = 0;
|
||||
const requireCalls = [];
|
||||
const options = {
|
||||
count: 1,
|
||||
exactCount: false,
|
||||
considerComments: false,
|
||||
...context.options[0],
|
||||
};
|
||||
function checkForNewLine(node, nextNode, type) {
|
||||
if (isExportDefaultClass(nextNode) || isExportNameClass(nextNode)) {
|
||||
const classNode = nextNode.declaration;
|
||||
if (isClassWithDecorator(classNode)) {
|
||||
nextNode = classNode.decorators[0];
|
||||
}
|
||||
}
|
||||
else if (isClassWithDecorator(nextNode)) {
|
||||
nextNode = nextNode.decorators[0];
|
||||
}
|
||||
const lineDifference = getLineDifference(node, nextNode);
|
||||
const EXPECTED_LINE_DIFFERENCE = options.count + 1;
|
||||
if (lineDifference < EXPECTED_LINE_DIFFERENCE ||
|
||||
(options.exactCount && lineDifference !== EXPECTED_LINE_DIFFERENCE)) {
|
||||
let column = node.loc.start.column;
|
||||
if (node.loc.start.line !== node.loc.end.line) {
|
||||
column = 0;
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
line: node.loc.end.line,
|
||||
column,
|
||||
},
|
||||
messageId: 'newline',
|
||||
data: {
|
||||
count: options.count,
|
||||
lineSuffix: options.count > 1 ? 's' : '',
|
||||
type,
|
||||
},
|
||||
fix: options.exactCount && EXPECTED_LINE_DIFFERENCE < lineDifference
|
||||
? undefined
|
||||
: fixer => fixer.insertTextAfter(node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference)),
|
||||
});
|
||||
}
|
||||
}
|
||||
function commentAfterImport(node, nextComment, type) {
|
||||
const lineDifference = getLineDifference(node, nextComment);
|
||||
const EXPECTED_LINE_DIFFERENCE = options.count + 1;
|
||||
if (lineDifference < EXPECTED_LINE_DIFFERENCE) {
|
||||
let column = node.loc.start.column;
|
||||
if (node.loc.start.line !== node.loc.end.line) {
|
||||
column = 0;
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
line: node.loc.end.line,
|
||||
column,
|
||||
},
|
||||
messageId: 'newline',
|
||||
data: {
|
||||
count: options.count,
|
||||
lineSuffix: options.count > 1 ? 's' : '',
|
||||
type,
|
||||
},
|
||||
fix: options.exactCount && EXPECTED_LINE_DIFFERENCE < lineDifference
|
||||
? undefined
|
||||
: fixer => fixer.insertTextAfter(node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference)),
|
||||
});
|
||||
}
|
||||
}
|
||||
function incrementLevel() {
|
||||
level++;
|
||||
}
|
||||
function decrementLevel() {
|
||||
level--;
|
||||
}
|
||||
function checkImport(node) {
|
||||
const { parent } = node;
|
||||
if (!parent || !('body' in parent) || !parent.body) {
|
||||
return;
|
||||
}
|
||||
const root = parent;
|
||||
const nodePosition = root.body.indexOf(node);
|
||||
const nextNode = root.body[nodePosition + 1];
|
||||
const endLine = node.loc.end.line;
|
||||
let nextComment;
|
||||
if (root.comments !== undefined && options.considerComments) {
|
||||
nextComment = root.comments.find(o => o.loc.start.line >= endLine &&
|
||||
o.loc.start.line <= endLine + options.count + 1);
|
||||
}
|
||||
if (node.type === 'TSImportEqualsDeclaration' &&
|
||||
node.isExport) {
|
||||
return;
|
||||
}
|
||||
if (nextComment) {
|
||||
commentAfterImport(node, nextComment, 'import');
|
||||
}
|
||||
else if (nextNode &&
|
||||
nextNode.type !== 'ImportDeclaration' &&
|
||||
(nextNode.type !== 'TSImportEqualsDeclaration' ||
|
||||
nextNode.isExport)) {
|
||||
checkForNewLine(node, nextNode, 'import');
|
||||
}
|
||||
}
|
||||
return {
|
||||
ImportDeclaration: checkImport,
|
||||
TSImportEqualsDeclaration: checkImport,
|
||||
CallExpression(node) {
|
||||
if (isStaticRequire(node) && level === 0) {
|
||||
requireCalls.push(node);
|
||||
}
|
||||
},
|
||||
'Program:exit'(node) {
|
||||
log('exit processing for', context.physicalFilename);
|
||||
const scopeBody = getScopeBody(context.sourceCode.getScope(node));
|
||||
log('got scope:', scopeBody);
|
||||
for (const [index, node] of requireCalls.entries()) {
|
||||
const nodePosition = findNodeIndexInScopeBody(scopeBody, node);
|
||||
log('node position in scope:', nodePosition);
|
||||
const statementWithRequireCall = scopeBody[nodePosition];
|
||||
const nextStatement = scopeBody[nodePosition + 1];
|
||||
const nextRequireCall = requireCalls[index + 1];
|
||||
if (nextRequireCall &&
|
||||
containsNodeOrEqual(statementWithRequireCall, nextRequireCall)) {
|
||||
continue;
|
||||
}
|
||||
if (nextStatement &&
|
||||
(!nextRequireCall ||
|
||||
!containsNodeOrEqual(nextStatement, nextRequireCall))) {
|
||||
let nextComment;
|
||||
if ('comments' in statementWithRequireCall.parent &&
|
||||
statementWithRequireCall.parent.comments !== undefined &&
|
||||
options.considerComments) {
|
||||
const endLine = node.loc.end.line;
|
||||
nextComment = statementWithRequireCall.parent.comments.find(o => o.loc.start.line >= endLine &&
|
||||
o.loc.start.line <= endLine + options.count + 1);
|
||||
}
|
||||
if (nextComment && nextComment !== undefined) {
|
||||
commentAfterImport(statementWithRequireCall, nextComment, 'require');
|
||||
}
|
||||
else {
|
||||
checkForNewLine(statementWithRequireCall, nextStatement, 'require');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
FunctionDeclaration: incrementLevel,
|
||||
FunctionExpression: incrementLevel,
|
||||
ArrowFunctionExpression: incrementLevel,
|
||||
BlockStatement: incrementLevel,
|
||||
ObjectExpression: incrementLevel,
|
||||
Decorator: incrementLevel,
|
||||
'FunctionDeclaration:exit': decrementLevel,
|
||||
'FunctionExpression:exit': decrementLevel,
|
||||
'ArrowFunctionExpression:exit': decrementLevel,
|
||||
'BlockStatement:exit': decrementLevel,
|
||||
'ObjectExpression:exit': decrementLevel,
|
||||
'Decorator:exit': decrementLevel,
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=newline-after-import.js.map
|
||||
Reference in New Issue
Block a user