123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- 'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);
- var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_docsUrl);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];return arr2;} else {return Array.from(arr);}}function _toArray(arr) {return Array.isArray(arr) ? arr : Array.from(arr);}
- function checkImports(imported, context) {
- for (const _ref of imported.entries()) {var _ref2 = _slicedToArray(_ref, 2);const module = _ref2[0];const nodes = _ref2[1];
- if (nodes.length > 1) {
- const message = `'${module}' imported multiple times.`;var _nodes = _toArray(
- nodes);const first = _nodes[0],rest = _nodes.slice(1);
- const sourceCode = context.getSourceCode();
- const fix = getFix(first, rest, sourceCode);
- context.report({
- node: first.source,
- message,
- fix
- });
- for (const node of rest) {
- context.report({
- node: node.source,
- message });
- }
- }
- }
- }
- function getFix(first, rest, sourceCode) {
-
-
-
-
-
-
- if (typeof sourceCode.getCommentsBefore !== 'function') {
- return undefined;
- }
-
-
-
-
- if (hasProblematicComments(first, sourceCode) || hasNamespace(first)) {
- return undefined;
- }
- const defaultImportNames = new Set(
- [first].concat(_toConsumableArray(rest)).map(getDefaultImportName).filter(Boolean));
-
-
- if (defaultImportNames.size > 1) {
- return undefined;
- }
-
-
- const restWithoutComments = rest.filter(node => !(
- hasProblematicComments(node, sourceCode) ||
- hasNamespace(node)));
- const specifiers = restWithoutComments.
- map(node => {
- const tokens = sourceCode.getTokens(node);
- const openBrace = tokens.find(token => isPunctuator(token, '{'));
- const closeBrace = tokens.find(token => isPunctuator(token, '}'));
- if (openBrace == null || closeBrace == null) {
- return undefined;
- }
- return {
- importNode: node,
- text: sourceCode.text.slice(openBrace.range[1], closeBrace.range[0]),
- hasTrailingComma: isPunctuator(sourceCode.getTokenBefore(closeBrace), ','),
- isEmpty: !hasSpecifiers(node) };
- }).
- filter(Boolean);
- const unnecessaryImports = restWithoutComments.filter(node =>
- !hasSpecifiers(node) &&
- !hasNamespace(node) &&
- !specifiers.some(specifier => specifier.importNode === node));
- const shouldAddDefault = getDefaultImportName(first) == null && defaultImportNames.size === 1;
- const shouldAddSpecifiers = specifiers.length > 0;
- const shouldRemoveUnnecessary = unnecessaryImports.length > 0;
- if (!(shouldAddDefault || shouldAddSpecifiers || shouldRemoveUnnecessary)) {
- return undefined;
- }
- return fixer => {
- const tokens = sourceCode.getTokens(first);
- const openBrace = tokens.find(token => isPunctuator(token, '{'));
- const closeBrace = tokens.find(token => isPunctuator(token, '}'));
- const firstToken = sourceCode.getFirstToken(first);var _defaultImportNames = _slicedToArray(
- defaultImportNames, 1);const defaultImportName = _defaultImportNames[0];
- const firstHasTrailingComma =
- closeBrace != null &&
- isPunctuator(sourceCode.getTokenBefore(closeBrace), ',');
- const firstIsEmpty = !hasSpecifiers(first);var _specifiers$reduce =
- specifiers.reduce(
- (_ref3, specifier) => {var _ref4 = _slicedToArray(_ref3, 2);let result = _ref4[0],needsComma = _ref4[1];
- return [
- needsComma && !specifier.isEmpty ?
- `${result},${specifier.text}` :
- `${result}${specifier.text}`,
- specifier.isEmpty ? needsComma : true];
- },
- ['', !firstHasTrailingComma && !firstIsEmpty]),_specifiers$reduce2 = _slicedToArray(_specifiers$reduce, 1);const specifiersText = _specifiers$reduce2[0];
- const fixes = [];
- if (shouldAddDefault && openBrace == null && shouldAddSpecifiers) {
-
- fixes.push(
- fixer.insertTextAfter(firstToken, ` ${defaultImportName}, {${specifiersText}} from`));
- } else if (shouldAddDefault && openBrace == null && !shouldAddSpecifiers) {
-
- fixes.push(fixer.insertTextAfter(firstToken, ` ${defaultImportName} from`));
- } else if (shouldAddDefault && openBrace != null && closeBrace != null) {
-
- fixes.push(fixer.insertTextAfter(firstToken, ` ${defaultImportName},`));
- if (shouldAddSpecifiers) {
-
- fixes.push(fixer.insertTextBefore(closeBrace, specifiersText));
- }
- } else if (!shouldAddDefault && openBrace == null && shouldAddSpecifiers) {
- if (first.specifiers.length === 0) {
-
- fixes.push(fixer.insertTextAfter(firstToken, ` {${specifiersText}} from`));
- } else {
-
- fixes.push(fixer.insertTextAfter(first.specifiers[0], `, {${specifiersText}}`));
- }
- } else if (!shouldAddDefault && openBrace != null && closeBrace != null) {
-
- fixes.push(fixer.insertTextBefore(closeBrace, specifiersText));
- }
-
- for (const specifier of specifiers) {
- fixes.push(fixer.remove(specifier.importNode));
- }
-
-
-
- for (const node of unnecessaryImports) {
- fixes.push(fixer.remove(node));
- }
- return fixes;
- };
- }
- function isPunctuator(node, value) {
- return node.type === 'Punctuator' && node.value === value;
- }
- function getDefaultImportName(node) {
- const defaultSpecifier = node.specifiers.
- find(specifier => specifier.type === 'ImportDefaultSpecifier');
- return defaultSpecifier != null ? defaultSpecifier.local.name : undefined;
- }
- function hasNamespace(node) {
- const specifiers = node.specifiers.
- filter(specifier => specifier.type === 'ImportNamespaceSpecifier');
- return specifiers.length > 0;
- }
- function hasSpecifiers(node) {
- const specifiers = node.specifiers.
- filter(specifier => specifier.type === 'ImportSpecifier');
- return specifiers.length > 0;
- }
- function hasProblematicComments(node, sourceCode) {
- return (
- hasCommentBefore(node, sourceCode) ||
- hasCommentAfter(node, sourceCode) ||
- hasCommentInsideNonSpecifiers(node, sourceCode));
- }
- function hasCommentBefore(node, sourceCode) {
- return sourceCode.getCommentsBefore(node).
- some(comment => comment.loc.end.line >= node.loc.start.line - 1);
- }
- function hasCommentAfter(node, sourceCode) {
- return sourceCode.getCommentsAfter(node).
- some(comment => comment.loc.start.line === node.loc.end.line);
- }
- function hasCommentInsideNonSpecifiers(node, sourceCode) {
- const tokens = sourceCode.getTokens(node);
- const openBraceIndex = tokens.findIndex(token => isPunctuator(token, '{'));
- const closeBraceIndex = tokens.findIndex(token => isPunctuator(token, '}'));
-
-
-
- const someTokens = openBraceIndex >= 0 && closeBraceIndex >= 0 ?
- tokens.slice(1, openBraceIndex + 1).concat(tokens.slice(closeBraceIndex + 1)) :
- tokens.slice(1);
- return someTokens.some(token => sourceCode.getCommentsBefore(token).length > 0);
- }
- module.exports = {
- meta: {
- type: 'problem',
- docs: {
- url: (0, _docsUrl2.default)('no-duplicates') },
- fixable: 'code',
- schema: [
- {
- type: 'object',
- properties: {
- considerQueryString: {
- type: 'boolean' } },
- additionalProperties: false }] },
- create: function (context) {
-
- const considerQueryStringOption = context.options[0] &&
- context.options[0]['considerQueryString'];
- const defaultResolver = sourcePath => (0, _resolve2.default)(sourcePath, context) || sourcePath;
- const resolver = considerQueryStringOption ? sourcePath => {
- const parts = sourcePath.match(/^([^?]*)\?(.*)$/);
- if (!parts) {
- return defaultResolver(sourcePath);
- }
- return defaultResolver(parts[1]) + '?' + parts[2];
- } : defaultResolver;
- const imported = new Map();
- const nsImported = new Map();
- const typesImported = new Map();
- return {
- 'ImportDeclaration': function (n) {
-
- const resolvedPath = resolver(n.source.value);
- const importMap = n.importKind === 'type' ? typesImported :
- hasNamespace(n) ? nsImported : imported;
- if (importMap.has(resolvedPath)) {
- importMap.get(resolvedPath).push(n);
- } else {
- importMap.set(resolvedPath, [n]);
- }
- },
- 'Program:exit': function () {
- checkImports(imported, context);
- checkImports(nsImported, context);
- checkImports(typesImported, context);
- } };
- } };
|