Skip to content

Commit

Permalink
Add destructuring support to no-deprecated
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickcr committed Apr 19, 2017
1 parent fd90dae commit 01fe095
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 42 deletions.
113 changes: 73 additions & 40 deletions lib/rules/no-deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,70 +34,103 @@ module.exports = {
var pragma = pragmaUtil.getFromContext(context);

function getDeprecated() {
var deprecated = {
MemberExpression: {}
};
var deprecated = {};
// 0.12.0
deprecated.MemberExpression[pragma + '.renderComponent'] = ['0.12.0', pragma + '.render'];
deprecated.MemberExpression[pragma + '.renderComponentToString'] = ['0.12.0', pragma + '.renderToString'];
deprecated.MemberExpression[pragma + '.renderComponentToStaticMarkup'] = [
'0.12.0',
pragma + '.renderToStaticMarkup'
];
deprecated.MemberExpression[pragma + '.isValidComponent'] = ['0.12.0', pragma + '.isValidElement'];
deprecated.MemberExpression[pragma + '.PropTypes.component'] = ['0.12.0', pragma + '.PropTypes.element'];
deprecated.MemberExpression[pragma + '.PropTypes.renderable'] = ['0.12.0', pragma + '.PropTypes.node'];
deprecated.MemberExpression[pragma + '.isValidClass'] = ['0.12.0'];
deprecated.MemberExpression['this.transferPropsTo'] = ['0.12.0', 'spread operator ({...})'];
deprecated[pragma + '.renderComponent'] = ['0.12.0', pragma + '.render'];
deprecated[pragma + '.renderComponentToString'] = ['0.12.0', pragma + '.renderToString'];
deprecated[pragma + '.renderComponentToStaticMarkup'] = ['0.12.0', pragma + '.renderToStaticMarkup'];
deprecated[pragma + '.isValidComponent'] = ['0.12.0', pragma + '.isValidElement'];
deprecated[pragma + '.PropTypes.component'] = ['0.12.0', pragma + '.PropTypes.element'];
deprecated[pragma + '.PropTypes.renderable'] = ['0.12.0', pragma + '.PropTypes.node'];
deprecated[pragma + '.isValidClass'] = ['0.12.0'];
deprecated['this.transferPropsTo'] = ['0.12.0', 'spread operator ({...})'];
// 0.13.0
deprecated.MemberExpression[pragma + '.addons.classSet'] = ['0.13.0', 'the npm module classnames'];
deprecated.MemberExpression[pragma + '.addons.cloneWithProps'] = ['0.13.0', pragma + '.cloneElement'];
deprecated[pragma + '.addons.classSet'] = ['0.13.0', 'the npm module classnames'];
deprecated[pragma + '.addons.cloneWithProps'] = ['0.13.0', pragma + '.cloneElement'];
// 0.14.0
deprecated.MemberExpression[pragma + '.render'] = ['0.14.0', 'ReactDOM.render'];
deprecated.MemberExpression[pragma + '.unmountComponentAtNode'] = ['0.14.0', 'ReactDOM.unmountComponentAtNode'];
deprecated.MemberExpression[pragma + '.findDOMNode'] = ['0.14.0', 'ReactDOM.findDOMNode'];
deprecated.MemberExpression[pragma + '.renderToString'] = ['0.14.0', 'ReactDOMServer.renderToString'];
deprecated.MemberExpression[pragma + '.renderToStaticMarkup'] = ['0.14.0', 'ReactDOMServer.renderToStaticMarkup'];
deprecated[pragma + '.render'] = ['0.14.0', 'ReactDOM.render'];
deprecated[pragma + '.unmountComponentAtNode'] = ['0.14.0', 'ReactDOM.unmountComponentAtNode'];
deprecated[pragma + '.findDOMNode'] = ['0.14.0', 'ReactDOM.findDOMNode'];
deprecated[pragma + '.renderToString'] = ['0.14.0', 'ReactDOMServer.renderToString'];
deprecated[pragma + '.renderToStaticMarkup'] = ['0.14.0', 'ReactDOMServer.renderToStaticMarkup'];
// 15.0.0
deprecated.MemberExpression[pragma + '.addons.LinkedStateMixin'] = ['15.0.0'];
deprecated.MemberExpression['ReactPerf.printDOM'] = ['15.0.0', 'ReactPerf.printOperations'];
deprecated.MemberExpression['Perf.printDOM'] = ['15.0.0', 'Perf.printOperations'];
deprecated.MemberExpression['ReactPerf.getMeasurementsSummaryMap'] = ['15.0.0', 'ReactPerf.getWasted'];
deprecated.MemberExpression['Perf.getMeasurementsSummaryMap'] = ['15.0.0', 'Perf.getWasted'];
deprecated[pragma + '.addons.LinkedStateMixin'] = ['15.0.0'];
deprecated['ReactPerf.printDOM'] = ['15.0.0', 'ReactPerf.printOperations'];
deprecated['Perf.printDOM'] = ['15.0.0', 'Perf.printOperations'];
deprecated['ReactPerf.getMeasurementsSummaryMap'] = ['15.0.0', 'ReactPerf.getWasted'];
deprecated['Perf.getMeasurementsSummaryMap'] = ['15.0.0', 'Perf.getWasted'];
// 15.5.0
deprecated[pragma + '.createClass'] = ['15.5.0', 'the npm module create-react-class'];
deprecated[pragma + '.PropTypes'] = ['15.5.0', 'the npm module prop-types'];

return deprecated;
}

function isDeprecated(type, method) {
function isDeprecated(method) {
var deprecated = getDeprecated();

return (
deprecated[type] &&
deprecated[type][method] &&
versionUtil.test(context, deprecated[type][method][0])
deprecated &&
deprecated[method] &&
versionUtil.test(context, deprecated[method][0])
);
}

function checkDeprecation(node, method) {
if (!isDeprecated(method)) {
return;
}
var deprecated = getDeprecated();
context.report({
node: node,
message: DEPRECATED_MESSAGE,
data: {
oldMethod: method,
version: deprecated[method][0],
newMethod: deprecated[method][1] ? ', use ' + deprecated[method][1] + ' instead' : ''
}
});
}

// --------------------------------------------------------------------------
// Public
// --------------------------------------------------------------------------

return {

MemberExpression: function(node) {
var method = sourceCode.getText(node);
if (!isDeprecated(node.type, method)) {
checkDeprecation(node, sourceCode.getText(node));
},

ImportDeclaration: function(node) {
var isReactImport = node.source.value === 'react';
if (!isReactImport) {
return;
}
var deprecated = getDeprecated();
context.report({
node: node,
message: DEPRECATED_MESSAGE,
data: {
oldMethod: method,
version: deprecated[node.type][method][0],
newMethod: deprecated[node.type][method][1] ? ', use ' + deprecated[node.type][method][1] + ' instead' : ''
node.specifiers.forEach(function(specifier) {
if (!specifier.imported) {
return;
}
checkDeprecation(node, pragma + '.' + specifier.imported.name);
});
},

VariableDeclarator: function(node) {
var isRequire = node.init && node.init.callee && node.init.callee.name === 'require';
var isReactRequire =
node.init && node.init.arguments &&
node.init.arguments.length && node.init.arguments[0].value === 'react'
;
var isDestructuring = node.id && node.id.type === 'ObjectPattern';
var isReactDestructuring = node.init && node.init.name === 'React';
if (
!(isDestructuring && isReactDestructuring) &&
!(isDestructuring && isRequire && isReactRequire)
) {
return;
}
node.id.properties.forEach(function(property) {
checkDeprecation(node, pragma + '.' + property.key.name);
});
},

Expand Down
44 changes: 42 additions & 2 deletions tests/lib/rules/no-deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ ruleTester.run('no-deprecated', rule, {

valid: [
// Not deprecated
'var MyClass = React.createClass({});',
'var element = React.createElement(\'p\', {}, null);',
'var clone = React.cloneElement(element);',
'ReactDOM.render(element, container);',
Expand Down Expand Up @@ -94,6 +93,47 @@ ruleTester.run('no-deprecated', rule, {
'use ReactDOMServer.renderToStaticMarkup instead'
)
}]
}, {
code: 'const {createClass} = require(\'react\');',
parser: 'babel-eslint',
errors: [{
message: 'React.createClass is deprecated since React 15.5.0, use the npm module create-react-class instead'
}]
}, {
code: 'const {PropTypes} = require(\'react\');',
parser: 'babel-eslint',
errors: [{
message: 'React.PropTypes is deprecated since React 15.5.0, use the npm module prop-types instead'
}]
}, {
code: 'import {createClass} from \'react\';',
parser: 'babel-eslint',
errors: [{
message: 'React.createClass is deprecated since React 15.5.0, use the npm module create-react-class instead'
}]
}, {
code: 'import {PropTypes} from \'react\';',
parser: 'babel-eslint',
errors: [{
message: 'React.PropTypes is deprecated since React 15.5.0, use the npm module prop-types instead'
}]
}, {
code: [
'import React from \'react\';',
'const {PropTypes} = React;'
].join('\n'),
parser: 'babel-eslint',
errors: [{
message: 'React.PropTypes is deprecated since React 15.5.0, use the npm module prop-types instead'
}]
}, {
code: [
'import React from \'react\';',
'const {createClass} = React;'
].join('\n'),
parser: 'babel-eslint',
errors: [{
message: 'React.createClass is deprecated since React 15.5.0, use the npm module create-react-class instead'
}]
}]

});

0 comments on commit 01fe095

Please sign in to comment.