Skip to content

Commit 3907822

Browse files
authored
feat(type-formatting): support trailingPunctuationMultilineOnly boolean option; fixes #1636 (#1638)
1 parent f443986 commit 3907822

File tree

5 files changed

+153
-6
lines changed

5 files changed

+153
-6
lines changed

.README/rules/type-formatting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Currently offers the following options for formatting types.
1818
|Tags|`param`, `property`, `returns`, `this`, `throws`, `type`, `typedef`, `yields`|
1919
|Recommended|false|
2020
|Settings|`mode`|
21-
|Options|`arrayBrackets`, `arrowFunctionPostReturnMarkerSpacing`, `arrowFunctionPreReturnMarkerSpacing`, `enableFixer`, `functionOrClassParameterSpacing`, `functionOrClassPostGenericSpacing`, `functionOrClassPostReturnMarkerSpacing`, `functionOrClassPreReturnMarkerSpacing`, `functionOrClassTypeParameterSpacing`, `genericAndTupleElementSpacing`, `genericDot`, `keyValuePostColonSpacing`, `keyValuePostKeySpacing`, `keyValuePostOptionalSpacing`, `keyValuePostVariadicSpacing`, `methodQuotes`, `objectFieldIndent`, `objectFieldQuote`, `objectFieldSeparator`, `objectFieldSeparatorOptionalLinebreak`, `objectFieldSeparatorTrailingPunctuation`, `objectTypeBracketSpacing`, `parameterDefaultValueSpacing`, `postMethodNameSpacing`, `postNewSpacing`, `separatorForSingleObjectField`, `stringQuotes`, `typeBracketSpacing`, `unionSpacing`|
21+
|Options|`arrayBrackets`, `arrowFunctionPostReturnMarkerSpacing`, `arrowFunctionPreReturnMarkerSpacing`, `enableFixer`, `functionOrClassParameterSpacing`, `functionOrClassPostGenericSpacing`, `functionOrClassPostReturnMarkerSpacing`, `functionOrClassPreReturnMarkerSpacing`, `functionOrClassTypeParameterSpacing`, `genericAndTupleElementSpacing`, `genericDot`, `keyValuePostColonSpacing`, `keyValuePostKeySpacing`, `keyValuePostOptionalSpacing`, `keyValuePostVariadicSpacing`, `methodQuotes`, `objectFieldIndent`, `objectFieldQuote`, `objectFieldSeparator`, `objectFieldSeparatorOptionalLinebreak`, `objectFieldSeparatorTrailingPunctuation`, `objectTypeBracketSpacing`, `parameterDefaultValueSpacing`, `postMethodNameSpacing`, `postNewSpacing`, `separatorForSingleObjectField`, `stringQuotes`, `trailingPunctuationMultilineOnly`, `typeBracketSpacing`, `unionSpacing`|
2222

2323
## Failing examples
2424

docs/rules/type-formatting.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ is only one property-value object field present. Defaults to `false`.
195195
How string literals should be quoted (e.g., `"abc"`). Set to `single`
196196
or `double`. Defaults to 'double'.
197197

