Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce memory allocation in rules and utils #2976

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
69 changes: 44 additions & 25 deletions lib/rules/no-typos.js
Expand Up @@ -4,7 +4,8 @@

'use strict';

const PROP_TYPES = Object.keys(require('prop-types'));
const PROP_TYPES = require('prop-types');
const fromEntries = require('object.fromentries');
const Components = require('../util/Components');
const docsUrl = require('../util/docsUrl');

Expand All @@ -13,7 +14,17 @@ const docsUrl = require('../util/docsUrl');
// ------------------------------------------------------------------------------

const STATIC_CLASS_PROPERTIES = ['propTypes', 'contextTypes', 'childContextTypes', 'defaultProps'];
const STATIC_CLASS_PROPERTIES_LOWER_CASE = fromEntries(STATIC_CLASS_PROPERTIES.map((name) => ([
name.toLowerCase(),
name
])));
const STATIC_CLASS_PROPERTIES_LOCALE_LOWER_CASE = fromEntries(
STATIC_CLASS_PROPERTIES.map((name) => [name.toLocaleLowerCase(), name])
);
const STATIC_LIFECYCLE_METHODS = ['getDerivedStateFromProps'];
const INVALID_STATIC_LIFECYCLE_METHODS = fromEntries(STATIC_LIFECYCLE_METHODS
.map((name) => [name.toLowerCase(), name])
);
const LIFECYCLE_METHODS = [
'getDerivedStateFromProps',
'componentWillMount',
Expand All @@ -30,6 +41,9 @@ const LIFECYCLE_METHODS = [
'componentWillUnmount',
'render'
];
const INVALID_LIFECYCLE_METHODS = fromEntries(LIFECYCLE_METHODS
.map((name) => [name.toLowerCase(), name])
);

module.exports = {
meta: {
Expand Down Expand Up @@ -69,7 +83,7 @@ module.exports = {
}

function checkValidPropType(node) {
if (node.name && !PROP_TYPES.some((propTypeName) => propTypeName === node.name)) {
if (node.name && !(node.name in PROP_TYPES)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use Sets here rather than in? also, using in here ensures we'll get false positives for things like toString, or anything else on Object.prototype.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on false positives with in, I definitely hadn't considered that.

Set looks like a good fit here!

context.report({
node,
messageId: 'typoPropType',
Expand Down Expand Up @@ -144,16 +158,18 @@ module.exports = {
if (propertyName === 'propTypes' || propertyName === 'contextTypes' || propertyName === 'childContextTypes') {
checkValidPropObject(propertyValue);
}
STATIC_CLASS_PROPERTIES.forEach((CLASS_PROP) => {
if (propertyName && CLASS_PROP.toLowerCase() === propertyName.toLowerCase() && CLASS_PROP !== propertyName) {
if (propertyName) {
const propertyNameLowerCase = propertyName.toLowerCase();
if (propertyNameLowerCase in STATIC_CLASS_PROPERTIES_LOWER_CASE
&& STATIC_CLASS_PROPERTIES_LOWER_CASE[propertyNameLowerCase] !== propertyName) {
context.report({
node: propertyKey,
messageId: isClassProperty
? 'typoStaticClassProp'
: 'typoPropDeclaration'
});
}
});
}
}

function reportErrorIfLifecycleMethodCasingTypo(node) {
Expand All @@ -165,8 +181,10 @@ module.exports = {
return;
}

STATIC_LIFECYCLE_METHODS.forEach((method) => {
if (!node.static && nodeKeyName.toLowerCase() === method.toLowerCase()) {
const nodeKeyNameLowerCase = nodeKeyName.toLowerCase();

if (!node.static) {
if (nodeKeyNameLowerCase in INVALID_STATIC_LIFECYCLE_METHODS) {
context.report({
node,
messageId: 'staticLifecycleMethod',
Expand All @@ -175,17 +193,16 @@ module.exports = {
}
});
}
});
}

LIFECYCLE_METHODS.forEach((method) => {
if (method.toLowerCase() === nodeKeyName.toLowerCase() && method !== nodeKeyName) {
context.report({
node,
messageId: 'typoLifecycleMethod',
data: {actual: nodeKeyName, expected: method}
});
}
});
if (nodeKeyNameLowerCase in INVALID_LIFECYCLE_METHODS
&& INVALID_LIFECYCLE_METHODS[nodeKeyNameLowerCase] !== nodeKeyName) {
context.report({
node,
messageId: 'typoLifecycleMethod',
data: {actual: nodeKeyName, expected: INVALID_LIFECYCLE_METHODS[nodeKeyNameLowerCase]}
});
}
}

return {
Expand Down Expand Up @@ -232,19 +249,21 @@ module.exports = {

if (
!propertyName
|| STATIC_CLASS_PROPERTIES.map((prop) => prop.toLocaleLowerCase()).indexOf(propertyName.toLowerCase()) === -1
|| !(propertyName.toLowerCase() in STATIC_CLASS_PROPERTIES_LOCALE_LOWER_CASE)
) {
return;
}

const relatedComponent = utils.getRelatedComponent(node);
if (node.parent && node.parent.type === 'AssignmentExpression' && node.parent.right) {
const relatedComponent = utils.getRelatedComponent(node);

if (
relatedComponent
&& (utils.isES6Component(relatedComponent.node) || utils.isReturningJSX(relatedComponent.node))
&& (node.parent && node.parent.type === 'AssignmentExpression' && node.parent.right)
) {
reportErrorIfPropertyCasingTypo(node.parent.right, node.property, true);
if (
relatedComponent
&& (utils.isES6Component(relatedComponent.node) || utils.isReturningJSX(relatedComponent.node))
&& (node.parent && node.parent.type === 'AssignmentExpression' && node.parent.right)
) {
reportErrorIfPropertyCasingTypo(node.parent.right, node.property, true);
}
}
},

Expand Down
11 changes: 1 addition & 10 deletions lib/rules/no-unsafe.js
Expand Up @@ -73,22 +73,13 @@ module.exports = {
unsafe.componentWillUpdate = unsafe.UNSAFE_componentWillUpdate;
}

/**
* Returns a list of unsafe methods
* @returns {Array} A list of unsafe methods
*/
function getUnsafeMethods() {
return Object.keys(unsafe);
}

/**
* Checks if a passed method is unsafe
* @param {string} method Life cycle method
* @returns {boolean} Returns true for unsafe methods, otherwise returns false
*/
function isUnsafe(method) {
const unsafeMethods = getUnsafeMethods();
return unsafeMethods.indexOf(method) !== -1;
return (method in unsafe);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}

/**
Expand Down