From f6b5a1a8dbaa8449d36ec2a8245c6011cd0a74ae Mon Sep 17 00:00:00 2001 From: Ujjwal Verma Date: Sun, 26 Jul 2026 15:29:54 +0530 Subject: [PATCH 1/2] feat: add \jsdoc-param-hyphen-spacing\ ESLint rule --- .../@stdlib/_tools/eslint/rules/README.md | 3 + .../jsdoc-param-hyphen-spacing/README.md | 157 ++++++++++++++ .../examples/index.js | 73 +++++++ .../lib/defaults.json | 4 + .../jsdoc-param-hyphen-spacing/lib/index.js | 39 ++++ .../jsdoc-param-hyphen-spacing/lib/main.js | 183 ++++++++++++++++ .../jsdoc-param-hyphen-spacing/package.json | 67 ++++++ .../test/fixtures/invalid.js | 201 ++++++++++++++++++ .../test/fixtures/unvalidated.js | 46 ++++ .../test/fixtures/valid.js | 120 +++++++++++ .../jsdoc-param-hyphen-spacing/test/test.js | 86 ++++++++ .../@stdlib/_tools/eslint/rules/lib/index.js | 9 + 12 files changed, 988 insertions(+) create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/README.md create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/examples/index.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/defaults.json create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/index.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/package.json create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/invalid.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/unvalidated.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/valid.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/test.js diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/README.md index 64f53a1c648d..0841159dc56d 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/README.md +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/README.md @@ -172,6 +172,7 @@ var eslint = rules; - [`jsdoc-no-unused-definitions`][@stdlib/_tools/eslint/rules/jsdoc-no-unused-definitions]: ESLint rule to prevent unused Markdown definitions in JSDoc descriptions. - [`jsdoc-ordered-list-marker-style`][@stdlib/_tools/eslint/rules/jsdoc-ordered-list-marker-style]: ESLint rule to enforce a specified Markdown ordered list marker style in JSDoc descriptions. - [`jsdoc-ordered-list-marker-value`][@stdlib/_tools/eslint/rules/jsdoc-ordered-list-marker-value]: ESLint rule to enforce a specified Markdown ordered list marker style in JSDoc descriptions. +- [`jsdoc-param-hyphen-spacing`][@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing]: ESLint rule to enforce hyphen spacing in JSDoc @param tags. - [`jsdoc-private-annotation`][@stdlib/_tools/eslint/rules/jsdoc-private-annotation]: ESLint rule enforcing that JSDoc comments of unassigned function declarations have a `@private` tag. - [`jsdoc-require-throws-tags`][@stdlib/_tools/eslint/rules/jsdoc-require-throws-tags]: ESLint rule enforcing that JSDoc comments of functions are not missing `@throws` tags. - [`jsdoc-rule-style`][@stdlib/_tools/eslint/rules/jsdoc-rule-style]: ESLint rule to enforce a specified Markdown style for horizontal rules in JSDoc descriptions. @@ -352,6 +353,8 @@ console.log( getKeys( rules ) ); [@stdlib/_tools/eslint/rules/jsdoc-ordered-list-marker-value]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/_tools/eslint/rules/jsdoc-ordered-list-marker-value +[@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing + [@stdlib/_tools/eslint/rules/jsdoc-private-annotation]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/_tools/eslint/rules/jsdoc-private-annotation [@stdlib/_tools/eslint/rules/jsdoc-require-throws-tags]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/_tools/eslint/rules/jsdoc-require-throws-tags diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/README.md new file mode 100644 index 000000000000..a4cd8040ecfa --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/README.md @@ -0,0 +1,157 @@ + + +# jsdoc-param-hyphen-spacing + +> [ESLint rule][eslint-rules] to enforce hyphen spacing in JSDoc `@param` tags. + +
+ +
+ + + +
+ +## Usage + +```javascript +var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing' ); +``` + +#### rule + +[ESLint rule][eslint-rules] to enforce hyphen spacing in JSDoc `@param` tags. + +**Bad**: + +```javascript +/** +* Squares a number. +* +* @param {number} x - input number +* @returns {number} x squared +*/ +function square( x ) { + return x * x; +} +``` + +**Good**: + +```javascript +/** +* Squares a number. +* +* @param {number} x - input number +* @returns {number} x squared +*/ +function square( x ) { + return x * x; +} +``` + +
+ + + +
+ +## Examples + + + +```javascript +var Linter = require( 'eslint' ).Linter; +var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing' ); + +var linter = new Linter(); +var result; +var code; + +code = [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' +].join( '\n' ); + +linter.defineRule( 'jsdoc-param-hyphen-spacing', rule ); + +result = linter.verify( code, { + 'rules': { + 'jsdoc-param-hyphen-spacing': 'error' + } +}); +console.log( result ); +/* => + [ + { + 'ruleId': 'jsdoc-param-hyphen-spacing', + 'severity': 2, + 'message': 'hyphen should be preceded by only one space', + 'line': 4, + 'column': 1, + 'nodeType': null, + 'source': '* @param {number} x - input number', + 'endLine': 4, + 'endColumn': 43 + }, + { + 'ruleId': 'jsdoc-param-hyphen-spacing', + 'severity': 2, + 'message': 'hyphen should be followed by only one space', + 'line': 4, + 'column': 1, + 'nodeType': null, + 'source': '* @param {number} x - input number', + 'endLine': 4, + 'endColumn': 43 + } + ] +*/ +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/examples/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/examples/index.js new file mode 100644 index 000000000000..4bfc3b4d0733 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/examples/index.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Linter = require( 'eslint' ).Linter; +var rule = require( './../lib' ); + +var linter = new Linter(); +var result; +var code; + +code = [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' +].join( '\n' ); + +linter.defineRule( 'jsdoc-param-hyphen-spacing', rule ); + +result = linter.verify( code, { + 'rules': { + 'jsdoc-param-hyphen-spacing': 'error' + } +}); +console.log( result ); +/* => + [ + { + 'ruleId': 'jsdoc-param-hyphen-spacing', + 'severity': 2, + 'message': 'hyphen should be preceded by only one space', + 'line': 4, + 'column': 1, + 'nodeType': null, + 'source': '* @param {number} x - input number', + 'endLine': 4, + 'endColumn': 43 + }, + { + 'ruleId': 'jsdoc-param-hyphen-spacing', + 'severity': 2, + 'message': 'hyphen should be followed by only one space', + 'line': 4, + 'column': 1, + 'nodeType': null, + 'source': '* @param {number} x - input number', + 'endLine': 4, + 'endColumn': 43 + } + ] +*/ diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/defaults.json b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/defaults.json new file mode 100644 index 000000000000..f35677c6bdeb --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/defaults.json @@ -0,0 +1,4 @@ +{ + "before": true, + "after": true +} diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/index.js new file mode 100644 index 000000000000..cbd3526f124e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/index.js @@ -0,0 +1,39 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* ESLint rule to enforce hyphen spacing in JSDoc `@param` tags. +* +* @module @stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing +* +* @example +* var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing' ); +* +* console.log( rule ); +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js new file mode 100644 index 000000000000..ad351fc1727e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js @@ -0,0 +1,183 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/utils/copy' ); +var isObject = require( '@stdlib/assert/is-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var findJSDoc = require( '@stdlib/_tools/eslint/utils/find-jsdoc' ); +var DEFAULTS = require( './defaults.json' ); + + +// VARIABLES // + +var rule; +var RE_PARAM = /\*(\s*)@param(\s*)\{[^}]*\}(\s*)(\[[^\]]+\]|[a-zA-Z0-9_$.]+)(.*)$/; +var RE_AFTER_PARAM = /^(\s*)([-–—−]|--|:)?(\s*)(\S.*)?$/; + + +// FUNCTIONS // + +/** +* Rule for validating hyphen spacing in JSDoc `@param` tags. +* +* @param {Object} context - ESLint context +* @returns {Object} validators +*/ +function main( context ) { + var options; + var source; + var opts; + + opts = copy( DEFAULTS ); + options = context.options[ 0 ]; + if ( isObject( options ) ) { + if ( hasOwnProp( options, 'before' ) ) { + opts.before = options.before; + } + if ( hasOwnProp( options, 'after' ) ) { + opts.after = options.after; + } + } + source = context.sourceCode; + + return { + 'FunctionExpression:exit': validate, + 'FunctionDeclaration:exit': validate, + 'VariableDeclaration:exit': validate, + 'ExpressionStatement:exit': validate + }; + + /** + * Checks whether JSDoc `@param` tags adhere to hyphen spacing rules. + * + * @private + * @param {ASTNode} node - AST node + */ + function validate( node ) { + var lineNumber; + var matches; + var match; + var lines; + var jsdoc; + var line; + var loc; + var i; + + jsdoc = findJSDoc( source, node ); + if ( isObject( jsdoc ) ) { + lines = jsdoc.value.split( '\n' ); + for ( i = 0; i < lines.length; i++ ) { + line = lines[ i ]; + matches = line.match( RE_PARAM ); + if ( matches ) { + lineNumber = jsdoc.loc.start.line + i; + loc = { + 'start': { + 'line': lineNumber, + 'column': 0 + }, + 'end': { + 'line': lineNumber, + 'column': line.length + } + }; + match = matches[ 5 ].match( RE_AFTER_PARAM ); + if ( match ) { + if ( !match[ 2 ] && match[ 4 ] ) { + report( 'parameter name and description should be separated by a hyphen', loc ); + } else if ( match[ 2 ] ) { + if ( match[ 2 ] !== '-' ) { + report( 'parameter name and description should be separated by a hyphen', loc ); + } + if ( opts.before ) { + if ( match[ 1 ].length < 1 ) { + report( 'hyphen should be preceded by a space', loc ); + } else if ( match[ 1 ].length > 1 ) { + report( 'hyphen should be preceded by only one space', loc ); + } + } else if ( match[ 1 ].length > 0 ) { + report( 'there should be no space before hyphen', loc ); + } + if ( match[ 4 ] ) { + if ( opts.after ) { + if ( match[ 3 ].length < 1 ) { + report( 'hyphen should be followed by a space', loc ); + } else if ( match[ 3 ].length > 1 ) { + report( 'hyphen should be followed by only one space', loc ); + } + } else if ( match[ 3 ].length > 0 ) { + report( 'there should be no space after hyphen', loc ); + } + } + } + } + } + } + } + } + + /** + * Reports the error message. + * + * @private + * @param {string} msg - error message + * @param {Object} loc - lines of code (object with `start` and `end` properties) + */ + function report( msg, loc ) { + context.report({ + 'node': null, + 'message': msg, + 'loc': loc + }); + } +} + + +// MAIN // + +rule = { + 'meta': { + 'docs': { + 'description': 'enforce hyphen spacing in JSDoc @param tags' + }, + 'schema': [ + { + 'type': 'object', + 'properties': { + 'before': { + 'type': 'boolean' + }, + 'after': { + 'type': 'boolean' + } + }, + 'additionalProperties': false + } + ] + }, + 'create': main +}; + + +// EXPORTS // + +module.exports = rule; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/package.json b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/package.json new file mode 100644 index 000000000000..5292145396f9 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing", + "version": "0.0.0", + "description": "ESLint rule to enforce hyphen spacing in JSDoc @param tags.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "bin": {}, + "main": "./lib", + "directories": { + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "tools", + "tool", + "eslint", + "lint", + "custom", + "rules", + "rule", + "plugin", + "jsdoc", + "param", + "hyphen", + "spaces", + "spacing", + "style", + "comment" + ] +} diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/invalid.js new file mode 100644 index 000000000000..996554186219 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/invalid.js @@ -0,0 +1,201 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +var invalid = []; +var test; + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'hyphen should be preceded by only one space' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x- input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'hyphen should be preceded by a space' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'hyphen should be followed by only one space' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x -input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'hyphen should be followed by a space' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'hyphen should be preceded by only one space' + }, + { + 'message': 'hyphen should be followed by only one space' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x – input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'parameter name and description should be separated by a hyphen' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'errors': [ + { + 'message': 'parameter name and description should be separated by a hyphen' + } + ] +}; +invalid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'options': [ + { + 'before': false, + 'after': false + } + ], + 'errors': [ + { + 'message': 'there should be no space before hyphen' + }, + { + 'message': 'there should be no space after hyphen' + } + ] +}; +invalid.push( test ); + + +// EXPORTS // + +module.exports = invalid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/unvalidated.js new file mode 100644 index 000000000000..42d6f720b6ae --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/unvalidated.js @@ -0,0 +1,46 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var valid = []; +var test; + +test = { + 'code': [ + 'function fizzBuzz() {', + ' // This is a single-line comment', + ' var out;', + ' var i;', + '', + ' for ( i = 1; i <= 100; i++ ) {', + ' /*', + ' * This is a multi-line comment...', + ' */', + ' out = ( i % 5 === 0 ) ? "Buzz" : ( i % 3 === 0 ) ? "Fizz" : i;', + ' console.log( out );', + ' }', + '}' + ].join( '\n' ) +}; +valid.push( test ); + + +// EXPORTS // + +module.exports = valid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/valid.js new file mode 100644 index 000000000000..6414c07ad181 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/fixtures/valid.js @@ -0,0 +1,120 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +var valid = []; +var test; + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*', + '* @example', + '* var y = square( 2.0 );', + '* // returns 4.0', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +test = { + 'code': [ + '/**', + '* Returns a pseudo-random number on [0,1].', + '*', + '* @param {string} [str="hello - world"] - input string with hyphen in default', + '* @returns {number} uniform random number', + '*/', + 'function rand( str ) {', + ' return Math.random();', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +test = { + 'code': [ + '/**', + '* Function with no description on param.', + '*', + '* @param {number} x', + '* @returns {number} x', + '*/', + 'function id( x ) {', + ' return x;', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x - input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'options': [ + { + 'before': true, + 'after': true + } + ] +}; +valid.push( test ); + +test = { + 'code': [ + '/**', + '* Squares a number.', + '*', + '* @param {number} x-input number', + '* @returns {number} x squared', + '*/', + 'function square( x ) {', + ' return x*x;', + '}' + ].join( '\n' ), + 'options': [ + { + 'before': false, + 'after': false + } + ] +}; +valid.push( test ); + + +// EXPORTS // + +module.exports = valid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/test.js new file mode 100644 index 000000000000..1f3c90d2a818 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/test/test.js @@ -0,0 +1,86 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var RuleTester = require( 'eslint' ).RuleTester; +var rule = require( './../lib' ); + + +// FIXTURES // + +var valid = require( './fixtures/valid.js' ); +var invalid = require( './fixtures/invalid.js' ); +var unvalidated = require( './fixtures/unvalidated.js' ); + + +// TESTS // + +tape( 'main export is an object', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof rule, 'object', 'main export is an object' ); + t.end(); +}); + +tape( 'the function negatively validates code with JSDoc comments containing @param tags that are properly formatted with hyphens and spaces', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'jsdoc-param-hyphen-spacing', rule, { + 'valid': valid, + 'invalid': [] + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); + +tape( 'the function negatively validates code with JSDoc comments containing @param tags that are not properly formatted with hyphens and spaces', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'jsdoc-param-hyphen-spacing', rule, { + 'valid': [], + 'invalid': invalid + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); + +tape( 'the function does not validate non-JSDoc comments', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'jsdoc-param-hyphen-spacing', rule, { + 'valid': unvalidated, + 'invalid': [] + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js index fcf6e671c4c9..05cb1b6ec467 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js @@ -675,6 +675,15 @@ setReadOnly( rules, 'jsdoc-ordered-list-marker-style', require( '@stdlib/_tools/ */ setReadOnly( rules, 'jsdoc-ordered-list-marker-value', require( '@stdlib/_tools/eslint/rules/jsdoc-ordered-list-marker-value' ) ); +/** +* @name jsdoc-param-hyphen-spacing +* @memberof rules +* @readonly +* @type {Function} +* @see {@link module:@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing} +*/ +setReadOnly( rules, 'jsdoc-param-hyphen-spacing', require( '@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing' ) ); + /** * @name jsdoc-private-annotation * @memberof rules From 3fffb31f4877e0202af4f2f5f7a8f10ef140439f Mon Sep 17 00:00:00 2001 From: Ujjwal Verma Date: Sun, 26 Jul 2026 15:46:55 +0530 Subject: [PATCH 2/2] refactor: reduce nesting depth in `validate` to satisfy eslint max-depth rule --- .../jsdoc-param-hyphen-spacing/lib/main.js | 149 ++++++++++++------ 1 file changed, 99 insertions(+), 50 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js index ad351fc1727e..13e617045c29 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-param-hyphen-spacing/lib/main.js @@ -73,65 +73,114 @@ function main( context ) { * @param {ASTNode} node - AST node */ function validate( node ) { - var lineNumber; - var matches; - var match; var lines; var jsdoc; - var line; - var loc; var i; jsdoc = findJSDoc( source, node ); if ( isObject( jsdoc ) ) { lines = jsdoc.value.split( '\n' ); for ( i = 0; i < lines.length; i++ ) { - line = lines[ i ]; - matches = line.match( RE_PARAM ); - if ( matches ) { - lineNumber = jsdoc.loc.start.line + i; - loc = { - 'start': { - 'line': lineNumber, - 'column': 0 - }, - 'end': { - 'line': lineNumber, - 'column': line.length - } - }; - match = matches[ 5 ].match( RE_AFTER_PARAM ); - if ( match ) { - if ( !match[ 2 ] && match[ 4 ] ) { - report( 'parameter name and description should be separated by a hyphen', loc ); - } else if ( match[ 2 ] ) { - if ( match[ 2 ] !== '-' ) { - report( 'parameter name and description should be separated by a hyphen', loc ); - } - if ( opts.before ) { - if ( match[ 1 ].length < 1 ) { - report( 'hyphen should be preceded by a space', loc ); - } else if ( match[ 1 ].length > 1 ) { - report( 'hyphen should be preceded by only one space', loc ); - } - } else if ( match[ 1 ].length > 0 ) { - report( 'there should be no space before hyphen', loc ); - } - if ( match[ 4 ] ) { - if ( opts.after ) { - if ( match[ 3 ].length < 1 ) { - report( 'hyphen should be followed by a space', loc ); - } else if ( match[ 3 ].length > 1 ) { - report( 'hyphen should be followed by only one space', loc ); - } - } else if ( match[ 3 ].length > 0 ) { - report( 'there should be no space after hyphen', loc ); - } - } - } - } - } + validateLine( lines[ i ], jsdoc, i ); + } + } + } + + /** + * Validates hyphen spacing for a single JSDoc line. + * + * @private + * @param {string} line - comment line + * @param {Object} jsdoc - JSDoc comment object + * @param {number} idx - line index + */ + function validateLine( line, jsdoc, idx ) { + var lineNumber; + var matches; + var match; + var loc; + + matches = line.match( RE_PARAM ); + if ( !matches ) { + return; + } + lineNumber = jsdoc.loc.start.line + idx; + loc = { + 'start': { + 'line': lineNumber, + 'column': 0 + }, + 'end': { + 'line': lineNumber, + 'column': line.length + } + }; + match = matches[ 5 ].match( RE_AFTER_PARAM ); + if ( match ) { + validateHyphenSpacing( match, loc ); + } + } + + /** + * Validates the separator and spacing around a hyphen in a `@param` tag. + * + * @private + * @param {Array} match - regex match results + * @param {Object} loc - line location + */ + function validateHyphenSpacing( match, loc ) { + if ( !match[ 2 ] && match[ 4 ] ) { + report( 'parameter name and description should be separated by a hyphen', loc ); + return; + } + if ( !match[ 2 ] ) { + return; + } + if ( match[ 2 ] !== '-' ) { + report( 'parameter name and description should be separated by a hyphen', loc ); + } + validateBeforeSpacing( match, loc ); + validateAfterSpacing( match, loc ); + } + + /** + * Validates spacing before a hyphen in a `@param` tag. + * + * @private + * @param {Array} match - regex match results + * @param {Object} loc - line location + */ + function validateBeforeSpacing( match, loc ) { + if ( opts.before ) { + if ( match[ 1 ].length < 1 ) { + report( 'hyphen should be preceded by a space', loc ); + } else if ( match[ 1 ].length > 1 ) { + report( 'hyphen should be preceded by only one space', loc ); + } + } else if ( match[ 1 ].length > 0 ) { + report( 'there should be no space before hyphen', loc ); + } + } + + /** + * Validates spacing after a hyphen in a `@param` tag. + * + * @private + * @param {Array} match - regex match results + * @param {Object} loc - line location + */ + function validateAfterSpacing( match, loc ) { + if ( !match[ 4 ] ) { + return; + } + if ( opts.after ) { + if ( match[ 3 ].length < 1 ) { + report( 'hyphen should be followed by a space', loc ); + } else if ( match[ 3 ].length > 1 ) { + report( 'hyphen should be followed by only one space', loc ); } + } else if ( match[ 3 ].length > 0 ) { + report( 'there should be no space after hyphen', loc ); } }