123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- '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 _ExportMap = require('../ExportMap');var _ExportMap2 = _interopRequireDefault(_ExportMap);
- var _importType = require('../core/importType');
- var _moduleVisitor = require('eslint-module-utils/moduleVisitor');var _moduleVisitor2 = _interopRequireDefault(_moduleVisitor);
- 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);}}
- var traversed = new Set();
- module.exports = {
- meta: {
- type: 'suggestion',
- docs: {
- category: 'Static analysis',
- description: 'Forbid a module from importing a module with a dependency path back to itself.',
- url: (0, _docsUrl2['default'])('no-cycle') },
- schema: [(0, _moduleVisitor.makeOptionsSchema)({
- maxDepth: {
- anyOf: [
- {
- description: 'maximum dependency depth to traverse',
- type: 'integer',
- minimum: 1 },
- {
- 'enum': ['∞'],
- type: 'string' }] },
- ignoreExternal: {
- description: 'ignore external modules',
- type: 'boolean',
- 'default': false },
- allowUnsafeDynamicCyclicDependency: {
- description: 'Allow cyclic dependency if there is at least one dynamic import in the chain',
- type: 'boolean',
- 'default': false } })] },
- create: function () {function create(context) {
- var myPath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
- if (myPath === '<text>') {return {};}
- var options = context.options[0] || {};
- var maxDepth = typeof options.maxDepth === 'number' ? options.maxDepth : Infinity;
- var ignoreModule = function () {function ignoreModule(name) {return options.ignoreExternal && (0, _importType.isExternalModule)(
- name,
- (0, _resolve2['default'])(name, context),
- context);}return ignoreModule;}();
- function checkSourceValue(sourceNode, importer) {
- if (ignoreModule(sourceNode.value)) {
- return;
- }
- if (
- options.allowUnsafeDynamicCyclicDependency && (
-
- importer.type === 'ImportExpression'
-
- || importer.type === 'CallExpression' && importer.callee.name !== 'require'))
- {
- return;
- }
- if (
- importer.type === 'ImportDeclaration' && (
-
- importer.importKind === 'type'
-
- || importer.specifiers.every(function (_ref) {var importKind = _ref.importKind;return importKind === 'type';})))
- {
- return;
- }
- var imported = _ExportMap2['default'].get(sourceNode.value, context);
- if (imported == null) {
- return;
- }
- if (imported.path === myPath) {
- return;
- }
- var untraversed = [{ mget: function () {function mget() {return imported;}return mget;}(), route: [] }];
- function detectCycle(_ref2) {var mget = _ref2.mget,route = _ref2.route;
- var m = mget();
- if (m == null) {return;}
- if (traversed.has(m.path)) {return;}
- traversed.add(m.path);var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
- for (var _iterator = m.imports[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var _ref3 = _step.value;var _ref4 = _slicedToArray(_ref3, 2);var path = _ref4[0];var _ref4$ = _ref4[1];var getter = _ref4$.getter;var declarations = _ref4$.declarations;
- if (traversed.has(path)) {continue;}
- var toTraverse = [].concat(_toConsumableArray(declarations)).filter(function (_ref5) {var source = _ref5.source,isOnlyImportingTypes = _ref5.isOnlyImportingTypes;return !ignoreModule(source.value)
-
- && !isOnlyImportingTypes;});
-
- if (options.allowUnsafeDynamicCyclicDependency && toTraverse.some(function (d) {return d.dynamic;})) {return;}
-
- if (path === myPath && toTraverse.length > 0) {return true;}
- if (route.length + 1 < maxDepth) {var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
- for (var _iterator2 = toTraverse[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {var _ref6 = _step2.value;var source = _ref6.source;
- untraversed.push({ mget: getter, route: route.concat(source) });
- }} catch (err) {_didIteratorError2 = true;_iteratorError2 = err;} finally {try {if (!_iteratorNormalCompletion2 && _iterator2['return']) {_iterator2['return']();}} finally {if (_didIteratorError2) {throw _iteratorError2;}}}
- }
- }} catch (err) {_didIteratorError = true;_iteratorError = err;} finally {try {if (!_iteratorNormalCompletion && _iterator['return']) {_iterator['return']();}} finally {if (_didIteratorError) {throw _iteratorError;}}}
- }
- while (untraversed.length > 0) {
- var next = untraversed.shift();
- if (detectCycle(next)) {
- var message = next.route.length > 0 ? 'Dependency cycle via ' + String(
- routeString(next.route)) :
- 'Dependency cycle detected.';
- context.report(importer, message);
- return;
- }
- }
- }
- return Object.assign((0, _moduleVisitor2['default'])(checkSourceValue, context.options[0]), {
- 'Program:exit': function () {function ProgramExit() {
- traversed.clear();
- }return ProgramExit;}() });
- }return create;}() };
- function routeString(route) {
- return route.map(function (s) {return String(s.value) + ':' + String(s.loc.start.line);}).join('=>');
- }
|