@iris-code/core 0.1.2 → 0.2.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 (49) hide show
  1. package/dist/config.d.ts +1 -1
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +4 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/fileNaming.d.ts +1 -0
  6. package/dist/fileNaming.d.ts.map +1 -1
  7. package/dist/fileNaming.js +29 -0
  8. package/dist/fileNaming.js.map +1 -1
  9. package/dist/guards.d.ts.map +1 -1
  10. package/dist/guards.js +44 -2
  11. package/dist/guards.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +45 -9
  14. package/dist/index.js.map +1 -1
  15. package/dist/java/analyser.d.ts +4 -0
  16. package/dist/java/analyser.d.ts.map +1 -0
  17. package/dist/java/analyser.js +394 -0
  18. package/dist/java/analyser.js.map +1 -0
  19. package/dist/java/lexer.d.ts +46 -0
  20. package/dist/java/lexer.d.ts.map +1 -0
  21. package/dist/java/lexer.js +198 -0
  22. package/dist/java/lexer.js.map +1 -0
  23. package/dist/languages.d.ts +2 -10
  24. package/dist/languages.d.ts.map +1 -1
  25. package/dist/languages.js +18 -35
  26. package/dist/languages.js.map +1 -1
  27. package/dist/registry.d.ts +39 -0
  28. package/dist/registry.d.ts.map +1 -0
  29. package/dist/registry.js +74 -0
  30. package/dist/registry.js.map +1 -0
  31. package/dist/rust/analyser.d.ts +26 -0
  32. package/dist/rust/analyser.d.ts.map +1 -0
  33. package/dist/rust/analyser.js +506 -0
  34. package/dist/rust/analyser.js.map +1 -0
  35. package/dist/rust/lexer.d.ts +39 -0
  36. package/dist/rust/lexer.d.ts.map +1 -0
  37. package/dist/rust/lexer.js +192 -0
  38. package/dist/rust/lexer.js.map +1 -0
  39. package/dist/secrets.d.ts.map +1 -1
  40. package/dist/secrets.js +357 -1
  41. package/dist/secrets.js.map +1 -1
  42. package/dist/sfc.d.ts.map +1 -1
  43. package/dist/sfc.js +4 -18
  44. package/dist/sfc.js.map +1 -1
  45. package/dist/types.d.ts +4 -4
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/types.js +6 -0
  48. package/dist/types.js.map +1 -1
  49. package/package.json +2 -2
