128 lines
17 KiB
JavaScript
128 lines
17 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
var _docsUrl = require('../docsUrl');
|
||
|
|
||
|
var _docsUrl2 = _interopRequireDefault(_docsUrl);
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
module.exports = {
|
||
|
meta: {
|
||
|
type: 'suggestion',
|
||
|
docs: {
|
||
|
url: (0, _docsUrl2.default)('first')
|
||
|
},
|
||
|
fixable: 'code',
|
||
|
schema: [{
|
||
|
type: 'string',
|
||
|
enum: ['absolute-first']
|
||
|
}]
|
||
|
},
|
||
|
|
||
|
create: function (context) {
|
||
|
function isPossibleDirective(node) {
|
||
|
return node.type === 'ExpressionStatement' && node.expression.type === 'Literal' && typeof node.expression.value === 'string';
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
'Program': function (n) {
|
||
|
const body = n.body,
|
||
|
absoluteFirst = context.options[0] === 'absolute-first',
|
||
|
message = 'Import in body of module; reorder to top.',
|
||
|
sourceCode = context.getSourceCode(),
|
||
|
originSourceCode = sourceCode.getText();
|
||
|
let nonImportCount = 0,
|
||
|
anyExpressions = false,
|
||
|
anyRelative = false,
|
||
|
lastLegalImp = null,
|
||
|
errorInfos = [],
|
||
|
shouldSort = true,
|
||
|
lastSortNodesIndex = 0;
|
||
|
body.forEach(function (node, index) {
|
||
|
if (!anyExpressions && isPossibleDirective(node)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
anyExpressions = true;
|
||
|
|
||
|
if (node.type === 'ImportDeclaration') {
|
||
|
if (absoluteFirst) {
|
||
|
if (/^\./.test(node.source.value)) {
|
||
|
anyRelative = true;
|
||
|
} else if (anyRelative) {
|
||
|
context.report({
|
||
|
node: node.source,
|
||
|
message: 'Absolute imports should come before relative imports.'
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
if (nonImportCount > 0) {
|
||
|
for (let variable of context.getDeclaredVariables(node)) {
|
||
|
if (!shouldSort) break;
|
||
|
const references = variable.references;
|
||
|
if (references.length) {
|
||
|
for (let reference of references) {
|
||
|
if (reference.identifier.range[0] < node.range[1]) {
|
||
|
shouldSort = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
shouldSort && (lastSortNodesIndex = errorInfos.length);
|
||
|
errorInfos.push({
|
||
|
node,
|
||
|
range: [body[index - 1].range[1], node.range[1]]
|
||
|
});
|
||
|
} else {
|
||
|
lastLegalImp = node;
|
||
|
}
|
||
|
} else {
|
||
|
nonImportCount++;
|
||
|
}
|
||
|
});
|
||
|
if (!errorInfos.length) return;
|
||
|
errorInfos.forEach(function (errorInfo, index) {
|
||
|
const node = errorInfo.node,
|
||
|
infos = {
|
||
|
node,
|
||
|
message
|
||
|
};
|
||
|
if (index < lastSortNodesIndex) {
|
||
|
infos.fix = function (fixer) {
|
||
|
return fixer.insertTextAfter(node, '');
|
||
|
};
|
||
|
} else if (index === lastSortNodesIndex) {
|
||
|
const sortNodes = errorInfos.slice(0, lastSortNodesIndex + 1);
|
||
|
infos.fix = function (fixer) {
|
||
|
const removeFixers = sortNodes.map(function (_errorInfo) {
|
||
|
return fixer.removeRange(_errorInfo.range);
|
||
|
}),
|
||
|
range = [0, removeFixers[removeFixers.length - 1].range[1]];
|
||
|
let insertSourceCode = sortNodes.map(function (_errorInfo) {
|
||
|
const nodeSourceCode = String.prototype.slice.apply(originSourceCode, _errorInfo.range);
|
||
|
if (/\S/.test(nodeSourceCode[0])) {
|
||
|
return '\n' + nodeSourceCode;
|
||
|
}
|
||
|
return nodeSourceCode;
|
||
|
}).join(''),
|
||
|
insertFixer = null,
|
||
|
replaceSourceCode = '';
|
||
|
if (!lastLegalImp) {
|
||
|
insertSourceCode = insertSourceCode.trim() + insertSourceCode.match(/^(\s+)/)[0];
|
||
|
}
|
||
|
insertFixer = lastLegalImp ? fixer.insertTextAfter(lastLegalImp, insertSourceCode) : fixer.insertTextBefore(body[0], insertSourceCode);
|
||
|
const fixers = [insertFixer].concat(removeFixers);
|
||
|
fixers.forEach(function (computedFixer, i) {
|
||
|
replaceSourceCode += originSourceCode.slice(fixers[i - 1] ? fixers[i - 1].range[1] : 0, computedFixer.range[0]) + computedFixer.text;
|
||
|
});
|
||
|
return fixer.replaceTextRange(range, replaceSourceCode);
|
||
|
};
|
||
|
}
|
||
|
context.report(infos);
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9maXJzdC5qcyJdLCJuYW1lcyI6WyJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsInR5cGUiLCJkb2NzIiwidXJsIiwiZml4YWJsZSIsInNjaGVtYSIsImVudW0iLCJjcmVhdGUiLCJjb250ZXh0IiwiaXNQb3NzaWJsZURpcmVjdGl2ZSIsIm5vZGUiLCJleHByZXNzaW9uIiwidmFsdWUiLCJuIiwiYm9keSIsImFic29sdXRlRmlyc3QiLCJvcHRpb25zIiwibWVzc2FnZSIsInNvdXJjZUNvZGUiLCJnZXRTb3VyY2VDb2RlIiwib3JpZ2luU291cmNlQ29kZSIsImdldFRleHQiLCJub25JbXBvcnRDb3VudCIsImFueUV4cHJlc3Npb25zIiwiYW55UmVsYXRpdmUiLCJsYXN0TGVnYWxJbXAiLCJlcnJvckluZm9zIiwic2hvdWxkU29ydCIsImxhc3RTb3J0Tm9kZXNJbmRleCIsImZvckVhY2giLCJpbmRleCIsInRlc3QiLCJzb3VyY2UiLCJyZXBvcnQiLCJ2YXJpYWJsZSIsImdldERlY2xhcmVkVmFyaWFibGVzIiwicmVmZXJlbmNlcyIsImxlbmd0aCIsInJlZmVyZW5jZSIsImlkZW50aWZpZXIiLCJyYW5nZSIsInB1c2giLCJlcnJvckluZm8iLCJpbmZvcyIsImZpeCIsImZpeGVyIiwiaW5zZXJ0VGV4dEFmdGVyIiwic29ydE5vZGVzIiwic2xpY2UiLCJyZW1vdmVGaXhlcnMiLCJtYXAiLCJfZXJyb3JJbmZvIiwicmVtb3ZlUmFuZ2UiLCJpbnNlcnRTb3VyY2VDb2RlIiwibm9kZVNvdXJjZUNvZGUiLCJTdHJpbmciLCJwcm90b3R5cGUiLCJhcHBseSIsImpvaW4iLCJpbnNlcnRGaXhlciIsInJlcGxhY2VTb3VyY2VDb2RlIiwidHJpbSIsIm1hdGNoIiwiaW5zZXJ0VGV4dEJlZm9yZSIsImZpeGVycyIsImNvbmNhdCIsImNvbXB1dGVkRml4ZXIiLCJpIiwidGV4dCIsInJlcGxhY2VUZXh0UmFuZ2UiXSwibWFwcGluZ3MiOiI7O0FBQUE7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
|