comment-parser 1.1.1 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -3
- package/browser/index.js +49 -31
- package/es6/index.d.ts +2 -1
- package/es6/index.js +1 -0
- package/es6/parser/index.d.ts +2 -1
- package/es6/parser/tokenizers/type.js +1 -1
- package/es6/stringifier/index.d.ts +2 -1
- package/es6/transforms/align.js +30 -11
- package/es6/transforms/index.d.ts +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +11 -0
- package/lib/parser/index.d.ts +2 -1
- package/lib/parser/tokenizers/type.js +1 -1
- package/lib/stringifier/index.d.ts +2 -1
- package/lib/transforms/align.js +30 -11
- package/lib/transforms/index.d.ts +1 -1
- package/package.json +4 -3
- package/src/index.ts +2 -0
- package/src/parser/index.ts +3 -1
- package/src/parser/tokenizers/name.ts +1 -1
- package/src/parser/tokenizers/type.ts +2 -2
- package/src/stringifier/index.ts +3 -1
- package/src/stringifier/inspect.ts +2 -2
- package/src/transforms/align.ts +38 -13
- package/src/transforms/indent.ts +1 -1
- package/src/transforms/index.ts +1 -1
- package/tests/e2e/examples.js +3 -3
- package/tests/e2e/issue-119.spec.js +29 -0
- package/tests/e2e/issue-120.spec.js +29 -0
- package/tests/e2e/issue-121.spec.js +102 -0
- package/tests/unit/spec-type-tokenizer.spec.ts +6 -20
- package/tests/unit/transforms-align.spec.ts +79 -15
- package/{tsconfig.es6.json → tsconfig.json} +1 -1
- package/tsconfig.node.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# v1.1.5
|
|
2
|
+
- drop unused variables
|
|
3
|
+
- add .editorconfig
|
|
4
|
+
|
|
5
|
+
# v1.1.4
|
|
6
|
+
- `bugfix` fix unsynced lib/
|
|
7
|
+
|
|
8
|
+
# v1.1.3
|
|
9
|
+
- export primitive type on the top level: Markers, Block, Spec, Line, Tokens, Problem
|
|
10
|
+
|
|
11
|
+
# v1.1.2
|
|
12
|
+
- `bugfix` Allow to build nested tags from `name.subname` even if `name` wasn't d
|
|
13
|
+
- `bugfix` Preserve indentation when extracting comments
|
|
14
|
+
|
|
15
|
+
# v1.1.1
|
|
16
|
+
- add helpers for rewiring Spec.source <-> Spec.tags.source
|
|
17
|
+
|
|
1
18
|
# v1.1.0
|
|
2
19
|
- split tokenizers into separate modules
|
|
3
20
|
- allow multiline {type} definitions - issue #109
|
|
@@ -5,9 +22,6 @@
|
|
|
5
22
|
- allow using "=" in quoted [name=default] defaults – issue #112
|
|
6
23
|
- add tokenizers usage example - issue #111
|
|
7
24
|
|
|
8
|
-
# v1.1.1
|
|
9
|
-
- add helpers for rewiring Spec.source <-> Spec.tags.source
|
|
10
|
-
|
|
11
25
|
# v1.0.0
|
|
12
26
|
- complete rewrite in TS with more flexible API
|
|
13
27
|
|
package/browser/index.js
CHANGED
|
@@ -62,13 +62,12 @@ var CommentParser = (function (exports) {
|
|
|
62
62
|
return fence;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
var Markers;
|
|
66
65
|
(function (Markers) {
|
|
67
66
|
Markers["start"] = "/**";
|
|
68
67
|
Markers["nostart"] = "/***";
|
|
69
68
|
Markers["delim"] = "*";
|
|
70
69
|
Markers["end"] = "*/";
|
|
71
|
-
})(Markers || (Markers = {}));
|
|
70
|
+
})(exports.Markers || (exports.Markers = {}));
|
|
72
71
|
|
|
73
72
|
function getParser$1({ startLine = 0, } = {}) {
|
|
74
73
|
let block = null;
|
|
@@ -78,29 +77,29 @@ var CommentParser = (function (exports) {
|
|
|
78
77
|
const tokens = seedTokens();
|
|
79
78
|
[tokens.start, rest] = splitSpace(rest);
|
|
80
79
|
if (block === null &&
|
|
81
|
-
rest.startsWith(Markers.start) &&
|
|
82
|
-
!rest.startsWith(Markers.nostart)) {
|
|
80
|
+
rest.startsWith(exports.Markers.start) &&
|
|
81
|
+
!rest.startsWith(exports.Markers.nostart)) {
|
|
83
82
|
block = [];
|
|
84
|
-
tokens.delimiter = rest.slice(0, Markers.start.length);
|
|
85
|
-
rest = rest.slice(Markers.start.length);
|
|
83
|
+
tokens.delimiter = rest.slice(0, exports.Markers.start.length);
|
|
84
|
+
rest = rest.slice(exports.Markers.start.length);
|
|
86
85
|
[tokens.postDelimiter, rest] = splitSpace(rest);
|
|
87
86
|
}
|
|
88
87
|
if (block === null) {
|
|
89
88
|
num++;
|
|
90
89
|
return null;
|
|
91
90
|
}
|
|
92
|
-
const isClosed = rest.trimRight().endsWith(Markers.end);
|
|
91
|
+
const isClosed = rest.trimRight().endsWith(exports.Markers.end);
|
|
93
92
|
if (tokens.delimiter === '' &&
|
|
94
|
-
rest.startsWith(Markers.delim) &&
|
|
95
|
-
!rest.startsWith(Markers.end)) {
|
|
96
|
-
tokens.delimiter = Markers.delim;
|
|
97
|
-
rest = rest.slice(Markers.delim.length);
|
|
93
|
+
rest.startsWith(exports.Markers.delim) &&
|
|
94
|
+
!rest.startsWith(exports.Markers.end)) {
|
|
95
|
+
tokens.delimiter = exports.Markers.delim;
|
|
96
|
+
rest = rest.slice(exports.Markers.delim.length);
|
|
98
97
|
[tokens.postDelimiter, rest] = splitSpace(rest);
|
|
99
98
|
}
|
|
100
99
|
if (isClosed) {
|
|
101
100
|
const trimmed = rest.trimRight();
|
|
102
|
-
tokens.end = rest.slice(trimmed.length - Markers.end.length);
|
|
103
|
-
rest = trimmed.slice(0, -Markers.end.length);
|
|
101
|
+
tokens.end = rest.slice(trimmed.length - exports.Markers.end.length);
|
|
102
|
+
rest = trimmed.slice(0, -exports.Markers.end.length);
|
|
104
103
|
}
|
|
105
104
|
tokens.description = rest;
|
|
106
105
|
block.push({ number: num, source, tokens });
|
|
@@ -200,7 +199,7 @@ var CommentParser = (function (exports) {
|
|
|
200
199
|
tokens.type = tokens.postDelimiter.slice(offset) + type;
|
|
201
200
|
tokens.postDelimiter = tokens.postDelimiter.slice(0, offset);
|
|
202
201
|
}
|
|
203
|
-
[tokens.postType, tokens.description] = splitSpace(tokens.description.slice(
|
|
202
|
+
[tokens.postType, tokens.description] = splitSpace(tokens.description.slice(type.length));
|
|
204
203
|
parts.push(tokens.type);
|
|
205
204
|
}
|
|
206
205
|
parts[0] = parts[0].slice(1);
|
|
@@ -343,13 +342,13 @@ var CommentParser = (function (exports) {
|
|
|
343
342
|
return '';
|
|
344
343
|
// skip the opening line with no description
|
|
345
344
|
if (lines[0].tokens.description === '' &&
|
|
346
|
-
lines[0].tokens.delimiter === Markers.start)
|
|
345
|
+
lines[0].tokens.delimiter === exports.Markers.start)
|
|
347
346
|
lines = lines.slice(1);
|
|
348
347
|
// skip the closing line with no description
|
|
349
348
|
const lastLine = lines[lines.length - 1];
|
|
350
349
|
if (lastLine !== undefined &&
|
|
351
350
|
lastLine.tokens.description === '' &&
|
|
352
|
-
lastLine.tokens.end.endsWith(Markers.end))
|
|
351
|
+
lastLine.tokens.end.endsWith(exports.Markers.end))
|
|
353
352
|
lines = lines.slice(0, -1);
|
|
354
353
|
// description starts at the last line of type definition
|
|
355
354
|
lines = lines.slice(lines.reduce(lineNo, 0));
|
|
@@ -425,19 +424,11 @@ var CommentParser = (function (exports) {
|
|
|
425
424
|
name: 0,
|
|
426
425
|
};
|
|
427
426
|
const getWidth = (w, { tokens: t }) => ({
|
|
428
|
-
start: t.delimiter === Markers.start ? t.start.length : w.start,
|
|
427
|
+
start: t.delimiter === exports.Markers.start ? t.start.length : w.start,
|
|
429
428
|
tag: Math.max(w.tag, t.tag.length),
|
|
430
429
|
type: Math.max(w.type, t.type.length),
|
|
431
430
|
name: Math.max(w.name, t.name.length),
|
|
432
431
|
});
|
|
433
|
-
// /**
|
|
434
|
-
// * Description may go
|
|
435
|
-
// * over multiple lines followed by @tags
|
|
436
|
-
// *
|
|
437
|
-
//* @my-tag {my.type} my-name description line 1
|
|
438
|
-
// description line 2
|
|
439
|
-
// * description line 3
|
|
440
|
-
// */
|
|
441
432
|
const space = (len) => ''.padStart(len, ' ');
|
|
442
433
|
function align() {
|
|
443
434
|
let intoTags = false;
|
|
@@ -451,26 +442,53 @@ var CommentParser = (function (exports) {
|
|
|
451
442
|
tokens.type === '' &&
|
|
452
443
|
tokens.description === '';
|
|
453
444
|
// dangling '*/'
|
|
454
|
-
if (tokens.end === Markers.end && isEmpty) {
|
|
445
|
+
if (tokens.end === exports.Markers.end && isEmpty) {
|
|
455
446
|
tokens.start = space(w.start + 1);
|
|
456
447
|
return Object.assign(Object.assign({}, line), { tokens });
|
|
457
448
|
}
|
|
458
449
|
switch (tokens.delimiter) {
|
|
459
|
-
case Markers.start:
|
|
450
|
+
case exports.Markers.start:
|
|
460
451
|
tokens.start = space(w.start);
|
|
461
452
|
break;
|
|
462
|
-
case Markers.delim:
|
|
453
|
+
case exports.Markers.delim:
|
|
463
454
|
tokens.start = space(w.start + 1);
|
|
464
455
|
break;
|
|
465
456
|
default:
|
|
466
|
-
tokens.start = space(w.start + 3);
|
|
467
457
|
tokens.delimiter = '';
|
|
458
|
+
tokens.start = space(w.start + 2); // compensate delimiter
|
|
468
459
|
}
|
|
469
|
-
if (intoTags) {
|
|
460
|
+
if (!intoTags) {
|
|
461
|
+
tokens.postDelimiter = tokens.description === '' ? '' : ' ';
|
|
462
|
+
return Object.assign(Object.assign({}, line), { tokens });
|
|
463
|
+
}
|
|
464
|
+
const nothingAfter = {
|
|
465
|
+
delim: false,
|
|
466
|
+
tag: false,
|
|
467
|
+
type: false,
|
|
468
|
+
name: false,
|
|
469
|
+
};
|
|
470
|
+
if (tokens.description === '') {
|
|
471
|
+
nothingAfter.name = true;
|
|
472
|
+
tokens.postName = '';
|
|
473
|
+
if (tokens.name === '') {
|
|
474
|
+
nothingAfter.type = true;
|
|
475
|
+
tokens.postType = '';
|
|
476
|
+
if (tokens.type === '') {
|
|
477
|
+
nothingAfter.tag = true;
|
|
478
|
+
tokens.postTag = '';
|
|
479
|
+
if (tokens.tag === '') {
|
|
480
|
+
nothingAfter.delim = true;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
|
|
486
|
+
if (!nothingAfter.tag)
|
|
470
487
|
tokens.postTag = space(w.tag - tokens.tag.length + 1);
|
|
488
|
+
if (!nothingAfter.type)
|
|
471
489
|
tokens.postType = space(w.type - tokens.type.length + 1);
|
|
490
|
+
if (!nothingAfter.name)
|
|
472
491
|
tokens.postName = space(w.name - tokens.name.length + 1);
|
|
473
|
-
}
|
|
474
492
|
return Object.assign(Object.assign({}, line), { tokens });
|
|
475
493
|
}
|
|
476
494
|
return (_a) => {
|
package/es6/index.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ import typeTokenizer from './parser/tokenizers/type';
|
|
|
6
6
|
import alignTransform from './transforms/align';
|
|
7
7
|
import indentTransform from './transforms/indent';
|
|
8
8
|
import { flow as flowTransform } from './transforms/index';
|
|
9
|
+
export * from './primitives';
|
|
9
10
|
export declare function parse(source: string, options?: Partial<ParserOptions>): import("./primitives").Block[];
|
|
10
|
-
export declare const stringify:
|
|
11
|
+
export declare const stringify: import("./stringifier").Stringifier;
|
|
11
12
|
export { default as inspect } from './stringifier/inspect';
|
|
12
13
|
export declare const transforms: {
|
|
13
14
|
flow: typeof flowTransform;
|
package/es6/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import getStringifier from './stringifier/index';
|
|
|
7
7
|
import alignTransform from './transforms/align';
|
|
8
8
|
import indentTransform from './transforms/indent';
|
|
9
9
|
import { flow as flowTransform } from './transforms/index';
|
|
10
|
+
export * from './primitives';
|
|
10
11
|
export function parse(source, options = {}) {
|
|
11
12
|
return getParser(options)(source);
|
|
12
13
|
}
|
package/es6/parser/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export interface Options {
|
|
|
6
6
|
spacing: 'compact' | 'preserve';
|
|
7
7
|
tokenizers: Tokenizer[];
|
|
8
8
|
}
|
|
9
|
-
export
|
|
9
|
+
export declare type Parser = (source: string) => Block[];
|
|
10
|
+
export default function getParser({ startLine, fence, spacing, tokenizers, }?: Partial<Options>): Parser;
|
|
@@ -47,7 +47,7 @@ export default function typeTokenizer(spacing = 'compact') {
|
|
|
47
47
|
tokens.type = tokens.postDelimiter.slice(offset) + type;
|
|
48
48
|
tokens.postDelimiter = tokens.postDelimiter.slice(0, offset);
|
|
49
49
|
}
|
|
50
|
-
[tokens.postType, tokens.description] = splitSpace(tokens.description.slice(
|
|
50
|
+
[tokens.postType, tokens.description] = splitSpace(tokens.description.slice(type.length));
|
|
51
51
|
parts.push(tokens.type);
|
|
52
52
|
}
|
|
53
53
|
parts[0] = parts[0].slice(1);
|
package/es6/transforms/align.js
CHANGED
|
@@ -23,14 +23,6 @@ const getWidth = (w, { tokens: t }) => ({
|
|
|
23
23
|
type: Math.max(w.type, t.type.length),
|
|
24
24
|
name: Math.max(w.name, t.name.length),
|
|
25
25
|
});
|
|
26
|
-
// /**
|
|
27
|
-
// * Description may go
|
|
28
|
-
// * over multiple lines followed by @tags
|
|
29
|
-
// *
|
|
30
|
-
//* @my-tag {my.type} my-name description line 1
|
|
31
|
-
// description line 2
|
|
32
|
-
// * description line 3
|
|
33
|
-
// */
|
|
34
26
|
const space = (len) => ''.padStart(len, ' ');
|
|
35
27
|
export default function align() {
|
|
36
28
|
let intoTags = false;
|
|
@@ -56,14 +48,41 @@ export default function align() {
|
|
|
56
48
|
tokens.start = space(w.start + 1);
|
|
57
49
|
break;
|
|
58
50
|
default:
|
|
59
|
-
tokens.start = space(w.start + 3);
|
|
60
51
|
tokens.delimiter = '';
|
|
52
|
+
tokens.start = space(w.start + 2); // compensate delimiter
|
|
61
53
|
}
|
|
62
|
-
if (intoTags) {
|
|
54
|
+
if (!intoTags) {
|
|
55
|
+
tokens.postDelimiter = tokens.description === '' ? '' : ' ';
|
|
56
|
+
return Object.assign(Object.assign({}, line), { tokens });
|
|
57
|
+
}
|
|
58
|
+
const nothingAfter = {
|
|
59
|
+
delim: false,
|
|
60
|
+
tag: false,
|
|
61
|
+
type: false,
|
|
62
|
+
name: false,
|
|
63
|
+
};
|
|
64
|
+
if (tokens.description === '') {
|
|
65
|
+
nothingAfter.name = true;
|
|
66
|
+
tokens.postName = '';
|
|
67
|
+
if (tokens.name === '') {
|
|
68
|
+
nothingAfter.type = true;
|
|
69
|
+
tokens.postType = '';
|
|
70
|
+
if (tokens.type === '') {
|
|
71
|
+
nothingAfter.tag = true;
|
|
72
|
+
tokens.postTag = '';
|
|
73
|
+
if (tokens.tag === '') {
|
|
74
|
+
nothingAfter.delim = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
|
|
80
|
+
if (!nothingAfter.tag)
|
|
63
81
|
tokens.postTag = space(w.tag - tokens.tag.length + 1);
|
|
82
|
+
if (!nothingAfter.type)
|
|
64
83
|
tokens.postType = space(w.type - tokens.type.length + 1);
|
|
84
|
+
if (!nothingAfter.name)
|
|
65
85
|
tokens.postName = space(w.name - tokens.name.length + 1);
|
|
66
|
-
}
|
|
67
86
|
return Object.assign(Object.assign({}, line), { tokens });
|
|
68
87
|
}
|
|
69
88
|
return (_a) => {
|
package/lib/index.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ import typeTokenizer from './parser/tokenizers/type';
|
|
|
6
6
|
import alignTransform from './transforms/align';
|
|
7
7
|
import indentTransform from './transforms/indent';
|
|
8
8
|
import { flow as flowTransform } from './transforms/index';
|
|
9
|
+
export * from './primitives';
|
|
9
10
|
export declare function parse(source: string, options?: Partial<ParserOptions>): import("./primitives").Block[];
|
|
10
|
-
export declare const stringify:
|
|
11
|
+
export declare const stringify: import("./stringifier").Stringifier;
|
|
11
12
|
export { default as inspect } from './stringifier/inspect';
|
|
12
13
|
export declare const transforms: {
|
|
13
14
|
flow: typeof flowTransform;
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
13
|
exports.tokenizers = exports.transforms = exports.inspect = exports.stringify = exports.parse = void 0;
|
|
4
14
|
const index_1 = require("./parser/index");
|
|
@@ -10,6 +20,7 @@ const index_2 = require("./stringifier/index");
|
|
|
10
20
|
const align_1 = require("./transforms/align");
|
|
11
21
|
const indent_1 = require("./transforms/indent");
|
|
12
22
|
const index_3 = require("./transforms/index");
|
|
23
|
+
__exportStar(require("./primitives"), exports);
|
|
13
24
|
function parse(source, options = {}) {
|
|
14
25
|
return index_1.default(options)(source);
|
|
15
26
|
}
|
package/lib/parser/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export interface Options {
|
|
|
6
6
|
spacing: 'compact' | 'preserve';
|
|
7
7
|
tokenizers: Tokenizer[];
|
|
8
8
|
}
|
|
9
|
-
export
|
|
9
|
+
export declare type Parser = (source: string) => Block[];
|
|
10
|
+
export default function getParser({ startLine, fence, spacing, tokenizers, }?: Partial<Options>): Parser;
|
|
@@ -49,7 +49,7 @@ function typeTokenizer(spacing = 'compact') {
|
|
|
49
49
|
tokens.type = tokens.postDelimiter.slice(offset) + type;
|
|
50
50
|
tokens.postDelimiter = tokens.postDelimiter.slice(0, offset);
|
|
51
51
|
}
|
|
52
|
-
[tokens.postType, tokens.description] = util_1.splitSpace(tokens.description.slice(
|
|
52
|
+
[tokens.postType, tokens.description] = util_1.splitSpace(tokens.description.slice(type.length));
|
|
53
53
|
parts.push(tokens.type);
|
|
54
54
|
}
|
|
55
55
|
parts[0] = parts[0].slice(1);
|
package/lib/transforms/align.js
CHANGED
|
@@ -25,14 +25,6 @@ const getWidth = (w, { tokens: t }) => ({
|
|
|
25
25
|
type: Math.max(w.type, t.type.length),
|
|
26
26
|
name: Math.max(w.name, t.name.length),
|
|
27
27
|
});
|
|
28
|
-
// /**
|
|
29
|
-
// * Description may go
|
|
30
|
-
// * over multiple lines followed by @tags
|
|
31
|
-
// *
|
|
32
|
-
//* @my-tag {my.type} my-name description line 1
|
|
33
|
-
// description line 2
|
|
34
|
-
// * description line 3
|
|
35
|
-
// */
|
|
36
28
|
const space = (len) => ''.padStart(len, ' ');
|
|
37
29
|
function align() {
|
|
38
30
|
let intoTags = false;
|
|
@@ -58,14 +50,41 @@ function align() {
|
|
|
58
50
|
tokens.start = space(w.start + 1);
|
|
59
51
|
break;
|
|
60
52
|
default:
|
|
61
|
-
tokens.start = space(w.start + 3);
|
|
62
53
|
tokens.delimiter = '';
|
|
54
|
+
tokens.start = space(w.start + 2); // compensate delimiter
|
|
63
55
|
}
|
|
64
|
-
if (intoTags) {
|
|
56
|
+
if (!intoTags) {
|
|
57
|
+
tokens.postDelimiter = tokens.description === '' ? '' : ' ';
|
|
58
|
+
return Object.assign(Object.assign({}, line), { tokens });
|
|
59
|
+
}
|
|
60
|
+
const nothingAfter = {
|
|
61
|
+
delim: false,
|
|
62
|
+
tag: false,
|
|
63
|
+
type: false,
|
|
64
|
+
name: false,
|
|
65
|
+
};
|
|
66
|
+
if (tokens.description === '') {
|
|
67
|
+
nothingAfter.name = true;
|
|
68
|
+
tokens.postName = '';
|
|
69
|
+
if (tokens.name === '') {
|
|
70
|
+
nothingAfter.type = true;
|
|
71
|
+
tokens.postType = '';
|
|
72
|
+
if (tokens.type === '') {
|
|
73
|
+
nothingAfter.tag = true;
|
|
74
|
+
tokens.postTag = '';
|
|
75
|
+
if (tokens.tag === '') {
|
|
76
|
+
nothingAfter.delim = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
|
|
82
|
+
if (!nothingAfter.tag)
|
|
65
83
|
tokens.postTag = space(w.tag - tokens.tag.length + 1);
|
|
84
|
+
if (!nothingAfter.type)
|
|
66
85
|
tokens.postType = space(w.type - tokens.type.length + 1);
|
|
86
|
+
if (!nothingAfter.name)
|
|
67
87
|
tokens.postName = space(w.name - tokens.name.length + 1);
|
|
68
|
-
}
|
|
69
88
|
return Object.assign(Object.assign({}, line), { tokens });
|
|
70
89
|
}
|
|
71
90
|
return (_a) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comment-parser",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Generic JSDoc-like comment parser",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
"node": ">= 10.0.0"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
-
"build": "rimraf lib es6 browser; tsc -p tsconfig.
|
|
23
|
+
"build": "rimraf lib es6 browser; tsc -p tsconfig.json && tsc -p tsconfig.node.json && rollup -o browser/index.js -f iife --context window -n CommentParser es6/index.js",
|
|
24
24
|
"format": "prettier --write src/ tests/",
|
|
25
25
|
"pretest": "rimraf coverage; npm run build",
|
|
26
|
-
"test": "prettier --check src/ tests/ && jest --verbose"
|
|
26
|
+
"test": "prettier --check src/ tests/ && jest --verbose",
|
|
27
|
+
"preversion": "npm run build"
|
|
27
28
|
},
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ import alignTransform from './transforms/align';
|
|
|
8
8
|
import indentTransform from './transforms/indent';
|
|
9
9
|
import { flow as flowTransform } from './transforms/index';
|
|
10
10
|
|
|
11
|
+
export * from './primitives';
|
|
12
|
+
|
|
11
13
|
export function parse(source: string, options: Partial<ParserOptions> = {}) {
|
|
12
14
|
return getParser(options)(source);
|
|
13
15
|
}
|
package/src/parser/index.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface Options {
|
|
|
22
22
|
tokenizers: Tokenizer[];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export type Parser = (source: string) => Block[];
|
|
26
|
+
|
|
25
27
|
export default function getParser({
|
|
26
28
|
startLine = 0,
|
|
27
29
|
fence = '```',
|
|
@@ -32,7 +34,7 @@ export default function getParser({
|
|
|
32
34
|
tokenizeName(),
|
|
33
35
|
tokenizeDescription(spacing),
|
|
34
36
|
],
|
|
35
|
-
}: Partial<Options> = {}) {
|
|
37
|
+
}: Partial<Options> = {}): Parser {
|
|
36
38
|
if (startLine < 0 || startLine % 1 > 0) throw new Error('Invalid startLine');
|
|
37
39
|
|
|
38
40
|
const parseSource = sourceParser({ startLine });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Spec, Line } from '../../primitives';
|
|
2
|
-
import { splitSpace, isSpace
|
|
2
|
+
import { splitSpace, isSpace } from '../../util';
|
|
3
3
|
import { Tokenizer } from './index';
|
|
4
4
|
|
|
5
5
|
const isQuoted = (s: string) => s && s.startsWith('"') && s.endsWith('"');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Spec,
|
|
1
|
+
import { Spec, Tokens } from '../../primitives';
|
|
2
2
|
import { splitSpace } from '../../util';
|
|
3
3
|
import { Tokenizer } from './index';
|
|
4
4
|
|
|
@@ -71,7 +71,7 @@ export default function typeTokenizer(spacing: Spacing = 'compact'): Tokenizer {
|
|
|
71
71
|
tokens.postDelimiter = tokens.postDelimiter.slice(0, offset);
|
|
72
72
|
}
|
|
73
73
|
[tokens.postType, tokens.description] = splitSpace(
|
|
74
|
-
tokens.description.slice(
|
|
74
|
+
tokens.description.slice(type.length)
|
|
75
75
|
);
|
|
76
76
|
parts.push(tokens.type);
|
|
77
77
|
}
|
package/src/stringifier/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Block, Tokens } from '../primitives';
|
|
2
2
|
|
|
3
|
+
export type Stringifier = (block: Block) => string;
|
|
4
|
+
|
|
3
5
|
function join(tokens: Tokens): string {
|
|
4
6
|
return (
|
|
5
7
|
tokens.start +
|
|
@@ -16,7 +18,7 @@ function join(tokens: Tokens): string {
|
|
|
16
18
|
);
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
export default function getStringifier() {
|
|
21
|
+
export default function getStringifier(): Stringifier {
|
|
20
22
|
return (block: Block): string =>
|
|
21
23
|
block.source.map(({ tokens }) => join(tokens)).join('\n');
|
|
22
24
|
}
|
package/src/transforms/align.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transform } from './index';
|
|
2
|
-
import { Markers,
|
|
2
|
+
import { Markers, Block, Line } from '../primitives';
|
|
3
3
|
import { rewireSource } from '../util';
|
|
4
4
|
|
|
5
5
|
interface Width {
|
|
@@ -23,15 +23,6 @@ const getWidth = (w: Width, { tokens: t }: Line) => ({
|
|
|
23
23
|
name: Math.max(w.name, t.name.length),
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
// /**
|
|
27
|
-
// * Description may go
|
|
28
|
-
// * over multiple lines followed by @tags
|
|
29
|
-
// *
|
|
30
|
-
//* @my-tag {my.type} my-name description line 1
|
|
31
|
-
// description line 2
|
|
32
|
-
// * description line 3
|
|
33
|
-
// */
|
|
34
|
-
|
|
35
26
|
const space = (len: number) => ''.padStart(len, ' ');
|
|
36
27
|
|
|
37
28
|
export default function align(): Transform {
|
|
@@ -62,15 +53,49 @@ export default function align(): Transform {
|
|
|
62
53
|
tokens.start = space(w.start + 1);
|
|
63
54
|
break;
|
|
64
55
|
default:
|
|
65
|
-
tokens.start = space(w.start + 3);
|
|
66
56
|
tokens.delimiter = '';
|
|
57
|
+
tokens.start = space(w.start + 2); // compensate delimiter
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!intoTags) {
|
|
61
|
+
tokens.postDelimiter = tokens.description === '' ? '' : ' ';
|
|
62
|
+
return { ...line, tokens };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const nothingAfter = {
|
|
66
|
+
delim: false,
|
|
67
|
+
tag: false,
|
|
68
|
+
type: false,
|
|
69
|
+
name: false,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (tokens.description === '') {
|
|
73
|
+
nothingAfter.name = true;
|
|
74
|
+
tokens.postName = '';
|
|
75
|
+
|
|
76
|
+
if (tokens.name === '') {
|
|
77
|
+
nothingAfter.type = true;
|
|
78
|
+
tokens.postType = '';
|
|
79
|
+
|
|
80
|
+
if (tokens.type === '') {
|
|
81
|
+
nothingAfter.tag = true;
|
|
82
|
+
tokens.postTag = '';
|
|
83
|
+
|
|
84
|
+
if (tokens.tag === '') {
|
|
85
|
+
nothingAfter.delim = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
67
89
|
}
|
|
68
90
|
|
|
69
|
-
|
|
91
|
+
tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
|
|
92
|
+
|
|
93
|
+
if (!nothingAfter.tag)
|
|
70
94
|
tokens.postTag = space(w.tag - tokens.tag.length + 1);
|
|
95
|
+
if (!nothingAfter.type)
|
|
71
96
|
tokens.postType = space(w.type - tokens.type.length + 1);
|
|
97
|
+
if (!nothingAfter.name)
|
|
72
98
|
tokens.postName = space(w.name - tokens.name.length + 1);
|
|
73
|
-
}
|
|
74
99
|
|
|
75
100
|
return { ...line, tokens };
|
|
76
101
|
}
|
package/src/transforms/indent.ts
CHANGED
|
@@ -9,7 +9,7 @@ const push = (offset: number) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export default function indent(pos: number): Transform {
|
|
12
|
-
let shift: (string) => string;
|
|
12
|
+
let shift: (string: string) => string;
|
|
13
13
|
const pad = (start: string) => {
|
|
14
14
|
if (shift === undefined) {
|
|
15
15
|
const offset = pos - start.length;
|
package/src/transforms/index.ts
CHANGED
package/tests/e2e/examples.js
CHANGED
|
@@ -161,9 +161,9 @@ function parse_source_exploration(source, parse, stringify, transforms) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
function parse_advanced_parsing(source, parse, _, _, tokenizers) {
|
|
164
|
-
// Each '@tag ...' section results into Spec. Spec is computed by
|
|
165
|
-
// the chain of tokenizers each contributing change to the Spec.* and Spec.tags[].tokens.
|
|
166
|
-
// Default parse() options come with stadart tokenizers
|
|
164
|
+
// Each '@tag ...' section results into a Spec. The Spec is computed by
|
|
165
|
+
// the chain of tokenizers each contributing a change to the the Spec.* and the Spec.tags[].tokens.
|
|
166
|
+
// Default parse() options come with stadart tokenizers:
|
|
167
167
|
// {
|
|
168
168
|
// ...,
|
|
169
169
|
// spacing = 'compact',
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const {
|
|
2
|
+
parse,
|
|
3
|
+
stringify,
|
|
4
|
+
transforms: { align },
|
|
5
|
+
} = require('../../lib');
|
|
6
|
+
|
|
7
|
+
test('align - ignore trailing right space', () => {
|
|
8
|
+
const source = `
|
|
9
|
+
/**
|
|
10
|
+
* Description may go
|
|
11
|
+
* over multiple lines followed by @tags
|
|
12
|
+
* @param {string} name
|
|
13
|
+
* @param {any} value the value parameter
|
|
14
|
+
*/`;
|
|
15
|
+
|
|
16
|
+
const expected = `
|
|
17
|
+
/**
|
|
18
|
+
* Description may go
|
|
19
|
+
* over multiple lines followed by @tags
|
|
20
|
+
* @param {string} name
|
|
21
|
+
* @param {any} value the value parameter
|
|
22
|
+
*/`.slice(1);
|
|
23
|
+
|
|
24
|
+
const parsed = parse(source);
|
|
25
|
+
const aligned = align()(parsed[0]);
|
|
26
|
+
const stringified = stringify(aligned);
|
|
27
|
+
|
|
28
|
+
expect(stringified).toEqual(expected);
|
|
29
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const {
|
|
2
|
+
parse,
|
|
3
|
+
stringify,
|
|
4
|
+
transforms: { align },
|
|
5
|
+
} = require('../../lib');
|
|
6
|
+
|
|
7
|
+
test('align - collapse postDelim', () => {
|
|
8
|
+
const source = `
|
|
9
|
+
/**
|
|
10
|
+
* Description may go
|
|
11
|
+
* over multiple lines followed by @tags
|
|
12
|
+
* @param {string} name the name parameter
|
|
13
|
+
* @param {any} value the value parameter
|
|
14
|
+
*/`.slice(1);
|
|
15
|
+
|
|
16
|
+
const expected = `
|
|
17
|
+
/**
|
|
18
|
+
* Description may go
|
|
19
|
+
* over multiple lines followed by @tags
|
|
20
|
+
* @param {string} name the name parameter
|
|
21
|
+
* @param {any} value the value parameter
|
|
22
|
+
*/`.slice(1);
|
|
23
|
+
|
|
24
|
+
const parsed = parse(source);
|
|
25
|
+
const aligned = align()(parsed[0]);
|
|
26
|
+
const stringified = stringify(aligned);
|
|
27
|
+
|
|
28
|
+
expect(stringified).toEqual(expected);
|
|
29
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const { parse, inspect } = require('../../lib');
|
|
2
|
+
|
|
3
|
+
test('name cut off', () => {
|
|
4
|
+
const source = `
|
|
5
|
+
/**
|
|
6
|
+
* @param {{includeWhiteSpace: (boolean|undefined),
|
|
7
|
+
* ignoreElementOrder: (boolean|undefined)}} [options] The options.
|
|
8
|
+
*/`.slice(1);
|
|
9
|
+
|
|
10
|
+
const tagSource = [
|
|
11
|
+
{
|
|
12
|
+
number: 1,
|
|
13
|
+
source: ' * @param {{includeWhiteSpace: (boolean|undefined),',
|
|
14
|
+
tokens: {
|
|
15
|
+
start: ' ',
|
|
16
|
+
delimiter: '*',
|
|
17
|
+
postDelimiter: ' ',
|
|
18
|
+
tag: '@param',
|
|
19
|
+
postTag: ' ',
|
|
20
|
+
type: '{{includeWhiteSpace: (boolean|undefined),',
|
|
21
|
+
postType: '',
|
|
22
|
+
name: '',
|
|
23
|
+
postName: '',
|
|
24
|
+
description: '',
|
|
25
|
+
end: '',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
number: 2,
|
|
30
|
+
source:
|
|
31
|
+
' * ignoreElementOrder: (boolean|undefined)}} [options] The options.',
|
|
32
|
+
tokens: {
|
|
33
|
+
start: ' ',
|
|
34
|
+
delimiter: '*',
|
|
35
|
+
postDelimiter: ' ',
|
|
36
|
+
tag: '',
|
|
37
|
+
postTag: '',
|
|
38
|
+
type: ' ignoreElementOrder: (boolean|undefined)}}',
|
|
39
|
+
postType: ' ',
|
|
40
|
+
name: '[options]',
|
|
41
|
+
postName: ' ',
|
|
42
|
+
description: 'The options.',
|
|
43
|
+
end: '',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
number: 3,
|
|
48
|
+
source: ' */',
|
|
49
|
+
tokens: {
|
|
50
|
+
start: ' ',
|
|
51
|
+
delimiter: '',
|
|
52
|
+
postDelimiter: '',
|
|
53
|
+
tag: '',
|
|
54
|
+
postTag: '',
|
|
55
|
+
type: '',
|
|
56
|
+
postType: '',
|
|
57
|
+
name: '',
|
|
58
|
+
postName: '',
|
|
59
|
+
description: '',
|
|
60
|
+
end: '*/',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const parsed = parse(source);
|
|
66
|
+
// console.log(inspect(parsed[0]));
|
|
67
|
+
|
|
68
|
+
expect(parsed[0]).toMatchObject({
|
|
69
|
+
problems: [],
|
|
70
|
+
tags: [
|
|
71
|
+
{
|
|
72
|
+
tag: 'param',
|
|
73
|
+
type:
|
|
74
|
+
'{includeWhiteSpace: (boolean|undefined),ignoreElementOrder: (boolean|undefined)}',
|
|
75
|
+
name: 'options',
|
|
76
|
+
optional: true,
|
|
77
|
+
description: 'The options.',
|
|
78
|
+
source: tagSource,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
source: [
|
|
82
|
+
{
|
|
83
|
+
number: 0,
|
|
84
|
+
source: ' /**',
|
|
85
|
+
tokens: {
|
|
86
|
+
start: ' ',
|
|
87
|
+
delimiter: '/**',
|
|
88
|
+
postDelimiter: '',
|
|
89
|
+
tag: '',
|
|
90
|
+
postTag: '',
|
|
91
|
+
type: '',
|
|
92
|
+
postType: '',
|
|
93
|
+
name: '',
|
|
94
|
+
postName: '',
|
|
95
|
+
description: '',
|
|
96
|
+
end: '',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
...tagSource,
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -137,7 +137,7 @@ test('omit', () => {
|
|
|
137
137
|
);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
test('multiline
|
|
140
|
+
test('multiline', () => {
|
|
141
141
|
const spec = seedSpec({
|
|
142
142
|
source: [
|
|
143
143
|
{
|
|
@@ -152,23 +152,16 @@ test('multiline - preserve', () => {
|
|
|
152
152
|
source: '...',
|
|
153
153
|
tokens: seedTokens({
|
|
154
154
|
postDelimiter: ' ',
|
|
155
|
-
description: 'number',
|
|
155
|
+
description: 'number)} function type',
|
|
156
156
|
}),
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
number: 3,
|
|
160
160
|
source: '...',
|
|
161
|
-
tokens: seedTokens({
|
|
162
|
-
description: ')} function type',
|
|
163
|
-
}),
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
number: 4,
|
|
167
|
-
source: '...',
|
|
168
161
|
tokens: seedTokens(),
|
|
169
162
|
},
|
|
170
163
|
{
|
|
171
|
-
number:
|
|
164
|
+
number: 4,
|
|
172
165
|
source: '...',
|
|
173
166
|
tokens: seedTokens({
|
|
174
167
|
end: '*/',
|
|
@@ -192,25 +185,18 @@ test('multiline - preserve', () => {
|
|
|
192
185
|
number: 2,
|
|
193
186
|
source: '...',
|
|
194
187
|
tokens: seedTokens({
|
|
195
|
-
type: ' number',
|
|
196
|
-
}),
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
number: 3,
|
|
200
|
-
source: '...',
|
|
201
|
-
tokens: seedTokens({
|
|
202
|
-
type: ')}',
|
|
188
|
+
type: ' number)}',
|
|
203
189
|
postType: ' ',
|
|
204
190
|
description: 'function type',
|
|
205
191
|
}),
|
|
206
192
|
},
|
|
207
193
|
{
|
|
208
|
-
number:
|
|
194
|
+
number: 3,
|
|
209
195
|
source: '...',
|
|
210
196
|
tokens: seedTokens(),
|
|
211
197
|
},
|
|
212
198
|
{
|
|
213
|
-
number:
|
|
199
|
+
number: 4,
|
|
214
200
|
source: '...',
|
|
215
201
|
tokens: seedTokens({
|
|
216
202
|
end: '*/',
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import align from '../../src/transforms/align';
|
|
2
|
-
import getParser from '../../src/parser/index';
|
|
3
|
-
import getStringifier from '../../src/stringifier/index';
|
|
2
|
+
import getParser, { Parser } from '../../src/parser/index';
|
|
3
|
+
import getStringifier, { Stringifier } from '../../src/stringifier/index';
|
|
4
|
+
|
|
5
|
+
let parse: Parser;
|
|
6
|
+
let stringify: Stringifier;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
parse = getParser();
|
|
10
|
+
stringify = getStringifier();
|
|
11
|
+
});
|
|
4
12
|
|
|
5
13
|
test('multiline', () => {
|
|
6
14
|
const source = `
|
|
@@ -23,18 +31,20 @@ test('multiline', () => {
|
|
|
23
31
|
* @another-tag {another-type} another-name description line 1
|
|
24
32
|
description line 2
|
|
25
33
|
* description line 3
|
|
26
|
-
|
|
34
|
+
*/`.slice(1);
|
|
27
35
|
|
|
28
|
-
const parsed =
|
|
29
|
-
const
|
|
36
|
+
const parsed = parse(source);
|
|
37
|
+
const aligned = align()(parsed[0]);
|
|
38
|
+
const out = stringify(aligned);
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
// console.log(inspect(aligned));
|
|
41
|
+
expect(out).toBe(expected);
|
|
32
42
|
});
|
|
33
43
|
|
|
34
44
|
test('one-liner', () => {
|
|
35
45
|
const source = ` /** @tag {type} name description */`;
|
|
36
|
-
const parsed =
|
|
37
|
-
const out =
|
|
46
|
+
const parsed = parse(source);
|
|
47
|
+
const out = stringify(align()(parsed[0]));
|
|
38
48
|
|
|
39
49
|
expect(out).toBe(source);
|
|
40
50
|
});
|
|
@@ -43,8 +53,8 @@ test('same line open', () => {
|
|
|
43
53
|
const source = `
|
|
44
54
|
/** @tag {type} name description
|
|
45
55
|
*/`.slice(1);
|
|
46
|
-
const parsed =
|
|
47
|
-
const out =
|
|
56
|
+
const parsed = parse(source);
|
|
57
|
+
const out = stringify(align()(parsed[0]));
|
|
48
58
|
|
|
49
59
|
expect(out).toBe(source);
|
|
50
60
|
});
|
|
@@ -52,22 +62,76 @@ test('same line open', () => {
|
|
|
52
62
|
test('same line close', () => {
|
|
53
63
|
const source = `
|
|
54
64
|
/**
|
|
65
|
+
* @tag {type} name description */`;
|
|
66
|
+
|
|
67
|
+
const expected = `
|
|
68
|
+
/**
|
|
55
69
|
* @tag {type} name description */`.slice(1);
|
|
56
|
-
const parsed = getParser()(source);
|
|
57
|
-
const out = getStringifier()(align()(parsed[0]));
|
|
58
70
|
|
|
59
|
-
|
|
71
|
+
const parsed = parse(source);
|
|
72
|
+
const aligned = align()(parsed[0]);
|
|
73
|
+
const out = stringify(aligned);
|
|
74
|
+
|
|
75
|
+
expect(out).toBe(expected);
|
|
60
76
|
});
|
|
61
77
|
|
|
62
78
|
test('spec source referencing', () => {
|
|
63
|
-
const parsed =
|
|
79
|
+
const parsed = parse(`/** @tag {type} name Description */`);
|
|
64
80
|
const block = align()(parsed[0]);
|
|
65
81
|
expect(block.tags[0].source[0] === block.source[0]).toBe(true);
|
|
66
82
|
});
|
|
67
83
|
|
|
68
84
|
test('block source clonning', () => {
|
|
69
|
-
const parsed =
|
|
85
|
+
const parsed = parse(`/** @tag {type} name Description */`);
|
|
70
86
|
const block = align()(parsed[0]);
|
|
71
87
|
parsed[0].source[0].tokens.description = 'test';
|
|
72
88
|
expect(block.source[0].tokens.description).toBe('Description ');
|
|
73
89
|
});
|
|
90
|
+
|
|
91
|
+
test('ignore right whitespace', () => {
|
|
92
|
+
const source = `
|
|
93
|
+
/**
|
|
94
|
+
* Description may go
|
|
95
|
+
* over multiple lines followed by @tags
|
|
96
|
+
* @param {string} name
|
|
97
|
+
* @param {any} value the value parameter
|
|
98
|
+
*/`.slice(1);
|
|
99
|
+
|
|
100
|
+
const expected = `
|
|
101
|
+
/**
|
|
102
|
+
* Description may go
|
|
103
|
+
* over multiple lines followed by @tags
|
|
104
|
+
* @param {string} name
|
|
105
|
+
* @param {any} value the value parameter
|
|
106
|
+
*/`.slice(1);
|
|
107
|
+
|
|
108
|
+
const parsed = parse(source);
|
|
109
|
+
const aligned = align()(parsed[0]);
|
|
110
|
+
const stringified = stringify(aligned);
|
|
111
|
+
|
|
112
|
+
expect(stringified).toEqual(expected);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('collapse postDelimiter', () => {
|
|
116
|
+
const source = `
|
|
117
|
+
/**
|
|
118
|
+
* Description may go
|
|
119
|
+
* over multiple lines followed by @tags
|
|
120
|
+
* @param {string} name the name parameter
|
|
121
|
+
* @param {any} value the value parameter
|
|
122
|
+
*/`.slice(1);
|
|
123
|
+
|
|
124
|
+
const expected = `
|
|
125
|
+
/**
|
|
126
|
+
* Description may go
|
|
127
|
+
* over multiple lines followed by @tags
|
|
128
|
+
* @param {string} name the name parameter
|
|
129
|
+
* @param {any} value the value parameter
|
|
130
|
+
*/`.slice(1);
|
|
131
|
+
|
|
132
|
+
const parsed = parse(source);
|
|
133
|
+
const aligned = align()(parsed[0]);
|
|
134
|
+
const stringified = stringify(aligned);
|
|
135
|
+
|
|
136
|
+
expect(stringified).toEqual(expected);
|
|
137
|
+
});
|
package/tsconfig.node.json
CHANGED