Skip to content

Commit 52c4a6d

Browse files
committed
Fix C# docs validation by wrapping code in classes
The C# documentation validation was failing because: 1. Multiple files had top-level statements (C# only allows one per project) 2. Some snippets were missing the 'using GitHub.Copilot.SDK;' directive This fix: - Wraps C# code snippets without class/namespace in unique static classes - Preserves existing using directives and adds SDK using if missing - Detects async code (await keyword) and creates async Main methods - Skips wrapping for code that already has structure (classes, namespaces, delegates)
1 parent 6ca8a2c commit 52c4a6d

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

scripts/docs-validation/extract.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,68 @@ function wrapCodeForValidation(block: CodeBlock): string {
260260
}
261261
}
262262

263-
// C#: wrap in minimal structure if needed
263+
// C#: wrap in a class to avoid top-level statements conflicts
264+
// (C# only allows one file with top-level statements per project)
264265
if (block.language === "csharp") {
265266
// Check if it's a complete file (has namespace or class)
266267
const hasStructure =
267268
code.includes("namespace ") ||
268269
code.includes("class ") ||
269-
code.includes("record ");
270+
code.includes("record ") ||
271+
code.includes("public delegate ");
272+
270273
if (!hasStructure) {
271-
// Top-level statements are fine in modern C#, just ensure usings are at top
274+
// Extract any existing using statements
275+
const lines = code.split("\n");
276+
const usings: string[] = [];
277+
const rest: string[] = [];
278+
279+
for (const line of lines) {
280+
if (line.trim().startsWith("using ") && line.trim().endsWith(";")) {
281+
usings.push(line);
282+
} else {
283+
rest.push(line);
284+
}
285+
}
286+
287+
// Always ensure SDK using is present
288+
if (!usings.some(u => u.includes("GitHub.Copilot.SDK"))) {
289+
usings.push("using GitHub.Copilot.SDK;");
290+
}
291+
292+
// Generate a unique class name based on block location
293+
const className = `ValidationClass_${block.file.replace(/[^a-zA-Z0-9]/g, "_")}_${block.line}`;
294+
295+
// Wrap in async method to support await
296+
const hasAwait = code.includes("await ");
297+
const indentedCode = rest.map(l => " " + l).join("\n");
298+
299+
if (hasAwait) {
300+
code = `${usings.join("\n")}
301+
302+
public static class ${className}
303+
{
304+
public static async Task Main()
305+
{
306+
${indentedCode}
307+
}
308+
}`;
309+
} else {
310+
code = `${usings.join("\n")}
311+
312+
public static class ${className}
313+
{
314+
public static void Main()
315+
{
316+
${indentedCode}
317+
}
318+
}`;
319+
}
320+
} else {
321+
// Has structure, but may still need using directive
322+
if (!code.includes("using GitHub.Copilot.SDK;")) {
323+
code = "using GitHub.Copilot.SDK;\n" + code;
324+
}
272325
}
273326
}
274327

0 commit comments

Comments
 (0)