Skip to content

Commit 786932b

Browse files
authored
fix: WASM build resilience + lint cleanup from TS migration (#629)
* fix: make WASM grammar build resilient to transient failures The prepare script now treats build:wasm as non-fatal since the native engine is the primary parser. Individual grammar build failures are caught and warned instead of aborting the entire build. * fix(lint): disable noNonNullAssertion and noExplicitAny rules, clean up suppressions These rules produce hundreds of warnings from the JS→TS migration (Phase 6) and are not actionable yet. Auto-fixed useLiteralKeys and noUnusedImports, removed 69 now-unnecessary biome-ignore comments, and deleted one unused interface. * fix: disable noPropertyAccessFromIndexSignature, clean up useLiteralKeys suppressions (#629) tsconfig's noPropertyAccessFromIndexSignature conflicted with biome's useLiteralKeys auto-fix, causing TS4111 errors on CI. Disable the TS rule so dot notation is valid for index signatures. Remove all now-unnecessary useLiteralKeys biome-ignore comments and convert remaining bracket notation. Also fix duplicate | undefined in types.ts and delete dead _taSub function in leiden adapter. * fix: make WASM build non-fatal without bash-only syntax (#629) The prepare script used bash-style (cmd || echo) which fails on Windows cmd.exe. Instead, make build-wasm.ts always exit 0 since failures are already non-fatal by design (per-grammar try/catch with warning logs). This restores the simple prepare script while keeping WASM resilience.
1 parent 0f9cca4 commit 786932b

65 files changed

Lines changed: 198 additions & 301 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

biome.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@
1010
},
1111
"linter": {
1212
"rules": {
13-
"recommended": true
13+
"recommended": true,
14+
"style": {
15+
"noNonNullAssertion": "off"
16+
},
17+
"suspicious": {
18+
"noExplicitAny": "off"
19+
}
1420
}
1521
},
1622
"javascript": {

scripts/build-wasm.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,27 @@ const grammars = [
3636
{ name: 'tree-sitter-php', pkg: 'tree-sitter-php', sub: 'php' },
3737
];
3838

39+
let failed = 0;
3940
for (const g of grammars) {
4041
const pkgDir = dirname(require.resolve(`${g.pkg}/package.json`));
4142
const grammarDir = g.sub ? resolve(pkgDir, g.sub) : pkgDir;
4243

4344
console.log(`Building ${g.name}.wasm from ${grammarDir}...`);
44-
execFileSync('npx', ['tree-sitter', 'build', '--wasm', grammarDir], {
45-
cwd: grammarsDir,
46-
stdio: 'inherit',
47-
shell: true,
48-
});
49-
console.log(` Done: ${g.name}.wasm`);
45+
try {
46+
execFileSync('npx', ['tree-sitter', 'build', '--wasm', grammarDir], {
47+
cwd: grammarsDir,
48+
stdio: 'inherit',
49+
shell: true,
50+
});
51+
console.log(` Done: ${g.name}.wasm`);
52+
} catch (err: any) {
53+
failed++;
54+
console.warn(` WARN: Failed to build ${g.name}.wasm — ${err.message ?? 'unknown error'}`);
55+
}
5056
}
5157

52-
console.log('\nAll grammars built successfully into grammars/');
58+
if (failed > 0) {
59+
console.warn(`\n${failed}/${grammars.length} grammars failed to build (non-fatal — native engine available)`);
60+
} else {
61+
console.log('\nAll grammars built successfully into grammars/');
62+
}

src/ast-analysis/engine.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ function setupVisitors(
219219
walkerOpts.getFunctionName = (node: TreeSitterNode): string | null => {
220220
const nameNode = node.childForFieldName('name');
221221
if (nameNode) return nameNode.text;
222-
// biome-ignore lint/suspicious/noExplicitAny: DataflowRulesConfig is structurally compatible at runtime
223222
if (dfRules) return getFuncName(node, dfRules as any);
224223
return null;
225224
};
@@ -260,8 +259,7 @@ function setupVisitors(
260259
// ─── Result storage helpers ─────────────────────────────────────────────
261260

262261
function storeComplexityResults(results: WalkResults, defs: Definition[], langId: string): void {
263-
// biome-ignore lint/complexity/useLiteralKeys: bracket notation required by noPropertyAccessFromIndexSignature
264-
const complexityResults = (results['complexity'] || []) as ComplexityFuncResult[];
262+
const complexityResults = (results.complexity || []) as ComplexityFuncResult[];
265263
const resultByLine = new Map<number, ComplexityFuncResult[]>();
266264
for (const r of complexityResults) {
267265
if (r.funcNode) {
@@ -302,8 +300,7 @@ function storeComplexityResults(results: WalkResults, defs: Definition[], langId
302300
}
303301

304302
function storeCfgResults(results: WalkResults, defs: Definition[]): void {
305-
// biome-ignore lint/complexity/useLiteralKeys: bracket notation required by noPropertyAccessFromIndexSignature
306-
const cfgResults = (results['cfg'] || []) as CfgFuncResult[];
303+
const cfgResults = (results.cfg || []) as CfgFuncResult[];
307304
const cfgByLine = new Map<number, CfgFuncResult[]>();
308305
for (const r of cfgResults) {
309306
if (r.funcNode) {
@@ -362,7 +359,6 @@ async function delegateToBuildFunctions(
362359
const t0 = performance.now();
363360
try {
364361
const { buildAstNodes } = await import('../features/ast.js');
365-
// biome-ignore lint/suspicious/noExplicitAny: ExtractorOutput is a superset of the local FileSymbols expected by buildAstNodes
366362
await buildAstNodes(db, fileSymbols as Map<string, any>, rootDir, engineOpts);
367363
} catch (err: unknown) {
368364
debug(`buildAstNodes failed: ${(err as Error).message}`);
@@ -374,7 +370,6 @@ async function delegateToBuildFunctions(
374370
const t0 = performance.now();
375371
try {
376372
const { buildComplexityMetrics } = await import('../features/complexity.js');
377-
// biome-ignore lint/suspicious/noExplicitAny: ExtractorOutput is a superset of the local FileSymbols expected by buildComplexityMetrics
378373
await buildComplexityMetrics(db, fileSymbols as Map<string, any>, rootDir, engineOpts);
379374
} catch (err: unknown) {
380375
debug(`buildComplexityMetrics failed: ${(err as Error).message}`);
@@ -453,8 +448,7 @@ export async function runAnalyses(
453448

454449
if (complexityVisitor) storeComplexityResults(results, defs, langId);
455450
if (cfgVisitor) storeCfgResults(results, defs);
456-
// biome-ignore lint/complexity/useLiteralKeys: bracket notation required by noPropertyAccessFromIndexSignature
457-
if (dataflowVisitor) symbols.dataflow = results['dataflow'] as DataflowResult;
451+
if (dataflowVisitor) symbols.dataflow = results.dataflow as DataflowResult;
458452
}
459453

460454
timing._unifiedWalkMs = performance.now() - t0walk;

src/ast-analysis/shared.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ export function findFunctionNode(
176176
}
177177

178178
for (let i = 0; i < node.childCount; i++) {
179-
// biome-ignore lint/style/noNonNullAssertion: tree-sitter child(i) within childCount is always non-null
180179
search(node.child(i)!);
181180
}
182181
}

src/ast-analysis/visitors/cfg-shared.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { TreeSitterNode } from '../../types.js';
22

3-
// biome-ignore lint/suspicious/noExplicitAny: CFG rules are opaque language-specific objects
43
export type AnyRules = any;
54

65
/** Callback type for the mutual recursion with processStatements in cfg-visitor. */

src/ast-analysis/visitors/complexity-visitor.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
computeMaintainabilityIndex,
66
} from '../metrics.js';
77

8-
// biome-ignore lint/suspicious/noExplicitAny: complexity/halstead rules are opaque language-specific objects
98
type AnyRules = any;
109

1110
interface ComplexityAcc {

src/ast-analysis/visitors/dataflow-visitor.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
truncate,
1111
} from '../visitor-utils.js';
1212

13-
// biome-ignore lint/suspicious/noExplicitAny: dataflow rules are opaque language-specific objects
1413
type AnyRules = any;
1514

1615
interface ScopeEntry {

src/cli/commands/branch-compare.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const command: CommandDefinition = {
1313
async execute([base, target], opts, ctx) {
1414
const { branchCompare } = await import('../../presentation/branch-compare.js');
1515
await branchCompare(base!, target!, {
16-
engine: ctx.program.opts()['engine'],
16+
engine: ctx.program.opts().engine,
1717
depth: parseInt(opts.depth as string, 10),
1818
noTests: ctx.resolveNoTests(opts),
1919
json: opts.json,

src/cli/commands/build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const command: CommandDefinition = {
1515
],
1616
async execute([dir], opts, ctx) {
1717
const root = path.resolve(dir || '.');
18-
const engine = ctx.program.opts()['engine'];
18+
const engine = ctx.program.opts().engine;
1919
await buildGraph(root, {
2020
incremental: opts.incremental as boolean,
2121
ast: opts.ast as boolean,

src/cli/commands/info.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const command: CommandDefinition = {
99
);
1010
const { getActiveEngine } = await import('../../domain/parser.js');
1111

12-
const engine = ctx.program.opts()['engine'];
12+
const engine = ctx.program.opts().engine;
1313
const { name: activeName, version: activeVersion } = getActiveEngine({ engine });
1414
const nativeAvailable = isNativeAvailable();
1515

0 commit comments

Comments
 (0)