Skip to content

Commit f28f87f

Browse files
authored
Merge pull request #298 from golopot/allnodes
BREAKING CHANGE: a subset of rules updated to work on all JSDoc blocks rather than just function-like nodes Changes apply to check-alignment, check-indentation, check-syntax, check-tag-names, check-types, newline-after-description, require-description-complete-sentence, require-hyphen-before-param-description, valid-types
2 parents 45b85ae + c01aa99 commit f28f87f

24 files changed

+233
-48
lines changed

.README/rules/check-indentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Reports invalid padding inside JSDoc block.
44

55
|||
66
|---|---|
7-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
7+
|Context|everywhere|
88
|Tags|N/A|
99

1010
<!-- assertions checkIndentation -->

.README/rules/check-syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Reports against Google Closure Compiler syntax.
44

55
|||
66
|---|---|
7-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
7+
|Context|everywhere|
88
|Tags|N/A|
99

1010
<!-- assertions checkSyntax -->

.README/rules/check-tag-names.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ yields
7777

7878
|||
7979
|---|---|
80-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
80+
|Context|everywhere|
8181
|Tags|N/A|
8282
|Settings|`tagNamePreference`, `additionalTagNames`|
8383

.README/rules/check-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
8282

8383
|||
8484
|---|---|
85-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
85+
|Context|everywhere|
8686
|Tags|`class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
8787
|Aliases|`constructor`, `const`, `var`, `arg`, `argument`, `prop`, `return`, `exception`|
8888
|Closure-only|`package`, `private`, `protected`, `public`, `static`|

.README/rules/newline-after-description.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This rule takes one argument. If it is `"always"` then a problem is raised when
66

77
|||
88
|---|---|
9-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
9+
|Context|everywhere|
1010
|Tags|N/A|
1111

1212
<!-- assertions newlineAfterDescription -->

.README/rules/no-undefined-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ An option object may have the following keys:
3232

3333
|||
3434
|---|---|
35-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
35+
|Context|everywhere|
3636
|Tags|`class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
3737
|Aliases|`constructor`, `const`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
3838
|Closure-only|`package`, `private`, `protected`, `public`, `static`|

.README/rules/require-description-complete-sentence.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Requires that block description and tag description are written in complete sent
99

1010
|||
1111
|---|---|
12-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
12+
|Context|everywhere|
1313
|Tags|`param`, `returns`|
1414
|Aliases|`arg`, `argument`, `return`|
1515

.README/rules/require-hyphen-before-param-description.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This rule takes one argument. If it is `"always"` then a problem is raised when
66

77
|||
88
|---|---|
9-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
9+
|Context|everywhere|
1010
|Tags|`param`|
1111
|Aliases|`arg`, `argument`|
1212

.README/rules/valid-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
3333

3434
|||
3535
|---|---|
36-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
36+
|Context|everywhere|
3737
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
3838
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
3939
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|

README.md

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,20 @@ function quux (foo) {
511511

512512
}
513513
// Message: Expected JSDoc block to be aligned.
514+
515+
/**
516+
* A jsdoc not attached to any node.
517+
*/
518+
// Message: Expected JSDoc block to be aligned.
519+
520+
class Foo {
521+
/**
522+
* Some method
523+
* @param a
524+
*/
525+
quux(a) {}
526+
}
527+
// Message: Expected JSDoc block to be aligned.
514528
````
515529

