From 2ba7d57e4304baa30456670484893b21aea1e2f7 Mon Sep 17 00:00:00 2001 From: HuangWenjie Date: Tue, 12 May 2026 14:15:47 +0800 Subject: [PATCH] fix(ci): complete formatting, lint, and typecheck fixes - prettier: format call-processor.ts, imported-return-types.ts, include-extractor.test.ts, cpp-captures.test.ts, cpp-imports.test.ts - eslint: suppress intentional console.warn in manifest-extractor.ts - typecheck: restore 'thrift' in ContractType union (was accidentally removed) and add thrift case to exhaustive switch in manifest-extractor --- .../group/extractors/manifest-extractor.ts | 3 ++ gitnexus/src/core/group/types.ts | 2 +- gitnexus/src/core/ingestion/call-processor.ts | 18 +++++++-- .../passes/imported-return-types.ts | 6 +-- .../test/unit/group/include-extractor.test.ts | 37 ++++--------------- .../scope-resolution/cpp/cpp-captures.test.ts | 16 ++------ .../scope-resolution/cpp/cpp-imports.test.ts | 6 +-- 7 files changed, 32 insertions(+), 56 deletions(-) diff --git a/gitnexus/src/core/group/extractors/manifest-extractor.ts b/gitnexus/src/core/group/extractors/manifest-extractor.ts index 36f8813d7..a38db4a22 100644 --- a/gitnexus/src/core/group/extractors/manifest-extractor.ts +++ b/gitnexus/src/core/group/extractors/manifest-extractor.ts @@ -291,6 +291,7 @@ export class ManifestExtractor { // fail the whole manifest extraction. Unresolved contracts still // get a synthetic symbolUid below, so cross-impact can proceed. const message = err instanceof Error ? err.message : String(err); + // eslint-disable-next-line no-console console.warn( `[manifest-extractor] resolveSymbol failed for ${link.type}:${link.contract} ` + `in ${repoPathKey}: ${message}`, @@ -345,6 +346,8 @@ export class ManifestExtractor { return `custom::${contract}`; case 'include': return `include::${contract}`; + case 'thrift': + return `thrift::${contract}`; default: { const _exhaustive: never = type; throw new Error(`Unhandled ContractType: ${String(_exhaustive)}`); diff --git a/gitnexus/src/core/group/types.ts b/gitnexus/src/core/group/types.ts index d54f0701b..d290cfa30 100644 --- a/gitnexus/src/core/group/types.ts +++ b/gitnexus/src/core/group/types.ts @@ -1,4 +1,4 @@ -export type ContractType = 'http' | 'grpc' | 'topic' | 'lib' | 'custom' | 'include'; +export type ContractType = 'http' | 'grpc' | 'thrift' | 'topic' | 'lib' | 'custom' | 'include'; export type MatchType = 'exact' | 'manifest' | 'wildcard' | 'bm25' | 'embedding'; export type ContractRole = 'provider' | 'consumer'; diff --git a/gitnexus/src/core/ingestion/call-processor.ts b/gitnexus/src/core/ingestion/call-processor.ts index 40bc50f9a..ad80e425d 100644 --- a/gitnexus/src/core/ingestion/call-processor.ts +++ b/gitnexus/src/core/ingestion/call-processor.ts @@ -934,7 +934,13 @@ export const processCalls = async ( // Defer resolution: Ruby attr_accessor properties are registered during // this same loop, so cross-file lookups fail if the declaring file hasn't // been processed yet. Collect now, resolve after all files are done. - pendingWrites.push({ receiverTypeName, propertyName, filePath: file.path, srcId, line: captureMap['assignment'].startPosition.row + 1 }); + pendingWrites.push({ + receiverTypeName, + propertyName, + filePath: file.path, + srcId, + line: captureMap['assignment'].startPosition.row + 1, + }); } // Assignment-only capture (no @call sibling): skip the rest of this // forEach iteration — this acts as a `continue` in the match loop. @@ -1383,7 +1389,10 @@ export const processCalls = async ( ); if (fieldOwner) { graph.addRelationship({ - id: generateId('ACCESSES', `${pw.srcId}:${fieldOwner.nodeId}:write${pw.line !== undefined ? `:${pw.line}` : ''}`), + id: generateId( + 'ACCESSES', + `${pw.srcId}:${fieldOwner.nodeId}:write${pw.line !== undefined ? `:${pw.line}` : ''}`, + ), sourceId: pw.srcId, targetId: fieldOwner.nodeId, type: 'ACCESSES', @@ -2980,7 +2989,10 @@ export const processAssignmentsFromExtracted = ( const fieldOwner = resolveFieldOwnership(receiverTypeName, asn.propertyName, asn.filePath, ctx); if (!fieldOwner) continue; graph.addRelationship({ - id: generateId('ACCESSES', `${asn.sourceId}:${fieldOwner.nodeId}:write${asn.line !== undefined ? `:${asn.line}` : ''}`), + id: generateId( + 'ACCESSES', + `${asn.sourceId}:${fieldOwner.nodeId}:write${asn.line !== undefined ? `:${asn.line}` : ''}`, + ), sourceId: asn.sourceId, targetId: fieldOwner.nodeId, type: 'ACCESSES', diff --git a/gitnexus/src/core/ingestion/scope-resolution/passes/imported-return-types.ts b/gitnexus/src/core/ingestion/scope-resolution/passes/imported-return-types.ts index a290b7779..33716778d 100644 --- a/gitnexus/src/core/ingestion/scope-resolution/passes/imported-return-types.ts +++ b/gitnexus/src/core/ingestion/scope-resolution/passes/imported-return-types.ts @@ -151,11 +151,7 @@ export function propagateImportedReturnTypes( const refs = lookupBindingsAt(importerModule.id, localName, indexes); for (const ref of refs) { - if ( - ref.origin !== 'import' && - ref.origin !== 'reexport' && - ref.origin !== 'wildcard' - ) + if (ref.origin !== 'import' && ref.origin !== 'reexport' && ref.origin !== 'wildcard') continue; const sourceModule = moduleScopeByFile.get(ref.def.filePath); if (sourceModule === undefined) continue; diff --git a/gitnexus/test/unit/group/include-extractor.test.ts b/gitnexus/test/unit/group/include-extractor.test.ts index 572d28959..49dcf0600 100644 --- a/gitnexus/test/unit/group/include-extractor.test.ts +++ b/gitnexus/test/unit/group/include-extractor.test.ts @@ -45,10 +45,7 @@ describe('IncludeExtractor', () => { expect(providers).toHaveLength(2); const ids = providers.map((p) => p.contractId).sort(); - expect(ids).toEqual([ - 'include::map/base/types.h', - 'include::map/base/view.h', - ]); + expect(ids).toEqual(['include::map/base/types.h', 'include::map/base/view.h']); expect(providers[0].type).toBe('include'); expect(providers[0].confidence).toBeGreaterThanOrEqual(0.95); }); @@ -91,10 +88,7 @@ int main() { return 0; }`, expect(consumers).toHaveLength(2); const ids = consumers.map((c) => c.contractId).sort(); - expect(ids).toEqual([ - 'include::map/base/types.h', - 'include::map/base/view.h', - ]); + expect(ids).toEqual(['include::map/base/types.h', 'include::map/base/view.h']); expect(consumers[0].type).toBe('include'); expect(consumers[0].confidence).toBe(0.85); }); @@ -181,22 +175,11 @@ int main() { return 0; }`, fs.mkdirSync(consumerDir, { recursive: true }); const consumerFile = path.join(consumerDir, 'src/controller.cpp'); fs.mkdirSync(path.dirname(consumerFile), { recursive: true }); - fs.writeFileSync( - consumerFile, - '#include "map/base/dice_map_view.h"\nvoid init() {}', - ); + fs.writeFileSync(consumerFile, '#include "map/base/dice_map_view.h"\nvoid init() {}'); try { - const providerContracts = await extractor.extract( - null, - providerDir, - makeRepo(providerDir), - ); - const consumerContracts = await extractor.extract( - null, - consumerDir, - makeRepo(consumerDir), - ); + const providerContracts = await extractor.extract(null, providerDir, makeRepo(providerDir)); + const consumerContracts = await extractor.extract(null, consumerDir, makeRepo(consumerDir)); const providers = providerContracts.filter((c) => c.role === 'provider'); const consumers = consumerContracts.filter((c) => c.role === 'consumer'); @@ -220,14 +203,8 @@ int main() { return 0; }`, describe('deduplication', () => { it('deduplicates same include from multiple source files', async () => { - writeFile( - 'src/a.cpp', - '#include "ext/api.h"\nvoid a() {}', - ); - writeFile( - 'src/b.cpp', - '#include "ext/api.h"\nvoid b() {}', - ); + writeFile('src/a.cpp', '#include "ext/api.h"\nvoid a() {}'); + writeFile('src/b.cpp', '#include "ext/api.h"\nvoid b() {}'); const contracts = await extractor.extract(null, tmpDir, makeRepo(tmpDir)); const consumers = contracts.filter((c) => c.role === 'consumer'); diff --git a/gitnexus/test/unit/scope-resolution/cpp/cpp-captures.test.ts b/gitnexus/test/unit/scope-resolution/cpp/cpp-captures.test.ts index 2334b6ddb..8e000261c 100644 --- a/gitnexus/test/unit/scope-resolution/cpp/cpp-captures.test.ts +++ b/gitnexus/test/unit/scope-resolution/cpp/cpp-captures.test.ts @@ -126,9 +126,7 @@ describe('emitCppScopeCaptures — namespace declarations', () => { }); it('anonymous namespace has no @declaration.namespace (only @scope.namespace)', () => { - const matches = allMatches('namespace { int x; }', (t) => - t.includes('@declaration.namespace'), - ); + const matches = allMatches('namespace { int x; }', (t) => t.includes('@declaration.namespace')); // Anonymous namespace should NOT produce a @declaration.namespace expect(matches.length).toBe(0); }); @@ -220,9 +218,7 @@ describe('emitCppScopeCaptures — variable declarations', () => { describe('emitCppScopeCaptures — enum declarations', () => { it('captures enum with @declaration.enum', () => { - const m = findMatch('enum Color { Red, Green, Blue };', (t) => - t.includes('@declaration.enum'), - ); + const m = findMatch('enum Color { Red, Green, Blue };', (t) => t.includes('@declaration.enum')); expect(m).toBeDefined(); expect(m!['@declaration.name'].text).toBe('Color'); }); @@ -288,9 +284,7 @@ describe('emitCppScopeCaptures — imports', () => { }); it('captures using namespace as wildcard import', () => { - const m = findMatch('using namespace std;', (t) => - t.includes('@import.using-namespace'), - ); + const m = findMatch('using namespace std;', (t) => t.includes('@import.using-namespace')); expect(m).toBeDefined(); expect(m!['@import.source'].text).toBe('std'); expect(m!['@import.kind'].text).toBe('wildcard'); @@ -381,9 +375,7 @@ describe('emitCppScopeCaptures — arity enrichment', () => { }); it('enriches zero-parameter function', () => { - const m = findMatch('void foo() {}', (t) => - t.includes('@declaration.parameter-count'), - ); + const m = findMatch('void foo() {}', (t) => t.includes('@declaration.parameter-count')); expect(m).toBeDefined(); expect(m!['@declaration.parameter-count'].text).toBe('0'); }); diff --git a/gitnexus/test/unit/scope-resolution/cpp/cpp-imports.test.ts b/gitnexus/test/unit/scope-resolution/cpp/cpp-imports.test.ts index 34b144777..6bc6e1b86 100644 --- a/gitnexus/test/unit/scope-resolution/cpp/cpp-imports.test.ts +++ b/gitnexus/test/unit/scope-resolution/cpp/cpp-imports.test.ts @@ -151,11 +151,7 @@ describe('C++ import target resolution (resolveCppImportTarget)', () => { }); it('resolves suffix match with depth tiebreak', () => { - const result = resolveCppImportTarget( - 'foo.h', - 'main.cpp', - new Set(['a/b/c/foo.h', 'z/foo.h']), - ); + const result = resolveCppImportTarget('foo.h', 'main.cpp', new Set(['a/b/c/foo.h', 'z/foo.h'])); expect(result).toBe('z/foo.h'); });