Skip to content

Commit 40dd0c5

Browse files
committed
fix(mcp): Update alias handling and cycle detection in decl rendering
1 parent 5bf1ae9 commit 40dd0c5

File tree

1 file changed

+55
-68
lines changed

1 file changed

+55
-68
lines changed

mcp/std.ts

Lines changed: 55 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -148,27 +148,37 @@ function renderModule(pkg_index: any) {
148148
}
149149

150150
function renderDecl(decl_index: any) {
151-
const category = wasm_exports.categorize_decl(decl_index, 0);
152-
switch (category) {
153-
case CAT_namespace:
154-
case CAT_container:
155-
return renderNamespacePage(decl_index);
156-
case CAT_global_variable:
157-
case CAT_primitive:
158-
case CAT_global_const:
159-
case CAT_type:
160-
case CAT_type_type:
161-
return renderGlobal(decl_index);
162-
case CAT_function:
163-
return renderFunction(decl_index);
164-
case CAT_type_function:
165-
return renderTypeFunction(decl_index);
166-
case CAT_error_set:
167-
return renderErrorSetPage(decl_index);
168-
case CAT_alias:
169-
return renderDecl(wasm_exports.get_aliasee());
170-
default:
171-
throw new Error("unrecognized category " + category);
151+
let current = decl_index;
152+
const seen = new Set<number>();
153+
while (true) {
154+
const category = wasm_exports.categorize_decl(current, 0);
155+
switch (category) {
156+
case CAT_namespace:
157+
case CAT_container:
158+
return renderNamespacePage(current);
159+
case CAT_global_variable:
160+
case CAT_primitive:
161+
case CAT_global_const:
162+
case CAT_type:
163+
case CAT_type_type:
164+
return renderGlobal(current);
165+
case CAT_function:
166+
return renderFunction(current);
167+
case CAT_type_function:
168+
return renderTypeFunction(current);
169+
case CAT_error_set:
170+
return renderErrorSetPage(current);
171+
case CAT_alias: {
172+
if (seen.has(current)) return renderNotFound();
173+
seen.add(current);
174+
const aliasee = wasm_exports.get_aliasee();
175+
if (aliasee === -1) return renderNotFound();
176+
current = aliasee;
177+
continue;
178+
}
179+
default:
180+
throw new Error("unrecognized category " + category);
181+
}
172182
}
173183
}
174184

@@ -406,6 +416,7 @@ function renderNamespaceMarkdown(base_decl: any, members: any, fields: any) {
406416
for (let i = 0; i < members.length; i++) {
407417
let member = members[i];
408418
const original = member;
419+
const seen = new Set<number>();
409420
while (true) {
410421
const member_category = wasm_exports.categorize_decl(member, 0);
411422
switch (member_category) {
@@ -433,9 +444,15 @@ function renderNamespaceMarkdown(base_decl: any, members: any, fields: any) {
433444
case CAT_primitive:
434445
valsList.push({ original: original, member: member });
435446
break;
436-
case CAT_alias:
447+
case CAT_alias: {
448+
if (seen.has(member)) {
449+
valsList.push({ original: original, member: member });
450+
break;
451+
}
452+
seen.add(member);
437453
member = wasm_exports.get_aliasee();
438454
continue;
455+
}
439456
default:
440457
throw new Error("unknown category: " + member_category);
441458
}
@@ -879,11 +896,21 @@ export async function getStdLibItem(
879896
}
880897

881898
if (getSourceFile) {
882-
// Get the source file using decl_source_html for the file root
883-
// We need to find the file that contains this declaration
884-
const fqn = fullyQualifiedName(decl_index);
885-
const filePath = getFilePathFromFqn(fqn);
886-
if (filePath) {
899+
// Resolve aliases by decl index
900+
let cur = decl_index;
901+
const seen = new Set<number>();
902+
while (true) {
903+
const cat = exports.categorize_decl(cur, 0);
904+
if (cat !== CAT_alias) break;
905+
if (seen.has(cur)) break; // cycle guard
906+
seen.add(cur);
907+
const next = exports.get_aliasee();
908+
if (next === -1 || next === cur) break;
909+
cur = next;
910+
}
911+
912+
const filePath = unwrapString(wasm_exports.decl_file_path(cur));
913+
if (filePath && filePath.length > 0) {
887914
const fileDecl = findFileRoot(filePath);
888915
if (fileDecl !== null) {
889916
let markdown = "";
@@ -895,45 +922,5 @@ export async function getStdLibItem(
895922
return `# Error\n\nCould not find source file for "${name}".`;
896923
}
897924

898-
const category = exports.categorize_decl(decl_index, 0);
899-
switch (category) {
900-
case CAT_namespace:
901-
case CAT_container:
902-
return renderNamespacePage(decl_index);
903-
case CAT_global_variable:
904-
case CAT_primitive:
905-
case CAT_global_const:
906-
case CAT_type:
907-
case CAT_type_type:
908-
return renderGlobal(decl_index);
909-
case CAT_function:
910-
return renderFunction(decl_index);
911-
case CAT_type_function:
912-
return renderTypeFunction(decl_index);
913-
case CAT_error_set:
914-
return renderErrorSetPage(decl_index);
915-
case CAT_alias:
916-
return getStdLibItem(
917-
wasmPath,
918-
stdSources,
919-
fullyQualifiedName(exports.get_aliasee()),
920-
getSourceFile,
921-
);
922-
default:
923-
return `# Error\n\nUnrecognized category ${category} for "${name}".`;
924-
}
925-
}
926-
927-
function getFilePathFromFqn(fqn: string): string | null {
928-
// Convert fully qualified name to file path
929-
const parts = fqn.split(".");
930-
if (parts.length < 2) return null;
931-
932-
if (parts[0] === "std" && parts.length >= 2) {
933-
return parts[0] + "/" + parts[1] + ".zig";
934-
}
935-
936-
const pathParts = parts.slice(0, -1);
937-
const filePath = pathParts.join("/") + ".zig";
938-
return filePath;
925+
return renderDecl(decl_index);
939926
}

0 commit comments

Comments
 (0)