Skip to content

Commit d5dbff0

Browse files
Possible naming improvements via codegen changes
Co-Authored-By: SteveSandersonMS <1101362+SteveSandersonMS@users.noreply.github.com>
1 parent e0a9028 commit d5dbff0

12 files changed

Lines changed: 2824 additions & 2750 deletions

File tree

dotnet/src/Generated/Rpc.cs

Lines changed: 407 additions & 403 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dotnet/src/Generated/SessionEvents.cs

Lines changed: 235 additions & 235 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/generated_session_events.go

Lines changed: 193 additions & 193 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/rpc/generated_rpc.go

Lines changed: 373 additions & 376 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nodejs/src/generated/rpc.ts

Lines changed: 309 additions & 304 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/copilot/generated/rpc.py

Lines changed: 877 additions & 879 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/copilot/generated/session_events.py

Lines changed: 274 additions & 274 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/codegen/csharp.ts

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import path from "path";
1212
import { promisify } from "util";
1313
import type { JSONSchema7 } from "json-schema";
1414
import {
15-
getSessionEventsSchemaPath,
15+
applyTitleSuggestions,
1616
getApiSchemaPath,
17-
writeGeneratedFile,
18-
isRpcMethod,
17+
getRpcSchemaTypeName,
18+
getSessionEventsSchemaPath,
1919
isNodeFullyExperimental,
20+
isRpcMethod,
2021
EXCLUDED_EVENT_TYPES,
2122
REPO_ROOT,
23+
writeGeneratedFile,
2224
type ApiSchema,
2325
type RpcMethod,
2426
} from "./utils.js";
@@ -199,12 +201,12 @@ interface EventVariant {
199201

200202
let generatedEnums = new Map<string, { enumName: string; values: string[] }>();
201203

202-
function getOrCreateEnum(parentClassName: string, propName: string, values: string[], enumOutput: string[], description?: string): string {
204+
function getOrCreateEnum(parentClassName: string, propName: string, values: string[], enumOutput: string[], description?: string, explicitName?: string): string {
203205
const valuesKey = [...values].sort().join("|");
204206
for (const [, existing] of generatedEnums) {
205207
if ([...existing.values].sort().join("|") === valuesKey) return existing.enumName;
206208
}
207-
const enumName = `${parentClassName}${propName}`;
209+
const enumName = explicitName ?? `${parentClassName}${propName}`;
208210
generatedEnums.set(enumName, { enumName, values });
209211

210212
const lines: string[] = [];
@@ -413,7 +415,7 @@ function resolveSessionPropertyType(
413415
const variants = nonNull as JSONSchema7[];
414416
const discriminatorInfo = findDiscriminator(variants);
415417
if (discriminatorInfo) {
416-
const baseClassName = `${parentClassName}${propName}`;
418+
const baseClassName = (propSchema.title as string) ?? `${parentClassName}${propName}`;
417419
const renamedBase = applyTypeRename(baseClassName);
418420
const polymorphicCode = generatePolymorphicClasses(baseClassName, discriminatorInfo.property, variants, knownTypes, nestedClasses, enumOutput, propSchema.description);
419421
nestedClasses.set(renamedBase, polymorphicCode);
@@ -423,11 +425,11 @@ function resolveSessionPropertyType(
423425
return hasNull || !isRequired ? "object?" : "object";
424426
}
425427
if (propSchema.enum && Array.isArray(propSchema.enum)) {
426-
const enumName = getOrCreateEnum(parentClassName, propName, propSchema.enum as string[], enumOutput, propSchema.description);
428+
const enumName = getOrCreateEnum(parentClassName, propName, propSchema.enum as string[], enumOutput, propSchema.description, propSchema.title as string | undefined);
427429
return isRequired ? enumName : `${enumName}?`;
428430
}
429431
if (propSchema.type === "object" && propSchema.properties) {
430-
const nestedClassName = `${parentClassName}${propName}`;
432+
const nestedClassName = (propSchema.title as string) ?? `${parentClassName}${propName}`;
431433
nestedClasses.set(nestedClassName, generateNestedClass(nestedClassName, propSchema, knownTypes, nestedClasses, enumOutput));
432434
return isRequired ? nestedClassName : `${nestedClassName}?`;
433435
}
@@ -438,20 +440,20 @@ function resolveSessionPropertyType(
438440
const variants = items.anyOf.filter((v): v is JSONSchema7 => typeof v === "object");
439441
const discriminatorInfo = findDiscriminator(variants);
440442
if (discriminatorInfo) {
441-
const baseClassName = `${parentClassName}${propName}Item`;
443+
const baseClassName = (items.title as string) ?? `${parentClassName}${propName}Item`;
442444
const renamedBase = applyTypeRename(baseClassName);
443445
const polymorphicCode = generatePolymorphicClasses(baseClassName, discriminatorInfo.property, variants, knownTypes, nestedClasses, enumOutput, items.description);
444446
nestedClasses.set(renamedBase, polymorphicCode);
445447
return isRequired ? `${renamedBase}[]` : `${renamedBase}[]?`;
446448
}
447449
}
448450
if (items.type === "object" && items.properties) {
449-
const itemClassName = `${parentClassName}${propName}Item`;
451+
const itemClassName = (items.title as string) ?? `${parentClassName}${propName}Item`;
450452
nestedClasses.set(itemClassName, generateNestedClass(itemClassName, items, knownTypes, nestedClasses, enumOutput));
451453
return isRequired ? `${itemClassName}[]` : `${itemClassName}[]?`;
452454
}
453455
if (items.enum && Array.isArray(items.enum)) {
454-
const enumName = getOrCreateEnum(parentClassName, `${propName}Item`, items.enum as string[], enumOutput, items.description);
456+
const enumName = getOrCreateEnum(parentClassName, `${propName}Item`, items.enum as string[], enumOutput, items.description, items.title as string | undefined);
455457
return isRequired ? `${enumName}[]` : `${enumName}[]?`;
456458
}
457459
const itemType = schemaTypeToCSharp(items, true, knownTypes);
@@ -584,7 +586,7 @@ namespace GitHub.Copilot.SDK;
584586
export async function generateSessionEvents(schemaPath?: string): Promise<void> {
585587
console.log("C#: generating session-events...");
586588
const resolvedPath = schemaPath ?? (await getSessionEventsSchemaPath());
587-
const schema = JSON.parse(await fs.readFile(resolvedPath, "utf-8")) as JSONSchema7;
589+
const schema = applyTitleSuggestions(JSON.parse(await fs.readFile(resolvedPath, "utf-8")) as JSONSchema7);
588590
const code = generateSessionEventsCode(schema);
589591
const outPath = await writeGeneratedFile("dotnet/src/Generated/SessionEvents.cs", code);
590592
console.log(` ✓ ${outPath}`);
@@ -608,12 +610,12 @@ function singularPascal(s: string): string {
608610
return p;
609611
}
610612

611-
function resultTypeName(rpcMethod: string): string {
612-
return `${typeToClassName(rpcMethod)}Result`;
613+
function resultTypeName(method: RpcMethod): string {
614+
return getRpcSchemaTypeName(method.result, `${typeToClassName(method.rpcMethod)}Result`);
613615
}
614616

615-
function paramsTypeName(rpcMethod: string): string {
616-
return `${typeToClassName(rpcMethod)}Params`;
617+
function paramsTypeName(method: RpcMethod): string {
618+
return getRpcSchemaTypeName(method.params, `${typeToClassName(method.rpcMethod)}Request`);
617619
}
618620

619621
function resolveRpcType(schema: JSONSchema7, isRequired: boolean, parentClassName: string, propName: string, classes: string[]): string {
@@ -627,7 +629,14 @@ function resolveRpcType(schema: JSONSchema7, isRequired: boolean, parentClassNam
627629
}
628630
// Handle enums (string unions like "interactive" | "plan" | "autopilot")
629631
if (schema.enum && Array.isArray(schema.enum)) {
630-
const enumName = getOrCreateEnum(parentClassName, propName, schema.enum as string[], rpcEnumOutput, schema.description);
632+
const enumName = getOrCreateEnum(
633+
parentClassName,
634+
propName,
635+
schema.enum as string[],
636+
rpcEnumOutput,
637+
schema.description,
638+
schema.title as string | undefined,
639+
);
631640
return isRequired ? enumName : `${enumName}?`;
632641
}
633642
if (schema.type === "object" && schema.properties) {
@@ -638,17 +647,28 @@ function resolveRpcType(schema: JSONSchema7, isRequired: boolean, parentClassNam
638647
if (schema.type === "array" && schema.items) {
639648
const items = schema.items as JSONSchema7;
640649
if (items.type === "object" && items.properties) {
641-
const itemClass = singularPascal(propName);
650+
const itemClass = (items.title as string) ?? singularPascal(propName);
642651
if (!emittedRpcClasses.has(itemClass)) classes.push(emitRpcClass(itemClass, items, "public", classes));
643652
return isRequired ? `List<${itemClass}>` : `List<${itemClass}>?`;
644653
}
654+
if (items.enum && Array.isArray(items.enum)) {
655+
const itemEnum = getOrCreateEnum(
656+
parentClassName,
657+
`${propName}Item`,
658+
items.enum as string[],
659+
rpcEnumOutput,
660+
items.description,
661+
items.title as string | undefined,
662+
);
663+
return isRequired ? `List<${itemEnum}>` : `List<${itemEnum}>?`;
664+
}
645665
const itemType = schemaTypeToCSharp(items, true, rpcKnownTypes);
646666
return isRequired ? `List<${itemType}>` : `List<${itemType}>?`;
647667
}
648668
if (schema.type === "object" && schema.additionalProperties && typeof schema.additionalProperties === "object") {
649669
const vs = schema.additionalProperties as JSONSchema7;
650670
if (vs.type === "object" && vs.properties) {
651-
const valClass = `${parentClassName}${propName}Value`;
671+
const valClass = (vs.title as string) ?? `${parentClassName}${propName}Value`;
652672
classes.push(emitRpcClass(valClass, vs, "public", classes));
653673
return isRequired ? `Dictionary<string, ${valClass}>` : `Dictionary<string, ${valClass}>?`;
654674
}
@@ -785,7 +805,7 @@ function emitServerInstanceMethod(
785805
groupExperimental: boolean
786806
): void {
787807
const methodName = toPascalCase(name);
788-
const resultClassName = `${typeToClassName(method.rpcMethod)}Result`;
808+
const resultClassName = resultTypeName(method);
789809
if (method.stability === "experimental") {
790810
experimentalRpcTypes.add(resultClassName);
791811
}
@@ -797,7 +817,7 @@ function emitServerInstanceMethod(
797817

798818
let requestClassName: string | null = null;
799819
if (paramEntries.length > 0) {
800-
requestClassName = `${typeToClassName(method.rpcMethod)}Request`;
820+
requestClassName = paramsTypeName(method);
801821
if (method.stability === "experimental") {
802822
experimentalRpcTypes.add(requestClassName);
803823
}
@@ -872,7 +892,7 @@ function emitSessionRpcClasses(node: Record<string, unknown>, classes: string[])
872892

873893
function emitSessionMethod(key: string, method: RpcMethod, lines: string[], classes: string[], indent: string, groupExperimental: boolean): void {
874894
const methodName = toPascalCase(key);
875-
const resultClassName = `${typeToClassName(method.rpcMethod)}Result`;
895+
const resultClassName = resultTypeName(method);
876896
if (method.stability === "experimental") {
877897
experimentalRpcTypes.add(resultClassName);
878898
}
@@ -889,7 +909,7 @@ function emitSessionMethod(key: string, method: RpcMethod, lines: string[], clas
889909
return aReq - bReq;
890910
});
891911

892-
const requestClassName = `${typeToClassName(method.rpcMethod)}Request`;
912+
const requestClassName = paramsTypeName(method);
893913
if (method.stability === "experimental") {
894914
experimentalRpcTypes.add(requestClassName);
895915
}
@@ -964,12 +984,12 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
964984
for (const { methods } of groups) {
965985
for (const method of methods) {
966986
if (method.result) {
967-
const resultClass = emitRpcClass(resultTypeName(method.rpcMethod), method.result, "public", classes);
987+
const resultClass = emitRpcClass(resultTypeName(method), method.result, "public", classes);
968988
if (resultClass) classes.push(resultClass);
969989
}
970990

971991
if (method.params?.properties && Object.keys(method.params.properties).length > 0) {
972-
const paramsClass = emitRpcClass(paramsTypeName(method.rpcMethod), method.params, "public", classes);
992+
const paramsClass = emitRpcClass(paramsTypeName(method), method.params, "public", classes);
973993
if (paramsClass) classes.push(paramsClass);
974994
}
975995
}
@@ -986,13 +1006,13 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
9861006
lines.push(`{`);
9871007
for (const method of methods) {
9881008
const hasParams = method.params?.properties && Object.keys(method.params.properties).length > 0;
989-
const taskType = method.result ? `Task<${resultTypeName(method.rpcMethod)}>` : "Task";
1009+
const taskType = method.result ? `Task<${resultTypeName(method)}>` : "Task";
9901010
lines.push(` /// <summary>Handles "${method.rpcMethod}".</summary>`);
9911011
if (method.stability === "experimental" && !groupExperimental) {
9921012
lines.push(` [Experimental(Diagnostics.Experimental)]`);
9931013
}
9941014
if (hasParams) {
995-
lines.push(` ${taskType} ${clientHandlerMethodName(method.rpcMethod)}(${paramsTypeName(method.rpcMethod)} request, CancellationToken cancellationToken = default);`);
1015+
lines.push(` ${taskType} ${clientHandlerMethodName(method.rpcMethod)}(${paramsTypeName(method)} request, CancellationToken cancellationToken = default);`);
9961016
} else {
9971017
lines.push(` ${taskType} ${clientHandlerMethodName(method.rpcMethod)}(CancellationToken cancellationToken = default);`);
9981018
}
@@ -1028,8 +1048,8 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
10281048
const handlerProperty = toPascalCase(groupName);
10291049
const handlerMethod = clientHandlerMethodName(method.rpcMethod);
10301050
const hasParams = method.params?.properties && Object.keys(method.params.properties).length > 0;
1031-
const paramsClass = paramsTypeName(method.rpcMethod);
1032-
const taskType = method.result ? `Task<${resultTypeName(method.rpcMethod)}>` : "Task";
1051+
const paramsClass = paramsTypeName(method);
1052+
const taskType = method.result ? `Task<${resultTypeName(method)}>` : "Task";
10331053
const registrationVar = `register${typeToClassName(method.rpcMethod)}Method`;
10341054

10351055
if (hasParams) {
@@ -1120,7 +1140,7 @@ internal static class Diagnostics
11201140
export async function generateRpc(schemaPath?: string): Promise<void> {
11211141
console.log("C#: generating RPC types...");
11221142
const resolvedPath = schemaPath ?? (await getApiSchemaPath());
1123-
const schema = JSON.parse(await fs.readFile(resolvedPath, "utf-8")) as ApiSchema;
1143+
const schema = applyTitleSuggestions(JSON.parse(await fs.readFile(resolvedPath, "utf-8")) as ApiSchema);
11241144
const code = generateRpcCode(schema);
11251145
const outPath = await writeGeneratedFile("dotnet/src/Generated/Rpc.cs", code);
11261146
console.log(` ✓ ${outPath}`);

0 commit comments

Comments
 (0)