Socket
Socket
Sign inDemoInstall

eslint-plugin-react

Package Overview
Dependencies
Maintainers
1
Versions
210
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-react - npm Package Compare versions

Comparing version 4.3.0 to 5.0.0

lib/rules/jsx-first-prop-new-line.js

31

CHANGELOG.md

@@ -6,2 +6,33 @@ # Change Log

## [5.0.0] - 2016-04-17
### Added
* Add `jsx-first-prop-new-line` rule ([#410][] @jseminck)
### Breaking
* Update rules for React 15:
* Add warnings for `LinkedStateMixin`, `ReactPerf.printDOM` and `ReactPerf.getMeasurementsSummaryMap` in `no-deprecated`
* Allow stateless components to return `null` in `prefer-stateless-function`
* Remove SVG attributes warnings ([#490][])
If you're still not using React 15 you can keep the old behavior by setting the React version to `0.14` in the [shared settings](README.md#configuration).
### Fixed
* Rewrite `require-render-return` rule ([#542][], [#543][])
* Fix `prefer-stateless-function` crash ([#544][])
* Fix external propTypes handling ([#545][])
* Do not mark inline functions in JSX as components ([#546][])
### Changed
* Update dependencies
* Documentation improvements
[5.0.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v4.3.0...v5.0.0
[#410]: https://github.com/yannickcr/eslint-plugin-react/issues/410
[#490]: https://github.com/yannickcr/eslint-plugin-react/issues/490
[#542]: https://github.com/yannickcr/eslint-plugin-react/issues/542
[#543]: https://github.com/yannickcr/eslint-plugin-react/issues/543
[#544]: https://github.com/yannickcr/eslint-plugin-react/issues/544
[#545]: https://github.com/yannickcr/eslint-plugin-react/issues/545
[#546]: https://github.com/yannickcr/eslint-plugin-react/issues/546
## [4.3.0] - 2016-04-07

@@ -8,0 +39,0 @@ ### Added

3

index.js

@@ -45,3 +45,4 @@ 'use strict';

'prefer-stateless-function': require('./lib/rules/prefer-stateless-function'),
'require-render-return': require('./lib/rules/require-render-return')
'require-render-return': require('./lib/rules/require-render-return'),
'jsx-first-prop-new-line': require('./lib/rules/jsx-first-prop-new-line')
},

@@ -48,0 +49,0 @@ configs: {

@@ -51,2 +51,8 @@ /**

deprecated.MemberExpression[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'];

@@ -53,0 +59,0 @@ return deprecated;

@@ -7,2 +7,4 @@ /**

var versionUtil = require('../util/version');
// ------------------------------------------------------------------------------

@@ -15,8 +17,9 @@ // Constants

var DOM_ATTRIBUTE_NAMES = {
// Standard
'accept-charset': 'acceptCharset',
class: 'className',
for: 'htmlFor',
'http-equiv': 'httpEquiv',
// SVG
'http-equiv': 'httpEquiv'
};
var SVGDOM_ATTRIBUTE_NAMES = {
'clip-path': 'clipPath',

@@ -92,9 +95,14 @@ 'fill-opacity': 'fillOpacity',

* Get the standard name of the attribute.
* @param {Object} context The current rule context.
* @param {String} name - Name of the attribute.
* @returns {String} The standard name of the attribute.
*/
function getStandardName(name) {
function getStandardName(context, name) {
if (DOM_ATTRIBUTE_NAMES[name]) {
return DOM_ATTRIBUTE_NAMES[name];
}
// Also check for SVG attribute for React <15
if (!versionUtil.test(context, '15.0.0') && SVGDOM_ATTRIBUTE_NAMES[name]) {
return SVGDOM_ATTRIBUTE_NAMES[name];
}
var i;

@@ -120,3 +128,3 @@ var found = DOM_PROPERTY_NAMES.some(function(element, index) {

var name = sourceCode.getText(node.name);
var standardName = getStandardName(name);
var standardName = getStandardName(context, name);
if (!isTagName(node) || !standardName) {

@@ -123,0 +131,0 @@ return;

@@ -10,2 +10,3 @@ /**

var Components = require('../util/Components');
var versionUtil = require('../util/version');

@@ -58,53 +59,127 @@ // ------------------------------------------------------------------------------

/**
* Checks whether the constructor body is a redundant super call.
* Checks whether a given array of statements is a single call of `super`.
* @see ESLint no-useless-constructor rule
* @param {Array} body - constructor body content.
* @param {Array} ctorParams - The params to check against super call.
* @returns {boolean} true if the construtor body is redundant
* @param {ASTNode[]} body - An array of statements to check.
* @returns {boolean} `true` if the body is a single call of `super`.
*/
function isRedundantSuperCall(body, ctorParams) {
if (
body.length !== 1 ||
body[0].type !== 'ExpressionStatement' ||
body[0].expression.callee.type !== 'Super'
) {
function isSingleSuperCall(body) {
return (
body.length === 1 &&
body[0].type === 'ExpressionStatement' &&
body[0].expression.type === 'CallExpression' &&
body[0].expression.callee.type === 'Super'
);
}
/**
* Checks whether a given node is a pattern which doesn't have any side effects.
* Default parameters and Destructuring parameters can have side effects.
* @see ESLint no-useless-constructor rule
* @param {ASTNode} node - A pattern node.
* @returns {boolean} `true` if the node doesn't have any side effects.
*/
function isSimple(node) {
return node.type === 'Identifier' || node.type === 'RestElement';
}
/**
* Checks whether a given array of expressions is `...arguments` or not.
* `super(...arguments)` passes all arguments through.
* @see ESLint no-useless-constructor rule
* @param {ASTNode[]} superArgs - An array of expressions to check.
* @returns {boolean} `true` if the superArgs is `...arguments`.
*/
function isSpreadArguments(superArgs) {
return (
superArgs.length === 1 &&
superArgs[0].type === 'SpreadElement' &&
superArgs[0].argument.type === 'Identifier' &&
superArgs[0].argument.name === 'arguments'
);
}
/**
* Checks whether given 2 nodes are identifiers which have the same name or not.
* @see ESLint no-useless-constructor rule
* @param {ASTNode} ctorParam - A node to check.
* @param {ASTNode} superArg - A node to check.
* @returns {boolean} `true` if the nodes are identifiers which have the same
* name.
*/
function isValidIdentifierPair(ctorParam, superArg) {
return (
ctorParam.type === 'Identifier' &&
superArg.type === 'Identifier' &&
ctorParam.name === superArg.name
);
}
/**
* Checks whether given 2 nodes are a rest/spread pair which has the same values.
* @see ESLint no-useless-constructor rule
* @param {ASTNode} ctorParam - A node to check.
* @param {ASTNode} superArg - A node to check.
* @returns {boolean} `true` if the nodes are a rest/spread pair which has the
* same values.
*/
function isValidRestSpreadPair(ctorParam, superArg) {
return (
ctorParam.type === 'RestElement' &&
superArg.type === 'SpreadElement' &&
isValidIdentifierPair(ctorParam.argument, superArg.argument)
);
}
/**
* Checks whether given 2 nodes have the same value or not.
* @see ESLint no-useless-constructor rule
* @param {ASTNode} ctorParam - A node to check.
* @param {ASTNode} superArg - A node to check.
* @returns {boolean} `true` if the nodes have the same value or not.
*/
function isValidPair(ctorParam, superArg) {
return (
isValidIdentifierPair(ctorParam, superArg) ||
isValidRestSpreadPair(ctorParam, superArg)
);
}
/**
* Checks whether the parameters of a constructor and the arguments of `super()`
* have the same values or not.
* @see ESLint no-useless-constructor rule
* @param {ASTNode} ctorParams - The parameters of a constructor to check.
* @param {ASTNode} superArgs - The arguments of `super()` to check.
* @returns {boolean} `true` if those have the same values.
*/
function isPassingThrough(ctorParams, superArgs) {
if (ctorParams.length !== superArgs.length) {
return false;
}
var superArgs = body[0].expression.arguments;
var firstSuperArg = superArgs[0];
var lastSuperArgIndex = superArgs.length - 1;
var lastSuperArg = superArgs[lastSuperArgIndex];
var isSimpleParameterList = ctorParams.every(function(param) {
return param.type === 'Identifier' || param.type === 'RestElement';
});
/**
* Checks if a super argument is the same with constructor argument
* @param {ASTNode} arg argument node
* @param {number} index argument index
* @returns {boolean} true if the arguments are same, false otherwise
*/
function isSameIdentifier(arg, index) {
return (
arg.type === 'Identifier' &&
arg.name === ctorParams[index].name
);
for (var i = 0; i < ctorParams.length; ++i) {
if (!isValidPair(ctorParams[i], superArgs[i])) {
return false;
}
}
var spreadsArguments =
superArgs.length === 1 &&
firstSuperArg.type === 'SpreadElement' &&
firstSuperArg.argument.name === 'arguments';
return true;
}
var passesParamsAsArgs =
superArgs.length === ctorParams.length &&
superArgs.every(isSameIdentifier) ||
superArgs.length <= ctorParams.length &&
superArgs.slice(0, -1).every(isSameIdentifier) &&
lastSuperArg.type === 'SpreadElement' &&
ctorParams[lastSuperArgIndex].type === 'RestElement' &&
lastSuperArg.argument.name === ctorParams[lastSuperArgIndex].argument.name;
return isSimpleParameterList && (spreadsArguments || passesParamsAsArgs);
/**
* Checks whether the constructor body is a redundant super call.
* @see ESLint no-useless-constructor rule
* @param {Array} body - constructor body content.
* @param {Array} ctorParams - The params to check against super call.
* @returns {boolean} true if the construtor body is redundant
*/
function isRedundantSuperCall(body, ctorParams) {
return (
isSingleSuperCall(body) &&
ctorParams.every(isSimple) &&
(
isSpreadArguments(body[0].expression.arguments) ||
isPassingThrough(ctorParams, body[0].expression.arguments)
)
);
}

@@ -214,3 +289,11 @@

}
if (!blockNode || !blockNode.key || blockNode.key.name !== 'render' || utils.isReturningJSX(node, true)) {
var isRender = blockNode && blockNode.key && blockNode.key.name === 'render';
var allowNull = versionUtil.test(context, '15.0.0'); // Stateless components can return null since React 15
var isReturningJSX = utils.isReturningJSX(node, !allowNull);
var isReturningNull = node.argument && (node.argument.value === null || node.argument.value === false);
if (
!isRender ||
(allowNull && (isReturningJSX || isReturningNull)) ||
(!allowNull && isReturningJSX)
) {
return;

@@ -217,0 +300,0 @@ }

@@ -664,2 +664,4 @@ /**

buildReactDeclarationTypes(propTypes.parent.right);
} else {
ignorePropsValidation = true;
}

@@ -666,0 +668,0 @@ break;

@@ -13,37 +13,41 @@ /**

module.exports = Components.detect(function(context) {
/**
* Helper for checking if parent node is render method.
* @param {ASTNode} node to check
* @returns {boolean} If previous node is method and name is render returns true, otherwise false;
*/
function checkParent(node) {
return (node.parent.type === 'Property' || node.parent.type === 'MethodDefinition')
&& node.parent.key
&& node.parent.key.name === 'render';
}
module.exports = Components.detect(function(context, components) {
/**
* Helper for checking if child node exists and if it's ReturnStatement
* @param {ASTNode} node to check
* @returns {boolean} True if ReturnStatement exists, otherwise false
* Mark a return statement as present
* @param {ASTNode} node The AST node being checked.
*/
function checkReturnStatementExistence(node) {
if (!node.body && !node.body.body && !node.body.body.length) {
return false;
}
var hasReturnStatement = node.body.body.some(function(elem) {
return elem.type === 'ReturnStatement';
function markReturnStatementPresent(node) {
components.set(node, {
hasReturnStatement: true
});
return hasReturnStatement;
}
return {
ReturnStatement: function(node) {
var ancestors = context.getAncestors(node).reverse();
var depth = 0;
for (var i = 0, j = ancestors.length; i < j; i++) {
if (/Function(Expression|Declaration)$/.test(ancestors[i].type)) {
depth++;
}
if (
(ancestors[i].type !== 'Property' && ancestors[i].type !== 'MethodDefinition') ||
ancestors[i].key.name !== 'render' ||
depth > 1
) {
continue;
}
markReturnStatementPresent(node);
}
},
return {
FunctionExpression: function(node) {
if (checkParent(node) && !checkReturnStatementExistence(node)) {
'Program:exit': function() {
var list = components.list();
for (var component in list) {
if (!list.hasOwnProperty(component) || list[component].hasReturnStatement) {
continue;
}
context.report({
node: node,
node: list[component].node,
message: 'Your render method should have return statement'

@@ -50,0 +54,0 @@ });

@@ -394,3 +394,6 @@ /**

node = utils.getParentComponent();
if (!node) {
if (
!node ||
(node.parent && node.parent.type === 'JSXExpressionContainer')
) {
return;

@@ -411,3 +414,6 @@ }

node = utils.getParentComponent();
if (!node) {
if (
!node ||
(node.parent && node.parent.type === 'JSXExpressionContainer')
) {
return;

@@ -414,0 +420,0 @@ }

{
"name": "eslint-plugin-react",
"version": "4.3.0",
"version": "5.0.0",
"author": "Yannick Croissant <yannick.croissant+npm@gmail.com>",

@@ -28,3 +28,3 @@ "description": "React specific linting rules for ESLint",

"coveralls": "2.11.9",
"eslint": "2.7.0",
"eslint": "2.8.0",
"istanbul": "0.4.3",

@@ -31,0 +31,0 @@ "mocha": "2.4.5"

@@ -41,3 +41,3 @@ ESLint-plugin-React

"pragma": "React", // Pragma to use, default to "React"
"version": "0.14.0" // React version, default to the latest React stable release
"version": "15.0" // React version, default to the latest React stable release
}

@@ -95,2 +95,3 @@ }

* [require-extension](docs/rules/require-extension.md): Restrict file extensions that may be required
* [require-render-return](docs/rules/require-render-return.md): Enforce ES5 or ES6 class for returning value in render function
* [self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children

@@ -107,2 +108,3 @@ * [sort-comp](docs/rules/sort-comp.md): Enforce component methods order

* [jsx-equals-spacing](docs/rules/jsx-equals-spacing.md): Enforce or disallow spaces around equal signs in JSX attributes (fixable)
* [jsx-first-prop-new-line](docs/rules/jsx-first-prop-new-line.md): Enforce position of the first prop in JSX
* [jsx-handler-names](docs/rules/jsx-handler-names.md): Enforce event handler naming conventions in JSX

@@ -109,0 +111,0 @@ * [jsx-indent-props](docs/rules/jsx-indent-props.md): Validate props indentation in JSX (fixable)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc