@sun-asterisk/sunlint 1.3.1 → 1.3.2
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 +47 -0
- package/CONTRIBUTING.md +210 -1691
- package/config/rule-analysis-strategies.js +17 -1
- package/config/rules/enhanced-rules-registry.json +369 -1135
- package/config/rules/rules-registry-generated.json +1 -1
- package/core/enhanced-rules-registry.js +2 -1
- package/core/semantic-engine.js +15 -3
- package/core/semantic-rule-base.js +4 -2
- package/engines/heuristic-engine.js +65 -4
- package/integrations/eslint/plugin/rules/common/c003-no-vague-abbreviations.js +59 -1
- package/integrations/eslint/plugin/rules/common/c006-function-name-verb-noun.js +26 -1
- package/integrations/eslint/plugin/rules/common/c030-use-custom-error-classes.js +54 -19
- package/origin-rules/common-en.md +11 -7
- package/package.json +1 -1
- package/rules/common/C002_no_duplicate_code/analyzer.js +334 -36
- package/rules/common/C003_no_vague_abbreviations/analyzer.js +220 -35
- package/rules/common/C006_function_naming/analyzer.js +29 -3
- package/rules/common/C010_limit_block_nesting/analyzer.js +181 -337
- package/rules/common/C010_limit_block_nesting/config.json +64 -0
- package/rules/common/C010_limit_block_nesting/regex-based-analyzer.js +379 -0
- package/rules/common/C010_limit_block_nesting/symbol-based-analyzer.js +231 -0
- package/rules/common/C013_no_dead_code/analyzer.js +75 -177
- package/rules/common/C013_no_dead_code/config.json +61 -0
- package/rules/common/C013_no_dead_code/regex-based-analyzer.js +345 -0
- package/rules/common/C013_no_dead_code/symbol-based-analyzer.js +640 -0
- package/rules/common/C014_dependency_injection/analyzer.js +48 -313
- package/rules/common/C014_dependency_injection/config.json +26 -0
- package/rules/common/C014_dependency_injection/symbol-based-analyzer.js +751 -0
- package/rules/common/C018_no_throw_generic_error/analyzer.js +232 -0
- package/rules/common/C018_no_throw_generic_error/config.json +50 -0
- package/rules/common/C018_no_throw_generic_error/regex-based-analyzer.js +387 -0
- package/rules/common/C018_no_throw_generic_error/symbol-based-analyzer.js +314 -0
- package/rules/common/C019_log_level_usage/analyzer.js +110 -317
- package/rules/common/C019_log_level_usage/pattern-analyzer.js +88 -0
- package/rules/common/C019_log_level_usage/system-log-analyzer.js +1267 -0
- package/rules/common/C023_no_duplicate_variable/analyzer.js +180 -0
- package/rules/common/C023_no_duplicate_variable/config.json +50 -0
- package/rules/common/C023_no_duplicate_variable/symbol-based-analyzer.js +158 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/analyzer.js +180 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/config.json +50 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/symbol-based-analyzer.js +181 -0
- package/rules/common/C030_use_custom_error_classes/analyzer.js +200 -0
- package/rules/common/C035_error_logging_context/analyzer.js +3 -1
- package/rules/index.js +5 -1
- package/rules/security/S009_no_insecure_encryption/README.md +158 -0
- package/rules/security/S009_no_insecure_encryption/analyzer.js +319 -0
- package/rules/security/S009_no_insecure_encryption/config.json +55 -0
- package/rules/security/S010_no_insecure_encryption/README.md +224 -0
- package/rules/security/S010_no_insecure_encryption/analyzer.js +493 -0
- package/rules/security/S010_no_insecure_encryption/config.json +48 -0
- package/rules/security/S016_no_sensitive_querystring/STRATEGY.md +149 -0
- package/rules/security/S016_no_sensitive_querystring/analyzer.js +276 -0
- package/rules/security/S016_no_sensitive_querystring/config.json +127 -0
- package/rules/security/S016_no_sensitive_querystring/regex-based-analyzer.js +258 -0
- package/rules/security/S016_no_sensitive_querystring/symbol-based-analyzer.js +495 -0
- package/rules/security/S048_no_current_password_in_reset/README.md +222 -0
- package/rules/security/S048_no_current_password_in_reset/analyzer.js +366 -0
- package/rules/security/S048_no_current_password_in_reset/config.json +48 -0
- package/rules/security/S055_content_type_validation/README.md +176 -0
- package/rules/security/S055_content_type_validation/analyzer.js +312 -0
- package/rules/security/S055_content_type_validation/config.json +48 -0
- package/rules/utils/rule-helpers.js +140 -1
- package/scripts/consolidate-config.js +116 -0
- package/config/rules/S027-categories.json +0 -122
- package/config/rules/rules-registry.json +0 -777
- package/rules/common/C006_function_naming/smart-analyzer.js +0 -503
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* C003_no_vague_abbreviations - Enhanced Regex-based Rule Analyzer
|
|
3
|
+
* Category: coding
|
|
4
|
+
*
|
|
5
|
+
* Detects vague variable names and unclear abbreviations
|
|
6
|
+
* Uses enhanced regex patterns with proper comment filtering
|
|
4
7
|
*/
|
|
5
8
|
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const { CommentDetector } = require('../../utils/rule-helpers');
|
|
12
|
+
|
|
6
13
|
class C003NoVagueAbbreviations {
|
|
7
14
|
constructor(options = {}) {
|
|
8
15
|
this.options = {
|
|
@@ -84,19 +91,43 @@ class C003NoVagueAbbreviations {
|
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
/**
|
|
87
|
-
* Check if variable is
|
|
94
|
+
* Check if variable is a generic type parameter
|
|
88
95
|
*/
|
|
89
|
-
|
|
96
|
+
isGenericTypeParameter(content, variableName, line) {
|
|
97
|
+
// Single uppercase letters T, U, V, K, etc. are common generic type names
|
|
98
|
+
if (!/^[T-Z]$/i.test(variableName)) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
const lines = content.split('\n');
|
|
91
103
|
const currentLine = lines[line - 1] || '';
|
|
104
|
+
const prevLine = lines[line - 2] || '';
|
|
105
|
+
const nextLine = lines[line] || '';
|
|
92
106
|
|
|
93
|
-
|
|
94
|
-
if (/const\s+[a-z]\s*=\s*\d+.*[a-z]\s*=\s*\d+/.test(currentLine)) {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
107
|
+
const contextLines = [prevLine, currentLine, nextLine].join(' ');
|
|
97
108
|
|
|
98
|
-
//
|
|
99
|
-
|
|
109
|
+
// Check for generic type context
|
|
110
|
+
const genericPatterns = [
|
|
111
|
+
/function\s*<[^>]*>/i, // function<T, U>
|
|
112
|
+
/class\s+\w+\s*<[^>]*>/i, // class Foo<T>
|
|
113
|
+
/interface\s+\w+\s*<[^>]*>/i, // interface Bar<T>
|
|
114
|
+
/type\s+\w+\s*<[^>]*>/i, // type Baz<T>
|
|
115
|
+
/<[^>]*>.*=>/i, // <T>(param: T) =>
|
|
116
|
+
/:\s*[T-Z]\s*[,)]/i // parameter: T,
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
return genericPatterns.some(pattern => pattern.test(contextLines));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check if variable is a TypeScript type annotation context
|
|
124
|
+
*/
|
|
125
|
+
isTypeAnnotationContext(content, variableName, line) {
|
|
126
|
+
const lines = content.split('\n');
|
|
127
|
+
const currentLine = lines[line - 1] || '';
|
|
128
|
+
|
|
129
|
+
// Check if variable is in type position: param: Type, variable: Type
|
|
130
|
+
if (/:\s*\w+\s*[,)=]/.test(currentLine)) {
|
|
100
131
|
return true;
|
|
101
132
|
}
|
|
102
133
|
|
|
@@ -104,20 +135,44 @@ class C003NoVagueAbbreviations {
|
|
|
104
135
|
}
|
|
105
136
|
|
|
106
137
|
/**
|
|
107
|
-
* Check if variable is
|
|
138
|
+
* Check if variable is function parameter context
|
|
108
139
|
*/
|
|
109
140
|
isFunctionParameter(content, variableName, line) {
|
|
110
141
|
const lines = content.split('\n');
|
|
111
142
|
const currentLine = lines[line - 1] || '';
|
|
112
143
|
|
|
113
144
|
// Check if we're in a function parameter list
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
const functionPatterns = [
|
|
146
|
+
/function.*\(.*\w+.*\)/, // function foo(param)
|
|
147
|
+
/\(.*\w+.*\)\s*=>/, // (param) =>
|
|
148
|
+
/\w+\s*=>\s*/, // param =>
|
|
149
|
+
/\w+\s*:\s*\w+\s*[,)]/, // param: Type,
|
|
150
|
+
/\w+\?\s*:\s*\w+\s*[,)]/ // param?: Type,
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
return functionPatterns.some(pattern => pattern.test(currentLine));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Check if variable has clear type information
|
|
158
|
+
*/
|
|
159
|
+
hasTypeInformation(content, variableName, line) {
|
|
160
|
+
const lines = content.split('\n');
|
|
161
|
+
const currentLine = lines[line - 1] || '';
|
|
162
|
+
|
|
163
|
+
// TypeScript type annotations make variables clearer
|
|
164
|
+
// Example: function process(u: User) - 'u' is clear from User type
|
|
165
|
+
const typePatterns = [
|
|
166
|
+
new RegExp(`${variableName}\\s*:\\s*[A-Z]\\w+`), // param: TypeName
|
|
167
|
+
new RegExp(`${variableName}\\s*:\\s*\\w+\\[\\]`), // param: Type[]
|
|
168
|
+
new RegExp(`${variableName}\\s*:\\s*string|number|boolean`) // primitive types
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
return typePatterns.some(pattern => pattern.test(currentLine));
|
|
117
172
|
}
|
|
118
173
|
|
|
119
174
|
/**
|
|
120
|
-
* Check if variable is coordinate-like
|
|
175
|
+
* Check if variable is coordinate-like or math notation
|
|
121
176
|
*/
|
|
122
177
|
isCoordinate(variableName) {
|
|
123
178
|
return /^[xyz](\d+)?$/i.test(variableName) ||
|
|
@@ -126,36 +181,62 @@ class C003NoVagueAbbreviations {
|
|
|
126
181
|
}
|
|
127
182
|
|
|
128
183
|
/**
|
|
129
|
-
* Check if variable is
|
|
184
|
+
* Check if variable is math/algorithm context
|
|
130
185
|
*/
|
|
131
186
|
isMathContext(content, variableName, line) {
|
|
132
187
|
const lines = content.split('\n');
|
|
133
188
|
const currentLine = lines[line - 1] || '';
|
|
189
|
+
const prevLine = lines[line - 2] || '';
|
|
190
|
+
const nextLine = lines[line] || '';
|
|
134
191
|
|
|
135
|
-
//
|
|
136
|
-
|
|
192
|
+
// Check for math variable patterns
|
|
193
|
+
const mathPatterns = [
|
|
194
|
+
// Coordinate pairs: x1, y1, x2, y2
|
|
195
|
+
/^[xyz][12]$/i,
|
|
196
|
+
// Delta notation: dx, dy, dt, dr
|
|
197
|
+
/^d[xyztr]$/i,
|
|
198
|
+
// Math constants: a, b, c in equations
|
|
199
|
+
/^[abc]$/i,
|
|
200
|
+
// Vector components: vx, vy, vz
|
|
201
|
+
/^v[xyz]$/i,
|
|
202
|
+
// Position/point notation: p1, p2
|
|
203
|
+
/^p\d+$/i
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
if (mathPatterns.some(pattern => pattern.test(variableName))) {
|
|
137
207
|
return true;
|
|
138
208
|
}
|
|
139
209
|
|
|
140
|
-
//
|
|
210
|
+
// Context-based detection
|
|
211
|
+
const contextLines = [prevLine, currentLine, nextLine].join(' ');
|
|
212
|
+
|
|
213
|
+
// Check for math function names in the context
|
|
214
|
+
if (/function\s+(distance|calculate|compute|solve|formula|algorithm|equation|math)/i.test(contextLines)) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Math operations context
|
|
141
219
|
if (/[+\-*/=]\s*\w+|\w+\s*[+\-*/=]/.test(currentLine)) {
|
|
142
220
|
return true;
|
|
143
221
|
}
|
|
144
222
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
* Check if variable is in function parameter context
|
|
150
|
-
*/
|
|
151
|
-
isFunctionParameter(content, variableName, line) {
|
|
152
|
-
const lines = content.split('\n');
|
|
153
|
-
const currentLine = lines[line - 1] || '';
|
|
223
|
+
// Math functions context
|
|
224
|
+
if (/Math\.|sqrt|pow|abs|sin|cos|tan|distance|calculate/i.test(contextLines)) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
154
227
|
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
228
|
+
// Multiple single-char variables (typical in math)
|
|
229
|
+
if (/const\s+[a-z]\s*=.*[a-z]\s*=/.test(currentLine)) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Check for function parameters that are clearly coordinates/math
|
|
234
|
+
// Example: function distance(x1: number, y1: number, x2: number, y2: number)
|
|
235
|
+
if (/function.*\([^)]*\b(x1|y1|x2|y2|dx|dy|dz|dt)\b.*\)/.test(contextLines)) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return false;
|
|
159
240
|
}
|
|
160
241
|
|
|
161
242
|
/**
|
|
@@ -244,6 +325,91 @@ class C003NoVagueAbbreviations {
|
|
|
244
325
|
return violations;
|
|
245
326
|
}
|
|
246
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Clean line by removing comments but preserving structure for regex matching
|
|
330
|
+
* @param {string} line - Original line
|
|
331
|
+
* @returns {object} { cleanLine, commentRanges }
|
|
332
|
+
*/
|
|
333
|
+
cleanLineForMatching(line) {
|
|
334
|
+
return CommentDetector.cleanLineForMatching(line);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Check if a variable at a specific position is inside a comment
|
|
339
|
+
* @param {string} line - Line content
|
|
340
|
+
* @param {number} position - Position in line where variable was found
|
|
341
|
+
* @returns {boolean} True if position is inside a comment
|
|
342
|
+
*/
|
|
343
|
+
isPositionInComment(line, position) {
|
|
344
|
+
return CommentDetector.isPositionInComment(line, position);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Check if a line is a comment or inside a comment block
|
|
349
|
+
* @param {string} line - Line to check
|
|
350
|
+
* @param {number} lineIndex - Current line index
|
|
351
|
+
* @param {string[]} allLines - All lines in content
|
|
352
|
+
* @returns {boolean} True if line is commented
|
|
353
|
+
*/
|
|
354
|
+
isCommentedLine(line, lineIndex, allLines) {
|
|
355
|
+
const trimmedLine = line.trim();
|
|
356
|
+
|
|
357
|
+
// Check single-line comments
|
|
358
|
+
if (trimmedLine.startsWith('//') || trimmedLine.startsWith('#')) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Check if we're inside a multi-line comment
|
|
363
|
+
let inComment = false;
|
|
364
|
+
for (let i = 0; i <= lineIndex; i++) {
|
|
365
|
+
const currentLine = allLines[i];
|
|
366
|
+
|
|
367
|
+
// Find /* and */ on the same line or across lines
|
|
368
|
+
let startPos = 0;
|
|
369
|
+
while (startPos < currentLine.length) {
|
|
370
|
+
const commentStart = currentLine.indexOf('/*', startPos);
|
|
371
|
+
const commentEnd = currentLine.indexOf('*/', startPos);
|
|
372
|
+
|
|
373
|
+
if (commentStart !== -1 && (commentEnd === -1 || commentStart < commentEnd)) {
|
|
374
|
+
inComment = true;
|
|
375
|
+
startPos = commentStart + 2;
|
|
376
|
+
} else if (commentEnd !== -1 && inComment) {
|
|
377
|
+
inComment = false;
|
|
378
|
+
startPos = commentEnd + 2;
|
|
379
|
+
} else {
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// If we're at the target line and inside a comment
|
|
385
|
+
if (i === lineIndex && inComment) {
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Remove comments from content
|
|
395
|
+
* @param {string} content - File content
|
|
396
|
+
* @returns {string} Content with comments removed
|
|
397
|
+
*/
|
|
398
|
+
removeComments(content) {
|
|
399
|
+
let result = content;
|
|
400
|
+
|
|
401
|
+
// Remove single line comments (// comments)
|
|
402
|
+
result = result.replace(/\/\/.*$/gm, '');
|
|
403
|
+
|
|
404
|
+
// Remove multi-line comments (/* comments */)
|
|
405
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
406
|
+
|
|
407
|
+
// Remove # comments (for other languages like Python, Shell)
|
|
408
|
+
result = result.replace(/#.*$/gm, '');
|
|
409
|
+
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
|
|
247
413
|
/**
|
|
248
414
|
* Analyze variable names in content
|
|
249
415
|
*/
|
|
@@ -255,12 +421,25 @@ class C003NoVagueAbbreviations {
|
|
|
255
421
|
}
|
|
256
422
|
|
|
257
423
|
const violations = [];
|
|
258
|
-
const lines = content.split('\n');
|
|
424
|
+
const lines = content.split('\n'); // Use original content to preserve line numbers
|
|
259
425
|
|
|
260
426
|
lines.forEach((line, index) => {
|
|
261
427
|
const lineNumber = index + 1;
|
|
262
428
|
|
|
263
|
-
//
|
|
429
|
+
// Skip commented lines
|
|
430
|
+
if (this.isCommentedLine(line, index, lines)) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Skip empty lines
|
|
435
|
+
if (!line.trim()) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Clean line for better pattern matching
|
|
440
|
+
const { cleanLine } = this.cleanLineForMatching(line);
|
|
441
|
+
|
|
442
|
+
// Match variable declarations on cleaned line
|
|
264
443
|
const patterns = [
|
|
265
444
|
// const/let/var declarations
|
|
266
445
|
/(?:const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*[=:]/g,
|
|
@@ -274,7 +453,7 @@ class C003NoVagueAbbreviations {
|
|
|
274
453
|
|
|
275
454
|
patterns.forEach(pattern => {
|
|
276
455
|
let match;
|
|
277
|
-
while ((match = pattern.exec(
|
|
456
|
+
while ((match = pattern.exec(cleanLine)) !== null) {
|
|
278
457
|
let variableNames = [];
|
|
279
458
|
|
|
280
459
|
if (match[1]) {
|
|
@@ -292,6 +471,7 @@ class C003NoVagueAbbreviations {
|
|
|
292
471
|
}
|
|
293
472
|
|
|
294
473
|
variableNames.forEach(variableName => {
|
|
474
|
+
// No need to check position since we're using cleaned line
|
|
295
475
|
const violation = this.checkVariableName(variableName, content, lineNumber, match.index);
|
|
296
476
|
if (violation) {
|
|
297
477
|
violations.push({
|
|
@@ -395,6 +575,11 @@ class C003NoVagueAbbreviations {
|
|
|
395
575
|
};
|
|
396
576
|
}
|
|
397
577
|
|
|
578
|
+
// Check for math context BEFORE suspicious patterns
|
|
579
|
+
if (this.isMathContext(content, variableName, line)) {
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
|
|
398
583
|
// Check for suspicious patterns
|
|
399
584
|
for (const pattern of this.suspiciousPatterns) {
|
|
400
585
|
if (pattern.test(lowerName)) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const ts = require('typescript');
|
|
4
|
+
const { CommentDetector } = require('../../utils/rule-helpers');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* SMART C006 ANALYZER - INTELLIGENT FUNCTION NAMING ANALYSIS
|
|
@@ -254,6 +255,20 @@ class SmartC006Analyzer {
|
|
|
254
255
|
* Uses multiple strategies to detect verbs
|
|
255
256
|
*/
|
|
256
257
|
isVerbLikeName(functionName) {
|
|
258
|
+
// Strategy 0: REJECT generic/vague verbs that should be flagged
|
|
259
|
+
const genericVerbs = [
|
|
260
|
+
'do', 'handle', 'process', 'manage', 'execute',
|
|
261
|
+
'something', 'stuff', 'thing', 'work', 'data'
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
const isGenericVerb = genericVerbs.some(verb => {
|
|
265
|
+
const verbPattern = new RegExp(`^${verb}([A-Z].*|$)`, 'i');
|
|
266
|
+
return verbPattern.test(functionName);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Reject names starting with generic verbs
|
|
270
|
+
if (isGenericVerb) return false;
|
|
271
|
+
|
|
257
272
|
// Strategy 1: Known verb prefixes (expanded beyond static list)
|
|
258
273
|
const verbPrefixes = [
|
|
259
274
|
'get', 'set', 'is', 'has', 'can', 'should', 'will', 'does',
|
|
@@ -262,9 +277,9 @@ class SmartC006Analyzer {
|
|
|
262
277
|
'delete', 'remove', 'destroy', 'clean', 'clear', 'reset',
|
|
263
278
|
'load', 'save', 'fetch', 'retrieve', 'find', 'search', 'query',
|
|
264
279
|
'validate', 'verify', 'check', 'confirm', 'ensure', 'test',
|
|
265
|
-
'calculate', 'compute', '
|
|
280
|
+
'calculate', 'compute', 'parse', 'format', 'convert',
|
|
266
281
|
'send', 'receive', 'transmit', 'broadcast', 'emit', 'publish',
|
|
267
|
-
'
|
|
282
|
+
'map', 'filter', 'sort', 'group', 'merge', 'split',
|
|
268
283
|
'connect', 'disconnect', 'open', 'close', 'start', 'stop', 'run',
|
|
269
284
|
'show', 'hide', 'display', 'render', 'draw', 'paint', 'animate',
|
|
270
285
|
'add', 'append', 'insert', 'push', 'pop', 'shift', 'splice',
|
|
@@ -272,7 +287,7 @@ class SmartC006Analyzer {
|
|
|
272
287
|
'refresh', 'restore', 'reload', 'retry', 'resume', 'redirect',
|
|
273
288
|
'select', 'toggle', 'switch', 'enable', 'disable', 'activate',
|
|
274
289
|
'expand', 'collapse', 'scroll', 'navigate', 'submit', 'cancel',
|
|
275
|
-
'on', '
|
|
290
|
+
'on', 'trigger', 'fire', 'dispatch', 'invoke', 'call'
|
|
276
291
|
];
|
|
277
292
|
|
|
278
293
|
// Strategy 2: Check if starts with known verb
|
|
@@ -365,6 +380,17 @@ class SmartC006Analyzer {
|
|
|
365
380
|
// 🧮 CONFIDENCE CALCULATION
|
|
366
381
|
let confidence = 0.5; // Base confidence
|
|
367
382
|
|
|
383
|
+
// Boost confidence for clearly generic/vague patterns
|
|
384
|
+
const vagueFunctionNames = [
|
|
385
|
+
'doSomething', 'handleStuff', 'processData', 'processInfo',
|
|
386
|
+
'executeWork', 'manageItems', 'doWork', 'handleData',
|
|
387
|
+
'something', 'stuff', 'thing', 'data', 'info', 'item'
|
|
388
|
+
];
|
|
389
|
+
|
|
390
|
+
if (vagueFunctionNames.some(vague => functionName.toLowerCase().includes(vague.toLowerCase()))) {
|
|
391
|
+
confidence += 0.4; // Strongly boost confidence for obviously vague names
|
|
392
|
+
}
|
|
393
|
+
|
|
368
394
|
// Boost confidence for clear noun-only patterns
|
|
369
395
|
if (/^[a-z]+$/.test(functionName)) {
|
|
370
396
|
confidence += 0.3; // Simple lowercase nouns: user, data
|