MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / arkuiRouterEdges

Function arkuiRouterEdges

src/resolution/callback-synthesizer.ts:694–755  ·  view source on GitHub ↗

* Phase 4b-ets3: HarmonyOS page navigation. `router.pushUrl({ url: * 'pages/Detail' })` reaches the `@Entry struct` of * ` /src/main/ets/pages/Detail.ets`, but the hop is a string — no * static edge — so "tap → openDetail → ???" ends at the router call. Bridge * literal urls to the page s

(ctx: ResolutionContext, onYield: MaybeYield)

Source from the content-addressed store, hash-verified

692 * structs qualify as targets — the decorator is what makes a file a page.
693 */
694async function arkuiRouterEdges(ctx: ResolutionContext, onYield: MaybeYield): Promise<Edge[]> {
695 const edges: Edge[] = [];
696 const seen = new Set<string>();
697
698 const allFiles = ctx.getAllFiles();
699 const moduleDirs = (() => {
700 const ws = ctx.getWorkspacePackages?.();
701 return ws ? [...new Set(ws.byName.values())].sort((a, b) => b.length - a.length) : [];
702 })();
703 const moduleScopeOf = (file: string): string => {
704 for (const dir of moduleDirs) {
705 if (file === dir || file.startsWith(dir + '/')) return dir;
706 }
707 return '';
708 };
709
710 let scannedFiles = 0;
711 for (const file of allFiles) {
712 if ((++scannedFiles & 15) === 0) await onYield();
713 if (!file.endsWith('.ets')) continue;
714 const content = ctx.readFile(file);
715 if (!content || !content.includes('router.')) continue;
716 const safe = stripCommentsForRegex(content, 'typescript');
717 const nodes = ctx.getNodesInFile(file)
718 .filter((n) => n.kind === 'method' || n.kind === 'function');
719
720 ARKUI_ROUTER_RE.lastIndex = 0;
721 let m: RegExpExecArray | null;
722 while ((m = ARKUI_ROUTER_RE.exec(safe))) {
723 const url = m[1]!;
724 const line = safe.slice(0, m.index).split('\n').length;
725 const encl = nodes
726 .filter((n) => n.startLine <= line && n.endLine >= line)
727 .sort((a, b) => (a.endLine - a.startLine) - (b.endLine - b.startLine))[0];
728 if (!encl) continue;
729
730 const suffix = `/src/main/ets/${url}.ets`;
731 let candidates = allFiles.filter((f) => f.endsWith(suffix));
732 if (candidates.length > 1) {
733 const scope = moduleScopeOf(file);
734 const sameModule = candidates.filter((f) => moduleScopeOf(f) === scope);
735 if (sameModule.length > 0) candidates = sameModule;
736 }
737 if (candidates.length !== 1) continue; // ambiguous or unresolved — never guess
738
739 const page = ctx.getNodesInFile(candidates[0]!).find(
740 (n) => n.kind === 'struct' && (n.decorators ?? []).includes('Entry')
741 );
742 if (!page) continue;
743
744 const key = `${encl.id}>${page.id}`;
745 if (seen.has(key)) continue;
746 seen.add(key);
747 edges.push({
748 source: encl.id, target: page.id, kind: 'calls', line,
749 provenance: 'heuristic',
750 metadata: { synthesizedBy: 'arkui-route', event: url, registeredAt: `${candidates[0]}:${page.startLine}` },
751 });

Callers 1

Calls 8

stripCommentsForRegexFunction · 0.90
moduleScopeOfFunction · 0.85
getWorkspacePackagesMethod · 0.80
readFileMethod · 0.80
hasMethod · 0.80
getAllFilesMethod · 0.65
getNodesInFileMethod · 0.65
execMethod · 0.65

Tested by

no test coverage detected