516530
The following patterns are not considered problems:
@@ -537,6 +551,11 @@ function quux (foo) {
537551
function quux (foo) {
538552

539553
}
554+
555+
/* <- JSDoc must start with 2 stars.
556+
* So this is unchecked.
557+
*/
558+
function quux (foo) {}
540559
````
541560

542561

@@ -788,7 +807,7 @@ Reports invalid padding inside JSDoc block.
788807

789808
|||
790809
|---|---|
791-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
810+
|Context|everywhere|
792811
|Tags|N/A|
793812

794813
The following patterns are considered problems:
@@ -804,6 +823,13 @@ function quux () {
804823

805824
}
806825
// Message: There must be no indentation.
826+
827+
/**
828+
* Foo
829+
* bar
830+
*/
831+
class Moo {}
832+
// Message: There must be no indentation.
807833
````
808834

809835
The following patterns are not considered problems:
@@ -1048,7 +1074,7 @@ Reports against Google Closure Compiler syntax.
10481074

10491075
|||
10501076
|---|---|
1051-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
1077+
|Context|everywhere|
10521078
|Tags|N/A|
10531079

10541080
The following patterns are considered problems:
@@ -1162,13 +1188,17 @@ yields
11621188

11631189
|||
11641190
|---|---|
1165-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
1191+
|Context|everywhere|
11661192
|Tags|N/A|
11671193
|Settings|`tagNamePreference`, `additionalTagNames`|
11681194

11691195
The following patterns are considered problems:
11701196

11711197
````js
1198+
/** @typoo {string} */
1199+
let a;
1200+
// Message: Invalid JSDoc tag name "typoo".
1201+
11721202
/**
11731203
* @Param
11741204
*/
@@ -1443,7 +1473,7 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
14431473

14441474
|||
14451475
|---|---|
1446-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
1476+
|Context|everywhere|
14471477
|Tags|`class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
14481478
|Aliases|`constructor`, `const`, `var`, `arg`, `argument`, `prop`, `return`, `exception`|
14491479
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
@@ -1958,6 +1988,9 @@ function quux (foo) {
19581988
}
19591989
// Settings: {"jsdoc":{"preferredTypes":{"<>":"[]"}}}
19601990
// Message: Invalid JSDoc @param "foo" type "Array"; prefer: "[]".
1991+
1992+
/** @typedef {String} foo */
1993+
// Message: Invalid JSDoc @typedef "foo" type "String"; prefer: "string".
19611994
````
19621995

19631996
The following patterns are not considered problems:
@@ -2597,7 +2630,7 @@ This rule takes one argument. If it is `"always"` then a problem is raised when
25972630

25982631
|||
25992632
|---|---|
2600-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
2633+
|Context|everywhere|
26012634
|Tags|N/A|
26022635

26032636
The following patterns are considered problems:
@@ -2762,7 +2795,7 @@ An option object may have the following keys:
27622795

27632796
|||
27642797
|---|---|
2765-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
2798+
|Context|everywhere|
27662799
|Tags|`class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
27672800
|Aliases|`constructor`, `const`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
27682801
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
@@ -3050,7 +3083,7 @@ Requires that block description and tag description are written in complete sent
30503083

30513084
|||
30523085
|---|---|
3053-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
3086+
|Context|everywhere|
30543087
|Tags|`param`, `returns`|
30553088
|Aliases|`arg`, `argument`, `return`|
30563089

@@ -3632,7 +3665,7 @@ This rule takes one argument. If it is `"always"` then a problem is raised when
36323665

36333666
|||
36343667
|---|---|
3635-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
3668+
|Context|everywhere|
36363669
|Tags|`param`|
36373670
|Aliases|`arg`, `argument`|
36383671

@@ -6040,7 +6073,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
60406073

60416074
|||
60426075
|---|---|
6043-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
6076+
|Context|everywhere|
60446077
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
60456078
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
60466079
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|

src/iterateJsdoc.js

Lines changed: 108 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -269,16 +269,115 @@ const getSettings = (context) => {
269269
return settings;
270270
};
271271

272-
export {
273-
parseComment
272+
/**
273+
* Create the report function
274+
*
275+
* @param {Object} context
276+
* @param {Object} commentNode
277+
*/
278+
const makeReport = (context, commentNode) => {
279+
const report = (message, fix = null, jsdocLoc = null, data = null) => {
280+
let loc;
281+
282+
if (jsdocLoc) {
283+
const lineNumber = commentNode.loc.start.line + jsdocLoc.line;
284+
285+
loc = {
286+
end: {line: lineNumber},
287+
start: {line: lineNumber}
288+
};
289+
if (jsdocLoc.column) {
290+
const colNumber = commentNode.loc.start.column + jsdocLoc.column;
291+
292+
loc.end.column = colNumber;
293+
loc.start.column = colNumber;
294+
}
295+
}
296+
297+
context.report({
298+
data,
299+
fix,
300+
loc,
301+
message,
302+
node: commentNode
303+
});
304+
};
305+
306+
return report;
274307
};
275308

276309
/**
277310
* @typedef {ReturnType<typeof getUtils>} Utils
278311
* @typedef {ReturnType<typeof getSettings>} Settings
312+
* @typedef {(
313+
* arg: {
314+
* context: Object,
315+
* sourceCode: Object,
316+
* indent: string,
317+
* jsdoc: Object,
318+
* jsdocNode: Object,
319+
* node: Object | null,
320+
* report: ReturnType<typeof makeReport>,
321+
* settings: Settings,
322+
* utils: Utils,
323+
* }
324+
* ) => any } JsdocVisitor
325+
*/
326+
327+
/**
328+
* Create an eslint rule that iterates over all JSDocs, regardless of whether
329+
* they are attached to a function-like node.
279330
*
280-
* @param {(arg: {utils: Utils, settings: Settings}) => any} iterator
281-
* @param {{contextDefaults: (true|string[]), meta: any, returns?: any}} ruleConfig
331+
* @param {JsdocVisitor} iterator
332+
* @param {{meta: any}} ruleConfig
333+
*/
334+
const iterateAllJsdocs = (iterator, ruleConfig) => {
335+
return {
336+
create (context) {
337+
return {
338+
'Program:exit' () {
339+
const comments = context.getSourceCode().getAllComments();
340+
341+
comments.forEach((comment) => {
342+
if (!context.getSourceCode().getText(comment).startsWith('/**')) {
343+
return;
344+
}
345+
346+
const indent = _.repeat(' ', comment.loc.start.column);
347+
const jsdoc = parseComment(comment, indent);
348+
const settings = getSettings(context);
349+
350+
iterator({
351+
context,
352+
indent,
353+
jsdoc,
354+
jsdocNode: comment,
355+
node: null,
356+
report: makeReport(context, comment),
357+
settings: getSettings(context),
358+
sourceCode: context.getSourceCode(),
359+
utils: getUtils(null, jsdoc, settings, context)
360+
});
361+
});
362+
}
363+
};
364+
},
365+
meta: ruleConfig.meta
366+
};
367+
};
368+
369+
export {
370+
parseComment
371+
};
372+
373+
/**
374+
* @param {JsdocVisitor} iterator
375+
* @param {{
376+
* meta: any,
377+
* contextDefaults?: true | string[],
378+
* returns?: any,
379+
* iterateAllJsdocs?: true,
380+
* }} ruleConfig
282381
*/
283382
export default function iterateJsdoc (iterator, ruleConfig) {
284383
const metaType = _.get(ruleConfig, 'meta.type');
@@ -289,6 +388,10 @@ export default function iterateJsdoc (iterator, ruleConfig) {
289388
throw new TypeError('The iterator argument must be a function or an object with a `returns` method.');
290389
}
291390

391+
if (ruleConfig.iterateAllJsdocs) {
392+
return iterateAllJsdocs(iterator, {meta: ruleConfig.meta});
393+
}
394+
292395
return {
293396
/**
294397
* The entrypoint for the JSDoc rule.
@@ -325,32 +428,7 @@ export default function iterateJsdoc (iterator, ruleConfig) {
325428

326429
const jsdoc = parseComment(jsdocNode, indent);
327430

328-
const report = (message, fix = null, jsdocLoc = null, data = null) => {
329-
let loc;
330-
331-
if (jsdocLoc) {
332-
const lineNumber = jsdocNode.loc.start.line + jsdocLoc.line;
333-
334-
loc = {
335-
end: {line: lineNumber},
336-
start: {line: lineNumber}
337-
};
338-
if (jsdocLoc.column) {
339-
const colNumber = jsdocNode.loc.start.column + jsdocLoc.column;
340-
341-
loc.end.column = colNumber;
342-
loc.start.column = colNumber;
343-
}
344-
}
345-
346-
context.report({
347-
data,
348-
fix,
349-
loc,
350-
message,
351-
node: jsdocNode
352-
});
353-
};
431+
const report = makeReport(context, jsdocNode);
354432

355433
const utils = getUtils(
356434
node,

0 commit comments

Comments
 (0)