diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/lib/main.js index fedde217d02e..9f54ca98a843 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/lib/main.js @@ -81,19 +81,88 @@ function main( context ) { break; } + /** + * Sorts the variable declarations by name length. + * + * @private + * @param {Object} a - input object + * @param {Object} b - comparison object + * @returns {number} number indicating sort order + */ + function sortVars( a, b ) { + if ( fun( a.name.length, b.name.length ) ) { + return 1; + } + return -1; + } + /** * Reports the error message. * * @private * @param {string} msg - error message - * @param {Object} loc - lines of code (object with `start` and `end` properties) + * @param {ASTNode} node - node to fix */ - function report( msg, loc ) { + function report( msg, node ) { context.report({ 'node': null, 'message': msg, - 'loc': loc + 'loc': node.loc, + 'fix': fix }); + + /** + * Fixes the lint error by reordering the variable declarations inside of the function. + * + * @private + * @param {Function} fixer - ESLint fixer + * @returns {(Object|null)} fix or null + */ + function fix( fixer ) { + var replacingText; + var declarations; + var startRange; + var endRange; + var source; + var elem; + var body; + var i; + var j; + + declarations = []; + replacingText = ''; + body = node.body.body; + source = context.getSourceCode(); + + for ( i = 0; i < body.length; i++ ) { + elem = body[ i ]; + if ( elem.type === 'VariableDeclaration' && elem.kind === 'var' ) { + declarations.push({ + 'text': source.getText( elem ), + 'name': elem.declarations[ 0 ].id.name, + 'col': elem.loc.start.column + }); + if ( declarations.length === 1 ) { + startRange = elem.range[ 0 ] - elem.loc.start.column; + } + endRange = elem.range[ 1 ]; + } + } + + declarations.sort( sortVars ); + + for ( i = 0; i < declarations.length; i++ ) { + for ( j = 0; j < declarations[ i ].col; j++ ) { + replacingText += '\t'; + } + replacingText += declarations[ i ].text; + if ( i !== declarations.length -1 ) { + replacingText += '\n'; + } + } + + return fixer.replaceTextRange( [ startRange, endRange ], replacingText ); // eslint-disable-line max-len + } } /** @@ -117,7 +186,7 @@ function main( context ) { if ( elem.type === 'VariableDeclaration' && elem.kind === 'var' ) { name = elem.declarations[ 0 ].id.name; if ( prevLength && !fun( name.length, prevLength ) ) { - return report( 'Variable declarations inside of function are not ordered by length (in '+ order +' order)', node.loc ); + return report( 'Variable declarations inside of function are not ordered by length (in '+ order +' order)', node ); } prevLength = name.length; } @@ -135,9 +204,11 @@ function main( context ) { rule = { 'meta': { + 'type': 'layout', 'docs': { 'description': 'require variable declarations inside of functions to be ordered by length' }, + 'fixable': 'code', 'schema': [ { 'order': [ 'increasing', 'decreasing' ] diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/test/fixtures/invalid.js index 6de001b4661e..bb09069ba350 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/vars-order/test/fixtures/invalid.js @@ -24,13 +24,13 @@ var test; test = { 'code': [ 'function fizzBuzz() {', - ' var i;', - ' var out;', + ' var i;', + ' var out;', '', - ' for ( i = 1; i <= 100; i++ ) {', - ' out = ( i % 5 === 0 ) ? "Buzz" : ( i % 3 === 0 ) ? "Fizz" : i;', - ' console.log( out );', - ' }', + ' for ( i = 1; i <= 100; i++ ) {', + ' out = ( i % 5 === 0 ) ? "Buzz" : ( i % 3 === 0 ) ? "Fizz" : i;', + ' console.log( out );', + ' }', '}' ].join( '\n' ), 'errors': [ @@ -38,16 +38,27 @@ test = { 'message': 'Variable declarations inside of function are not ordered by length (in decreasing order)', 'type': null } - ] + ], + 'output': [ + 'function fizzBuzz() {', + ' var out;', + ' var i;', + '', + ' for ( i = 1; i <= 100; i++ ) {', + ' out = ( i % 5 === 0 ) ? "Buzz" : ( i % 3 === 0 ) ? "Fizz" : i;', + ' console.log( out );', + ' }', + '}' + ].join( '\n' ) }; invalid.push( test ); test = { 'code': [ 'function addFour( y ) {', - ' var x = 4.0;', - ' var out = x + y;', - ' return out;', + ' var x = 4.0;', + ' var out = x + y;', + ' return out;', '}' ].join( '\n' ), 'errors': [ @@ -55,7 +66,14 @@ test = { 'message': 'Variable declarations inside of function are not ordered by length (in decreasing order)', 'type': null } - ] + ], + 'output': [ + 'function addFour( y ) {', + ' var out = x + y;', + ' var x = 4.0;', + ' return out;', + '}' + ].join( '\n' ) }; invalid.push( test ); @@ -72,17 +90,17 @@ test = { '* @returns {number} pseudorandom number', '*/', 'function triangular( rand, a, b, c ) {', - ' var x;', - ' var fc;', - ' var u;', - ' fc = (c - a) / (b - a);', - ' u = rand();', - ' if ( u < fc ) {', - ' x = (b - a) * (c - a);', - ' return a + sqrt( x * u );', - ' }', - ' x = (b - a) * (b - c);', - ' return b - sqrt( x * (1.0 - u) );', + ' var x;', + ' var fc;', + ' var u;', + ' fc = (c - a) / (b - a);', + ' u = rand();', + ' if ( u < fc ) {', + ' x = (b - a) * (c - a);', + ' return a + sqrt( x * u );', + ' }', + ' x = (b - a) * (b - c);', + ' return b - sqrt( x * (1.0 - u) );', '}' ].join( '\n' ), 'errors': [ @@ -90,16 +108,41 @@ test = { 'message': 'Variable declarations inside of function are not ordered by length (in decreasing order)', 'type': null } - ] + ], + 'output': [ + '/**', + '* Returns a pseudorandom number drawn from a triangular distribution with minimum support `a`, maximum support `b` and mode `c`.', + '*', + '* @private', + '* @param {Function} rand - PRNG for generating uniformly distributed numbers', + '* @param {number} a - minimum support', + '* @param {number} b - maximum support', + '* @param {number} c - mode', + '* @returns {number} pseudorandom number', + '*/', + 'function triangular( rand, a, b, c ) {', + ' var fc;', + ' var x;', + ' var u;', + ' fc = (c - a) / (b - a);', + ' u = rand();', + ' if ( u < fc ) {', + ' x = (b - a) * (c - a);', + ' return a + sqrt( x * u );', + ' }', + ' x = (b - a) * (b - c);', + ' return b - sqrt( x * (1.0 - u) );', + '}' + ].join( '\n' ) }; invalid.push( test ); test = { 'code': [ 'function addFour( y ) {', - ' var x = 4.0;', - ' var out = x + y;', - ' return out;', + ' var x = 4.0;', + ' var out = x + y;', + ' return out;', '}' ].join( '\n' ), 'options': [{ @@ -110,7 +153,14 @@ test = { 'message': 'Variable declarations inside of function are not ordered by length (in decreasing order)', 'type': null } - ] + ], + 'output': [ + 'function addFour( y ) {', + ' var out = x + y;', + ' var x = 4.0;', + ' return out;', + '}' + ].join( '\n' ) }; invalid.push( test ); @@ -127,17 +177,17 @@ test = { '* @returns {number} pseudorandom number', '*/', 'function triangular( rand, a, b, c ) {', - ' var fc;', - ' var x;', - ' var u;', - ' fc = (c - a) / (b - a);', - ' u = rand();', - ' if ( u < fc ) {', - ' x = (b - a) * (c - a);', - ' return a + sqrt( x * u );', - ' }', - ' x = (b - a) * (b - c);', - ' return b - sqrt( x * (1.0 - u) );', + ' var fc;', + ' var x;', + ' var u;', + ' fc = (c - a) / (b - a);', + ' u = rand();', + ' if ( u < fc ) {', + ' x = (b - a) * (c - a);', + ' return a + sqrt( x * u );', + ' }', + ' x = (b - a) * (b - c);', + ' return b - sqrt( x * (1.0 - u) );', '}' ].join( '\n' ), 'options': [{ @@ -148,7 +198,115 @@ test = { 'message': 'Variable declarations inside of function are not ordered by length (in increasing order)', 'type': null } - ] + ], + 'output': [ + '/**', + '* Returns a pseudorandom number drawn from a triangular distribution with minimum support `a`, maximum support `b` and mode `c`.', + '*', + '* @private', + '* @param {Function} rand - PRNG for generating uniformly distributed numbers', + '* @param {number} a - minimum support', + '* @param {number} b - maximum support', + '* @param {number} c - mode', + '* @returns {number} pseudorandom number', + '*/', + 'function triangular( rand, a, b, c ) {', + ' var x;', + ' var u;', + ' var fc;', + ' fc = (c - a) / (b - a);', + ' u = rand();', + ' if ( u < fc ) {', + ' x = (b - a) * (c - a);', + ' return a + sqrt( x * u );', + ' }', + ' x = (b - a) * (b - c);', + ' return b - sqrt( x * (1.0 - u) );', + '}' + ].join( '\n' ) +}; +invalid.push( test ); + +test = { + 'code': [ + 'function outer() {', + ' var xyz;', + ' var x;', + ' function inner() {', + ' var a = 10;', + ' var abc = 5;', + ' var ab = 5;', + ' return a + b + c;', + ' }', + ' xyz = inner() + x;', + ' return xyz;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Variable declarations inside of function are not ordered by length (in decreasing order)', + 'type': null + } + ], + 'output': [ + 'function outer() {', + ' var xyz;', + ' var x;', + ' function inner() {', + ' var abc = 5;', + ' var ab = 5;', + ' var a = 10;', + ' return a + b + c;', + ' }', + ' xyz = inner() + x;', + ' return xyz;', + '}' + ].join( '\n' ) +}; +invalid.push( test ); + +test = { + 'code': [ + 'function outer() {', + ' var xyz;', + ' var x;', + ' function inner() {', + ' var abc = 5;', + ' var ab = 5;', + ' var a = 10;', + ' return a + b + c;', + ' }', + ' xyz = inner() + x;', + ' return xyz;', + '}' + ].join( '\n' ), + 'options': [{ + 'order': 'increasing' + }], + 'errors': [ + { + 'message': 'Variable declarations inside of function are not ordered by length (in increasing order)', + 'type': null + }, + { + 'message': 'Variable declarations inside of function are not ordered by length (in increasing order)', + 'type': null + } + ], + 'output': [ + 'function outer() {', + ' var x;', + ' var xyz;', + ' function inner() {', + ' var a = 10;', + ' var ab = 5;', + ' var abc = 5;', + ' return a + b + c;', + ' }', + ' xyz = inner() + x;', + ' return xyz;', + '}' + ].join( '\n' ) }; invalid.push( test );