diff --git a/lib/node-utils.js b/lib/node-utils.js index 928ff14..2501507 100644 --- a/lib/node-utils.js +++ b/lib/node-utils.js @@ -185,7 +185,9 @@ module.exports = { convertTokens, getNodeContainer, isWithinTypeAnnotation, - isTypeKeyword + isTypeKeyword, + isComment, + isJSDocComment }; /* eslint-enable no-use-before-define */ @@ -244,6 +246,24 @@ function isComma(token) { return token.kind === SyntaxKind.CommaToken; } +/** + * Returns true if the given TSNode is a comment + * @param {TSNode} node the TypeScript node + * @returns {boolean} is commment + */ +function isComment(node) { + return node.kind === SyntaxKind.SingleLineCommentTrivia || node.kind === SyntaxKind.MultiLineCommentTrivia; +} + +/** + * Returns true if the given TSNode is a JSDoc comment + * @param {TSNode} node the TypeScript node + * @returns {boolean} is JSDoc comment + */ +function isJSDocComment(node) { + return node.kind === SyntaxKind.JSDocComment; +} + /** * Returns the binary expression type of the given TSToken * @param {TSToken} operator the operator token @@ -256,7 +276,6 @@ function getBinaryExpressionType(operator) { return "LogicalExpression"; } return "BinaryExpression"; - } /** @@ -693,6 +712,12 @@ function convertTokens(ast) { * @returns {undefined} */ function walk(node) { + // TypeScript generates tokens for types in JSDoc blocks. Comment tokens + // and their children should not be walked or added to the resulting tokens list. + if (isComment(node) || isJSDocComment(node)) { + return; + } + if (isToken(node) && node.kind !== SyntaxKind.EndOfFileToken) { const converted = convertToken(node, ast); diff --git a/tests/fixtures/comments/jsdoc-comment.src.js b/tests/fixtures/comments/jsdoc-comment.src.js new file mode 100644 index 0000000..29298a1 --- /dev/null +++ b/tests/fixtures/comments/jsdoc-comment.src.js @@ -0,0 +1,8 @@ +/** + * This is a function. + * @param {String} bar some string + * @returns {String} returns bar + */ +function foo(bar) { + return bar; +} diff --git a/tests/integration/external-fixtures/jsdoc-indent.js b/tests/integration/external-fixtures/jsdoc-indent.js index 25641d5..c402637 100644 --- a/tests/integration/external-fixtures/jsdoc-indent.js +++ b/tests/integration/external-fixtures/jsdoc-indent.js @@ -9,4 +9,13 @@ foo; /** * a */ -foo; \ No newline at end of file +foo; + +/** + * This is a function. + * @param {String} bar some string + * @returns {String} returns bar + */ +function foo(bar) { + return bar; +} diff --git a/tests/integration/typescript.spec.js b/tests/integration/typescript.spec.js index 6a83a13..c2a6f80 100644 --- a/tests/integration/typescript.spec.js +++ b/tests/integration/typescript.spec.js @@ -80,7 +80,7 @@ describe("TypeScript", () => { ); }); - it("should not produce any lint errors on valid JSDoc indentation (#344)", () => { + it("should not produce any lint errors on valid JSDoc indentation (#344 & #422)", () => { verifyAndAssertMessages( loadExternalFixture("jsdoc-indent"), { diff --git a/tests/lib/__snapshots__/comments.js.snap b/tests/lib/__snapshots__/comments.js.snap index 72ee0ac..41309c3 100644 --- a/tests/lib/__snapshots__/comments.js.snap +++ b/tests/lib/__snapshots__/comments.js.snap @@ -830,6 +830,347 @@ Object { } `; +exports[`Comments fixtures/jsdoc-comment.src 1`] = ` +Object { + "body": Array [ + Object { + "async": false, + "body": Object { + "body": Array [ + Object { + "argument": Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 7, + }, + "start": Object { + "column": 11, + "line": 7, + }, + }, + "name": "bar", + "range": Array [ + 130, + 133, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 15, + "line": 7, + }, + "start": Object { + "column": 4, + "line": 7, + }, + }, + "range": Array [ + 123, + 134, + ], + "type": "ReturnStatement", + }, + ], + "loc": Object { + "end": Object { + "column": 1, + "line": 8, + }, + "start": Object { + "column": 18, + "line": 6, + }, + }, + "range": Array [ + 117, + 136, + ], + "type": "BlockStatement", + }, + "expression": false, + "generator": false, + "id": Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 6, + }, + "start": Object { + "column": 9, + "line": 6, + }, + }, + "name": "foo", + "range": Array [ + 108, + 111, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 8, + }, + "start": Object { + "column": 0, + "line": 6, + }, + }, + "params": Array [ + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 6, + }, + "start": Object { + "column": 13, + "line": 6, + }, + }, + "name": "bar", + "range": Array [ + 112, + 115, + ], + "type": "Identifier", + }, + ], + "range": Array [ + 99, + 136, + ], + "type": "FunctionDeclaration", + }, + ], + "comments": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 98, + ], + "type": "Block", + "value": "* + * This is a function. + * @param {String} bar some string + * @returns {String} returns bar + ", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 9, + }, + "start": Object { + "column": 0, + "line": 6, + }, + }, + "range": Array [ + 99, + 137, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 6, + }, + "start": Object { + "column": 0, + "line": 6, + }, + }, + "range": Array [ + 99, + 107, + ], + "type": "Keyword", + "value": "function", + }, + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 6, + }, + "start": Object { + "column": 9, + "line": 6, + }, + }, + "range": Array [ + 108, + 111, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 6, + }, + "start": Object { + "column": 12, + "line": 6, + }, + }, + "range": Array [ + 111, + 112, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 6, + }, + "start": Object { + "column": 13, + "line": 6, + }, + }, + "range": Array [ + 112, + 115, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 6, + }, + "start": Object { + "column": 16, + "line": 6, + }, + }, + "range": Array [ + 115, + 116, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 6, + }, + "start": Object { + "column": 18, + "line": 6, + }, + }, + "range": Array [ + 117, + 118, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 7, + }, + "start": Object { + "column": 4, + "line": 7, + }, + }, + "range": Array [ + 123, + 129, + ], + "type": "Keyword", + "value": "return", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 7, + }, + "start": Object { + "column": 11, + "line": 7, + }, + }, + "range": Array [ + 130, + 133, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 7, + }, + "start": Object { + "column": 14, + "line": 7, + }, + }, + "range": Array [ + 133, + 134, + ], + "type": "Punctuator", + "value": ";", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 8, + }, + "start": Object { + "column": 0, + "line": 8, + }, + }, + "range": Array [ + 135, + 136, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + exports[`Comments fixtures/jsx-block-comment.src 1`] = ` Object { "body": Array [