mirror of
https://github.com/joelwmale/webhook-action.git
synced 2024-11-26 09:25:24 +01:00
160 lines
20 KiB
JavaScript
160 lines
20 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
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);}} /**
|
||
|
* @fileoverview Rule to disallow namespace import
|
||
|
* @author Radek Benkel
|
||
|
*/ //------------------------------------------------------------------------------
|
||
|
// Rule Definition
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
module.exports = {
|
||
|
meta: {
|
||
|
type: 'suggestion',
|
||
|
docs: {
|
||
|
url: (0, _docsUrl2.default)('no-namespace') },
|
||
|
|
||
|
fixable: 'code',
|
||
|
schema: [] },
|
||
|
|
||
|
|
||
|
create: function (context) {
|
||
|
return {
|
||
|
'ImportNamespaceSpecifier': function (node) {
|
||
|
const scopeVariables = context.getScope().variables;
|
||
|
const namespaceVariable = scopeVariables.find(variable =>
|
||
|
variable.defs[0].node === node);
|
||
|
|
||
|
const namespaceReferences = namespaceVariable.references;
|
||
|
const namespaceIdentifiers = namespaceReferences.map(reference => reference.identifier);
|
||
|
const canFix = namespaceIdentifiers.length > 0 && !usesNamespaceAsObject(namespaceIdentifiers);
|
||
|
|
||
|
context.report({
|
||
|
node,
|
||
|
message: `Unexpected namespace import.`,
|
||
|
fix: canFix && (fixer => {
|
||
|
const scopeManager = context.getSourceCode().scopeManager;
|
||
|
const fixes = [];
|
||
|
|
||
|
// Pass 1: Collect variable names that are already in scope for each reference we want
|
||
|
// to transform, so that we can be sure that we choose non-conflicting import names
|
||
|
const importNameConflicts = {};
|
||
|
namespaceIdentifiers.forEach(identifier => {
|
||
|
const parent = identifier.parent;
|
||
|
if (parent && parent.type === 'MemberExpression') {
|
||
|
const importName = getMemberPropertyName(parent);
|
||
|
const localConflicts = getVariableNamesInScope(scopeManager, parent);
|
||
|
if (!importNameConflicts[importName]) {
|
||
|
importNameConflicts[importName] = localConflicts;
|
||
|
} else {
|
||
|
localConflicts.forEach(c => importNameConflicts[importName].add(c));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Choose new names for each import
|
||
|
const importNames = Object.keys(importNameConflicts);
|
||
|
const importLocalNames = generateLocalNames(
|
||
|
importNames,
|
||
|
importNameConflicts,
|
||
|
namespaceVariable.name);
|
||
|
|
||
|
|
||
|
// Replace the ImportNamespaceSpecifier with a list of ImportSpecifiers
|
||
|
const namedImportSpecifiers = importNames.map(importName =>
|
||
|
importName === importLocalNames[importName] ?
|
||
|
importName :
|
||
|
`${importName} as ${importLocalNames[importName]}`);
|
||
|
|
||
|
fixes.push(fixer.replaceText(node, `{ ${namedImportSpecifiers.join(', ')} }`));
|
||
|
|
||
|
// Pass 2: Replace references to the namespace with references to the named imports
|
||
|
namespaceIdentifiers.forEach(identifier => {
|
||
|
const parent = identifier.parent;
|
||
|
if (parent && parent.type === 'MemberExpression') {
|
||
|
const importName = getMemberPropertyName(parent);
|
||
|
fixes.push(fixer.replaceText(parent, importLocalNames[importName]));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return fixes;
|
||
|
}) });
|
||
|
|
||
|
} };
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @param {Identifier[]} namespaceIdentifiers
|
||
|
* @returns {boolean} `true` if the namespace variable is more than just a glorified constant
|
||
|
*/ };
|
||
|
function usesNamespaceAsObject(namespaceIdentifiers) {
|
||
|
return !namespaceIdentifiers.every(identifier => {
|
||
|
const parent = identifier.parent;
|
||
|
|
||
|
// `namespace.x` or `namespace['x']`
|
||
|
return (
|
||
|
parent && parent.type === 'MemberExpression' && (
|
||
|
parent.property.type === 'Identifier' || parent.property.type === 'Literal'));
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {MemberExpression} memberExpression
|
||
|
* @returns {string} the name of the member in the object expression, e.g. the `x` in `namespace.x`
|
||
|
*/
|
||
|
function getMemberPropertyName(memberExpression) {
|
||
|
return memberExpression.property.type === 'Identifier' ?
|
||
|
memberExpression.property.name :
|
||
|
memberExpression.property.value;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {ScopeManager} scopeManager
|
||
|
* @param {ASTNode} node
|
||
|
* @return {Set<string>}
|
||
|
*/
|
||
|
function getVariableNamesInScope(scopeManager, node) {
|
||
|
let currentNode = node;
|
||
|
let scope = scopeManager.acquire(currentNode);
|
||
|
while (scope == null) {
|
||
|
currentNode = currentNode.parent;
|
||
|
scope = scopeManager.acquire(currentNode, true);
|
||
|
}
|
||
|
return new Set([].concat(_toConsumableArray(
|
||
|
scope.variables.map(variable => variable.name)), _toConsumableArray(
|
||
|
scope.upper.variables.map(variable => variable.name))));
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param {*} names
|
||
|
* @param {*} nameConflicts
|
||
|
* @param {*} namespaceName
|
||
|
*/
|
||
|
function generateLocalNames(names, nameConflicts, namespaceName) {
|
||
|
const localNames = {};
|
||
|
names.forEach(name => {
|
||
|
let localName;
|
||
|
if (!nameConflicts[name].has(name)) {
|
||
|
localName = name;
|
||
|
} else if (!nameConflicts[name].has(`${namespaceName}_${name}`)) {
|
||
|
localName = `${namespaceName}_${name}`;
|
||
|
} else {
|
||
|
for (let i = 1; i < Infinity; i++) {
|
||
|
if (!nameConflicts[name].has(`${namespaceName}_${name}_${i}`)) {
|
||
|
localName = `${namespaceName}_${name}_${i}`;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
localNames[name] = localName;
|
||
|
});
|
||
|
return localNames;
|
||
|
}
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1uYW1lc3BhY2UuanMiXSwibmFtZXMiOlsibW9kdWxlIiwiZXhwb3J0cyIsIm1ldGEiLCJ0eXBlIiwiZG9jcyIsInVybCIsImZpeGFibGUiLCJzY2hlbWEiLCJjcmVhdGUiLCJjb250ZXh0Iiwibm9kZSIsInNjb3BlVmFyaWFibGVzIiwiZ2V0U2NvcGUiLCJ2YXJpYWJsZXMiLCJuYW1lc3BhY2VWYXJpYWJsZSIsImZpbmQiLCJ2YXJpYWJsZSIsImRlZnMiLCJuYW1lc3BhY2VSZWZlcmVuY2VzIiwicmVmZXJlbmNlcyIsIm5hbWVzcGFjZUlkZW50aWZpZXJzIiwibWFwIiwicmVmZXJlbmNlIiwiaWRlbnRpZmllciIsImNhbkZpeCIsImxlbmd0aCIsInVzZXNOYW1lc3BhY2VBc09iamVjdCIsInJlcG9ydCIsIm1lc3NhZ2UiLCJmaXgiLCJmaXhlciIsInNjb3BlTWFuYWdlciIsImdldFNvdXJjZUNvZGUiLCJmaXhlcyIsImltcG9ydE5hbWVDb25mbGljdHMiLCJmb3JFYWNoIiwicGFyZW50IiwiaW1wb3J0TmFtZSIsImdldE1lbWJlclByb3BlcnR5TmFtZSIsImxvY2FsQ29uZmxpY3RzIiwiZ2V0VmFyaWFibGVOYW1lc0luU2NvcGUiLCJjIiwiYWRkIiwiaW1wb3J0TmFtZXMiLCJPYmplY3QiLCJrZXlzIiwiaW1wb3J0TG9jYWxOYW1lcyIsImdlbmVyYXRlTG9jYWxOYW1lcyIsIm5hbWUiLCJuYW1lZEltcG9ydFNwZWNpZmllcnMiLCJwdXNoIiwicmVwbGFjZVRleHQiLCJqb2luIiwiZXZlcnkiLCJwcm9wZXJ0eSIsIm1lbWJlckV4cHJlc3Npb24iLCJ2YWx1ZSIsImN1cnJlbnROb2RlIiwic2NvcGUiLCJhY3F1aXJlIiwiU2V0IiwidXBwZXIiLCJuYW1lcyIsIm5hbWVDb25mbGljdHMiLCJuYW1lc3BhY2VOYW1lIiwibG9jYWxOYW1lcyIsImxvY2FsTmFtZSIsImhhcyIsImkiLCJJbmZpbml0eSJdLCJtYXBwaW5ncyI6Ijs7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
|