Skip to content

Commit 2dd230b

Browse files
author
Linh Phan
committed
make key crossLanguageDefinitionId and fall back on namespace.name if empty
1 parent dfbf3b0 commit 2dd230b

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

packages/http-client-csharp/emitter/src/lib/client-model-builder.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export function createModel(sdkContext: CSharpEmitterContext): [CodeModel, reado
5858
if (type.kind === "model") {
5959
const model = type as InputModelType;
6060
models.push(model);
61-
existingModelKeys.add(`${model.namespace}.${model.name}`);
61+
existingModelKeys.add(typeDedupeKey(model));
6262
} else if (type.kind === "enum") {
6363
enums.push(type as InputEnumType);
6464
}
@@ -67,20 +67,22 @@ export function createModel(sdkContext: CSharpEmitterContext): [CodeModel, reado
6767
// response models for protocol-only paging operations where TCGC does not include the
6868
// response model in sdkPackage.models, or enums only reachable through nested property
6969
// types of such models). See https://github.com/microsoft/typespec/issues/9391. Dedupe
70-
// by namespace + name to avoid duplicates when TCGC produces a different reference for
71-
// the same type, while still allowing distinct types that share a name across namespaces.
72-
const existingEnumKeys = new Set(enums.map((e) => `${e.namespace}.${e.name}`));
70+
// by crossLanguageDefinitionId when available, falling back to namespace + name for
71+
// anonymous types (empty crossLanguageDefinitionId). This avoids duplicates when TCGC
72+
// produces a different reference for the same logical type, while still preserving
73+
// distinct types that share a name across different namespaces.
74+
const existingEnumKeys = new Set(enums.map((e) => typeDedupeKey(e)));
7375
for (const type of sdkContext.__typeCache.types.values()) {
7476
if (typesBeforeClients.has(type)) continue;
7577
if (type.kind === "model") {
7678
const model = type as InputModelType;
77-
const key = `${model.namespace}.${model.name}`;
79+
const key = typeDedupeKey(model);
7880
if (existingModelKeys.has(key)) continue;
7981
models.push(model);
8082
existingModelKeys.add(key);
8183
} else if (type.kind === "enum") {
8284
const enumType = type as InputEnumType;
83-
const key = `${enumType.namespace}.${enumType.name}`;
85+
const key = typeDedupeKey(enumType);
8486
if (existingEnumKeys.has(key)) continue;
8587
enums.push(enumType);
8688
existingEnumKeys.add(key);
@@ -187,6 +189,15 @@ function fixNamingConflicts(models: InputModelType[], constants: InputLiteralTyp
187189
}
188190
}
189191

192+
/**
193+
* Returns a dedup key for a model or enum type. Prefers `crossLanguageDefinitionId`
194+
* because it is the canonical identity TCGC assigns. Falls back to `namespace.name`
195+
* for anonymous/constant-derived types whose `crossLanguageDefinitionId` is empty.
196+
*/
197+
function typeDedupeKey(type: InputModelType | InputEnumType): string {
198+
return type.crossLanguageDefinitionId || `${type.namespace}.${type.name}`;
199+
}
200+
190201
function navigateModels(sdkContext: CSharpEmitterContext): [void, readonly Diagnostic[]] {
191202
const diagnostics = createDiagnosticCollector();
192203
for (const m of sdkContext.sdkPackage.models) {

0 commit comments

Comments
 (0)