Skip to content

Commit 40504d9

Browse files
committed
feat(escape-inline-tags): add new rule
1 parent f72ac1a commit 40504d9

File tree

10 files changed

+796
-0
lines changed

10 files changed

+796
-0
lines changed

.README/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ Finally, enable all of the rules that you would like to use.
227227
"jsdoc/check-values": 1, // Recommended
228228
"jsdoc/convert-to-jsdoc-comments": 1,
229229
"jsdoc/empty-tags": 1, // Recommended
230+
"jsdoc/escape-inline-tags": 1, // Recommended for TS configs
230231
"jsdoc/implements-on-classes": 1, // Recommended
231232
"jsdoc/imports-as-dependencies": 1,
232233
"jsdoc/informative-docs": 1,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# `escape-inline-tags`
2+
3+
Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode).
4+
5+
Note that while the JSDoc standard refers to inline tags as those being surrounded
6+
by curly brackets, such as those in the form `{@link https://example.com}`, for the
7+
purposes of this rule, we are referring to inline tags as a simple reference to
8+
tags such as `@param` outside of the normal location of a tag.
9+
10+
## Options
11+
12+
{"gitdown": "options"}
13+
14+
|||
15+
|---|---|
16+
|Context|everywhere|
17+
|Tags|``|
18+
|Recommended|true (unless `mode` is changed away from "typescript")|
19+
|Settings|`mode`|
20+
|Options|`allowedInlineTags`, `enableFixer`, `fixAsCode`|
21+
22+
## Failing examples
23+
24+
<!-- assertions-failing escapeInlineTags -->
25+
26+
## Passing examples
27+
28+
<!-- assertions-passing escapeInlineTags -->

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ Finally, enable all of the rules that you would like to use.
254254
"jsdoc/check-values": 1, // Recommended
255255
"jsdoc/convert-to-jsdoc-comments": 1,
256256
"jsdoc/empty-tags": 1, // Recommended
257+
"jsdoc/escape-inline-tags": 1, // Recommended for TS configs
257258
"jsdoc/implements-on-classes": 1, // Recommended
258259
"jsdoc/imports-as-dependencies": 1,
259260
"jsdoc/informative-docs": 1,
@@ -442,6 +443,7 @@ non-default-recommended fixer).
442443
|:heavy_check_mark:|| [check-values](./docs/rules/check-values.md#readme) | This rule checks the values for a handful of tags: `@version`, `@since`, `@license` and `@author`. |
443444
||:wrench:| [convert-to-jsdoc-comments](./docs/rules/convert-to-jsdoc-comments.md#readme) | Converts non-JSDoc comments preceding or following nodes into JSDoc ones |
444445
|:heavy_check_mark:|:wrench:| [empty-tags](./docs/rules/empty-tags.md#readme) | Checks tags that are expected to be empty (e.g., `@abstract` or `@async`), reporting if they have content |
446+
|:heavy_check_mark:|:wrench:| [escape-inline-tags](./docs/rules/escape-inline-tags.md#readme) | Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode). |
445447
|:heavy_check_mark:|| [implements-on-classes](./docs/rules/implements-on-classes.md#readme) | Prohibits use of `@implements` on non-constructor functions (to enforce the tag only being used on classes/constructors). |
446448
||| [imports-as-dependencies](./docs/rules/imports-as-dependencies.md#readme) | Reports if JSDoc `import()` statements point to a package which is not listed in `dependencies` or `devDependencies` |
447449
||| [informative-docs](./docs/rules/informative-docs.md#readme) | This rule reports doc comments that only restate their attached name. |

docs/rules/escape-inline-tags.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<a name="user-content-escape-inline-tags"></a>
2+
<a name="escape-inline-tags"></a>
3+
# <code>escape-inline-tags</code>
4+
5+
Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode).
6+
7+
Note that while the JSDoc standard refers to inline tags as those being surrounded
8+
by curly brackets, such as those in the form `{@link https://example.com}`, for the
9+
purposes of this rule, we are referring to inline tags as a simple reference to
10+
tags such as `@param` outside of the normal location of a tag.
11+
12+
<a name="user-content-escape-inline-tags-options"></a>
13+
<a name="escape-inline-tags-options"></a>
14+
## Options
15+
16+
A single options object has the following properties.
17+
18+
<a name="user-content-escape-inline-tags-options-allowedinlinetags"></a>
19+
<a name="escape-inline-tags-options-allowedinlinetags"></a>
20+
### <code>allowedInlineTags</code>
21+
22+
A listing of tags you wish to allow unescaped. Defaults to an empty array.
23+
<a name="user-content-escape-inline-tags-options-enablefixer"></a>
24+
<a name="escape-inline-tags-options-enablefixer"></a>
25+
### <code>enableFixer</code>
26+
27+
Whether to enable the fixer. Defaults to `true`.
28+
<a name="user-content-escape-inline-tags-options-fixascode"></a>
29+
<a name="escape-inline-tags-options-fixascode"></a>
30+
### <code>fixAsCode</code>
31+
32+
Whether to enclose tags in backticks, treating as code segments rather than a `@` literal
33+
34+
35+
|||
36+
|---|---|
37+
|Context|everywhere|
38+
|Tags|``|
39+
|Recommended|true (unless `mode` is changed away from "typescript")|
40+
|Settings|`mode`|
41+
|Options|`allowedInlineTags`, `enableFixer`, `fixAsCode`|
42+
43+
<a name="user-content-escape-inline-tags-failing-examples"></a>
44+
<a name="escape-inline-tags-failing-examples"></a>
45+
## Failing examples
46+
47+
The following patterns are considered problems:
48+
49+
````ts
50+
/**
51+
*
52+
* Whether to include a @yearly, @monthly etc text labels in the generated expression.
53+
*/
54+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
55+
56+
/**
57+
* Some text
58+
* Whether to include a @yearly, @monthly etc text labels in the generated expression.
59+
*/
60+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
61+
62+
/**
63+
* Whether to include a @yearly, @yearly etc text labels in the generated expression.
64+
*/
65+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
66+
67+
/**
68+
* Whether to include a @yearly,
69+
* or @yearly etc text labels in the generated expression.
70+
*/
71+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
72+
73+
/**
74+
* Whether to include a @yearly, @monthly etc text labels in the generated expression.
75+
*/
76+
// "jsdoc/escape-inline-tags": ["error"|"warn", {"allowedInlineTags":["monthly"],"fixAsCode":true}]
77+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
78+
79+
/**
80+
* Some description @sth
81+
*/
82+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@sth}, \@sth, or `@sth`?
83+
84+
/**
85+
* Some description @sth
86+
*/
87+
// "jsdoc/escape-inline-tags": ["error"|"warn", {"enableFixer":false}]
88+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@sth}, \@sth, or `@sth`?
89+
90+
/**
91+
* @param includeNonStandard Whether to include a @yearly, @monthly etc text labels in the generated expression.
92+
*/
93+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
94+
95+
/**
96+
* @param includeNonStandard Whether to include a @yearly, @monthly etc text labels in the generated expression.
97+
*/
98+
// "jsdoc/escape-inline-tags": ["error"|"warn", {"allowedInlineTags":["monthly"],"fixAsCode":true}]
99+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@yearly}, \@yearly, or `@yearly`?
100+
101+
/**
102+
* @param aName @sth
103+
*/
104+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@sth}, \@sth, or `@sth`?
105+
106+
/**
107+
* @param aName @sth
108+
* and @another
109+
* @param anotherName @yetAnother
110+
*/
111+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@sth}, \@sth, or `@sth`?
112+
113+
/**
114+
* @param aName @sth
115+
*/
116+
// "jsdoc/escape-inline-tags": ["error"|"warn", {"enableFixer":false}]
117+
// Message: Unexpected inline JSDoc tag. Did you mean to use {@sth}, \@sth, or `@sth`?
118+
````
119+
120+
121+
122+
<a name="user-content-escape-inline-tags-passing-examples"></a>
123+
<a name="escape-inline-tags-passing-examples"></a>
124+
## Passing examples
125+
126+
The following patterns are not considered problems:
127+
128+
````ts
129+
/**
130+
* A description with an escaped \@tag.
131+
*/
132+
133+
/**
134+
* A description with a markdown `@tag`.
135+
*/
136+
137+
/**
138+
* A description with a non@tag.
139+
*/
140+
141+
/**
142+
* @param {SomeType} aName A description with an escaped \@tag.
143+
*/
144+
145+
/**
146+
* @param {SomeType} aName A description with a markdown `@tag`.
147+
*/
148+
149+
/**
150+
* @param {SomeType} aName A description with a non@tag.
151+
*/
152+
153+
/**
154+
* {@link https://example.com}
155+
*/
156+
157+
/**
158+
* A description with a {@link https://example.com}
159+
*/
160+
161+
/**
162+
* @someTag {@link https://example.com}
163+
*/
164+
165+
/**
166+
* @param {SomeType} aName {@link https://example.com}
167+
*/
168+
169+
/**
170+
* @param {SomeType} aName A description with a {@link https://example.com}.
171+
*/
172+
173+
/**
174+
* @example
175+
* Here are some unescaped tags: @yearly, @monthly
176+
*/
177+
178+
/**
179+
* Whether to include a @yearly, @monthly etc text labels in the generated expression.
180+
*/
181+
// Settings: {"jsdoc":{"mode":"jsdoc"}}
182+
````
183+

src/index-cjs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import checkTypes from './rules/checkTypes.js';
2121
import checkValues from './rules/checkValues.js';
2222
import convertToJsdocComments from './rules/convertToJsdocComments.js';
2323
import emptyTags from './rules/emptyTags.js';
24+
import escapeInlineTags from './rules/escapeInlineTags.js';
2425
import implementsOnClasses from './rules/implementsOnClasses.js';
2526
import importsAsDependencies from './rules/importsAsDependencies.js';
2627
import informativeDocs from './rules/informativeDocs.js';
@@ -101,6 +102,7 @@ index.rules = {
101102
'check-values': checkValues,
102103
'convert-to-jsdoc-comments': convertToJsdocComments,
103104
'empty-tags': emptyTags,
105+
'escape-inline-tags': escapeInlineTags,
104106
'implements-on-classes': implementsOnClasses,
105107
'imports-as-dependencies': importsAsDependencies,
106108
'informative-docs': informativeDocs,
@@ -285,6 +287,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
285287
'jsdoc/check-values': warnOrError,
286288
'jsdoc/convert-to-jsdoc-comments': 'off',
287289
'jsdoc/empty-tags': warnOrError,
290+
'jsdoc/escape-inline-tags': warnOrError,
288291
'jsdoc/implements-on-classes': warnOrError,
289292
'jsdoc/imports-as-dependencies': 'off',
290293
'jsdoc/informative-docs': 'off',
@@ -451,6 +454,7 @@ const logicalRules = [
451454
'jsdoc/check-types',
452455
'jsdoc/check-values',
453456
'jsdoc/empty-tags',
457+
'jsdoc/escape-inline-tags',
454458
'jsdoc/implements-on-classes',
455459
'jsdoc/require-returns-check',
456460
'jsdoc/require-yields-check',

src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import checkTypes from './rules/checkTypes.js';
2727
import checkValues from './rules/checkValues.js';
2828
import convertToJsdocComments from './rules/convertToJsdocComments.js';
2929
import emptyTags from './rules/emptyTags.js';
30+
import escapeInlineTags from './rules/escapeInlineTags.js';
3031
import implementsOnClasses from './rules/implementsOnClasses.js';
3132
import importsAsDependencies from './rules/importsAsDependencies.js';
3233
import informativeDocs from './rules/informativeDocs.js';
@@ -107,6 +108,7 @@ index.rules = {
107108
'check-values': checkValues,
108109
'convert-to-jsdoc-comments': convertToJsdocComments,
109110
'empty-tags': emptyTags,
111+
'escape-inline-tags': escapeInlineTags,
110112
'implements-on-classes': implementsOnClasses,
111113
'imports-as-dependencies': importsAsDependencies,
112114
'informative-docs': informativeDocs,
@@ -291,6 +293,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
291293
'jsdoc/check-values': warnOrError,
292294
'jsdoc/convert-to-jsdoc-comments': 'off',
293295
'jsdoc/empty-tags': warnOrError,
296+
'jsdoc/escape-inline-tags': warnOrError,
294297
'jsdoc/implements-on-classes': warnOrError,
295298
'jsdoc/imports-as-dependencies': 'off',
296299
'jsdoc/informative-docs': 'off',
@@ -457,6 +460,7 @@ const logicalRules = [
457460
'jsdoc/check-types',
458461
'jsdoc/check-values',
459462
'jsdoc/empty-tags',
463+
'jsdoc/escape-inline-tags',
460464
'jsdoc/implements-on-classes',
461465
'jsdoc/require-returns-check',
462466
'jsdoc/require-yields-check',

src/rules.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,26 @@ export interface Rules {
532532
}
533533
];
534534

535+
/** Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode). */
536+
"jsdoc/escape-inline-tags":
537+
| []
538+
| [
539+
{
540+
/**
541+
* A listing of tags you wish to allow unescaped. Defaults to an empty array.
542+
*/
543+
allowedInlineTags?: string[];
544+
/**
545+
* Whether to enable the fixer. Defaults to `true`.
546+
*/
547+
enableFixer?: boolean;
548+
/**
549+
* Whether to enclose tags in backticks, treating as code segments rather than a `@` literal
550+
*/
551+
fixAsCode?: boolean;
552+
}
553+
];
554+
535555
/** Prohibits use of `@implements` on non-constructor functions (to enforce the tag only being used on classes/constructors). */
536556
"jsdoc/implements-on-classes":
537557
| []

0 commit comments

Comments
 (0)