eslint-plugin-reactxp
Version:
ESlint rules for ReactXP
198 lines (197 loc) • 7.58 kB
JavaScript
;
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var experimental_utils_1 = require("@typescript-eslint/experimental-utils");
var utils_1 = require("../utils");
exports.default = (0, utils_1.createRule)({
name: 'no-unreferenced-styles',
meta: {
docs: {
description: "disallow unused styles",
recommended: 'error',
},
messages: {
unreferencedStyle: 'Unreferenced style',
notConst: 'Styles array is not marked const',
},
schema: [
{
type: 'object',
properties: {
variableName: {
type: 'string',
},
},
},
],
type: 'suggestion',
},
defaultOptions: [
{
variableName: '_styles',
},
],
create: function (context, _a) {
var variableName = _a[0].variableName;
/**
* getRefsFromObjectPattern
*
* @param node
* @returns {string[]}
*/
function getRefsFromObjectPattern(node) {
var keys = [];
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var property = _a[_i];
if (property.type === experimental_utils_1.AST_NODE_TYPES.Property &&
property.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
if (property.value.type === experimental_utils_1.AST_NODE_TYPES.ObjectPattern) {
keys.push([
property.key.name,
getRefsFromObjectPattern(property.value),
].join('.'));
}
else {
keys.push(property.key.name);
}
}
}
return keys;
}
/**
* getRefs
*
* @param references
* @returns {Map}
*/
function getRefs(references) {
var refs = new Map();
var _loop_1 = function (ref) {
var current = ref.identifier.parent;
var keys = [ref.identifier.name];
while (current) {
if (current.type === experimental_utils_1.AST_NODE_TYPES.MemberExpression &&
current.property.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
keys.push(current.property.name);
current = current.parent;
}
else if (current.type === experimental_utils_1.AST_NODE_TYPES.VariableDeclarator) {
current = current.id;
}
else if (current.type === experimental_utils_1.AST_NODE_TYPES.ObjectPattern) {
keys = getRefsFromObjectPattern(current).map(function (ref) {
return __spreadArray(__spreadArray([], keys, true), [ref], false).join('.');
});
current = undefined;
}
else {
keys = [keys.join('.')];
current = undefined;
}
}
for (var _a = 0, keys_1 = keys; _a < keys_1.length; _a++) {
var key = keys_1[_a];
if (key !== ref.identifier.name && !refs.has(key)) {
refs.set(key, key);
}
}
};
for (var _i = 0, references_1 = references; _i < references_1.length; _i++) {
var ref = references_1[_i];
_loop_1(ref);
}
return refs;
}
/**
* checkProps
*
* @param node
* @param refs
* @param parentName
* @param keys
* @returns {void}
*/
function checkProps(node, refs, parentName, keys) {
if (keys === void 0) { keys = [parentName]; }
for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
var property = _a[_i];
if (property.type === experimental_utils_1.AST_NODE_TYPES.Property &&
property.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
if (property.value.type === experimental_utils_1.AST_NODE_TYPES.ObjectExpression) {
checkProps(property.value, refs, parentName, __spreadArray(__spreadArray([], keys, true), [
property.key.name,
], false));
}
if (property.value.type === experimental_utils_1.AST_NODE_TYPES.CallExpression &&
!refs.has(__spreadArray(__spreadArray([], keys, true), [property.key.name], false).join('.'))) {
context.report({ node: property, messageId: 'unreferencedStyle' });
}
}
}
}
/**
* checkUnreferencedStyles
*
* @param references
* @param defs
* @returns {void}
*/
function checkUnreferencedStyles(_a) {
var references = _a.references, defs = _a.defs;
var def = defs[0];
var node = def.node;
if (node.type !== experimental_utils_1.AST_NODE_TYPES.VariableDeclarator) {
return;
}
if (node.parent &&
node.parent.type === experimental_utils_1.AST_NODE_TYPES.VariableDeclaration &&
node.parent.kind !== 'const') {
context.report({ node: node.parent, messageId: 'notConst' });
return;
}
if (node.id &&
node.id.type === experimental_utils_1.AST_NODE_TYPES.Identifier &&
node.init &&
node.init.type === experimental_utils_1.AST_NODE_TYPES.ObjectExpression) {
checkProps(node.init, getRefs(references), node.id.name);
}
}
/**
* findVariable
*
* @param scope
* @returns {TSESLint.Scope.Variable | undefined}
*/
function findVariable(scope) {
var variable = scope.variables.find(function (variable) { return variable.name === variableName; });
if (variable) {
return variable;
}
for (var _i = 0, _a = scope.childScopes; _i < _a.length; _i++) {
var childScope = _a[_i];
var variable_1 = findVariable(childScope);
if (variable_1) {
return variable_1;
}
}
return undefined;
}
return {
Program: function () {
var variable = findVariable(context.getScope());
if (!variable) {
return;
}
checkUnreferencedStyles(variable);
},
};
},
});