eslint-plugin-traceability 1.21.0 → 1.22.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.
- package/CHANGELOG.md +7 -2
- package/README.md +6 -6
- package/lib/src/maintenance/batch.js +0 -1
- package/lib/src/maintenance/cli.js +8 -10
- package/lib/src/maintenance/commands.d.ts +2 -2
- package/lib/src/maintenance/commands.js +2 -2
- package/lib/src/maintenance/detect.js +7 -7
- package/lib/src/maintenance/report.js +2 -2
- package/lib/src/maintenance/storyParser.d.ts +16 -0
- package/lib/src/maintenance/storyParser.js +167 -0
- package/lib/src/rules/helpers/pattern-validators.d.ts +42 -0
- package/lib/src/rules/helpers/pattern-validators.js +65 -0
- package/lib/src/rules/helpers/prefer-implements-inline.d.ts +16 -0
- package/lib/src/rules/helpers/prefer-implements-inline.js +146 -0
- package/lib/src/rules/helpers/require-story-comment-detection.d.ts +47 -0
- package/lib/src/rules/helpers/require-story-comment-detection.js +141 -0
- package/lib/src/rules/helpers/require-story-core.d.ts +6 -6
- package/lib/src/rules/helpers/require-story-core.js +10 -10
- package/lib/src/rules/helpers/require-story-helpers.d.ts +5 -63
- package/lib/src/rules/helpers/require-story-helpers.js +29 -337
- package/lib/src/rules/helpers/require-story-io.js +1 -0
- package/lib/src/rules/helpers/require-story-name-extraction.d.ts +35 -0
- package/lib/src/rules/helpers/require-story-name-extraction.js +107 -0
- package/lib/src/rules/helpers/require-story-node-utils.d.ts +43 -0
- package/lib/src/rules/helpers/require-story-node-utils.js +115 -0
- package/lib/src/rules/helpers/require-test-traceability-helpers.js +1 -0
- package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +2 -2
- package/lib/src/rules/helpers/valid-annotation-format-internal.js +13 -5
- package/lib/src/rules/helpers/valid-annotation-format-validators.d.ts +14 -14
- package/lib/src/rules/helpers/valid-annotation-format-validators.js +31 -22
- package/lib/src/rules/helpers/valid-annotation-options.d.ts +0 -10
- package/lib/src/rules/helpers/valid-annotation-options.js +22 -92
- package/lib/src/rules/helpers/valid-annotation-utils.js +1 -0
- package/lib/src/rules/helpers/valid-req-reference-helpers.js +1 -1
- package/lib/src/rules/no-redundant-annotation.js +4 -238
- package/lib/src/rules/prefer-implements-annotation.d.ts +12 -0
- package/lib/src/rules/prefer-implements-annotation.js +9 -164
- package/lib/src/rules/require-traceability.d.ts +8 -0
- package/lib/src/rules/require-traceability.js +8 -0
- package/lib/src/rules/valid-annotation-format.js +14 -10
- package/lib/src/utils/annotation-checker.d.ts +3 -2
- package/lib/src/utils/annotation-checker.js +4 -2
- package/lib/src/utils/branch-annotation-catch-helpers.d.ts +22 -0
- package/lib/src/utils/branch-annotation-catch-helpers.js +70 -0
- package/lib/src/utils/branch-annotation-helpers.js +11 -187
- package/lib/src/utils/branch-annotation-if-helpers.d.ts +1 -0
- package/lib/src/utils/branch-annotation-if-helpers.js +59 -0
- package/lib/src/utils/branch-annotation-indent-helpers.d.ts +1 -1
- package/lib/src/utils/branch-annotation-switch-helpers.d.ts +8 -2
- package/lib/src/utils/branch-annotation-switch-helpers.js +10 -4
- package/lib/src/utils/branch-validation.d.ts +9 -0
- package/lib/src/utils/branch-validation.js +58 -0
- package/lib/src/utils/comment-text-helpers.d.ts +31 -0
- package/lib/src/utils/comment-text-helpers.js +54 -0
- package/lib/src/utils/redundancy-detector.d.ts +85 -0
- package/lib/src/utils/redundancy-detector.js +235 -0
- package/lib/src/utils/reqAnnotationDetection.js +1 -0
- package/lib/tests/config/eslint-config-validation.test.js +1 -0
- package/lib/tests/config/flat-config-presets-integration.test.js +1 -0
- package/lib/tests/config/require-story-annotation-config.test.js +1 -0
- package/lib/tests/fixtures/stale/example.js +1 -0
- package/lib/tests/fixtures/update/example.js +1 -0
- package/lib/tests/integration/annotation-placement-inside-prettier.integration.test.js +1 -0
- package/lib/tests/integration/catch-annotation-prettier.integration.test.js +1 -0
- package/lib/tests/integration/else-if-annotation-prettier.integration.test.js +1 -0
- package/lib/tests/integration/prettier-test-helpers.js +1 -0
- package/lib/tests/integration/require-traceability-test-callbacks.integration.test.js +1 -0
- package/lib/tests/maintenance/detect-isolated.test.js +1 -0
- package/lib/tests/maintenance/storyParser.test.d.ts +8 -0
- package/lib/tests/maintenance/storyParser.test.js +505 -0
- package/lib/tests/perf/maintenance-large-workspace.test.js +1 -0
- package/lib/tests/perf/valid-annotation-format-large-file.test.js +1 -0
- package/lib/tests/plugin-setup.test.js +1 -0
- package/lib/tests/rules/error-reporting.test.js +1 -0
- package/lib/tests/rules/no-redundant-annotation.test.js +1 -0
- package/lib/tests/rules/require-story-helpers.test.js +3 -2
- package/lib/tests/rules/require-test-traceability.test.js +1 -0
- package/lib/tests/rules/valid-req-reference.test.js +2 -0
- package/lib/tests/utils/branch-annotation-catch-insert-position.test.js +1 -0
- package/lib/tests/utils/branch-annotation-else-if-insert-position.test.js +1 -0
- package/lib/tests/utils/branch-annotation-helpers.test.js +1 -0
- package/package.json +18 -10
- package/user-docs/api-reference.md +2 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const annotation_scope_analyzer_1 = require("../utils/annotation-scope-analyzer");
|
|
3
|
+
const redundancy_detector_1 = require("../utils/redundancy-detector");
|
|
5
4
|
/**
|
|
6
5
|
* ESLint rule to detect redundant traceability annotations on statements
|
|
7
6
|
* that are already covered by their containing scope.
|
|
@@ -47,239 +46,6 @@ function normalizeOptions(raw) {
|
|
|
47
46
|
alwaysCovered,
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Collect comments around a scope node using JSDoc, leading comments,
|
|
52
|
-
* and any comments that appear immediately before the node.
|
|
53
|
-
*
|
|
54
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-SCOPE-ANALYSIS REQ-SCOPE-INHERITANCE
|
|
55
|
-
*/
|
|
56
|
-
function getScopeCommentsFromJSDocAndLeading(sourceCode, scopeNode) {
|
|
57
|
-
const comments = [];
|
|
58
|
-
const jsdoc = sourceCode.getJSDocComment
|
|
59
|
-
? sourceCode.getJSDocComment(scopeNode)
|
|
60
|
-
: null;
|
|
61
|
-
const before = sourceCode.getCommentsBefore
|
|
62
|
-
? sourceCode.getCommentsBefore(scopeNode) || []
|
|
63
|
-
: [];
|
|
64
|
-
if (jsdoc) {
|
|
65
|
-
comments.push(jsdoc);
|
|
66
|
-
}
|
|
67
|
-
if (Array.isArray(scopeNode.leadingComments)) {
|
|
68
|
-
comments.push(...scopeNode.leadingComments);
|
|
69
|
-
}
|
|
70
|
-
comments.push(...before);
|
|
71
|
-
return comments;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Compute the story/requirement pairs for annotations that apply to the
|
|
75
|
-
* given scope node.
|
|
76
|
-
*
|
|
77
|
-
* For branch scopes we reuse the same comment-gathering helper used by
|
|
78
|
-
* the require-branch-annotation rule so that REQ-SCOPE-INHERITANCE
|
|
79
|
-
* aligns with existing behavior. For non-branch scopes, we reuse a
|
|
80
|
-
* shared helper that collects JSDoc, leading, and immediately-before
|
|
81
|
-
* comments around the scope node.
|
|
82
|
-
*
|
|
83
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-SCOPE-ANALYSIS REQ-SCOPE-INHERITANCE
|
|
84
|
-
*/
|
|
85
|
-
function getScopePairs(context, scopeNode, parent) {
|
|
86
|
-
const sourceCode = context.getSourceCode();
|
|
87
|
-
// Branch-style scope: use the branch helpers to collect comment text.
|
|
88
|
-
if (branch_annotation_helpers_1.DEFAULT_BRANCH_TYPES.includes(scopeNode.type)) {
|
|
89
|
-
/**
|
|
90
|
-
* Inside-brace annotations used as branch-level indicators (inside placement
|
|
91
|
-
* mode) should not be folded into scopePairs for redundancy purposes; only
|
|
92
|
-
* before-brace annotations define the covering scope here.
|
|
93
|
-
*
|
|
94
|
-
* @supports docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md REQ-NON-REDUNDANT-INSIDE REQ-PLACEMENT-CONFIG
|
|
95
|
-
*/
|
|
96
|
-
const text = (0, branch_annotation_helpers_1.gatherBranchCommentText)(sourceCode, scopeNode, parent, "before");
|
|
97
|
-
return (0, annotation_scope_analyzer_1.extractStoryReqPairsFromText)(text);
|
|
98
|
-
}
|
|
99
|
-
const comments = getScopeCommentsFromJSDocAndLeading(sourceCode, scopeNode);
|
|
100
|
-
return (0, annotation_scope_analyzer_1.extractStoryReqPairsFromComments)(comments);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Collect the comments directly associated with a statement node.
|
|
104
|
-
*
|
|
105
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-STATEMENT-SIGNIFICANCE REQ-SCOPE-ANALYSIS
|
|
106
|
-
*/
|
|
107
|
-
function getStatementComments(context, node) {
|
|
108
|
-
const sourceCode = context.getSourceCode();
|
|
109
|
-
const comments = [];
|
|
110
|
-
if (sourceCode.getCommentsBefore) {
|
|
111
|
-
comments.push(...(sourceCode.getCommentsBefore(node) || []));
|
|
112
|
-
}
|
|
113
|
-
if (Array.isArray(node.leadingComments)) {
|
|
114
|
-
comments.push(...node.leadingComments);
|
|
115
|
-
}
|
|
116
|
-
return comments;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Debug helper for logging scope-level pairs in TRACEABILITY_DEBUG mode.
|
|
120
|
-
*
|
|
121
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-REDUNDANCY-PATTERNS
|
|
122
|
-
*/
|
|
123
|
-
function debugScopePairs(scopeNode, scopePairs) {
|
|
124
|
-
if (process.env.TRACEABILITY_DEBUG !== "1") {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
console.log("[no-redundant-annotation] Scope node type=%s pairs=%o", scopeNode && scopeNode.type, Array.from(scopePairs));
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Walk up enclosing scopes starting from the given scope node and
|
|
131
|
-
* accumulate all story/requirement pairs, limited by maxScopeDepth.
|
|
132
|
-
*
|
|
133
|
-
* This keeps REQ-SCOPE-INHERITANCE and REQ-CONFIGURABLE-STRICTNESS
|
|
134
|
-
* aligned with the story's configuration model while delegating the
|
|
135
|
-
* actual comment parsing to getScopePairs.
|
|
136
|
-
*
|
|
137
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-SCOPE-ANALYSIS REQ-SCOPE-INHERITANCE REQ-CONFIGURABLE-STRICTNESS
|
|
138
|
-
*/
|
|
139
|
-
function collectScopePairs(context, startingScopeNode, maxScopeDepth) {
|
|
140
|
-
const result = new Set();
|
|
141
|
-
if (!startingScopeNode || maxScopeDepth <= 0) {
|
|
142
|
-
return result;
|
|
143
|
-
}
|
|
144
|
-
let current = startingScopeNode;
|
|
145
|
-
let depth = 0;
|
|
146
|
-
while (current && depth < maxScopeDepth) {
|
|
147
|
-
const parent = current.parent;
|
|
148
|
-
const pairs = getScopePairs(context, current, parent);
|
|
149
|
-
for (const key of pairs) {
|
|
150
|
-
result.add(key);
|
|
151
|
-
}
|
|
152
|
-
current = parent;
|
|
153
|
-
depth += 1;
|
|
154
|
-
}
|
|
155
|
-
return result;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Extract statement-level comments and story/requirement pairs that are
|
|
159
|
-
* relevant for redundancy analysis within a given scope.
|
|
160
|
-
*
|
|
161
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-REDUNDANCY-PATTERNS REQ-STATEMENT-SIGNIFICANCE REQ-SCOPE-ANALYSIS
|
|
162
|
-
*/
|
|
163
|
-
function getStatementPairsForRedundancy(context, stmt, scopePairs, options) {
|
|
164
|
-
if (scopePairs.size === 0) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
if (!(0, annotation_scope_analyzer_1.isStatementEligibleForRedundancy)(stmt, options, branch_annotation_helpers_1.DEFAULT_BRANCH_TYPES)) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
const stmtComments = getStatementComments(context, stmt);
|
|
171
|
-
if (stmtComments.length === 0) {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
const stmtPairs = (0, annotation_scope_analyzer_1.extractStoryReqPairsFromComments)(stmtComments);
|
|
175
|
-
if (process.env.TRACEABILITY_DEBUG === "1") {
|
|
176
|
-
console.log("[no-redundant-annotation] Statement type=%s eligible=%s commentCount=%d pairs=%o", stmt && stmt.type, (0, annotation_scope_analyzer_1.isStatementEligibleForRedundancy)(stmt, options, branch_annotation_helpers_1.DEFAULT_BRANCH_TYPES), stmtComments.length, Array.from(stmtPairs));
|
|
177
|
-
}
|
|
178
|
-
if (stmtPairs.size === 0) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
return { comments: stmtComments, pairs: stmtPairs };
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Decide whether the provided statement-level pairs should be considered
|
|
185
|
-
* redundant within the given scope, respecting configuration options.
|
|
186
|
-
*
|
|
187
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-REDUNDANCY-PATTERNS REQ-SAFE-REMOVAL REQ-CONFIGURABLE-STRICTNESS
|
|
188
|
-
*/
|
|
189
|
-
function isStatementRedundantWithinScope(stmtPairs, scopePairs, options) {
|
|
190
|
-
if (options.allowEmphasisDuplication &&
|
|
191
|
-
stmtPairs.size === 1 &&
|
|
192
|
-
(0, annotation_scope_analyzer_1.arePairsFullyCovered)(stmtPairs, scopePairs)) {
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
if (!(0, annotation_scope_analyzer_1.arePairsFullyCovered)(stmtPairs, scopePairs)) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Filter a list of comments down to those that contain traceability
|
|
202
|
-
* annotations relevant for redundancy detection.
|
|
203
|
-
*
|
|
204
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-SAFE-REMOVAL REQ-REDUNDANCY-PATTERNS
|
|
205
|
-
*/
|
|
206
|
-
function getAnnotationCommentsFromStatement(comments) {
|
|
207
|
-
return comments.filter((comment) => {
|
|
208
|
-
const commentText = typeof comment.value === "string" ? comment.value : "";
|
|
209
|
-
return /@story\b|@req\b|@supports\b/.test(commentText);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Determine whether a statement is redundant relative to the provided
|
|
214
|
-
* scopePairs and options, using helper functions to gather statement
|
|
215
|
-
* pairs, apply redundancy rules, and collect the associated annotation
|
|
216
|
-
* comments. Returns null when the statement should not be treated as
|
|
217
|
-
* redundant.
|
|
218
|
-
*
|
|
219
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-REDUNDANCY-PATTERNS REQ-SAFE-REMOVAL REQ-STATEMENT-SIGNIFICANCE REQ-CONFIGURABLE-STRICTNESS
|
|
220
|
-
*/
|
|
221
|
-
function getRedundantStatementContext(context, stmt, scopePairs, options) {
|
|
222
|
-
const stmtInfo = getStatementPairsForRedundancy(context, stmt, scopePairs, options);
|
|
223
|
-
if (!stmtInfo) {
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
226
|
-
const { comments, pairs } = stmtInfo;
|
|
227
|
-
if (!isStatementRedundantWithinScope(pairs, scopePairs, options)) {
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
const annotationComments = getAnnotationCommentsFromStatement(comments);
|
|
231
|
-
if (annotationComments.length === 0) {
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
return { comments: annotationComments };
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Compute unique removal ranges for the given annotation comments.
|
|
238
|
-
*
|
|
239
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-SAFE-REMOVAL
|
|
240
|
-
*/
|
|
241
|
-
function getRemovalRangesForAnnotationComments(comments, sourceCode) {
|
|
242
|
-
const rangeMap = new Map();
|
|
243
|
-
for (const comment of comments) {
|
|
244
|
-
const [removalStart, removalEnd] = (0, annotation_scope_analyzer_1.getCommentRemovalRange)(comment, sourceCode);
|
|
245
|
-
const key = `${removalStart}:${removalEnd}`;
|
|
246
|
-
if (!rangeMap.has(key)) {
|
|
247
|
-
rangeMap.set(key, [removalStart, removalEnd]);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return Array.from(rangeMap.values()).sort((a, b) => b[0] - a[0]);
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Analyze a block's statements and report redundant traceability annotations.
|
|
254
|
-
*
|
|
255
|
-
* This helper encapsulates the iteration and reporting logic so that the
|
|
256
|
-
* BlockStatement visitor remains small and focused on scope setup.
|
|
257
|
-
*
|
|
258
|
-
* @supports docs/stories/027.0-DEV-REDUNDANT-ANNOTATION-DETECTION.story.md REQ-REDUNDANCY-PATTERNS REQ-SAFE-REMOVAL REQ-STATEMENT-SIGNIFICANCE
|
|
259
|
-
*/
|
|
260
|
-
function reportRedundantAnnotationsInBlock(context, blockNode, scopePairs, options) {
|
|
261
|
-
const statements = Array.isArray(blockNode.body) ? blockNode.body : [];
|
|
262
|
-
if (statements.length === 0 || scopePairs.size === 0)
|
|
263
|
-
return;
|
|
264
|
-
const sourceCode = context.getSourceCode();
|
|
265
|
-
for (const stmt of statements) {
|
|
266
|
-
const info = getRedundantStatementContext(context, stmt, scopePairs, options);
|
|
267
|
-
if (!info) {
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
const ranges = getRemovalRangesForAnnotationComments(info.comments, sourceCode);
|
|
271
|
-
if (ranges.length === 0) {
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
context.report({
|
|
275
|
-
node: stmt,
|
|
276
|
-
messageId: "redundantAnnotation",
|
|
277
|
-
fix(fixer) {
|
|
278
|
-
return ranges.map(([start, end]) => fixer.removeRange([start, end]));
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
49
|
const rule = {
|
|
284
50
|
meta: {
|
|
285
51
|
type: "suggestion",
|
|
@@ -337,11 +103,11 @@ const rule = {
|
|
|
337
103
|
if (parent && parent.type === "CatchClause") {
|
|
338
104
|
return;
|
|
339
105
|
}
|
|
340
|
-
const scopePairs = collectScopePairs(context, parent, options.maxScopeDepth);
|
|
341
|
-
debugScopePairs(parent, scopePairs);
|
|
106
|
+
const scopePairs = (0, redundancy_detector_1.collectScopePairs)(context, parent, options.maxScopeDepth);
|
|
107
|
+
(0, redundancy_detector_1.debugScopePairs)(parent, scopePairs);
|
|
342
108
|
if (scopePairs.size === 0)
|
|
343
109
|
return;
|
|
344
|
-
reportRedundantAnnotationsInBlock(context, node, scopePairs, options);
|
|
110
|
+
(0, redundancy_detector_1.reportRedundantAnnotationsInBlock)(context, node, scopePairs, options);
|
|
345
111
|
},
|
|
346
112
|
};
|
|
347
113
|
},
|
|
@@ -23,6 +23,18 @@
|
|
|
23
23
|
* @req REQ-AUTO-FIX - Provide safe, opt-in auto-fix for simple legacy patterns
|
|
24
24
|
*/
|
|
25
25
|
import type { Rule } from "eslint";
|
|
26
|
+
/**
|
|
27
|
+
* ESLint rule: prefer-implements-annotation
|
|
28
|
+
*
|
|
29
|
+
* Recommend migrating from legacy `@story` + `@req` annotations to the
|
|
30
|
+
* newer `@supports` format. This rule is **disabled by default** and
|
|
31
|
+
* is intended as an optional, opt-in migration aid.
|
|
32
|
+
*
|
|
33
|
+
* @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
|
|
34
|
+
* @req REQ-OPTIONAL-WARNING - Emit configurable recommendation diagnostics for legacy @story/@req usage
|
|
35
|
+
* @req REQ-MULTI-STORY-DETECT - Detect multi-story patterns that cannot be auto-fixed
|
|
36
|
+
* @req REQ-BACKWARD-COMP-VALIDATION - Keep legacy @story/@req annotations valid when the rule is disabled
|
|
37
|
+
*/
|
|
26
38
|
/**
|
|
27
39
|
* ESLint rule: prefer-implements-annotation
|
|
28
40
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const valid_annotation_format_internal_1 = require("./helpers/valid-annotation-format-internal");
|
|
4
|
+
const prefer_implements_inline_1 = require("./helpers/prefer-implements-inline");
|
|
4
5
|
// Maximum number of distinct @story paths allowed before treating as "multi-story".
|
|
5
6
|
// @req REQ-MULTI-STORY-DETECT - Centralized threshold constant for detecting multi-story patterns
|
|
6
7
|
const MULTI_STORY_THRESHOLD = 1;
|
|
@@ -223,173 +224,17 @@ function processBlockComment(comment, context) {
|
|
|
223
224
|
});
|
|
224
225
|
}
|
|
225
226
|
/**
|
|
226
|
-
*
|
|
227
|
-
* source text so that new inline annotations can be inserted with matching
|
|
228
|
-
* indentation and formatting.
|
|
229
|
-
*
|
|
230
|
-
* @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
|
|
231
|
-
* @req REQ-MIGRATE-INLINE
|
|
232
|
-
*/
|
|
233
|
-
function getLinePrefixFromText(fullText) {
|
|
234
|
-
const match = fullText.match(/^(\s*\/\/\s*)/);
|
|
235
|
-
return match ? match[1] : "";
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Attempt to construct an inline auto-fix that replaces a contiguous
|
|
239
|
-
* sequence of `@story` and `@req` line comments with a single `@supports`
|
|
240
|
-
* annotation while preserving the original comment prefix.
|
|
241
|
-
*
|
|
242
|
-
* @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
|
|
243
|
-
* @req REQ-MIGRATE-INLINE
|
|
244
|
-
*/
|
|
245
|
-
function tryBuildInlineAutoFix(context, comments, storyIndex, reqIndices) {
|
|
246
|
-
const sourceCode = context.getSourceCode();
|
|
247
|
-
const storyComment = comments[storyIndex];
|
|
248
|
-
const storyNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(storyComment.value || "");
|
|
249
|
-
if (!storyNormalized || !/^@story\b/.test(storyNormalized)) {
|
|
250
|
-
return null;
|
|
251
|
-
}
|
|
252
|
-
const storyParts = storyNormalized.split(/\s+/);
|
|
253
|
-
if (storyParts.length !== MIN_STORY_TOKENS) {
|
|
254
|
-
return null;
|
|
255
|
-
}
|
|
256
|
-
const storyPath = storyParts[1];
|
|
257
|
-
const reqIds = [];
|
|
258
|
-
for (const idx of reqIndices) {
|
|
259
|
-
const reqComment = comments[idx];
|
|
260
|
-
const reqNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(reqComment.value || "");
|
|
261
|
-
if (!reqNormalized || !/^@req\b/.test(reqNormalized)) {
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
const reqParts = reqNormalized.split(/\s+/);
|
|
265
|
-
if (reqParts.length !== MIN_REQ_TOKENS) {
|
|
266
|
-
return null;
|
|
267
|
-
}
|
|
268
|
-
reqIds.push(reqParts[1]);
|
|
269
|
-
}
|
|
270
|
-
if (!reqIds.length) {
|
|
271
|
-
return null;
|
|
272
|
-
}
|
|
273
|
-
const fullText = sourceCode.text.slice(storyComment.range[0], storyComment.range[1]);
|
|
274
|
-
const linePrefix = getLinePrefixFromText(fullText);
|
|
275
|
-
const implAnnotation = `@supports ${storyPath} ${reqIds.join(" ")}`;
|
|
276
|
-
const implLine = `${linePrefix}${implAnnotation}`;
|
|
277
|
-
const start = storyComment.range[0];
|
|
278
|
-
const end = comments[reqIndices[reqIndices.length - 1]].range[1];
|
|
279
|
-
return (fixer) => fixer.replaceTextRange([start, end], implLine);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Coordinate detection and optional migration of a single inline `@story`
|
|
283
|
-
* comment and its following `@req` comments, reporting diagnostics and
|
|
284
|
-
* scheduling auto-fixes where safe.
|
|
227
|
+
* ESLint rule: prefer-implements-annotation
|
|
285
228
|
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
|
|
289
|
-
function collectReqIndicesAfterStory(group, startIndex) {
|
|
290
|
-
const n = group.length;
|
|
291
|
-
const reqIndices = [];
|
|
292
|
-
let j = startIndex + 1;
|
|
293
|
-
while (j < n) {
|
|
294
|
-
const next = group[j];
|
|
295
|
-
const nextNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(next.value || "");
|
|
296
|
-
if (!nextNormalized || /^@supports\b/.test(nextNormalized)) {
|
|
297
|
-
break;
|
|
298
|
-
}
|
|
299
|
-
if (/^@req\b/.test(nextNormalized)) {
|
|
300
|
-
reqIndices.push(j);
|
|
301
|
-
j += 1;
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
break;
|
|
305
|
-
}
|
|
306
|
-
return { reqIndices, nextIndex: j };
|
|
307
|
-
}
|
|
308
|
-
function handleInlineStorySequence(context, group, startIndex) {
|
|
309
|
-
const current = group[startIndex];
|
|
310
|
-
const normalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(current.value || "");
|
|
311
|
-
if (!normalized || !/^@story\b/.test(normalized)) {
|
|
312
|
-
return startIndex + 1;
|
|
313
|
-
}
|
|
314
|
-
if (/^@supports\b/.test(normalized)) {
|
|
315
|
-
return startIndex + 1;
|
|
316
|
-
}
|
|
317
|
-
const storyIndex = startIndex;
|
|
318
|
-
const { reqIndices, nextIndex } = collectReqIndicesAfterStory(group, startIndex);
|
|
319
|
-
if (reqIndices.length === 0) {
|
|
320
|
-
context.report({
|
|
321
|
-
node: current,
|
|
322
|
-
messageId: "preferImplements",
|
|
323
|
-
});
|
|
324
|
-
return startIndex + 1;
|
|
325
|
-
}
|
|
326
|
-
const fix = tryBuildInlineAutoFix(context, group, storyIndex, reqIndices);
|
|
327
|
-
if (fix) {
|
|
328
|
-
context.report({
|
|
329
|
-
node: current,
|
|
330
|
-
messageId: "preferImplements",
|
|
331
|
-
fix,
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
context.report({
|
|
336
|
-
node: current,
|
|
337
|
-
messageId: "preferImplements",
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
return nextIndex;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Process a contiguous group of inline line comments, identifying legacy
|
|
344
|
-
* `@story`/`@req` sequences and scheduling the corresponding diagnostics
|
|
345
|
-
* and potential auto-fixes for migration to `@supports`.
|
|
229
|
+
* Recommend migrating from legacy `@story` + `@req` annotations to the
|
|
230
|
+
* newer `@supports` format. This rule is **disabled by default** and
|
|
231
|
+
* is intended as an optional, opt-in migration aid.
|
|
346
232
|
*
|
|
347
233
|
* @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
|
|
348
|
-
* @req REQ-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const current = group[currentIndex];
|
|
352
|
-
const normalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(current.value || "");
|
|
353
|
-
if (!normalized || !/^@story\b/.test(normalized)) {
|
|
354
|
-
return currentIndex + 1;
|
|
355
|
-
}
|
|
356
|
-
return handleInlineStorySequence(context, group, currentIndex);
|
|
357
|
-
}
|
|
358
|
-
function processInlineGroup(context, group) {
|
|
359
|
-
if (group.length === 0)
|
|
360
|
-
return;
|
|
361
|
-
let i = 0;
|
|
362
|
-
while (i < group.length) {
|
|
363
|
-
i = advanceInlineGroupIndex(context, group, i);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Scan sequences of Line comments for inline legacy @story/@req patterns and
|
|
368
|
-
* report diagnostics and optional auto-fixes.
|
|
234
|
+
* @req REQ-OPTIONAL-WARNING - Emit configurable recommendation diagnostics for legacy @story/@req usage
|
|
235
|
+
* @req REQ-MULTI-STORY-DETECT - Detect multi-story patterns that cannot be auto-fixed
|
|
236
|
+
* @req REQ-BACKWARD-COMP-VALIDATION - Keep legacy @story/@req annotations valid when the rule is disabled
|
|
369
237
|
*/
|
|
370
|
-
function processInlineComments(context, lineComments) {
|
|
371
|
-
if (!lineComments.length)
|
|
372
|
-
return;
|
|
373
|
-
// Group by contiguous line numbers
|
|
374
|
-
let group = [lineComments[0]];
|
|
375
|
-
const flushGroup = () => {
|
|
376
|
-
processInlineGroup(context, group);
|
|
377
|
-
group = [];
|
|
378
|
-
};
|
|
379
|
-
for (let idx = 1; idx < lineComments.length; idx++) {
|
|
380
|
-
const prev = lineComments[idx - 1];
|
|
381
|
-
const curr = lineComments[idx];
|
|
382
|
-
if (curr.loc.start.line === prev.loc.start.line + 1 &&
|
|
383
|
-
curr.loc.start.column === prev.loc.start.column) {
|
|
384
|
-
group.push(curr);
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
flushGroup();
|
|
388
|
-
group.push(curr);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
flushGroup();
|
|
392
|
-
}
|
|
393
238
|
/**
|
|
394
239
|
* ESLint rule: prefer-implements-annotation
|
|
395
240
|
*
|
|
@@ -472,7 +317,7 @@ const preferImplementsAnnotationRule = {
|
|
|
472
317
|
processBlockComment(comment, context);
|
|
473
318
|
});
|
|
474
319
|
const lineComments = comments.filter((comment) => comment.type === "Line");
|
|
475
|
-
processInlineComments(context, lineComments);
|
|
320
|
+
(0, prefer_implements_inline_1.processInlineComments)(context, lineComments);
|
|
476
321
|
},
|
|
477
322
|
};
|
|
478
323
|
},
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
* Composite ESLint rule that enforces both story and requirement traceability
|
|
3
3
|
* annotations on functions and methods.
|
|
4
4
|
*
|
|
5
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
6
|
+
* @req REQ-ANNOTATION-REQUIRED - Require both @story and @req annotations via composition
|
|
7
|
+
* @req REQ-FUNCTION-DETECTION - Detect functions via composed rules
|
|
8
|
+
* @req REQ-CONFIGURABLE-SCOPE - Support scope configuration through underlying rules
|
|
9
|
+
* @req REQ-EXPORT-PRIORITY - Support export priority through underlying rules
|
|
10
|
+
* @req REQ-ERROR-LOCATION - Report errors at function locations via composed rules
|
|
11
|
+
* @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript syntax via composed rules
|
|
12
|
+
*
|
|
5
13
|
* Implements Story 003.0-DEV-FUNCTION-ANNOTATIONS with:
|
|
6
14
|
* - REQ-ANNOTATION-REQUIRED
|
|
7
15
|
* - REQ-FUNCTION-DETECTION
|
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
* Composite ESLint rule that enforces both story and requirement traceability
|
|
4
4
|
* annotations on functions and methods.
|
|
5
5
|
*
|
|
6
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
7
|
+
* @req REQ-ANNOTATION-REQUIRED - Require both @story and @req annotations via composition
|
|
8
|
+
* @req REQ-FUNCTION-DETECTION - Detect functions via composed rules
|
|
9
|
+
* @req REQ-CONFIGURABLE-SCOPE - Support scope configuration through underlying rules
|
|
10
|
+
* @req REQ-EXPORT-PRIORITY - Support export priority through underlying rules
|
|
11
|
+
* @req REQ-ERROR-LOCATION - Report errors at function locations via composed rules
|
|
12
|
+
* @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript syntax via composed rules
|
|
13
|
+
*
|
|
6
14
|
* Implements Story 003.0-DEV-FUNCTION-ANNOTATIONS with:
|
|
7
15
|
* - REQ-ANNOTATION-REQUIRED
|
|
8
16
|
* - REQ-FUNCTION-DETECTION
|
|
@@ -5,7 +5,9 @@ const valid_annotation_format_internal_1 = require("./helpers/valid-annotation-f
|
|
|
5
5
|
const valid_annotation_format_validators_1 = require("./helpers/valid-annotation-format-validators");
|
|
6
6
|
function handleImplementsLine(normalized, pending, deps) {
|
|
7
7
|
const { context, comment, options } = deps;
|
|
8
|
-
|
|
8
|
+
// Only match `@supports` at the START of the normalized line to avoid
|
|
9
|
+
// false matches when this keyword appears in prose
|
|
10
|
+
const isImplements = /^@supports\b/.test(normalized);
|
|
9
11
|
if (!isImplements) {
|
|
10
12
|
return pending;
|
|
11
13
|
}
|
|
@@ -15,8 +17,10 @@ function handleImplementsLine(normalized, pending, deps) {
|
|
|
15
17
|
}
|
|
16
18
|
function handleStoryOrReqLine(normalized, pending, deps) {
|
|
17
19
|
const { context, comment, options } = deps;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
// Only match `@story`/`@req` at the START of the normalized line to avoid
|
|
21
|
+
// false matches when these keywords appear in prose (e.g., "@returns ... `@story` annotations")
|
|
22
|
+
const isStory = /^@story\b/.test(normalized);
|
|
23
|
+
const isReq = /^@req\b/.test(normalized);
|
|
20
24
|
if (!isStory && !isReq) {
|
|
21
25
|
return pending;
|
|
22
26
|
}
|
|
@@ -81,7 +85,7 @@ function processCommentLine({ normalized, pending, context, comment, options, })
|
|
|
81
85
|
if (afterStoryOrReq !== pending) {
|
|
82
86
|
return afterStoryOrReq;
|
|
83
87
|
}
|
|
84
|
-
// Implement JSDoc tag coexistence behavior: terminate
|
|
88
|
+
// Implement JSDoc tag coexistence behavior: terminate `@story`/`@req` values when a new non-traceability JSDoc tag line (e.g., @param, @returns) is encountered.
|
|
85
89
|
// @supports docs/stories/022.0-DEV-JSDOC-COEXISTENCE.story.md REQ-ANNOTATION-TERMINATION REQ-CONTINUATION-LOGIC
|
|
86
90
|
if ((0, valid_annotation_format_internal_1.isNonTraceabilityJSDocTagLine)(normalized)) {
|
|
87
91
|
(0, valid_annotation_format_validators_1.finalizePendingAnnotation)(context, comment, options, pending);
|
|
@@ -96,13 +100,13 @@ function processCommentLine({ normalized, pending, context, comment, options, })
|
|
|
96
100
|
return extendPendingAnnotation(normalized, pending);
|
|
97
101
|
}
|
|
98
102
|
/**
|
|
99
|
-
* Process a single comment node and validate any
|
|
103
|
+
* Process a single comment node and validate any `@story`/`@req`/`@supports` annotations it contains.
|
|
100
104
|
*
|
|
101
|
-
* Supports
|
|
105
|
+
* Supports `@story` and `@req` annotations whose values span multiple lines within the same
|
|
102
106
|
* comment block, collapsing whitespace so that the logical value can be
|
|
103
107
|
* validated against the configured patterns.
|
|
104
108
|
*
|
|
105
|
-
*
|
|
109
|
+
* `@supports` annotations are validated immediately per-line and are not
|
|
106
110
|
* accumulated into pending multi-line state.
|
|
107
111
|
*
|
|
108
112
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
@@ -172,8 +176,8 @@ exports.default = {
|
|
|
172
176
|
},
|
|
173
177
|
schema: (0, valid_annotation_options_1.getRuleSchema)(),
|
|
174
178
|
/**
|
|
175
|
-
* This rule's fixable support is limited to safe
|
|
176
|
-
* Fixes are limited strictly to adjusting the suffix portion of the
|
|
179
|
+
* This rule's fixable support is limited to safe `@story` path suffix normalization per Story 008.0.
|
|
180
|
+
* Fixes are limited strictly to adjusting the suffix portion of the `@story` path (e.g., adding
|
|
177
181
|
* `.md` or `.story.md`), preserving all other comment text and whitespace exactly as written.
|
|
178
182
|
*
|
|
179
183
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
@@ -204,7 +208,7 @@ exports.default = {
|
|
|
204
208
|
const optionErrors = (0, valid_annotation_options_1.getOptionErrors)();
|
|
205
209
|
return {
|
|
206
210
|
/**
|
|
207
|
-
* Program-level handler that inspects all comments for
|
|
211
|
+
* Program-level handler that inspects all comments for `@story`, `@req`, and `@supports` tags
|
|
208
212
|
*
|
|
209
213
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
210
214
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Helper to check @req annotation presence on TS declare functions and method signatures.
|
|
3
|
+
*
|
|
3
4
|
* This helper is intentionally scope/exportPriority agnostic and focuses solely
|
|
4
5
|
* on detection and reporting of @req annotations for the given node.
|
|
6
|
+
*
|
|
5
7
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
6
8
|
* @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript-specific function syntax
|
|
7
9
|
* @req REQ-ANNOTATION-REQ-DETECTION - Determine presence of @req annotation
|
|
8
10
|
* @req REQ-ANNOTATION-REPORTING - Report missing @req annotation to context
|
|
9
11
|
* @param context - ESLint rule context used to obtain source and report problems
|
|
10
12
|
* @param node - Function-like AST node whose surrounding comments should be inspected
|
|
11
|
-
* @param options - Optional configuration controlling behaviour (e.g., enableFix)
|
|
12
|
-
* @returns void
|
|
13
|
+
* @param options - Optional configuration controlling behaviour (e.g., enableFix, annotationPlacement)
|
|
13
14
|
*/
|
|
14
15
|
export declare function checkReqAnnotation(context: any, node: any, options?: {
|
|
15
16
|
enableFix?: boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.checkReqAnnotation = checkReqAnnotation;
|
|
4
|
+
/* eslint-disable traceability/valid-annotation-format */
|
|
4
5
|
const require_story_utils_1 = require("../rules/helpers/require-story-utils");
|
|
5
6
|
const reqAnnotationDetection_1 = require("./reqAnnotationDetection");
|
|
6
7
|
const function_annotation_helpers_1 = require("./function-annotation-helpers");
|
|
@@ -168,16 +169,17 @@ function reportMissing(context, node, enableFix = true) {
|
|
|
168
169
|
}
|
|
169
170
|
/**
|
|
170
171
|
* Helper to check @req annotation presence on TS declare functions and method signatures.
|
|
172
|
+
*
|
|
171
173
|
* This helper is intentionally scope/exportPriority agnostic and focuses solely
|
|
172
174
|
* on detection and reporting of @req annotations for the given node.
|
|
175
|
+
*
|
|
173
176
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
174
177
|
* @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript-specific function syntax
|
|
175
178
|
* @req REQ-ANNOTATION-REQ-DETECTION - Determine presence of @req annotation
|
|
176
179
|
* @req REQ-ANNOTATION-REPORTING - Report missing @req annotation to context
|
|
177
180
|
* @param context - ESLint rule context used to obtain source and report problems
|
|
178
181
|
* @param node - Function-like AST node whose surrounding comments should be inspected
|
|
179
|
-
* @param options - Optional configuration controlling behaviour (e.g., enableFix)
|
|
180
|
-
* @returns void
|
|
182
|
+
* @param options - Optional configuration controlling behaviour (e.g., enableFix, annotationPlacement)
|
|
181
183
|
*/
|
|
182
184
|
function checkReqAnnotation(context, node, options) {
|
|
183
185
|
const { enableFix = true } = options ?? {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Gather comment text from inside a CatchClause body.
|
|
4
|
+
*
|
|
5
|
+
* Uses dual-position detection strategy: first attempts getCommentsInside API,
|
|
6
|
+
* then falls back to line-based scanning if API is unavailable or returns empty.
|
|
7
|
+
*
|
|
8
|
+
* @story docs/stories/025.0-DEV-CATCH-ANNOTATION-POSITION.story.md
|
|
9
|
+
* @req REQ-DUAL-POSITION-DETECTION REQ-FALLBACK-LOGIC
|
|
10
|
+
* @param sourceCode - ESLint source code object providing comment access APIs
|
|
11
|
+
* @param node - CatchClause AST node whose body will be scanned for comments
|
|
12
|
+
* @returns Concatenated comment text from inside the catch body, or empty string if none found
|
|
13
|
+
*/
|
|
14
|
+
export declare function getInsideCatchCommentText(sourceCode: ReturnType<Rule.RuleContext["getSourceCode"]>, node: any): string;
|
|
15
|
+
/**
|
|
16
|
+
* Gather comment text from the first contiguous comment lines inside a TryStatement block body.
|
|
17
|
+
* @supports docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md REQ-INSIDE-BRACE-PLACEMENT
|
|
18
|
+
* @param sourceCode - ESLint source code object providing line access
|
|
19
|
+
* @param node - TryStatement AST node whose block will be scanned for comments
|
|
20
|
+
* @returns Concatenated comment text from inside the try block, or empty string if none found
|
|
21
|
+
*/
|
|
22
|
+
export declare function getInsideTryBlockCommentText(sourceCode: ReturnType<Rule.RuleContext["getSourceCode"]>, node: any): string;
|