eslint-plugin-crisp 1.6.6 → 1.7.0

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.
Files changed (54) hide show
  1. package/package.json +5 -5
  2. package/rules/align-comments.js +1 -1
  3. package/rules/align-consecutive-class-assignements.js +1 -1
  4. package/rules/align-one-var.js +1 -1
  5. package/rules/arrow-block-newline.js +1 -1
  6. package/rules/consecutive-line-comments.js +1 -1
  7. package/rules/const.js +1 -1
  8. package/rules/constructor-variables.js +1 -1
  9. package/rules/enforce-optional.js +1 -1
  10. package/rules/header-check.js +2 -2
  11. package/rules/header-comments-check.js +3 -36
  12. package/rules/import-group-comment.js +3 -3
  13. package/rules/import-group-order.js +1 -1
  14. package/rules/jsdoc-align-params.js +1 -1
  15. package/rules/jsdoc-check-indentation.js +1 -1
  16. package/rules/jsdoc-check-optional-params.js +4 -1
  17. package/rules/jsdoc-description-length.js +1 -1
  18. package/rules/jsdoc-description-multiline.js +1 -1
  19. package/rules/jsdoc-enforce-access.js +1 -1
  20. package/rules/jsdoc-enforce-classdesc.js +5 -1
  21. package/rules/jsdoc-no-param-return.js +1 -1
  22. package/rules/jsdoc-require-description-uppercase.js +1 -1
  23. package/rules/logger-arguments.js +1 -1
  24. package/rules/methods-naming.js +1 -1
  25. package/rules/methods-ordering.js +1 -1
  26. package/rules/multiline-comment-end-backslash.js +1 -1
  27. package/rules/newline-after-switch-case.js +4 -2
  28. package/rules/no-extra-line-within-function.js +1 -1
  29. package/rules/no-space-in-optional-arguments.js +1 -1
  30. package/rules/one-space-after-operator.js +1 -1
  31. package/rules/regex-in-constructor.js +1 -1
  32. package/rules/ternary-parenthesis.js +1 -1
  33. package/rules/two-lines-between-class-members.js +1 -1
  34. package/rules/utils/get-jsdoc-comment.js +72 -0
  35. package/rules/vue-attribute-comma.js +1 -1
  36. package/rules/vue-class-attribute-last.js +1 -1
  37. package/rules/vue-class-shorthand-max-len.js +1 -1
  38. package/rules/vue-computed-order.js +1 -1
  39. package/rules/vue-data-comment.js +1 -1
  40. package/rules/vue-define-component.js +2 -2
  41. package/rules/vue-emits-order.js +1 -1
  42. package/rules/vue-header-check.js +1 -1
  43. package/rules/vue-html-indent.js +1 -1
  44. package/rules/vue-html-quotes.js +1 -1
  45. package/rules/vue-methods-separator.js +1 -1
  46. package/rules/vue-no-component-class-shorthand.js +1 -1
  47. package/rules/vue-no-name-option.js +2 -2
  48. package/rules/vue-pinia-action-single-parameter.js +1 -1
  49. package/rules/vue-props-declaration-line-break.js +1 -1
  50. package/rules/vue-props-declaration-multiline.js +1 -1
  51. package/rules/vue-props-declaration-order.js +1 -1
  52. package/tests/rules/header-comments-check.test.js +6 -26
  53. package/tests/rules/jsdoc-check-optional-params.test.js +11 -0
  54. package/tests/rules/jsdoc-enforce-classdesc.test.js +11 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-crisp",
3
- "version": "1.6.6",
3
+ "version": "1.7.0",
4
4
  "description": "Custom ESLint Rules for Crisp",
5
5
  "author": "Crisp IM SAS",
6
6
  "main": "index.js",
@@ -17,20 +17,20 @@
17
17
  "test": "node --test"
18
18
  },
19
19
  "dependencies": {
20
- "@eslint/js": "9.39.5",
20
+ "@eslint/js": "10.0.1",
21
21
  "doctrine": "3.0.0",
22
- "eslint-plugin-jsdoc": "50.8.0",
22
+ "eslint-plugin-jsdoc": "65.4.0",
23
23
  "lodash-es": "4.18.1",
24
24
  "typescript": "5.9.3",
25
25
  "typescript-eslint": "8.72.0"
26
26
  },
