Skip to content

Commit

Permalink
fix: Fix converting single line JSDoc comment to AST
Browse files Browse the repository at this point in the history
  • Loading branch information
macku committed Jan 15, 2022
1 parent c0b0bd1 commit 011ddd2
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
node_modules
coverage
/.idea
59 changes: 41 additions & 18 deletions src/commentParserToESTree.js
Expand Up @@ -17,6 +17,25 @@ const stripEncapsulatingBrackets = (container, isArr) => {
).replace(/\}$/u, '');
};

const cleanUpLastTag = (lastTag, mode) => {
// Strip out `}` that encapsulates and is not part of
// the type
stripEncapsulatingBrackets(lastTag);
if (lastTag.typeLines.length) {
stripEncapsulatingBrackets(lastTag.typeLines, true);
}

// With even a multiline type now in full, add parsing
let parsedType = null;
try {
parsedType = jsdocTypePrattParse(lastTag.rawType, mode);
} catch {
// Ignore
}

lastTag.parsedType = parsedType;
};

const commentParserToESTree = (jsdoc, mode) => {
const {tokens: {
delimiter: delimiterRoot,
Expand All @@ -42,7 +61,13 @@ const commentParserToESTree = (jsdoc, mode) => {
const tags = [];
let lastDescriptionLine;
let lastTag = null;
jsdoc.source.slice(1).forEach((info, idx) => {

const isSingleLineBlock = Boolean(jsdoc.source.length === 1 &&
jsdoc.source[0].tokens.end);

const source = isSingleLineBlock ? jsdoc.source : jsdoc.source.slice(1);

source.forEach((info, idx) => {
const {tokens} = info;
const {
delimiter,
Expand All @@ -61,25 +86,12 @@ const commentParserToESTree = (jsdoc, mode) => {

// Clean-up with last tag before end or new tag
if (lastTag) {
// Strip out `}` that encapsulates and is not part of
// the type
stripEncapsulatingBrackets(lastTag);
if (lastTag.typeLines.length) {
stripEncapsulatingBrackets(lastTag.typeLines, true);
}

// With even a multiline type now in full, add parsing
let parsedType = null;
try {
parsedType = jsdocTypePrattParse(lastTag.rawType, mode);
} catch {
// Ignore
}

lastTag.parsedType = parsedType;
cleanUpLastTag(lastTag, mode);
}

if (end) {
// Stop the iteration when we reached the last tag
// but only in with multi-line block comment
if (end && !isSingleLineBlock) {
ast.end = end;

return;
Expand Down Expand Up @@ -131,6 +143,17 @@ const commentParserToESTree = (jsdoc, mode) => {
? '\n' + description
: description;
}

// Clean-up in single line mode
if (isSingleLineBlock) {
if (end) {
ast.end = end;
}

if (lastTag) {
cleanUpLastTag(lastTag, mode);
}
}
});

ast.lastDescriptionLine = lastDescriptionLine;
Expand Down
100 changes: 100 additions & 0 deletions test/commentParserToESTree.js
@@ -0,0 +1,100 @@
import {expect} from 'chai';

import {commentParserToESTree} from '../src/commentParserToESTree.js';
import {parseComment} from '../src/parseComment.js';

describe('commentParserToESTree', function () {
it('handles single line jsdoc comment with tag', () => {
const parsedComment = parseComment({
value: `* @type {string} `
});

const ast = commentParserToESTree(parsedComment, 'javascript');

expect(ast).to.deep.equal({
type: 'JsdocBlock',
delimiter: '/**',
description: '',
descriptionLines: [],
end: '*/',
lastDescriptionLine: 0,
lineEnd: '',
postDelimiter: ' ',
tags: [
{
delimiter: '/**',
description: '',
descriptionLines: [],
lineEnd: '',
name: '',
parsedType: null,
postDelimiter: ' ',
postName: '',
postTag: ' ',
postType: ' ',
tag: 'type',
type: 'JsdocTag',
rawType: 'string',
start: '',
typeLines: [
{
delimiter: '/**',
postDelimiter: ' ',
rawType: 'string',
start: '',
type: 'JsdocTypeLine'
}
]
}
]
});
});

it('handles multi line jsdoc comment with tag', () => {
const parsedComment = parseComment({
value: '*\n' +
' * @type {string}\n' +
' *'
});

const ast = commentParserToESTree(parsedComment, 'javascript');

expect(ast).to.deep.equal({
type: 'JsdocBlock',
delimiter: '/**',
description: '',
descriptionLines: [],
end: '*/',
lastDescriptionLine: 0,
lineEnd: '',
postDelimiter: '',
tags: [
{
delimiter: '*',
description: '',
descriptionLines: [],
lineEnd: '',
name: '',
parsedType: null,
postDelimiter: ' ',
postName: '',
postTag: ' ',
postType: '',
tag: 'type',
type: 'JsdocTag',
rawType: 'string',
start: ' ',
typeLines: [
{
delimiter: '*',
postDelimiter: ' ',
rawType: 'string',
start: ' ',
type: 'JsdocTypeLine'
}
]
}
]
});
});
});

0 comments on commit 011ddd2

Please sign in to comment.