@@ -0,0 +1,506 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testRanges = testRanges;
4
+ exports.unsafeWithoutSafetyComment = unsafeWithoutSafetyComment;
5
+ exports.analyseRust = analyseRust;
6
+ const lines_1 = require("../lines");
7
+ const scoring_1 = require("../scoring");
8
+ const secrets_1 = require("../secrets");
9
+ const guards_1 = require("../guards");
10
+ const lexer_1 = require("./lexer");
11
+ const ZEROED_TS_METRICS = {
12
+ anyUsages: [], tsIgnoreCount: 0, tsExpectErrorCount: 0,
13
+ nonNullAssertions: 0, typeAssertions: 0, missingReturnTypes: 0,
14
+ };
15
+ function emptyRustSmells() {
16
+ return {
17
+ consoleLogs: [], todos: [], deepNesting: 0, longParameterLists: [],
18
+ magicNumbers: [], unusedVars: [], unusedFunctions: [], bareSuppressions: [],
19
+ duplicateBlocks: [], fileNamingViolations: [], evalUsage: [],
20
+ sqlConcatenation: [], insecureRandom: [], unsafeRegex: [],
21
+ hardcodedLocalhost: [], disabledTlsVerification: [], debugFlagsEnabled: [],
22
+ weakHashing: [], openRedirect: [],
23
+ };
24
+ }
25
+ /**
26
+ * Lines that legitimately carry a literal number in Rust: a `const` or `static`
27
+ * item, or an attribute argument. Each of those IS the name for its number,
28
+ * which is what the magic-number rule asks for.
29
+ *
30
+ * Matches the exemption C# has had since it shipped, and Java gained in the same
31
+ * change. Found by the benchmark's negative fixture, which reported
32
+ * `const SURCHARGE_MINOR_UNITS: u32 = 4750` as magic.
33
+ */
34
+ const RUST_MAGIC_NUMBER_EXEMPT_RE = /^\s*#\[|^\s*(?:pub(?:\s*\([^)]*\))?\s+)?(?:const|static)(?:\s+mut)?\s/;
35
+ /** Index of the `}` closing the block whose `{` sits at `openIndex`. */
36
+ function findBlockEnd(code, openIndex) {
37
+ let depth = 0;
38
+ for (let i = openIndex; i < code.length; i++) {
39
+ if (code[i] === '{')
40
+ depth++;
41
+ else if (code[i] === '}') {
42
+ depth--;
43
+ if (depth === 0)
44
+ return i;
45
+ }
46
+ }
47
+ return code.length;
48
+ }
49
+ /**
50
+ * Character ranges covered by `#[cfg(test)]` modules and `#[test]` functions.
51
+ *
52
+ * THIS HAS NO PRECEDENT IN THE OTHER EIGHT LANGUAGES. Every one of them puts
53
+ * tests in separate FILES, so `isTestFile` was enough. Rust puts them inside
54
+ * the file under test:
55
+ *
56
+ * pub fn parse(s: &str) -> u32 { s.parse().unwrap() } // production
57
+ * #[cfg(test)]
58
+ * mod tests { #[test] fn works() { assert_eq!(parse("1"), 1) } }
59
+ *
60
+ * A file-level exemption is either wrong (it exempts the production half too)
61
+ * or useless (it exempts nothing). Without a range-aware exemption, `unwrap()`
62
+ * density floods every well-tested Rust file, which is exactly the population
63
+ * most likely to be evaluating us.
64
+ */
65
+ function testRanges(source) {
66
+ const code = (0, lexer_1.rustCodeOnly)(source);
67
+ const ranges = [];
68
+ const attr = /#\s*\[\s*(?:cfg\s*\(\s*test\s*\)|test|tokio::test|async_std::test)\s*\]/g;
69
+ let match;
70
+ while ((match = attr.exec(code)) !== null) {
71
+ // The attribute applies to the next item, so the range runs from the
72
+ // attribute to the end of that item's block.
73
+ const brace = code.indexOf('{', match.index);
74
+ if (brace === -1)
75
+ continue;
76
+ ranges.push({ start: match.index, end: findBlockEnd(code, brace) });
77
+ }
78
+ return ranges;
79
+ }
80
+ function inTestRange(ranges, index) {
81
+ return ranges.some(range => index >= range.start && index <= range.end);
82
+ }
83
+ const RUST_FN_RE = /(?:^|[{};])\s*(?:#\[[^\]]*\]\s*)*(?:pub(?:\s*\([^)]*\))?\s+)?(?:const\s+|async\s+|unsafe\s+|extern\s+"[^"]*"\s+)*fn\s+([A-Za-z_][\w]*)\s*(?:<[^>]*>)?\s*\(([^)]*)\)/g;
84
+ function countParams(raw) {
85
+ const trimmed = raw.trim();
86
+ if (trimmed === '')
87
+ return 0;
88
+ let depth = 0;
89
+ let count = 1;
90
+ for (const ch of trimmed) {
91
+ if (ch === '<' || ch === '(' || ch === '[')
92
+ depth++;
93
+ else if (ch === '>' || ch === ')' || ch === ']')
94
+ depth--;
95
+ else if (ch === ',' && depth === 0)
96
+ count++;
97
+ }
98
+ return count;
99
+ }
100
+ function detectRustFns(source) {
101
+ const code = (0, lexer_1.rustCodeOnly)(source);
102
+ const fns = [];
103
+ RUST_FN_RE.lastIndex = 0;
104
+ let match;
105
+ while ((match = RUST_FN_RE.exec(code)) !== null) {
106
+ const name = match[1];
107
+ const start = match.index + match[0].indexOf(name);
108
+ // A trait method declaration ends in `;` and has no body.
109
+ const brace = code.indexOf('{', match.index + match[0].length);
110
+ const semi = code.indexOf(';', match.index + match[0].length);
111
+ if (brace === -1 || (semi !== -1 && semi < brace))
112
+ continue;
113
+ fns.push({
114
+ name,
115
+ line: (0, lines_1.lineOf)(code, start),
116
+ paramCount: countParams(match[2]),
117
+ start,
118
+ end: findBlockEnd(code, brace),
119
+ });
120
+ }
121
+ return fns;
122
+ }
123
+ /**
124
+ * `use` declarations, excluding the prelude-adjacent std paths.
125
+ *
126
+ * `std`, `core` and `alloc` ship with the language, so counting them would make
127
+ * the import count meaningless - the same reasoning that excludes `java.*` and
128
+ * `System.*`. `crate::`, `self::` and `super::` are internal, not dependencies.
129
+ */
130
+ /** Splits a brace-group body on commas that are not inside a nested group. */
131
+ function splitTopLevel(body) {
132
+ const parts = [];
133
+ let depth = 0;
134
+ let current = '';
135
+ for (const ch of body) {
136
+ if (ch === '{')
137
+ depth++;
138
+ else if (ch === '}')
139
+ depth--;
140
+ if (ch === ',' && depth === 0) {
141
+ parts.push(current);
142
+ current = '';
143
+ continue;
144
+ }
145
+ current += ch;
146
+ }
147
+ parts.push(current);
148
+ return parts;
149
+ }
150
+ /** `button::{Button, ButtonVariants}` under a prefix, as one entry per leaf. */
151
+ function expandNestedGroup(prefix, piece, line) {
152
+ const inner = /^(.*?)\{(.+)\}$/.exec(piece);
153
+ if (!inner)
154
+ return [];
155
+ const innerPrefix = prefix + inner[1];
156
+ const out = [];
157
+ for (const nested of splitTopLevel(inner[2])) {
158
+ const trimmed = nested.trim();
159
+ if (trimmed === '' || trimmed === 'self')
160
+ continue;
161
+ if (trimmed.includes('{')) {
162
+ for (const deeper of expandNestedGroup(innerPrefix, trimmed, line))
163
+ out.push(deeper);
164
+ continue;
165
+ }
166
+ const leaf = trimmed.split(' as ').pop()?.trim() ?? '';
167
+ if (leaf === '' || leaf === 'self')
168
+ continue;
169
+ out.push({ name: innerPrefix + trimmed, line, leaf: leaf.replace(/^.*::/, ''), isGlob: leaf === '*' });
170
+ }
171
+ return out;
172
+ }
173
+ function extractRustUses(source) {
174
+ const code = (0, lexer_1.stripRustComments)(source);
175
+ const out = [];
176
+ // `[ \t]*` rather than `\s*` for the indentation - see the note on the Java
177
+ // import pattern. `\s` matches newlines, so under /m this anchors at every line
178
+ // start and backtracks across the whole file: the same defect class as the
179
+ // `METHOD_RE` quadratic recorded in SECURITY.md 1.4.
180
+ const re = /^[ \t]*(?:pub[ \t]+)?use[ \t]+([^;]+);/gm;
181
+ let match;
182
+ while ((match = re.exec(code)) !== null) {
183
+ const line = (0, lines_1.lineOf)(code, match.index);
184
+ const body = match[1].replace(/\s+/g, ' ').trim();
185
+ // A brace group imports several leaves from one path: use std::io::{Read, Write}
186
+ const group = /^(.*?)\{(.+)\}$/.exec(body);
187
+ if (group) {
188
+ const prefix = group[1];
189
+ // Split on TOP-LEVEL commas only. Rust nests groups freely, and
190
+ // `use gpui_component::{button::{Button, ButtonVariants}, Sizable};` split on
191
+ // every comma produced the leaf names `button::{Button`, `ButtonVariants}`
192
+ // and `Sizable` - two of them carrying a brace, which then matched nothing in
193
+ // the body and were reported as unused. Measured on the real gpui-component
194
+ // repo 2026-08-17: brace-bearing garbage names accounted for a large share of
195
+ // 2,037 unused-import findings across 471 files.
196
+ for (const piece of splitTopLevel(group[2])) {
197
+ const trimmed = piece.trim();
198
+ if (trimmed === '' || trimmed === 'self')
199
+ continue;
200
+ // A nested group contributes its own leaves rather than one mangled name.
201
+ if (trimmed.includes('{')) {
202
+ for (const nested of expandNestedGroup(prefix, trimmed, line))
203
+ out.push(nested);
204
+ continue;
205
+ }
206
+ const leaf = trimmed.split(' as ').pop()?.trim() ?? '';
207
+ if (leaf === '' || leaf === 'self')
208
+ continue;
209
+ out.push({ name: prefix + trimmed, line, leaf: leaf.replace(/^.*::/, ''), isGlob: leaf === '*' });
210
+ }
211
+ continue;
212
+ }
213
+ const leaf = body.split(' as ').pop()?.trim().split('::').pop() ?? '';
214
+ out.push({ name: body, line, leaf, isGlob: body.endsWith('::*') });
215
+ }
216
+ return out;
217
+ }
218
+ function thirdPartyUses(uses) {
219
+ return uses
220
+ .filter(entry => !/^(?:std|core|alloc|crate|self|super)\b/.test(entry.name.trim()))
221
+ .map(entry => entry.name.trim());
222
+ }
223
+ /**
224
+ * UNUSED IMPORTS ARE DELIBERATELY NOT REPORTED FOR RUST, the same call Ruby and C#
225
+ * already make, and for the same underlying reason: the verdict cannot be stood
226
+ * behind.
227
+ *
228
+ * Rust's blocker is the TRAIT. You import a trait so its methods become callable,
229
+ * and then you never write its name again:
230
+ *
231
+ * use gpui::Styled; // required for `.bg(...)` to compile
232
+ * div().bg(red()) // `Styled` appears nowhere
233
+ *
234
+ * A text search cannot see that usage, and rustc does not warn about it, because
235
+ * the import is correct and genuinely used. Measured on the real gpui-component
236
+ * repository 2026-08-17: 1,411 findings across 471 files, roughly three per file,
237
+ * and the top of the list was entirely traits - `ParentElement` 78 times, `Styled`
238
+ * 75, `AppContext` 69, `InteractiveElement` 67, `StyledExt` 56, `FluentBuilder` 38.
239
+ * Every one correct code. Resolving them needs the dependency's own source, which
240
+ * is well beyond a regex analyser.
241
+ *
242
+ * That is not a tuning problem, so the check is removed rather than narrowed. A
243
+ * rule that is wrong three times per file does not get trusted less - it gets the
244
+ * whole tool switched off.
245
+ *
246
+ * JAVA IS THE OPPOSITE CASE and keeps its check: an import there is a compile-time
247
+ * type alias, there is no trait-method equivalent, javac itself warns, and the same
248
+ * measurement on Elasticsearch gave 25 findings per 1,000 files.
249
+ *
250
+ * `extractRustUses` is still used, and its nested-group parsing still matters: it
251
+ * feeds the third-party import COUNT behind `too-many-imports`, which was also
252
+ * wrong while `use a::{b::{c, d}, e}` was being split on every comma.
253
+ */
254
+ const RUST_UNUSED_IMPORTS = [];
255
+ function detectRustWarnings(source, fns, imports, config) {
256
+ const warnings = [];
257
+ const code = (0, lexer_1.rustCodeOnly)(source);
258
+ const lines = source.split(String.fromCharCode(10));
259
+ // Severity is overridable per rule, the same as every other language.
260
+ const severity = (type, fallback) => config.severityOverrides[type] ?? fallback;
261
+ const warningThreshold = Math.round(config.fileLengthThreshold * 2 / 3);
262
+ if (lines.length > config.fileLengthThreshold) {
263
+ warnings.push({ type: 'file-too-long', message: `File is ${lines.length} lines (>${config.fileLengthThreshold})`, severity: severity('file-too-long', 'error'), line: 1 });
264
+ }
265
+ else if (lines.length > warningThreshold) {
266
+ warnings.push({ type: 'file-too-long', message: `File is ${lines.length} lines (>${warningThreshold})`, severity: severity('file-too-long', 'warning'), line: 1 });
267
+ }
268
+ for (const item of fns) {
269
+ const span = (0, lines_1.lineOf)(code, item.end) - item.line + 1;
270
+ const errorThreshold = config.functionLengthThreshold * 2;
271
+ if (span > errorThreshold) {
272
+ warnings.push({ type: 'function-too-long', message: `${item.name} is ~${span} lines (>${errorThreshold})`, severity: severity('function-too-long', 'error'), line: item.line });
273
+ }
274
+ else if (span > config.functionLengthThreshold) {
275
+ warnings.push({ type: 'function-too-long', message: `${item.name} is ~${span} lines (>${config.functionLengthThreshold})`, severity: severity('function-too-long', 'warning'), line: item.line });
276
+ }
277
+ }
278
+ if (fns.length > config.maxFunctionsPerFile) {
279
+ warnings.push({ type: 'too-many-functions', message: `${fns.length} functions in one file (>${config.maxFunctionsPerFile})`, severity: severity('too-many-functions', 'warning') });
280
+ }
281
+ if (imports.length > config.maxImportsPerFile) {
282
+ warnings.push({ type: 'too-many-imports', message: `${imports.length} third-party imports (>${config.maxImportsPerFile})`, severity: severity('too-many-imports', 'warning') });
283
+ }
284
+ return warnings;
285
+ }
286
+ function detectRustSmells(source, fns, config, fileIsTest) {
287
+ const smells = emptyRustSmells();
288
+ const code = (0, lexer_1.rustCodeOnly)(source);
289
+ const withStrings = (0, lexer_1.stripRustComments)(source);
290
+ const ranges = testRanges(source);
291
+ // A whole test file exempts everything; otherwise only the inline test
292
+ // modules are exempt.
293
+ const exempt = (index) => fileIsTest || inTestRange(ranges, index);
294
+ const pushLines = (re, target, haystack, honourTests,
295
+ // Collapse repeat matches on ONE line into a single finding. Needed where a
296
+ // pattern's alternations can both match the same construct: `use sha1::Sha1`
297
+ // matches `sha1::` AND `\bSha1\b`, so one import was reported twice, which
298
+ // doubled both the smell count and its score penalty. Off by default,
299
+ // because two `.unwrap()` calls on one line really are two findings.
300
+ onePerLine = false) => {
301
+ re.lastIndex = 0;
302
+ const seen = new Set();
303
+ let match;
304
+ while ((match = re.exec(haystack)) !== null) {
305
+ if (honourTests && exempt(match.index))
306
+ continue;
307
+ const line = (0, lines_1.lineOf)(haystack, match.index);
308
+ if (onePerLine) {
309
+ if (seen.has(line))
310
+ continue;
311
+ seen.add(line);
312
+ }
313
+ target.push({ line });
314
+ }
315
+ };
316
+ pushLines(/\b(?:println!|eprintln!|print!|eprint!|dbg!)\s*\(/g, smells.consoleLogs, code, true);
317
+ const todoRe = /\/\/+\s*(TODO|FIXME|HACK|XXX)\b[:\s]*(.*)/gi;
318
+ let todo;
319
+ while ((todo = todoRe.exec(source)) !== null) {
320
+ smells.todos.push({ text: `${todo[1]}: ${todo[2].trim()}`.trim(), line: (0, lines_1.lineOf)(source, todo.index) });
321
+ }
322
+ for (const fn of fns) {
323
+ if (fn.paramCount > config.maxParameterCount) {
324
+ smells.longParameterLists.push({ name: fn.name, paramCount: fn.paramCount, line: fn.line });
325
+ }
326
+ }
327
+ let deepest = 0;
328
+ for (const fn of fns) {
329
+ if (exempt(fn.start))
330
+ continue;
331
+ let depth = 0;
332
+ let peak = 0;
333
+ for (let i = fn.start; i <= fn.end && i < code.length; i++) {
334
+ if (code[i] === '{') {
335
+ depth++;
336
+ peak = Math.max(peak, depth);
337
+ }
338
+ else if (code[i] === '}')
339
+ depth--;
340
+ }
341
+ deepest = Math.max(deepest, Math.max(0, peak - 1));
342
+ }
343
+ smells.deepNesting = deepest;
344
+ const magicRe = /(?<![\w.])(-?\d{2,})(?:_[iu](?:8|16|32|64|size))?(?![\w.])/g;
345
+ const codeLines = code.split('\n');
346
+ let magic;
347
+ while ((magic = magicRe.exec(code)) !== null) {
348
+ if (exempt(magic.index))
349
+ continue;
350
+ const value = magic[1];
351
+ if (['0', '1', '-1', '100', '1000'].includes(value))
352
+ continue;
353
+ const magicLine = (0, lines_1.lineOf)(code, magic.index);
354
+ // A NAMED constant is not a magic number - naming it is the fix the rule
355
+ // asks for. C# has exempted this since it shipped; Rust was missed, and the
356
+ // benchmark's negative fixture is what surfaced it.
357
+ if (RUST_MAGIC_NUMBER_EXEMPT_RE.test(codeLines[magicLine - 1] ?? ''))
358
+ continue;
359
+ smells.magicNumbers.push({ value, line: magicLine });
360
+ }
361
+ if (config.enableSecuritySmells) {
362
+ // NOTE: `unwrap`/`expect` and `panic!` are NOT here any more. They were
363
+ // pushed into `evalUsage`, which reaches the user labelled "eval() / exec()
364
+ // usage - arbitrary code execution risk". That is what every other language
365
+ // puts there - Python `exec()`, Ruby `Kernel.eval` - and an `unwrap` is
366
+ // nothing of the kind. They are now `unwrap-abuse` and `explicit-panic`,
367
+ // emitted as warnings by detectRustPanicRules so they carry their own name,
368
+ // their own severity override, and their own iris-ignore id.
369
+ pushLines(/\bformat!\s*\(\s*"[^"]*(?:SELECT|INSERT|UPDATE|DELETE)[^"]*"\s*,/gi, smells.sqlConcatenation, withStrings, true);
370
+ pushLines(/\brand::random\s*\(|\bthread_rng\s*\(/g, smells.insecureRandom, code, true);
371
+ pushLines(/\bMd5\b|\bSha1\b|\bmd5::|sha1::/g, smells.weakHashing, code, true, true);
372
+ pushLines(/\bdanger_accept_invalid_certs\s*\(\s*true\s*\)|\bdanger_accept_invalid_hostnames\s*\(\s*true\s*\)/g, smells.disabledTlsVerification, code, true);
373
+ if (!fileIsTest) {
374
+ pushLines(/(?:https?:\/\/)?(?:localhost|127\.0\.0\.1)(?::\d+)?/g, smells.hardcodedLocalhost, withStrings, true);
375
+ pushLines(/\b(?:debug|dev_mode)\s*[:=]\s*true\b/gi, smells.debugFlagsEnabled, withStrings, true);
376
+ }
377
+ }
378
+ return smells;
379
+ }
380
+ /**
381
+ * The two Rust panic rules, as first-class warnings.
382
+ *
383
+ * Both were originally pushed into `codeSmells.evalUsage`, which was expedient
384
+ * and wrong: that array's user-facing label is "eval() / exec() usage -
385
+ * arbitrary code execution risk", so the single most common Rust finding
386
+ * arrived under a heading describing a different class of defect entirely.
387
+ * Giving them real ids also gives them the three things a shared array cannot:
388
+ * a `severityOverrides` entry, an `iris-ignore: unwrap-abuse` directive, and
389
+ * their own group in the Problems tab.
390
+ *
391
+ * They are SEPARATE rules because the fixes differ. An `unwrap` is an unhandled
392
+ * error path - the fix is `?` or a match. A `panic!`/`todo!`/`unimplemented!` is
393
+ * deliberate abort - the fix is to return a Result, or to finish the function.
394
+ *
395
+ * Both honour the inline test ranges, which is the whole reason `testRanges`
396
+ * exists: `#[cfg(test)]` code is full of `unwrap` by design, and a file-level
397
+ * exemption would either spare the production half too or spare nothing.
398
+ */
399
+ function detectRustPanicRules(source, config, fileIsTest) {
400
+ if (!config.enableSecuritySmells)
401
+ return [];
402
+ const warnings = [];
403
+ const code = (0, lexer_1.rustCodeOnly)(source);
404
+ const ranges = testRanges(source);
405
+ const severity = (type, fallback) => config.severityOverrides[type] ?? fallback;
406
+ const scan = (re, type, message, fallback) => {
407
+ re.lastIndex = 0;
408
+ let match;
409
+ while ((match = re.exec(code)) !== null) {
410
+ if (fileIsTest || inTestRange(ranges, match.index))
411
+ continue;
412
+ warnings.push({ type, message, severity: severity(type, fallback), line: (0, lines_1.lineOf)(code, match.index) });
413
+ }
414
+ };
415
+ scan(/\.\s*(?:unwrap|expect)\s*\(/g, 'unwrap-abuse', 'unwrap/expect panics on the error case; propagate with ? or match instead', 'warning');
416
+ scan(/\bpanic!\s*\(|\btodo!\s*\(|\bunimplemented!\s*\(/g, 'explicit-panic', 'Explicit panic aborts the process; return a Result so callers can recover', 'warning');
417
+ return warnings;
418
+ }
419
+ /** `unsafe` blocks with no safety comment above them. */
420
+ function unsafeWithoutSafetyComment(source) {
421
+ const code = (0, lexer_1.rustCodeOnly)(source);
422
+ const lines = source.split('\n');
423
+ let count = 0;
424
+ const re = /\bunsafe\s*\{/g;
425
+ let match;
426
+ while ((match = re.exec(code)) !== null) {
427
+ const line = (0, lines_1.lineOf)(code, match.index);
428
+ const preceding = lines.slice(Math.max(0, line - 4), line - 1).join('\n');
429
+ if (!/SAFETY\s*:/i.test(preceding))
430
+ count++;
431
+ }
432
+ return count;
433
+ }
434
+ function scoreRustComplexity(source, codeLineCount, fns, uses) {
435
+ const code = (0, lexer_1.rustCodeOnly)(source);
436
+ let score = 1;
437
+ const branches = (code.match(/\b(?:if|for|while|match|loop)\b|&&|\|\|/g) ?? []).length;
438
+ const density = codeLineCount > 0 ? fns.length / (codeLineCount / 50) : 0;
439
+ score += Math.min(3, Math.floor(density));
440
+ score += Math.min(3, Math.floor(branches / 10));
441
+ score += Math.min(2, Math.floor(uses.length / 12));
442
+ score += Math.min(1, unsafeWithoutSafetyComment(source));
443
+ return Math.max(1, Math.min(10, score));
444
+ }
445
+ /**
446
+ * Drops secrets that live inside an inline `#[cfg(test)]` module.
447
+ *
448
+ * `detectHardcodedSecrets` is shared by every language and knows only
449
+ * `isTestFile(filePath)`, which is a FILE-level question. That is enough
450
+ * everywhere else, because every other supported language puts tests in
451
+ * separate files - but it is exactly the assumption Rust breaks, and the reason
452
+ * `testRanges` exists in the first place.
453
+ *
454
+ * Without this, a fixture credential in a `#[cfg(test)] mod tests` block is
455
+ * reported as a production secret: the heaviest finding Iris emits at 10 points,
456
+ * on the file population most likely to be well tested. Someone acting on it
457
+ * would delete a test fixture to fix a leak that was never there. Found
458
+ * 2026-08-16 by running the Rust testbed, after the range exemption had already
459
+ * been wired through unwrap, panic, console output and magic numbers - secrets
460
+ * were the one path that never got it.
461
+ *
462
+ * Matching is by LINE because a HardcodedSecret carries a line, not an offset;
463
+ * the ranges are character offsets, so they are converted once here.
464
+ */
465
+ function filterTestRangeSecrets(secrets, source, fileIsTest) {
466
+ // A whole test file is already handled by the shared detector.
467
+ if (fileIsTest || secrets.length === 0)
468
+ return secrets;
469
+ const ranges = testRanges(source);
470
+ if (ranges.length === 0)
471
+ return secrets;
472
+ const code = (0, lexer_1.rustCodeOnly)(source);
473
+ const lineRanges = ranges.map(range => ({
474
+ start: (0, lines_1.lineOf)(code, range.start),
475
+ end: (0, lines_1.lineOf)(code, range.end),
476
+ }));
477
+ return secrets.filter(secret => !lineRanges.some(range => secret.line >= range.start && secret.line <= range.end));
478
+ }
479
+ function analyseRust(source, config, filePath = '') {
480
+ const lines = source.split('\n');
481
+ const blankLines = lines.filter(line => line.trim() === '' || /^\s*\/\//.test(line)).length;
482
+ const codeLineCount = lines.length - blankLines;
483
+ const allFns = detectRustFns(source);
484
+ const fns = config.ignoreFunctions.length > 0
485
+ ? allFns.filter(fn => !config.ignoreFunctions.includes(fn.name))
486
+ : allFns;
487
+ const uses = thirdPartyUses(extractRustUses(source));
488
+ const fileIsTest = (0, guards_1.isTestFile)(filePath) || /(^|[\\/])(tests|benches|examples)[\\/]/.test(filePath);
489
+ const warnings = [
490
+ ...detectRustWarnings(source, fns, uses, config),
491
+ ...detectRustPanicRules(source, config, fileIsTest),
492
+ ];
493
+ const baseSmells = detectRustSmells(source, fns, config, fileIsTest);
494
+ const hardcodedSecrets = filterTestRangeSecrets((0, secrets_1.detectHardcodedSecrets)(source, config, 'rust', filePath), source, fileIsTest);
495
+ const codeSmells = { ...baseSmells, hardcodedSecrets };
496
+ return {
497
+ lineCount: lines.length, blankLines, codeLines: codeLineCount,
498
+ functions: fns.map(({ name, line }) => ({ name, line })),
499
+ thirdPartyImports: uses,
500
+ unusedImports: RUST_UNUSED_IMPORTS,
501
+ complexityScore: scoreRustComplexity(source, codeLineCount, fns, uses),
502
+ warnings, typeScriptMetrics: ZEROED_TS_METRICS, codeSmells,
503
+ healthScore: (0, scoring_1.computeHealthScore)(warnings, ZEROED_TS_METRICS, codeSmells, config),
504
+ };
505
+ }
506
+ //# sourceMappingURL=analyser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyser.js","sourceRoot":"","sources":["../../src/rust/analyser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The Rust lexical layer, in its own module because TWO callers need it: the
3
+ * Rust analyser (every structural rule) and `detectParseErrorReason` in
4
+ * guards.ts (the delimiter balance check that decides whether a file is
5
+ * analysed at all).
6
+ *
7
+ * That second caller is why this exists before any rule. C# shipped a defect
8
+ * where a verbatim string read as unterminated, every brace after it landed at
9
+ * the wrong depth, and the file came back a parse error with every finding
10
+ * zeroed - and a zeroed file is indistinguishable from a clean one.
11
+ *
12
+ * Both modes are LENGTH- and LINE-PRESERVING, so a finding's offset still maps
13
+ * to its native line with no remapping layer that could drift.
14
+ *
15
+ * THE LIFETIME IS THE RUST-SPECIFIC TRAP, and it is the exact shape that breaks
16
+ * a naive scanner. `&'a str` is a reference with a lifetime, not a char literal:
17
+ * a scanner that treats `'` as opening a character would run to the NEXT
18
+ * apostrophe somewhere further down the file, blanking real code in between.
19
+ * Lifetimes appear in most non-trivial Rust, so this is the common case rather
20
+ * than an edge one.
21
+ *
22
+ * Also handled, each with its own way of breaking a naive scan:
23
+ * - raw strings at any hash depth: `r"..."`, `r#"..."#`, `r##"..."##`, where a
24
+ * `"` inside does NOT close the literal
25
+ * - raw identifiers: `r#type` is an identifier, not a raw string, so `r#` only
26
+ * opens a literal when a quote follows the hashes
27
+ * - byte strings `b"..."` and byte chars `b'x'`, plus `br#"..."#`
28
+ * - NESTED block comments, which Rust allows and C does not. An inner block
29
+ * comment's closer does NOT end the outer one, so a depth counter is the only
30
+ * way to see where the comment really ends. (Writing that construct literally
31
+ * in this very comment ended it early on the first build - the same class of
32
+ * mistake the module exists to prevent.)
33
+ */
34
+ export declare function transformRust(source: string, blankStrings: boolean): string;
35
+ /** Comments blanked, string contents intact. */
36
+ export declare function stripRustComments(source: string): string;
37
+ /** Comments AND string contents blanked: the input for anything structural. */
38
+ export declare function rustCodeOnly(source: string): string;
39
+ //# sourceMappingURL=lexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/rust/lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAYH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAwH3E;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD"}