27
27
  "devDependencies": {
28
- "eslint": "9.39.5",
28
+ "eslint": "10.13.0",
29
29
  "vue-eslint-parser": "10.4.1",
30
30
  "vue-eslint-parser-template-tokenizer-pug": "1.0.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "eslint": "^9.39.5",
33
+ "eslint": "^10.13.0",
34
34
  "eslint-plugin-vue": "^10.11.1",
35
35
  "eslint-plugin-vue-pug": "1.0.0-alpha.6",
36
36
  "globals": "15.15.0"
@@ -11,7 +11,7 @@ export default {
11
11
  },
12
12
 
13
13
  create(context) {
14
- const sourceCode = context.sourceCode || context.getSourceCode();
14
+ const sourceCode = context.sourceCode;
15
15
  const processedComments = new Set();
16
16
 
17
17
  function checkNode(node) {
@@ -11,7 +11,7 @@ export default {
11
11
  },
12
12
 
13
13
  create: function (context) {
14
- let sourceCode = context.getSourceCode();
14
+ let sourceCode = context.sourceCode;
15
15
  let currentBlock = [];
16
16
  let maxColumn = 0;
17
17
 
@@ -8,7 +8,7 @@ export default {
8
8
  },
9
9
  },
10
10
  create(context) {
11
- const sourceCode = context.getSourceCode();
11
+ const sourceCode = context.sourceCode;
12
12
 
13
13
  return {
14
14
  VariableDeclaration(node) {
@@ -15,7 +15,7 @@ export default {
15
15
  },
16
16
 
17
17
  create(context) {
18
- const sourceCode = context.sourceCode || context.getSourceCode();
18
+ const sourceCode = context.sourceCode;
19
19
 
20
20
  return {
21
21
  ArrowFunctionExpression(node) {
@@ -64,7 +64,7 @@ export default {
64
64
  },
65
65
 
66
66
  create(context) {
67
- const sourceCode = context.sourceCode || context.getSourceCode();
67
+ const sourceCode = context.sourceCode;
68
68
 
69
69
  function isStandalone(comment) {
70
70
  const lineText = sourceCode.lines[comment.loc.start.line - 1] || "";
package/rules/const.js CHANGED
@@ -50,7 +50,7 @@ export default {
50
50
  create(context) {
51
51
  const options = context.options[0] || {};
52
52
  const exceptions = options.exceptions || [];
53
- const sourceCode = context.sourceCode || context.getSourceCode();
53
+ const sourceCode = context.sourceCode;
54
54
 
55
55
  const isTopLevelCallArgument = (identifier) => {
56
56
  let scope = sourceCode.getScope(identifier);
@@ -25,7 +25,7 @@ export default {
25
25
 
26
26
  create(context) {
27
27
  const options = context.options[0] || {};
28
- const filename = context.filename || context.getFilename();
28
+ const filename = context.filename;
29
29
  const filenameExceptions = options.filenameExceptions || [];
30
30
  const variableExceptions = options.variableExceptions || [];
31
31
 
@@ -14,7 +14,7 @@ export default {
14
14
  },
15
15
 
16
16
  create(context) {
17
- const sourceCode = context.sourceCode || context.getSourceCode();
17
+ const sourceCode = context.sourceCode;
18
18
 
19
19
  const patterns = [
20
20
  // Search for `foo && foo.` or `foo && foo[`
@@ -27,8 +27,8 @@ export default {
27
27
  return {
28
28
  Program(node) {
29
29
  const options = context.options[0] || {};
30
- const fileName = context.getFilename();
31
- const sourceCode = context.sourceCode || context.getSourceCode();
30
+ const fileName = context.filename;
31
+ const sourceCode = context.sourceCode;
32
32
 
33
33
  let fileContent = sourceCode.getText().trim();
34
34
 
@@ -2,12 +2,6 @@ const COMMENT_HEADER_FORMAT = (section) => {
2
2
  return `/**************************************************************************\n * ${section.toUpperCase()}\n ***************************************************************************/`;
3
3
  };
4
4
 
5
- const HEADER_COMMENT_REGEX = /^\*+\n \* [A-Z][A-Z0-9 _:-]*\n \*+$/;
6
-
7
- function isHeaderComment(comment) {
8
- return comment.type === "Block" && HEADER_COMMENT_REGEX.test(comment.value);
9
- }
10
-
11
5
  function isTypeComment(comment) {
12
6
  if (comment.type !== "Block" || !comment.value.startsWith("*")) {
13
7
  return false;
@@ -115,11 +109,11 @@ export default {
115
109
  category: "Best Practices",
116
110
  recommended: false,
117
111
  },
118
- fixable: "whitespace",
112
+ fixable: null,
119
113
  },
120
114
 
121
115
  create(context) {
122
- const filename = context.filename || context.getFilename();
116
+ const filename = context.filename;
123
117
 
124
118
  if (!filename.endsWith(".js") && !filename.endsWith(".ts")) {
125
119
  return {};
@@ -128,7 +122,7 @@ export default {
128
122
  let lastNode = null;
129
123
  let groupStart = null;
130
124
 
131
- const sourceCode = context.sourceCode || context.getSourceCode();
125
+ const sourceCode = context.sourceCode;
132
126
  const allBlockComments = sourceCode.getAllComments()
133
127
  .filter(c => c.type === "Block")
134
128
  .sort((a, b) => a.range[0] - b.range[0]);
@@ -230,30 +224,6 @@ export default {
230
224
  }
231
225
  }
232
226
 
233
- // Checks that a header comment block is followed by a blank line
234
- function checkBlankLineAfterHeaders() {
235
- for (const comment of allBlockComments) {
236
- if (!isHeaderComment(comment)) {
237
- continue;
238
- }
239
-
240
- const next = sourceCode.getTokenAfter(comment, { includeComments: true });
241
-
242
- if (!next || next.loc.start.line - comment.loc.end.line >= 2) {
243
- continue;
244
- }
245
-
246
- const isOnNextLine = next.loc.start.line - comment.loc.end.line === 1;
247
-
248
- context.report({
249
- loc: comment.loc,
250
- message: "Header comment block must be followed by a blank line",
251
-
252
- fix: isOnNextLine ? (fixer) => fixer.insertTextAfter(comment, "\n") : null,
253
- });
254
- }
255
- }
256
-
257
227
  return {
258
228
  ":statement": (node) => {
259
229
  if (node.parent.type !== "Program") {
@@ -286,9 +256,6 @@ export default {
286
256
 
287
257
  // Check type comments group
288
258
  checkTypeCommentsGroup();
289
-
290
- // Check blank line after header comments
291
- checkBlankLineAfterHeaders();
292
259
  }
293
260
  };
294
261
  }
@@ -71,7 +71,7 @@ export default {
71
71
  },
72
72
 
73
73
  create(context) {
74
- const sourceCode = context.sourceCode || context.getSourceCode();
74
+ const sourceCode = context.sourceCode;
75
75
  const customGroups = context.options[0] || {}; // Get custom groups from options
76
76
 
77
77
  // Pre-compile custom regexes once instead of on every import
@@ -171,7 +171,7 @@ export default {
171
171
 
172
172
  function checkImportGroup(node) {
173
173
  const importPath = node.source.value;
174
- const filePath = context.getFilename();
174
+ const filePath = context.filename;
175
175
 
176
176
  // Get group from import path
177
177
  const expectedGroup = extractGroupFromPath(importPath, filePath);
@@ -201,7 +201,7 @@ export default {
201
201
  const typeComments = allComments.filter(c => isTypeComment(c));
202
202
 
203
203
  function checkTypeCommentsGroup() {
204
- const filename = context.getFilename();
204
+ const filename = context.filename;
205
205
 
206
206
  // Only check for // TYPES in .vue files (block header is checked by header-comments-check rule for .js/.ts)
207
207
  if (!filename.endsWith(".vue")) {
@@ -71,7 +71,7 @@ export default {
71
71
  }
72
72
 
73
73
  function updateAndCheckGroup(node) {
74
- const comments = context.getSourceCode().getCommentsBefore(node);
74
+ const comments = context.sourceCode.getCommentsBefore(node);
75
75
  for (let i = comments.length - 1; i >= 0; i--) {
76
76
  const comment = comments[i];
77
77
  if (isGroupComment(comment)) {
@@ -182,7 +182,7 @@ export default {
182
182
  create: function(context) {
183
183
  return {
184
184
  Program: function(node) {
185
- const comments = context.getSourceCode().getAllComments(node);
185
+ const comments = context.sourceCode.getAllComments(node);
186
186
 
187
187
  comments
188
188
  .filter(comment => comment.type === "Block" && comment.value.startsWith("*"))
@@ -43,7 +43,7 @@ const maskLineContinuations = (str) => {
43
43
  });
44
44
  }
45
45
 
46
- export default iterateJsdoc.default(({
46
+ export default iterateJsdoc(({
47
47
  sourceCode,
48
48
  jsdocNode,
49
49
  report,
@@ -1,4 +1,5 @@
1
1
  import doctrine from "doctrine";
2
+ import getJSDocComment from "./utils/get-jsdoc-comment.js";
2
3
 
3
4
  export default {
4
5
  meta: {
@@ -11,9 +12,11 @@ export default {
11
12
  },
12
13
 
13
14
  create(context) {
15
+ const sourceCode = context.sourceCode;
16
+
14
17
  function checkOptionalParams(node) {
15
18
  // Get JSDoc comments
16
- const jsDocComment = context.getSourceCode().getJSDocComment(node);
19
+ const jsDocComment = getJSDocComment(sourceCode, node);
17
20
 
18
21
  if (!jsDocComment) {
19
22
  return;
@@ -23,7 +23,7 @@ export default {
23
23
  create(context) {
24
24
  const options = context.options[0] || {};
25
25
  const maxLines = options.maxLines || 2;
26
- const sourceCode = context.sourceCode || context.getSourceCode();
26
+ const sourceCode = context.sourceCode;
27
27
 
28
28
  function checkComment(comment) {
29
29
  if (comment.type !== "Block" || !comment.value.startsWith("*")) {
@@ -1,6 +1,6 @@
1
1
  import iterateJsdoc from "eslint-plugin-jsdoc/iterateJsdoc.js";
2
2
 
3
- export default iterateJsdoc.default(({
3
+ export default iterateJsdoc(({
4
4
  context,
5
5
  indent,
6
6
  jsdocNode,
@@ -12,7 +12,7 @@ export default {
12
12
  },
13
13
 
14
14
  create: function(context) {
15
- const sourceCode = context.sourceCode || context.getSourceCode();
15
+ const sourceCode = context.sourceCode;
16
16
 
17
17
  function checkNodeForJSDoc(node) {
18
18
  const comments = sourceCode.getCommentsBefore(node);
@@ -1,3 +1,5 @@
1
+ import getJSDocComment from "./utils/get-jsdoc-comment.js";
2
+
1
3
  export default {
2
4
  meta: {
3
5
  type: "suggestion",
@@ -9,9 +11,11 @@ export default {
9
11
  },
10
12
 
11
13
  create(context) {
14
+ const sourceCode = context.sourceCode;
15
+
12
16
  return {
13
17
  ClassDeclaration(node) {
14
- const jsdoc = context.getSourceCode().getJSDocComment(node);
18
+ const jsdoc = getJSDocComment(sourceCode, node);
15
19
 
16
20
  if (jsdoc) {
17
21
  const hasClassdesc = /@classdesc/.test(jsdoc.value);
@@ -18,7 +18,7 @@ export default {
18
18
  },
19
19
 
20
20
  create(context) {
21
- const sourceCode = context.sourceCode || context.getSourceCode();
21
+ const sourceCode = context.sourceCode;
22
22
 
23
23
  function checkComment(comment) {
24
24
  if (comment.type !== "Block" || !comment.value.startsWith("*")) {
@@ -131,7 +131,7 @@ const validateDescription = (
131
131
  });
132
132
  };
133
133
 
134
- export default iterateJsdoc.default(({
134
+ export default iterateJsdoc(({
135
135
  sourceCode,
136
136
  context,
137
137
  jsdoc,
@@ -112,7 +112,7 @@ export default {
112
112
  },
113
113
 
114
114
  create(context) {
115
- const sourceCode = context.sourceCode || context.getSourceCode();
115
+ const sourceCode = context.sourceCode;
116
116
 
117
117
  return {
118
118
  CallExpression(node) {
@@ -12,7 +12,7 @@ export default {
12
12
  create: function(context) {
13
13
  return {
14
14
  MethodDefinition: function(node) {
15
- const sourceCode = context.getSourceCode();
15
+ const sourceCode = context.sourceCode;
16
16
  const commentsBefore = sourceCode.getCommentsBefore(node);
17
17
 
18
18
  const jsDocComment = commentsBefore.find(comment =>
@@ -6,7 +6,7 @@ const SECTION_COMMENT_PATTERN = /--> (.*) <--/;
6
6
  export default {
7
7
  create(context) {
8
8
  let methodOrder = []; // Keep track of method order
9
- const sourceCode = context.sourceCode || context.getSourceCode();
9
+ const sourceCode = context.sourceCode;
10
10
 
11
11
  return {
12
12
  MethodDefinition(node) {
@@ -12,7 +12,7 @@ export default {
12
12
  create(context) {
13
13
  return {
14
14
  Program() {
15
- const sourceCode = context.getSourceCode();
15
+ const sourceCode = context.sourceCode;
16
16
  const comments = sourceCode.getAllComments();
17
17
 
18
18
  let groupComments = [];
@@ -6,7 +6,9 @@ function getTokensWithNewlineBetween(sourceCode, startNode, endNode) {
6
6
 
7
7
  do {
8
8
  previous = next;
9
- next = sourceCode.getTokenOrCommentAfter(next);
9
+ next = sourceCode.getTokenAfter(next, {
10
+ includeComments: true
11
+ });
10
12
 
11
13
  if (next.loc.start.line > previous.loc.end.line + 1) {
12
14
  return [previous, next];
@@ -24,7 +26,7 @@ export default {
24
26
 
25
27
  create: function newlineBetweenSwitchCase(context) {
26
28
  let currentCodePath = null;
27
- const sourceCode = context.getSourceCode();
29
+ const sourceCode = context.sourceCode;
28
30
 
29
31
  return {
30
32
  onCodePathStart(codePath) {
@@ -9,7 +9,7 @@ export default {
9
9
  fixable: "whitespace",
10
10
  },
11
11
  create(context) {
12
- const sourceCode = context.getSourceCode();
12
+ const sourceCode = context.sourceCode;
13
13
 
14
14
  function checkFunctionBody(node) {
15
15
  const bodyNode = node.body;
@@ -4,7 +4,7 @@ export default {
4
4
  "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression, MethodDefinition": function(node) {
5
5
  (node.params || []).forEach(param => {
6
6
  if (param.type === "AssignmentPattern") {
7
- const sourceCode = context.sourceCode || context.getSourceCode();
7
+ const sourceCode = context.sourceCode;
8
8
  const operatorToken = sourceCode.getFirstTokenBetween(param.left, param.right, token => token.value === "=");
9
9
 
10
10
  if (
@@ -23,7 +23,7 @@ export default {
23
23
  ]
24
24
  },
25
25
  create(context) {
26
- const sourceCode = context.sourceCode || context.getSourceCode();
26
+ const sourceCode = context.sourceCode;
27
27
  const config = context.options[0] || {};
28
28
  const checkColon = config.checkColon !== false;
29
29
 
@@ -11,7 +11,7 @@ export default {
11
11
  create(context) {
12
12
  return {
13
13
  'MethodDefinition[kind!="constructor"] > FunctionExpression > BlockStatement': function(node) {
14
- const regexes = context.getSourceCode().getTokens(node).filter(token => token.type === "RegularExpression");
14
+ const regexes = context.sourceCode.getTokens(node).filter(token => token.type === "RegularExpression");
15
15
 
16
16
  if (regexes.length > 0) {
17
17
  context.report({
@@ -13,7 +13,7 @@ export default {
13
13
  return {
14
14
  ConditionalExpression(node) {
15
15
  if (node.test.type === "BinaryExpression" || node.test.type === "LogicalExpression") {
16
- const sourceCode = context.getSourceCode();
16
+ const sourceCode = context.sourceCode;
17
17
  const beforeOperatorToken = sourceCode.getTokenBefore(node.test);
18
18
  const afterOperatorToken = sourceCode.getTokenAfter(node.test);
19
19
 
@@ -10,7 +10,7 @@ export default {
10
10
  create(context) {
11
11
  return {
12
12
  MethodDefinition(node) {
13
- const sourceCode = context.getSourceCode();
13
+ const sourceCode = context.sourceCode;
14
14
  const lines = sourceCode.lines;
15
15
 
16
16
  const parent = node.parent;
@@ -0,0 +1,72 @@
1
+ function findJSDocComment(sourceCode, node) {
2
+ const comments = sourceCode.getCommentsBefore(node);
3
+ const comment = comments.at(-1);
4
+
5
+ if (
6
+ !comment ||
7
+ comment.type !== "Block" ||
8
+ !comment.value.startsWith("*") ||
9
+ node.loc.start.line - comment.loc.end.line > 1
10
+ ) {
11
+ return null;
12
+ }
13
+
14
+ const tokenBefore = sourceCode.getTokenBefore(node, {
15
+ includeComments: true
16
+ });
17
+
18
+ return tokenBefore === comment ? comment : null;
19
+ }
20
+
21
+ export default function getJSDocComment(sourceCode, node) {
22
+ let parent = node.parent;
23
+
24
+ switch (node.type) {
25
+ case "ClassDeclaration":
26
+ case "FunctionDeclaration":
27
+ if (
28
+ parent?.type === "ExportDefaultDeclaration" ||
29
+ parent?.type === "ExportNamedDeclaration"
30
+ ) {
31
+ return findJSDocComment(sourceCode, parent);
32
+ }
33
+
34
+ return findJSDocComment(sourceCode, node);
35
+
36
+ case "ClassExpression":
37
+ return findJSDocComment(sourceCode, parent.parent);
38
+
39
+ case "ArrowFunctionExpression":
40
+ case "FunctionExpression":
41
+ if (
42
+ parent.type !== "CallExpression" &&
43
+ parent.type !== "NewExpression"
44
+ ) {
45
+ while (
46
+ !sourceCode.getCommentsBefore(parent).length &&
47
+ !/Function/u.test(parent.type) &&
48
+ parent.type !== "MethodDefinition" &&
49
+ parent.type !== "Property"
50
+ ) {
51
+ parent = parent.parent;
52
+
53
+ if (!parent) {
54
+ break;
55
+ }
56
+ }
57
+
58
+ if (
59
+ parent &&
60
+ parent.type !== "FunctionDeclaration" &&
61
+ parent.type !== "Program"
62
+ ) {
63
+ return findJSDocComment(sourceCode, parent);
64
+ }
65
+ }
66
+
67
+ return findJSDocComment(sourceCode, node);
68
+
69
+ default:
70
+ return null;
71
+ }
72
+ }
@@ -15,7 +15,7 @@ export default {
15
15
  create(context) {
16
16
  return utils.default.defineTemplateBodyVisitor(context, {
17
17
  "VAttribute"(node) {
18
- const sourceCode = context.getSourceCode();
18
+ const sourceCode = context.sourceCode;
19
19
  const attributeText = sourceCode.getText(node);
20
20
  const attributeEndIndex = node.range[1];
21
21
  const nextChar = sourceCode.getText().slice(attributeEndIndex, attributeEndIndex + 1);
@@ -43,7 +43,7 @@ export default {
43
43
  },
44
44
 
45
45
  create(context) {
46
- const sourceCode = context.getSourceCode();
46
+ const sourceCode = context.sourceCode;
47
47
 
48
48
  // Reports attributes declared after the class attribute they should precede
49
49
  function reportAttributesAfter(attributes, classIndex, className, isMisplaced) {
@@ -38,7 +38,7 @@ export default {
38
38
  },
39
39
 
40
40
  create(context) {
41
- const sourceCode = context.getSourceCode();
41
+ const sourceCode = context.sourceCode;
42
42
  const maxLength = context.options[0]?.max ?? DEFAULT_MAX_LENGTH;
43
43
 
44
44
  return utils.default.defineTemplateBodyVisitor(context, {
@@ -29,7 +29,7 @@ export default {
29
29
  message: "Computed properties should be in alphabetical order.",
30
30
 
31
31
  fix(fixer) {
32
- const sourceCode = context.getSourceCode();
32
+ const sourceCode = context.sourceCode;
33
33
  const propertyText = sourceCode.getText(property);
34
34
  const nextPropertyText = sourceCode.getText(nextProperty);
35
35
 
@@ -22,7 +22,7 @@ export default {
22
22
  return;
23
23
  }
24
24
 
25
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = context.sourceCode;
26
26
  const comments = sourceCode.getCommentsInside(node);
27
27
 
28
28
  if (comments.length === 0) {
@@ -11,7 +11,7 @@ export default {
11
11
  },
12
12
 
13
13
  create(context) {
14
- const fileName = (context.filename || context.getFilename()).replace(/\\/g, "/");
14
+ const fileName = context.filename.replace(/\\/g, "/");
15
15
 
16
16
  if (fileName.endsWith("/index.js") || !isVueComponentOrMixin(fileName)) {
17
17
  return {};
@@ -68,7 +68,7 @@ function buildFixes(fixer, context, exportNode) {
68
68
  return null;
69
69
  }
70
70
 
71
- const sourceCode = context.sourceCode || context.getSourceCode();
71
+ const sourceCode = context.sourceCode;
72
72
  const importFix = buildDefineComponentImportFix(fixer, sourceCode);
73
73
 
74
74
  if (importFix === false) {
@@ -23,7 +23,7 @@ export default {
23
23
  message: "Emits should be in alphabetical order.",
24
24
 
25
25
  fix(fixer) {
26
- const sourceCode = context.getSourceCode();
26
+ const sourceCode = context.sourceCode;
27
27
  const elementText = sourceCode.getText(element);
28
28
  const nextElementText = sourceCode.getText(nextElement);
29
29
 
@@ -15,7 +15,7 @@ export default {
15
15
  create(context) {
16
16
  return {
17
17
  Program(node) {
18
- const fileName = context.physicalFilename || context.filename || context.getFilename();
18
+ const fileName = context.physicalFilename || context.filename;
19
19
 
20
20
  // Determine the file extension
21
21
  const fileExtension = path.extname(fileName);
@@ -12,7 +12,7 @@ export default {
12
12
  },
13
13
 
14
14
  create(context) {
15
- const sourceCode = context.getSourceCode()
15
+ const sourceCode = context.sourceCode
16
16
  const template = (
17
17
  sourceCode.parserServices.getTemplateBodyTokenStore &&
18
18
  sourceCode.parserServices.getTemplateBodyTokenStore()
@@ -26,7 +26,7 @@ export default {
26
26
  },
27
27
 
28
28
  create(context) {
29
- const sourceCode = context.getSourceCode()
29
+ const sourceCode = context.sourceCode
30
30
  const double = context.options[0] !== "single"
31
31
  const avoidEscape =
32
32
  context.options[1] && context.options[1].avoidEscape === true
@@ -22,7 +22,7 @@ export default {
22
22
  return;
23
23
  }
24
24
 
25
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = context.sourceCode;
26
26
  const comments = sourceCode.getCommentsInside(node);
27
27
 
28
28
  const hasSeparator = comments.some((comment) => {
@@ -24,7 +24,7 @@ export default {
24
24
  },
25
25
 
26
26
  create(context) {
27
- const sourceCode = context.getSourceCode();
27
+ const sourceCode = context.sourceCode;
28
28
 
29
29
  return utils.default.defineTemplateBodyVisitor(context, {
30
30
  VElement(node) {
@@ -11,7 +11,7 @@ export default {
11
11
  },
12
12
 
13
13
  create(context) {
14
- const fileName = (context.filename || context.getFilename()).replace(/\\/g, "/");
14
+ const fileName = context.filename.replace(/\\/g, "/");
15
15
 
16
16
  if (!fileName.endsWith(".vue")) {
17
17
  return {};
@@ -87,7 +87,7 @@ function isNameProperty(property) {
87
87
 
88
88
  // Removes a property and its adjacent comma
89
89
  function removeProperty(fixer, context, options, property) {
90
- const sourceCode = context.sourceCode || context.getSourceCode();
90
+ const sourceCode = context.sourceCode;
91
91
  const nextToken = sourceCode.getTokenAfter(property);
92
92
 
93
93
  if (nextToken?.value === ",") {
@@ -15,7 +15,7 @@ export default {
15
15
  },
16
16
 
17
17
  create(context) {
18
- const sourceCode = context.sourceCode || context.getSourceCode();
18
+ const sourceCode = context.sourceCode;
19
19
  const defineStoreImports = collectDefineStoreImports(sourceCode.ast);
20
20
 
21
21
  return {
@@ -11,7 +11,7 @@ export default {
11
11
  },
12
12
 
13
13
  create(context) {
14
- const sourceCode = context.getSourceCode();
14
+ const sourceCode = context.sourceCode;
15
15
 
16
16
  function checkPropDefinition(propNode) {
17
17
  const typeProperty = propNode.properties.find(p => p.key.name === "type");
@@ -25,7 +25,7 @@ export default {
25
25
  message: "Props should be declared in multiple lines.",
26
26
 
27
27
  fix(fixer) {
28
- const sourceCode = context.getSourceCode();
28
+ const sourceCode = context.sourceCode;
29
29
  const propText = sourceCode.getText(propDefinition);
30
30
 
31
31
  // Construct the multi-line version of the prop
@@ -23,7 +23,7 @@ export default {
23
23
  message: "Props should be in alphabetical order.",
24
24
 
25
25
  fix(fixer) {
26
- const sourceCode = context.getSourceCode();
26
+ const sourceCode = context.sourceCode;
27
27
  const propertyText = sourceCode.getText(property);
28
28
  const nextPropertyText = sourceCode.getText(nextProperty);
29
29
 
@@ -12,17 +12,17 @@ ruleTester.run("header-comments-check", rule, {
12
12
  valid: [
13
13
  {
14
14
  filename: "/project/src/example.js",
15
- code: `${header("IMPORTS")}\n\nimport value from "package";`
15
+ code: `${header("IMPORTS")}\nimport value from "package";`
16
16
  },
17
17
  {
18
18
  filename: "/project/src/example.ts",
19
- code: `${header("CONSTANTS")}\n\nconst MAX_RETRIES = 3;\n\n${header("INSTANCES")}\n\nconst pattern = /value/;`
19
+ code: `${header("CONSTANTS")}\nconst MAX_RETRIES = 3;\n\n${header("INSTANCES")}\nconst pattern = /value/;`
20
20
  },
21
21
  {
22
22
  filename: "/project/src/example.js",
23
23
  code:
24
- `${header("TYPES")}\n\n/** @typedef {string} Identifier */\n\n` +
25
- `${header("EXPORTS")}\n\nexport default {};`
24
+ `${header("TYPES")}\n/** @typedef {string} Identifier */\n\n` +
25
+ `${header("EXPORTS")}\nexport default {};`
26
26
  },
27
27
  {
28
28
  filename: "/project/src/example.js",
@@ -30,12 +30,12 @@ ruleTester.run("header-comments-check", rule, {
30
30
  },
31
31
  {
32
32
  filename: "/project/src/example.js",
33
- code: `${header("MIXIN TO MANAGE HANDOFF")}\n\nexport default {};`
33
+ code: `${header("MIXIN TO MANAGE HANDOFF")}\nexport default {};`
34
34
  },
35
35
  {
36
36
  filename: "/project/src/example.js",
37
37
  code:
38
- `${header("IMPORTS")}\n\nimport first from "first";\n` +
38
+ `${header("IMPORTS")}\nimport first from "first";\n` +
39
39
  "import second from \"second\";"
40
40
  },
41
41
  {
@@ -84,26 +84,6 @@ ruleTester.run("header-comments-check", rule, {
84
84
  message: "Type comments group must be preceded by a 'TYPES' comment block"
85
85
  }
86
86
  ]
87
- },
88
- {
89
- filename: "/project/src/example.js",
90
- code: `${header("CONSTANTS")}\nconst MAX_RETRIES = 3;`,
91
- output: `${header("CONSTANTS")}\n\nconst MAX_RETRIES = 3;`,
92
- errors: [
93
- {
94
- message: "Header comment block must be followed by a blank line"
95
- }
96
- ]
97
- },
98
- {
99
- filename: "/project/src/example.js",
100
- code: `${header("IMPORTS")}\n// NPM\nimport value from "package";`,
101
- output: `${header("IMPORTS")}\n\n// NPM\nimport value from "package";`,
102
- errors: [
103
- {
104
- message: "Header comment block must be followed by a blank line"
105
- }
106
- ]
107
87
  }
108
88
  ]
109
89
  });
@@ -6,8 +6,11 @@ const ruleTester = createRuleTester();
6
6
  ruleTester.run("jsdoc-check-optional-params", rule, {
7
7
  valid: [
8
8
  "/** @param {string} value */\nfunction required(value) {}",
9
+ "/** @param {string} value */\nexport function required(value) {}",
9
10
  "/** @param {string} [value] */\nfunction optional(value = \"default\") {}",
10
11
  "/** @param {number} [count=1] */\nconst optional = function(count = 1) {};",
12
+ "/* @param {string} value */\nfunction optional(value = \"default\") {}",
13
+ "/** @param {string} value */\nconst unrelated = true;\nfunction optional(value = \"default\") {}",
11
14
  "function undocumented(value) {}"
12
15
  ],
13
16
 
@@ -20,6 +23,14 @@ ruleTester.run("jsdoc-check-optional-params", rule, {
20
23
  }
21
24
  ]
22
25
  },
26
+ {
27
+ code: "/** @param {string} value */\nexport function optional(value = \"default\") {}",
28
+ errors: [
29
+ {
30
+ message: "Optional parameters in JSDoc should be surrounded by brackets"
31
+ }
32
+ ]
33
+ },
23
34
  {
24
35
  code: "/** @param {string} [value] */\nfunction required(value) {}",
25
36
  errors: [
@@ -6,7 +6,10 @@ const ruleTester = createRuleTester();
6
6
  ruleTester.run("jsdoc-enforce-classdesc", rule, {
7
7
  valid: [
8
8
  "/**\n * @classdesc Represents an example.\n */\nclass Example {}",
9
+ "/**\n * @classdesc Represents an example.\n */\nexport default class Example {}",
9
10
  "class Undocumented {}",
11
+ "/* Represents an example. */\nclass Example {}",
12
+ "/** Represents an unrelated value. */\nconst value = 1;\nclass Example {}",
10
13
  "/** A factory function. */\nfunction createExample() {}"
11
14
  ],
12
15
 
@@ -19,6 +22,14 @@ ruleTester.run("jsdoc-enforce-classdesc", rule, {
19
22
  }
20
23
  ]
21
24
  },
25
+ {
26
+ code: "/** Represents an example. */\nexport class Example {}",
27
+ errors: [
28
+ {
29
+ message: "JSDoc class header should include @classdesc"
30
+ }
31
+ ]
32
+ },
22
33
  {
23
34
  code: "/**\n * @classdesc\n */\nclass Example {}",
24
35
  errors: [