Skip to content

Commit c1b5b46

Browse files
committed
fix(require-jsdoc): placement of jsdoc block by fixer; fixes #369, #403, #502, #522
Properly finds base node for affixing jsdoc block and uses to determine appropriate indent (finds base node in a manner sensitive to context, reusing existing and more accurate detection for this purpose, improving detection for function expressions, including arrow function expressions and method definitions). As part of `getReducedASTNode` (used also within `getJSDocComment`), need to stop at `VariableDeclaration` or `ExpressionStatement` (where comments shouldl be checked). Needed for proper function expression documentation placement. Also provides `getJSDocComment` as a named export
1 parent 1f010f9 commit c1b5b46

File tree

4 files changed

+178
-6
lines changed

4 files changed

+178
-6
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7994,6 +7994,38 @@ export default class Test {
79947994
}
79957995
// Options: [{"contexts":["MethodDefinition:not([accessibility=\"private\"]) > FunctionExpression"],"publicOnly":true,"require":{"ArrowFunctionExpression":false,"ClassDeclaration":false,"ClassExpression":false,"FunctionDeclaration":false,"FunctionExpression":false,"MethodDefinition":false}}]
79967996
// Message: Missing JSDoc comment.
7997+
7998+
e = function () {
7999+
};
8000+
// Options: [{"require":{"FunctionDeclaration":false,"FunctionExpression":true}}]
8001+
// Message: Missing JSDoc comment.
8002+
8003+
/**
8004+
*
8005+
*/
8006+
export class Class {
8007+
test = 1;
8008+
8009+
foo() {
8010+
this.test = 2;
8011+
}
8012+
}
8013+
// Options: [{"require":{"FunctionDeclaration":false,"MethodDefinition":true}}]
8014+
// Message: Missing JSDoc comment.
8015+
8016+
class Dog {
8017+
eat() {
8018+
8019+
}
8020+
}
8021+
// Options: [{"require":{"FunctionDeclaration":false,"MethodDefinition":true}}]
8022+
// Message: Missing JSDoc comment.
8023+
8024+
const hello = name => {
8025+
document.body.textContent = "Hello, " + name + "!";
8026+
};
8027+
// Options: [{"require":{"ArrowFunctionExpression":true,"FunctionDeclaration":false}}]
8028+
// Message: Missing JSDoc comment.
79978029
````
79988030
79998031
The following patterns are not considered problems:

src/eslint/getJSDocComment.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ const getReducedASTNode = function (node, sourceCode) {
142142
while (
143143
!sourceCode.getCommentsBefore(parent).length &&
144144
!/Function/u.test(parent.type) &&
145+
parent.type !== 'VariableDeclaration' &&
146+
parent.type !== 'ExpressionStatement' &&
145147
parent.type !== 'MethodDefinition' &&
146148
parent.type !== 'Property'
147149
) {
@@ -227,5 +229,5 @@ const getJSDocComment = function (sourceCode, node, settings) {
227229
return findJSDocComment(reducedNode);
228230
};
229231

230-
export {getReducedASTNode};
232+
export {getReducedASTNode, getJSDocComment};
231233
export default getJSDocComment;

src/rules/requireJsdoc.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from 'lodash';
22
import jsdocUtils from '../jsdocUtils';
33
import exportParser from '../exportParser';
4-
import getJSDocComment from '../eslint/getJSDocComment';
4+
import {getJSDocComment, getReducedASTNode} from '../eslint/getJSDocComment';
55
import warnRemovedSettings from '../warnRemovedSettings';
66
import {getSettings} from '../iterateJsdoc';
77

@@ -141,11 +141,17 @@ export default {
141141
const fix = (fixer) => {
142142
// Default to one line break if the `minLines`/`maxLines` settings allow
143143
const lines = settings.minLines === 0 && settings.maxLines >= 1 ? 1 : settings.minLines;
144-
const indent = jsdocUtils.getIndent(sourceCode);
144+
const baseNode = getReducedASTNode(node, sourceCode);
145+
146+
const indent = jsdocUtils.getIndent({
147+
text: sourceCode.getText(
148+
baseNode,
149+
150+
// Could also use `baseNode.start - 1`
151+
baseNode.loc.start.column,
152+
),
153+
});
145154
const insertion = `/**\n${indent}*\n${indent}*/${'\n'.repeat(lines)}${indent.slice(0, -1)}`;
146-
const baseNode = [
147-
'ExportDefaultDeclaration', 'ExportNamedDeclaration',
148-
].includes(node.parent && node.parent.type) ? node.parent : node;
149155

150156
return fixer.insertTextBefore(baseNode, insertion);
151157
};

test/rules/assertions/requireJsdoc.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,138 @@ export default {
12521252
sourceType: 'module',
12531253
},
12541254
},
1255+
{
1256+
code: `
1257+
e = function () {
1258+
};
1259+
`,
1260+
errors: [
1261+
{
1262+
message: 'Missing JSDoc comment.',
1263+
},
1264+
],
1265+
options: [
1266+
{
1267+
require: {
1268+
FunctionDeclaration: false,
1269+
FunctionExpression: true,
1270+
},
1271+
},
1272+
],
1273+
output: `
1274+
/**
1275+
*
1276+
*/
1277+
e = function () {
1278+
};
1279+
`,
1280+
},
1281+
{
1282+
code: `
1283+
/**
1284+
*
1285+
*/
1286+
export class Class {
1287+
test = 1;
1288+
1289+
foo() {
1290+
this.test = 2;
1291+
}
1292+
}
1293+
`,
1294+
errors: [
1295+
{
1296+
message: 'Missing JSDoc comment.',
1297+
},
1298+
],
1299+
options: [
1300+
{
1301+
require: {
1302+
FunctionDeclaration: false,
1303+
MethodDefinition: true,
1304+
},
1305+
},
1306+
],
1307+
output: `
1308+
/**
1309+
*
1310+
*/
1311+
export class Class {
1312+
test = 1;
1313+
1314+
/**
1315+
*
1316+
*/
1317+
foo() {
1318+
this.test = 2;
1319+
}
1320+
}
1321+
`,
1322+
parser: require.resolve('@typescript-eslint/parser'),
1323+
parserOptions: {
1324+
sourceType: 'module',
1325+
},
1326+
},
1327+
{
1328+
code: `
1329+
class Dog {
1330+
eat() {
1331+
1332+
}
1333+
}
1334+
`,
1335+
errors: [
1336+
{
1337+
message: 'Missing JSDoc comment.',
1338+
},
1339+
],
1340+
options: [
1341+
{
1342+
require: {
1343+
FunctionDeclaration: false,
1344+
MethodDefinition: true,
1345+
},
1346+
},
1347+
],
1348+
output: `
1349+
class Dog {
1350+
/**
1351+
*
1352+
*/
1353+
eat() {
1354+
1355+
}
1356+
}
1357+
`,
1358+
},
1359+
{
1360+
code: `
1361+
const hello = name => {
1362+
document.body.textContent = "Hello, " + name + "!";
1363+
};
1364+
`,
1365+
errors: [
1366+
{
1367+
message: 'Missing JSDoc comment.',
1368+
},
1369+
],
1370+
options: [
1371+
{
1372+
require: {
1373+
ArrowFunctionExpression: true,
1374+
FunctionDeclaration: false,
1375+
},
1376+
},
1377+
],
1378+
output: `
1379+
/**
1380+
*
1381+
*/
1382+
const hello = name => {
1383+
document.body.textContent = "Hello, " + name + "!";
1384+
};
1385+
`,
1386+
},
12551387
],
12561388
valid: [{
12571389
code: `

0 commit comments

Comments
 (0)