198+
<a name="user-content-type-formatting-options-trailingpunctuationmultilineonly"></a>
199+
<a name="type-formatting-options-trailingpunctuationmultilineonly"></a>
200+
### <code>trailingPunctuationMultilineOnly</code>
201+
202+
If `objectFieldSeparatorTrailingPunctuation` is set, this will determine whether the trailing puncutation is only added when the type is multiline
203+
198204
<a name="user-content-type-formatting-options-typebracketspacing"></a>
199205
<a name="type-formatting-options-typebracketspacing"></a>
200206
### <code>typeBracketSpacing</code>
@@ -216,7 +222,7 @@ Determines the spacing to add to unions (`|`). Defaults to a single space (`" "`
216222
|Tags|`param`, `property`, `returns`, `this`, `throws`, `type`, `typedef`, `yields`|
217223
|Recommended|false|
218224
|Settings|`mode`|
219-
|Options|`arrayBrackets`, `arrowFunctionPostReturnMarkerSpacing`, `arrowFunctionPreReturnMarkerSpacing`, `enableFixer`, `functionOrClassParameterSpacing`, `functionOrClassPostGenericSpacing`, `functionOrClassPostReturnMarkerSpacing`, `functionOrClassPreReturnMarkerSpacing`, `functionOrClassTypeParameterSpacing`, `genericAndTupleElementSpacing`, `genericDot`, `keyValuePostColonSpacing`, `keyValuePostKeySpacing`, `keyValuePostOptionalSpacing`, `keyValuePostVariadicSpacing`, `methodQuotes`, `objectFieldIndent`, `objectFieldQuote`, `objectFieldSeparator`, `objectFieldSeparatorOptionalLinebreak`, `objectFieldSeparatorTrailingPunctuation`, `objectTypeBracketSpacing`, `parameterDefaultValueSpacing`, `postMethodNameSpacing`, `postNewSpacing`, `separatorForSingleObjectField`, `stringQuotes`, `typeBracketSpacing`, `unionSpacing`|
225+
|Options|`arrayBrackets`, `arrowFunctionPostReturnMarkerSpacing`, `arrowFunctionPreReturnMarkerSpacing`, `enableFixer`, `functionOrClassParameterSpacing`, `functionOrClassPostGenericSpacing`, `functionOrClassPostReturnMarkerSpacing`, `functionOrClassPreReturnMarkerSpacing`, `functionOrClassTypeParameterSpacing`, `genericAndTupleElementSpacing`, `genericDot`, `keyValuePostColonSpacing`, `keyValuePostKeySpacing`, `keyValuePostOptionalSpacing`, `keyValuePostVariadicSpacing`, `methodQuotes`, `objectFieldIndent`, `objectFieldQuote`, `objectFieldSeparator`, `objectFieldSeparatorOptionalLinebreak`, `objectFieldSeparatorTrailingPunctuation`, `objectTypeBracketSpacing`, `parameterDefaultValueSpacing`, `postMethodNameSpacing`, `postNewSpacing`, `separatorForSingleObjectField`, `stringQuotes`, `trailingPunctuationMultilineOnly`, `typeBracketSpacing`, `unionSpacing`|
220226

221227
<a name="user-content-type-formatting-failing-examples"></a>
222228
<a name="type-formatting-failing-examples"></a>
@@ -515,7 +521,23 @@ The following patterns are considered problems:
515521
* @param {{a: string}} cfg
516522
*/
517523
// "jsdoc/type-formatting": ["error"|"warn", {"objectTypeBracketSpacing":" "}]
518-
// Message: Object type bracket spacing should be " "
524+
// Message: There was an error with type formatting
525+
526+
/**
527+
* @typedef {{ a: boolean, b: string, c: number, }} Example
528+
*/
529+
// "jsdoc/type-formatting": ["error"|"warn", {"objectFieldSeparator":"comma-and-linebreak","objectFieldSeparatorTrailingPunctuation":true,"objectTypeBracketSpacing":" ","trailingPunctuationMultilineOnly":true}]
530+
// Message: There was an error with type formatting
531+
532+
/**
533+
* @typedef {{
534+
* a: boolean,
535+
* b: string,
536+
* c: number
537+
* }} Example
538+
*/
539+
// "jsdoc/type-formatting": ["error"|"warn", {"objectFieldSeparator":"comma-and-linebreak","objectFieldSeparatorTrailingPunctuation":true,"objectTypeBracketSpacing":" ","trailingPunctuationMultilineOnly":true}]
540+
// Message: Inconsistent comma-and-linebreak separator usage
519541
````
520542

521543

@@ -705,5 +727,19 @@ The following patterns are not considered problems:
705727
* @param {{a: string}} cfg
706728
*/
707729
// "jsdoc/type-formatting": ["error"|"warn", {"objectTypeBracketSpacing":""}]
730+
731+
/**
732+
* @typedef {{ a: boolean, b: string, c: number }} Example
733+
*/
734+
// "jsdoc/type-formatting": ["error"|"warn", {"objectFieldSeparator":"comma-and-linebreak","objectFieldSeparatorTrailingPunctuation":true,"objectTypeBracketSpacing":" ","trailingPunctuationMultilineOnly":true}]
735+
736+
/**
737+
* @typedef {{
738+
* a: boolean,
739+
* b: string,
740+
* c: number,
741+
* }} Example
742+
*/
743+
// "jsdoc/type-formatting": ["error"|"warn", {"objectFieldSeparator":"comma-and-linebreak","objectFieldSeparatorTrailingPunctuation":true,"objectTypeBracketSpacing":" ","trailingPunctuationMultilineOnly":true}]
708744
````
709745

src/rules.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,6 +3162,10 @@ export interface Rules {
31623162
* or `double`. Defaults to 'double'.
31633163
*/
31643164
stringQuotes?: "double" | "single";
3165+
/**
3166+
* If `objectFieldSeparatorTrailingPunctuation` is set, this will determine whether the trailing puncutation is only added when the type is multiline
3167+
*/
3168+
trailingPunctuationMultilineOnly?: boolean;
31653169
/**
31663170
* A string of spaces that will be added immediately after the type's initial
31673171
* curly bracket and immediately before its ending curly bracket. Defaults

src/rules/typeFormatting.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default iterateJsdoc(({
4848
// propertyQuotes = null,
4949
separatorForSingleObjectField = false,
5050
stringQuotes = 'double',
51+
trailingPunctuationMultilineOnly = false,
5152
typeBracketSpacing = '',
5253
unionSpacing = ' ',
5354
} = context.options[0] || {};
@@ -329,6 +330,7 @@ export default iterateJsdoc(({
329330
const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectResult} */ (nde);
330331
/* c8 ignore next -- Guard */
331332
const separator = typeNode.meta.separator ?? 'comma';
333+
332334
if (
333335
(separator !== objectFieldSeparator &&
334336
(!objectFieldSeparatorOptionalLinebreak ||
@@ -337,7 +339,12 @@ export default iterateJsdoc(({
337339
(typeNode.meta.separatorForSingleObjectField ?? false) !== separatorForSingleObjectField ||
338340
((typeNode.meta.propertyIndent ?? '') !== objectFieldIndent &&
339341
separator.endsWith('-linebreak')) ||
340-
(typeNode.meta.trailingPunctuation ?? false) !== objectFieldSeparatorTrailingPunctuation
342+
/* c8 ignore next 5 -- jsdoc-type-pratt-parser doesn't encode as should */
343+
((typeNode.meta.trailingPunctuation ?? false) !== objectFieldSeparatorTrailingPunctuation &&
344+
((typeNode.meta.trailingPunctuation && (!trailingPunctuationMultilineOnly ||
345+
!stringify(typeNode).includes('\n'))) ||
346+
(!typeNode.meta.trailingPunctuation && (!trailingPunctuationMultilineOnly ||
347+
stringify(typeNode).includes('\n')))))
341348
) {
342349
typeNode.meta.separator = objectFieldSeparatorOptionalLinebreak && !separator.endsWith('and-linebreak') ?
343350
objectFieldSeparator.replace(/-and-linebreak$/v, '') :
@@ -348,7 +355,8 @@ export default iterateJsdoc(({
348355
errorMessage = `Inconsistent ${objectFieldSeparator} separator usage`;
349356
} else if ((typeNode.meta.bracketSpacing ?? '') !== objectTypeBracketSpacing) {
350357
typeNode.meta.bracketSpacing = objectTypeBracketSpacing;
351-
errorMessage = `Object type bracket spacing should be "${objectTypeBracketSpacing}"`;
358+
// This might not be the cause
359+
// errorMessage = `Object type bracket spacing should be "${objectTypeBracketSpacing}"`;
352360
}
353361

354362
break;
@@ -659,6 +667,10 @@ or \`double\`. Defaults to 'double'.`,
659667
],
660668
type: 'string',
661669
},
670+
trailingPunctuationMultilineOnly: {
671+
description: 'If `objectFieldSeparatorTrailingPunctuation` is set, this will determine whether the trailing puncutation is only added when the type is multiline',
672+
type: 'boolean',
673+
},
662674
typeBracketSpacing: {
663675
description: `A string of spaces that will be added immediately after the type's initial
664676
curly bracket and immediately before its ending curly bracket. Defaults

test/rules/assertions/typeFormatting.js

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ export default {
11791179
errors: [
11801180
{
11811181
line: 3,
1182-
message: 'Object type bracket spacing should be " "',
1182+
message: 'There was an error with type formatting',
11831183
},
11841184
],
11851185
options: [
@@ -1193,6 +1193,67 @@ export default {
11931193
*/
11941194
`,
11951195
},
1196+
1197+
{
1198+
code: `
1199+
/**
1200+
* @typedef {{ a: boolean, b: string, c: number, }} Example
1201+
*/
1202+
`,
1203+
errors: [
1204+
{
1205+
line: 3,
1206+
message: 'There was an error with type formatting',
1207+
},
1208+
],
1209+
options: [
1210+
{
1211+
objectFieldSeparator: 'comma-and-linebreak',
1212+
objectFieldSeparatorTrailingPunctuation: true,
1213+
objectTypeBracketSpacing: ' ',
1214+
trailingPunctuationMultilineOnly: true,
1215+
},
1216+
],
1217+
output: `
1218+
/**
1219+
* @typedef {{ a: boolean, b: string, c: number }} Example
1220+
*/
1221+
`,
1222+
},
1223+
{
1224+
code: `
1225+
/**
1226+
* @typedef {{
1227+
* a: boolean,
1228+
* b: string,
1229+
* c: number
1230+
* }} Example
1231+
*/
1232+
`,
1233+
errors: [
1234+
{
1235+
line: 3,
1236+
message: 'Inconsistent comma-and-linebreak separator usage',
1237+
},
1238+
],
1239+
options: [
1240+
{
1241+
objectFieldSeparator: 'comma-and-linebreak',
1242+
objectFieldSeparatorTrailingPunctuation: true,
1243+
objectTypeBracketSpacing: ' ',
1244+
trailingPunctuationMultilineOnly: true,
1245+
},
1246+
],
1247+
output: `
1248+
/**
1249+
* @typedef {{
1250+
* a: boolean,
1251+
* b: string,
1252+
* c: number,
1253+
* }} Example
1254+
*/
1255+
`,
1256+
},
11961257
],
11971258
valid: [
11981259
{
@@ -1638,5 +1699,39 @@ export default {
16381699
},
16391700
],
16401701
},
1702+
{
1703+
code: `
1704+
/**
1705+
* @typedef {{ a: boolean, b: string, c: number }} Example
1706+
*/
1707+
`,
1708+
options: [
1709+
{
1710+
objectFieldSeparator: 'comma-and-linebreak',
1711+
objectFieldSeparatorTrailingPunctuation: true,
1712+
objectTypeBracketSpacing: ' ',
1713+
trailingPunctuationMultilineOnly: true,
1714+
},
1715+
],
1716+
},
1717+
{
1718+
code: `
1719+
/**
1720+
* @typedef {{
1721+
* a: boolean,
1722+
* b: string,
1723+
* c: number,
1724+
* }} Example
1725+
*/
1726+
`,
1727+
options: [
1728+
{
1729+
objectFieldSeparator: 'comma-and-linebreak',
1730+
objectFieldSeparatorTrailingPunctuation: true,
1731+
objectTypeBracketSpacing: ' ',
1732+
trailingPunctuationMultilineOnly: true,
1733+
},
1734+
],
1735+
},
16411736
],
16421737
};

0 commit comments

Comments
 (0)