From cc511819276dd924e1c9fadc2461be32ef615e47 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Sun, 5 Nov 2023 00:28:51 +0100 Subject: [PATCH] feat!: Remove `SourceCode#getComments()` Fixes #14744 --- docs/src/extend/custom-rules.md | 1 - lib/rule-tester/flat-rule-tester.js | 15 +- lib/rule-tester/rule-tester.js | 15 +- lib/source-code/source-code.js | 78 -- tests/lib/rule-tester/flat-rule-tester.js | 33 - tests/lib/rule-tester/rule-tester.js | 34 - tests/lib/source-code/source-code.js | 838 ---------------------- 7 files changed, 2 insertions(+), 1012 deletions(-) diff --git a/docs/src/extend/custom-rules.md b/docs/src/extend/custom-rules.md index 35df20541b6..910af97b273 100644 --- a/docs/src/extend/custom-rules.md +++ b/docs/src/extend/custom-rules.md @@ -872,7 +872,6 @@ ESLint analyzes code paths while traversing AST. You can access code path object Please note that the following `SourceCode` methods have been deprecated and will be removed in a future version of ESLint: -* `getComments()`: Replaced by `SourceCode#getCommentsBefore()`, `SourceCode#getCommentsAfter()`, and `SourceCode#getCommentsInside()`. * `getTokenOrCommentBefore()`: Replaced by `SourceCode#getTokenBefore()` with the `{ includeComments: true }` option. * `getTokenOrCommentAfter()`: Replaced by `SourceCode#getTokenAfter()` with the `{ includeComments: true }` option. * `isSpaceBetweenTokens()`: Replaced by `SourceCode#isSpaceBetween()` diff --git a/lib/rule-tester/flat-rule-tester.js b/lib/rule-tester/flat-rule-tester.js index 51cb73b5f80..01163c48e4d 100644 --- a/lib/rule-tester/flat-rule-tester.js +++ b/lib/rule-tester/flat-rule-tester.js @@ -274,17 +274,6 @@ function wrapParser(parser) { }; } -/** - * Function to replace `SourceCode.prototype.getComments`. - * @returns {void} - * @throws {Error} Deprecation message. - */ -function getCommentsDeprecation() { - throw new Error( - "`SourceCode#getComments()` is deprecated and will be removed in a future major version. Use `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()` instead." - ); -} - /** * Emit a deprecation warning if rule uses CodePath#currentSegments. * @param {string} ruleName Name of the rule. @@ -727,12 +716,11 @@ class FlatRuleTester { } // Verify the code. - const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype; + const { applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype; const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments"); let messages; try { - SourceCode.prototype.getComments = getCommentsDeprecation; Object.defineProperty(CodePath.prototype, "currentSegments", { get() { emitCodePathCurrentSegmentsWarning(ruleName); @@ -746,7 +734,6 @@ class FlatRuleTester { messages = linter.verify(code, configs, filename); } finally { - SourceCode.prototype.getComments = getComments; Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments); SourceCode.prototype.applyInlineConfig = applyInlineConfig; SourceCode.prototype.applyLanguageOptions = applyLanguageOptions; diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js index 3bc80ab1837..e21423bbcfd 100644 --- a/lib/rule-tester/rule-tester.js +++ b/lib/rule-tester/rule-tester.js @@ -330,17 +330,6 @@ function wrapParser(parser) { }; } -/** - * Function to replace `SourceCode.prototype.getComments`. - * @returns {void} - * @throws {Error} Deprecation message. - */ -function getCommentsDeprecation() { - throw new Error( - "`SourceCode#getComments()` is deprecated and will be removed in a future major version. Use `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()` instead." - ); -} - /** * Function to replace forbidden `SourceCode` methods. * @param {string} methodName The name of the method to forbid. @@ -812,12 +801,11 @@ class RuleTester { validate(config, "rule-tester", id => (id === ruleName ? rule : null)); // Verify the code. - const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype; + const { applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype; const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments"); let messages; try { - SourceCode.prototype.getComments = getCommentsDeprecation; Object.defineProperty(CodePath.prototype, "currentSegments", { get() { emitCodePathCurrentSegmentsWarning(ruleName); @@ -831,7 +819,6 @@ class RuleTester { messages = linter.verify(code, config, filename); } finally { - SourceCode.prototype.getComments = getComments; Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments); SourceCode.prototype.applyInlineConfig = applyInlineConfig; SourceCode.prototype.applyLanguageOptions = applyLanguageOptions; diff --git a/lib/source-code/source-code.js b/lib/source-code/source-code.js index 4bbd5ae3a5c..123169b121b 100644 --- a/lib/source-code/source-code.js +++ b/lib/source-code/source-code.js @@ -438,9 +438,6 @@ class SourceCode extends TokenStore { } this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1])); - // Cache for comments found using getComments(). - this._commentCache = new WeakMap(); - // don't allow further modification of this object Object.freeze(this); Object.freeze(this.lines); @@ -490,81 +487,6 @@ class SourceCode extends TokenStore { return this.ast.comments; } - /** - * Gets all comments for the given node. - * @param {ASTNode} node The AST node to get the comments for. - * @returns {Object} An object containing a leading and trailing array - * of comments indexed by their position. - * @public - * @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside(). - */ - getComments(node) { - if (this._commentCache.has(node)) { - return this._commentCache.get(node); - } - - const comments = { - leading: [], - trailing: [] - }; - - /* - * Return all comments as leading comments of the Program node when - * there is no executable code. - */ - if (node.type === "Program") { - if (node.body.length === 0) { - comments.leading = node.comments; - } - } else { - - /* - * Return comments as trailing comments of nodes that only contain - * comments (to mimic the comment attachment behavior present in Espree). - */ - if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 || - node.type === "ObjectExpression" && node.properties.length === 0 || - node.type === "ArrayExpression" && node.elements.length === 0 || - node.type === "SwitchStatement" && node.cases.length === 0 - ) { - comments.trailing = this.getTokens(node, { - includeComments: true, - filter: isCommentToken - }); - } - - /* - * Iterate over tokens before and after node and collect comment tokens. - * Do not include comments that exist outside of the parent node - * to avoid duplication. - */ - let currentToken = this.getTokenBefore(node, { includeComments: true }); - - while (currentToken && isCommentToken(currentToken)) { - if (node.parent && node.parent.type !== "Program" && (currentToken.start < node.parent.start)) { - break; - } - comments.leading.push(currentToken); - currentToken = this.getTokenBefore(currentToken, { includeComments: true }); - } - - comments.leading.reverse(); - - currentToken = this.getTokenAfter(node, { includeComments: true }); - - while (currentToken && isCommentToken(currentToken)) { - if (node.parent && node.parent.type !== "Program" && (currentToken.end > node.parent.end)) { - break; - } - comments.trailing.push(currentToken); - currentToken = this.getTokenAfter(currentToken, { includeComments: true }); - } - } - - this._commentCache.set(node, comments); - return comments; - } - /** * Retrieves the JSDoc comment for a given node. * @param {ASTNode} node The AST node to get the comment for. diff --git a/tests/lib/rule-tester/flat-rule-tester.js b/tests/lib/rule-tester/flat-rule-tester.js index 679a87b99da..6aa80d0291a 100644 --- a/tests/lib/rule-tester/flat-rule-tester.js +++ b/tests/lib/rule-tester/flat-rule-tester.js @@ -2665,39 +2665,6 @@ describe("FlatRuleTester", () => { }); - describe("SourceCode#getComments()", () => { - const useGetCommentsRule = { - create: context => ({ - Program(node) { - const sourceCode = context.sourceCode; - - sourceCode.getComments(node); - } - }) - }; - - it("should throw if called from a valid test case", () => { - assert.throws(() => { - ruleTester.run("use-get-comments", useGetCommentsRule, { - valid: [""], - invalid: [] - }); - }, /`SourceCode#getComments\(\)` is deprecated/u); - }); - - it("should throw if called from an invalid test case", () => { - assert.throws(() => { - ruleTester.run("use-get-comments", useGetCommentsRule, { - valid: [], - invalid: [{ - code: "", - errors: [{}] - }] - }); - }, /`SourceCode#getComments\(\)` is deprecated/u); - }); - }); - describe("SourceCode forbidden methods", () => { [ diff --git a/tests/lib/rule-tester/rule-tester.js b/tests/lib/rule-tester/rule-tester.js index a28b345501f..e21bf478a31 100644 --- a/tests/lib/rule-tester/rule-tester.js +++ b/tests/lib/rule-tester/rule-tester.js @@ -2895,40 +2895,6 @@ describe("RuleTester", () => { }); - describe("SourceCode#getComments()", () => { - const useGetCommentsRule = { - create: context => ({ - Program(node) { - const sourceCode = context.sourceCode; - - sourceCode.getComments(node); - } - }) - }; - - it("should throw if called from a valid test case", () => { - assert.throws(() => { - ruleTester.run("use-get-comments", useGetCommentsRule, { - valid: [""], - invalid: [] - }); - }, /`SourceCode#getComments\(\)` is deprecated/u); - }); - - it("should throw if called from an invalid test case", () => { - assert.throws(() => { - ruleTester.run("use-get-comments", useGetCommentsRule, { - valid: [], - invalid: [{ - code: "", - errors: [{}] - }] - }); - }, /`SourceCode#getComments\(\)` is deprecated/u); - }); - }); - - describe("SourceCode forbidden methods", () => { [ diff --git a/tests/lib/source-code/source-code.js b/tests/lib/source-code/source-code.js index 763db27bc46..0d5074cb55b 100644 --- a/tests/lib/source-code/source-code.js +++ b/tests/lib/source-code/source-code.js @@ -1053,844 +1053,6 @@ describe("SourceCode", () => { }); - describe("getComments()", () => { - const config = { rules: { checker: "error" }, parserOptions: { ecmaVersion: 6, sourceType: "module" } }; - let unusedAssertionFuncs; - - - beforeEach(() => { - unusedAssertionFuncs = new Set(); - }); - - /** - * Check comment count - * @param {int} leading Leading comment count - * @param {int} trailing Trailing comment count - * @returns {Function} function to execute - * @private - */ - function assertCommentCount(leading, trailing) { - - /** - * Asserts the comment count for a node - * @param {ASTNode} node the node being traversed - * @returns {void} - */ - function assertionFunc(node) { - unusedAssertionFuncs.delete(assertionFunc); - const sourceCode = linter.getSourceCode(); - const comments = sourceCode.getComments(node); - - assert.strictEqual(comments.leading.length, leading); - assert.strictEqual(comments.trailing.length, trailing); - } - unusedAssertionFuncs.add(assertionFunc); - return assertionFunc; - } - - afterEach(() => { - assert.strictEqual( - unusedAssertionFuncs.size, - 0, - "An assertion function was created with assertCommentCount, but the function was not called." - ); - }); - - it("should return comments around nodes", () => { - const code = [ - "// Leading comment for VariableDeclaration", - "var a = 42;", - "/* Trailing comment for VariableDeclaration */" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(1, 1), - VariableDeclarator: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments inside a block", () => { - const code = [ - "{", - " a();", - " // Trailing comment for ExpressionStatement", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 1), - CallExpression: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments within a conditional", () => { - const code = [ - "/* Leading comment for IfStatement */", - "if (/* Leading comment for Identifier */ a) {}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - IfStatement: assertCommentCount(1, 0), - Identifier: assertCommentCount(1, 0), - BlockStatement: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should not return comments within a previous node", () => { - const code = [ - "function a() {", - " var b = {", - " // Trailing comment for ObjectExpression", - " };", - " return b;", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(0, 0), - VariableDeclarator: assertCommentCount(0, 0), - ObjectExpression: assertCommentCount(0, 1), - ReturnStatement: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments only for children of parent node", () => { - const code = [ - "var foo = {", - " bar: 'bar'", - " // Trailing comment for Property", - "};", - "var baz;" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(0, 0), - VariableDeclarator: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - ObjectExpression: assertCommentCount(0, 0), - Property: assertCommentCount(0, 1), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments for an export default anonymous class", () => { - const code = [ - "/**", - " * Leading comment for ExportDefaultDeclaration", - " */", - "export default class {", - " /**", - " * Leading comment for MethodDefinition", - " */", - " method1(){", - " }", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ExportDefaultDeclaration: assertCommentCount(1, 0), - ClassDeclaration: assertCommentCount(0, 0), - ClassBody: assertCommentCount(0, 0), - MethodDefinition: assertCommentCount(1, 0), - Identifier: assertCommentCount(0, 0), - FunctionExpression: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return leading comments", () => { - const code = [ - "// Leading comment for first VariableDeclaration", - "var a;", - "// Leading comment for previous VariableDeclaration and trailing comment for next VariableDeclaration", - "var b;" - ].join("\n"); - let varDeclCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - - VariableDeclaration(node) { - if (varDeclCount === 0) { - assertCommentCount(1, 1)(node); - } else { - assertCommentCount(1, 0)(node); - } - varDeclCount++; - }, - - VariableDeclarator: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return shebang comments", () => { - const code = [ - "#!/usr/bin/env node", // Leading comment for following VariableDeclaration - "var a;", - "// Leading comment for previous VariableDeclaration and trailing comment for next VariableDeclaration", - "var b;" - ].join("\n"); - let varDeclCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - - VariableDeclaration(node) { - if (varDeclCount === 0) { - assertCommentCount(1, 1)(node); - } else { - assertCommentCount(1, 0)(node); - } - varDeclCount++; - }, - - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should include shebang comment when program only contains shebang", () => { - const code = "#!/usr/bin/env node"; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(1, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return mixture of line and block comments", () => { - const code = [ - "// Leading comment for VariableDeclaration", - "var zzz /* Trailing comment for Identifier */ = 777;", - "// Trailing comment for VariableDeclaration" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(1, 1), - VariableDeclarator: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 1), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments surrounding a call expression", () => { - const code = [ - "function a() {", - " /* Leading comment for ExpressionStatement */", - " foo();", - " /* Trailing comment for ExpressionStatement */", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(1, 1), - CallExpression: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments surrounding a debugger statement", () => { - const code = [ - "function a() {", - " /* Leading comment for DebuggerStatement */", - " debugger;", - " /* Trailing comment for DebuggerStatement */", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - DebuggerStatement: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments surrounding a return statement", () => { - const code = [ - "function a() {", - " /* Leading comment for ReturnStatement */", - " return;", - " /* Trailing comment for ReturnStatement */", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - ReturnStatement: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments surrounding a throw statement", () => { - const code = [ - "function a() {", - " /* Leading comment for ThrowStatement */", - " throw 55;", - " /* Trailing comment for ThrowStatement */", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - ThrowStatement: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments surrounding a while loop", () => { - const code = [ - "function f() {", - " /* Leading comment for WhileStatement */", - " while (true) {}", - " /* Trailing comment for WhileStatement and leading comment for VariableDeclaration */", - " var each;", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - WhileStatement: assertCommentCount(1, 1), - Literal: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(1, 0), - VariableDeclarator: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return switch case fallthrough comments in functions", () => { - const code = [ - "function bar(foo) {", - " switch(foo) {", - " /* Leading comment for SwitchCase */", - " case 1:", - " // falls through", // Trailing comment for previous SwitchCase and leading comment for next SwitchCase - " case 2:", - " doIt();", - " }", - "}" - ].join("\n"); - let switchCaseCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 0), - - SwitchCase(node) { - if (switchCaseCount === 0) { - assertCommentCount(1, 1)(node); - } else { - assertCommentCount(1, 0)(node); - } - switchCaseCount++; - }, - - Literal: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 0), - CallExpression: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return switch case fallthrough comments", () => { - const code = [ - "switch(foo) {", - " /* Leading comment for SwitchCase */", - "case 1:", - " // falls through", // Trailing comment for previous SwitchCase and leading comment for next SwitchCase - "case 2:", - " doIt();", - "}" - ].join("\n"); - let switchCaseCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 0), - - SwitchCase(node) { - if (switchCaseCount === 0) { - assertCommentCount(1, 1)(node); - } else { - assertCommentCount(1, 0)(node); - } - switchCaseCount++; - }, - - Literal: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 0), - CallExpression: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return switch case no-default comments in functions", () => { - const code = [ - "function bar(a) {", - " switch (a) {", - " case 2:", - " break;", - " case 1:", - " break;", - " // no default", // Trailing comment for SwitchCase - " }", - "}" - ].join("\n"); - let breakStatementCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 0), - - SwitchCase(node) { - if (breakStatementCount === 0) { - assertCommentCount(0, 0)(node); - } else { - assertCommentCount(0, 1)(node); - } - breakStatementCount++; - }, - - BreakStatement: assertCommentCount(0, 0), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return switch case no-default comments", () => { - const code = [ - "switch (a) {", - " case 1:", - " break;", - " // no default", // Trailing comment for SwitchCase - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - SwitchCase: assertCommentCount(0, 1), - BreakStatement: assertCommentCount(0, 0), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return switch case no-default comments in nested functions", () => { - const code = [ - "module.exports = function(context) {", - " function isConstant(node) {", - " switch (node.type) {", - " case 'SequenceExpression':", - " return isConstant(node.expressions[node.expressions.length - 1]);", - " // no default", // Trailing comment for SwitchCase - " }", - " return false;", - " }", - "};" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 0), - AssignmentExpression: assertCommentCount(0, 0), - MemberExpression: assertCommentCount(0, 0), - Identifier: assertCommentCount(0, 0), - FunctionExpression: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 0), - SwitchCase: assertCommentCount(0, 1), - ReturnStatement: assertCommentCount(0, 0), - CallExpression: assertCommentCount(0, 0), - BinaryExpression: assertCommentCount(0, 0), - Literal: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return leading comments if the code only contains comments", () => { - const code = [ - "//comment", - "/*another comment*/" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(2, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments if a block statement only contains comments", () => { - const code = [ - "{", - " //comment", - " /*another comment*/", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - BlockStatement: assertCommentCount(0, 2) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments if a class body only contains comments", () => { - const code = [ - "class Foo {", - " //comment", - " /*another comment*/", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ClassDeclaration: assertCommentCount(0, 0), - ClassBody: assertCommentCount(0, 2) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments if an object only contains comments", () => { - const code = [ - "({", - " //comment", - " /*another comment*/", - "})" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 0), - ObjectExpression: assertCommentCount(0, 2) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments if an array only contains comments", () => { - const code = [ - "[", - " //comment", - " /*another comment*/", - "]" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ExpressionStatement: assertCommentCount(0, 0), - ArrayExpression: assertCommentCount(0, 2) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return trailing comments if a switch statement only contains comments", () => { - const code = [ - "switch (foo) {", - " //comment", - " /*another comment*/", - "}" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(0, 2), - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments for multiple declarations with a single variable", () => { - const code = [ - "// Leading comment for VariableDeclaration", - "var a, // Leading comment for next VariableDeclarator", - " b, // Leading comment for next VariableDeclarator", - " c; // Trailing comment for VariableDeclaration", - "// Trailing comment for VariableDeclaration" - ].join("\n"); - let varDeclCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(1, 2), - - VariableDeclarator(node) { - if (varDeclCount === 0) { - assertCommentCount(0, 0)(node); - } else if (varDeclCount === 1) { - assertCommentCount(1, 0)(node); - } else { - assertCommentCount(1, 0)(node); - } - varDeclCount++; - }, - - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return comments when comments exist between var keyword and VariableDeclarator", () => { - const code = [ - "var // Leading comment for VariableDeclarator", - " // Leading comment for VariableDeclarator", - " a;" - ].join("\n"); - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - VariableDeclaration: assertCommentCount(0, 0), - VariableDeclarator: assertCommentCount(2, 0), - Identifier: assertCommentCount(0, 0) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return attached comments between tokens to the correct nodes for empty function declarations", () => { - const code = "/* 1 */ function /* 2 */ foo(/* 3 */) /* 4 */ { /* 5 */ } /* 6 */"; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - FunctionDeclaration: assertCommentCount(1, 1), - Identifier: assertCommentCount(1, 0), - BlockStatement: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return attached comments between tokens to the correct nodes for empty class declarations", () => { - const code = "/* 1 */ class /* 2 */ Foo /* 3 */ extends /* 4 */ Bar /* 5 */ { /* 6 */ } /* 7 */"; - let idCount = 0; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - ClassDeclaration: assertCommentCount(1, 1), - - Identifier(node) { - if (idCount === 0) { - assertCommentCount(1, 1)(node); - } else { - assertCommentCount(1, 1)(node); - } - idCount++; - }, - - ClassBody: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - - it("should return attached comments between tokens to the correct nodes for empty switch statements", () => { - const code = "/* 1 */ switch /* 2 */ (/* 3 */ foo /* 4 */) /* 5 */ { /* 6 */ } /* 7 */"; - - linter.defineRule("checker", { - create() { - return ({ - Program: assertCommentCount(0, 0), - SwitchStatement: assertCommentCount(1, 6), - Identifier: assertCommentCount(1, 1) - }); - } - }); - - assert.isEmpty(linter.verify(code, config)); - }); - }); - describe("getLines()", () => { it("should get proper lines when using \\n as a line break", () => {