Skip to content

Commit

Permalink
feat: add getNonJsdocComment for getting non-JSDoc comments above node
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Jul 5, 2024
1 parent e3834a3 commit b2255cf
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGES for `@es-joy/jsdoccomment`

## 0.44.0

- feat: add `getNonJsdocComment` for getting non-JSDoc comments above node

## 0.43.1

- fix: for `@template` name parsing, ensure (default-)bracketed name is not broken with internal spaces.
Expand Down
31 changes: 28 additions & 3 deletions dist/index.cjs.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -887,12 +887,16 @@ const getReducedASTNode = function (node, sourceCode) {
* the comment for.
* @param {import('eslint').SourceCode} sourceCode
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings
* @param {{nonJSDoc?: boolean}} [opts]
* @returns {Token|null} The Block comment token containing the JSDoc comment
* for the given node or null if not found.
* @private
*/
const findJSDocComment = (astNode, sourceCode, settings) => {
const findJSDocComment = (astNode, sourceCode, settings, opts = {}) => {
var _parenthesisToken, _parenthesisToken2;
const {
nonJSDoc
} = opts;
const {
minLines,
maxLines
Expand Down Expand Up @@ -921,7 +925,7 @@ const findJSDocComment = (astNode, sourceCode, settings) => {
if (!tokenBefore || !isCommentToken(tokenBefore)) {
return null;
}
if (tokenBefore.type === 'Line') {
if (!nonJSDoc && tokenBefore.type === 'Line') {
currentNode = tokenBefore;
continue;
}
Expand All @@ -932,7 +936,7 @@ const findJSDocComment = (astNode, sourceCode, settings) => {
if (!tokenBefore || !currentNode.loc || !tokenBefore.loc) {
return null;
}
if (tokenBefore.type === 'Block' && /^\*\s/u.test(tokenBefore.value) && currentNode.loc.start.line - ( /** @type {import('eslint').AST.Token} */(_parenthesisToken = parenthesisToken) !== null && _parenthesisToken !== void 0 ? _parenthesisToken : tokenBefore).loc.end.line >= minLines && currentNode.loc.start.line - ( /** @type {import('eslint').AST.Token} */(_parenthesisToken2 = parenthesisToken) !== null && _parenthesisToken2 !== void 0 ? _parenthesisToken2 : tokenBefore).loc.end.line <= maxLines) {
if ((nonJSDoc && (tokenBefore.type !== 'Block' || !/^\*\s/u.test(tokenBefore.value)) || !nonJSDoc && tokenBefore.type === 'Block' && /^\*\s/u.test(tokenBefore.value)) && currentNode.loc.start.line - ( /** @type {import('eslint').AST.Token} */(_parenthesisToken = parenthesisToken) !== null && _parenthesisToken !== void 0 ? _parenthesisToken : tokenBefore).loc.end.line >= minLines && currentNode.loc.start.line - ( /** @type {import('eslint').AST.Token} */(_parenthesisToken2 = parenthesisToken) !== null && _parenthesisToken2 !== void 0 ? _parenthesisToken2 : tokenBefore).loc.end.line <= maxLines) {
return tokenBefore;
}
return null;
Expand All @@ -956,6 +960,26 @@ const getJSDocComment = function (sourceCode, node, settings) {
return findJSDocComment(reducedNode, sourceCode, settings);
};

/**
* Retrieves the comment preceding a given node.
*
* @param {import('eslint').SourceCode} sourceCode The ESLint SourceCode
* @param {import('eslint').Rule.Node} node The AST node to get
* the comment for.
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings The
* settings in context
* @returns {Token|null} The Block comment
* token containing the JSDoc comment for the given node or
* null if not found.
* @public
*/
const getNonJsdocComment = function (sourceCode, node, settings) {
const reducedNode = getReducedASTNode(node, sourceCode);
return findJSDocComment(reducedNode, sourceCode, settings, {
nonJSDoc: true
});
};

/**
* @param {RegExpMatchArray & {
* indices: {
Expand Down Expand Up @@ -1228,6 +1252,7 @@ exports.estreeToString = estreeToString;
exports.findJSDocComment = findJSDocComment;
exports.getDecorator = getDecorator;
exports.getJSDocComment = getJSDocComment;
exports.getNonJsdocComment = getNonJsdocComment;
exports.getReducedASTNode = getReducedASTNode;
exports.getTokenizers = getTokenizers;
exports.hasSeeWithLink = hasSeeWithLink;
Expand Down
27 changes: 27 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,28 @@ declare function getJSDocComment(
minLines: int;
},
): Token | null;
/**
* Retrieves the comment preceding a given node.
*
* @param {import('eslint').SourceCode} sourceCode The ESLint SourceCode
* @param {import('eslint').Rule.Node} node The AST node to get
* the comment for.
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings The
* settings in context
* @returns {Token|null} The Block comment
* token containing the JSDoc comment for the given node or
* null if not found.
* @public
*/
declare function getNonJsdocComment(
sourceCode: eslint.SourceCode,
node: eslint.Rule.Node,
settings: {
[name: string]: any;
maxLines: int;
minLines: int;
},
): Token | null;
/**
* @param {(import('estree').Comment|import('eslint').Rule.Node) & {
* declaration?: any,
Expand All @@ -195,6 +217,7 @@ declare function getDecorator(
* the comment for.
* @param {import('eslint').SourceCode} sourceCode
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings
* @param {{nonJSDoc?: boolean}} [opts]
* @returns {Token|null} The Block comment token containing the JSDoc comment
* for the given node or null if not found.
* @private
Expand All @@ -207,6 +230,9 @@ declare function findJSDocComment(
maxLines: int;
minLines: int;
},
opts?: {
nonJSDoc?: boolean;
},
): Token | null;

declare function hasSeeWithLink(spec: comment_parser.Spec): boolean;
Expand Down Expand Up @@ -311,6 +337,7 @@ export {
findJSDocComment,
getDecorator,
getJSDocComment,
getNonJsdocComment,
getReducedASTNode,
getTokenizers,
hasSeeWithLink,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@es-joy/jsdoccomment",
"version": "0.43.1",
"version": "0.44.0",
"author": "Brett Zamir <[email protected]>",
"contributors": [],
"description": "Maintained replacement for ESLint's deprecated SourceCode#getJSDocComment along with other jsdoc utilities",
Expand Down Expand Up @@ -31,7 +31,7 @@
"lint": "npm run eslint --",
"open": "open ./coverage/index.html",
"prepublishOnly": "pnpm i && npm run build",
"test": "npm run lint && npm run build && vitest run --coverage",
"test": "npm run lint && npm run build && npm run test-ui",
"test-ui": "vitest --ui --coverage",
"tsc": "tsc",
"types": "esm-d-ts gen ./src/index.js --output ./dist/index.d.ts"
Expand Down
38 changes: 33 additions & 5 deletions src/jsdoccomment.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,13 @@ const getReducedASTNode = function (node, sourceCode) {
* the comment for.
* @param {import('eslint').SourceCode} sourceCode
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings
* @param {{nonJSDoc?: boolean}} [opts]
* @returns {Token|null} The Block comment token containing the JSDoc comment
* for the given node or null if not found.
* @private
*/
const findJSDocComment = (astNode, sourceCode, settings) => {
const findJSDocComment = (astNode, sourceCode, settings, opts = {}) => {
const {nonJSDoc} = opts;
const {minLines, maxLines} = settings;

/** @type {import('eslint').Rule.Node|import('estree').Comment} */
Expand Down Expand Up @@ -308,7 +310,7 @@ const findJSDocComment = (astNode, sourceCode, settings) => {
if (!tokenBefore || !isCommentToken(tokenBefore)) {
return null;
}
if (tokenBefore.type === 'Line') {
if (!nonJSDoc && tokenBefore.type === 'Line') {
currentNode = tokenBefore;
continue;
}
Expand All @@ -321,8 +323,12 @@ const findJSDocComment = (astNode, sourceCode, settings) => {
}

if (
tokenBefore.type === 'Block' &&
(/^\*\s/u).test(tokenBefore.value) &&
(
(nonJSDoc && (tokenBefore.type !== 'Block' ||
!(/^\*\s/u).test(tokenBefore.value))) ||
(!nonJSDoc && tokenBefore.type === 'Block' &&
(/^\*\s/u).test(tokenBefore.value))
) &&
currentNode.loc.start.line - (
/** @type {import('eslint').AST.Token} */
(parenthesisToken ?? tokenBefore)
Expand Down Expand Up @@ -357,6 +363,28 @@ const getJSDocComment = function (sourceCode, node, settings) {
return findJSDocComment(reducedNode, sourceCode, settings);
};

/**
* Retrieves the comment preceding a given node.
*
* @param {import('eslint').SourceCode} sourceCode The ESLint SourceCode
* @param {import('eslint').Rule.Node} node The AST node to get
* the comment for.
* @param {{maxLines: int, minLines: int, [name: string]: any}} settings The
* settings in context
* @returns {Token|null} The Block comment
* token containing the JSDoc comment for the given node or
* null if not found.
* @public
*/
const getNonJsdocComment = function (sourceCode, node, settings) {
const reducedNode = getReducedASTNode(node, sourceCode);

return findJSDocComment(reducedNode, sourceCode, settings, {
nonJSDoc: true
});
};

export {
getReducedASTNode, getJSDocComment, getDecorator, findJSDocComment
getReducedASTNode, getJSDocComment, getNonJsdocComment,
getDecorator, findJSDocComment
};
55 changes: 54 additions & 1 deletion test/jsdoccomment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {traverse} from 'estraverse';
import {SourceCode} from 'eslint';

import {
getReducedASTNode
getReducedASTNode,
// getJSDocComment, getDecorator, findJSDocComment
getNonJsdocComment
} from '../src/index.js';

const ESPREE_DEFAULT_CONFIG = {
Expand Down Expand Up @@ -56,3 +57,55 @@ describe('`getReducedASTNode`', function () {
expect(parsed.type).to.equal('FunctionDeclaration');
});
});

describe('`getComment`', function () {
it('gets line comment', function () {
const code = `// Test
function quux () {}`;
const ast = parseAddingParents(code);
const sourceCode = new SourceCode(code, ast);

const comment = getNonJsdocComment(
sourceCode,
/** @type {import('eslint').Rule.Node} */ (ast.body[0]),
{
minLines: 0, maxLines: 1
}
);
expect(comment?.type).to.equal('Line');
expect(comment?.value).to.equal(' Test');
});

it('gets non-JSDoc multiline comments', function () {
const code = `/* Test */
function quux () {}`;
const ast = parseAddingParents(code);
const sourceCode = new SourceCode(code, ast);

const comment = getNonJsdocComment(
sourceCode,
/** @type {import('eslint').Rule.Node} */ (ast.body[0]),
{
minLines: 0, maxLines: 1
}
);
expect(comment?.type).to.equal('Block');
expect(comment?.value).to.equal(' Test ');
});

it('ignores JSDoc multiline comments', function () {
const code = `/** Test */
function quux () {}`;
const ast = parseAddingParents(code);
const sourceCode = new SourceCode(code, ast);

const comment = getNonJsdocComment(
sourceCode,
/** @type {import('eslint').Rule.Node} */ (ast.body[0]),
{
minLines: 0, maxLines: 1
}
);
expect(comment).to.equal(null);
});
});

0 comments on commit b2255cf

Please sign in to comment.