From a6c452433675f023e90c28432a7379eb2bea9100 Mon Sep 17 00:00:00 2001 From: Will Temple Date: Tue, 7 Oct 2025 15:20:52 -0400 Subject: [PATCH 1/3] core: exclude false members from @encodedName duplication tracking --- packages/compiler/src/lib/encoded-names.ts | 11 ++++++++++- packages/compiler/src/lib/visibility.ts | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/compiler/src/lib/encoded-names.ts b/packages/compiler/src/lib/encoded-names.ts index 3ccb45ecdd2..a7c04b792f9 100644 --- a/packages/compiler/src/lib/encoded-names.ts +++ b/packages/compiler/src/lib/encoded-names.ts @@ -106,7 +106,16 @@ export function validateEncodedNamesConflicts(program: Program) { for (const [target, map] of getEncodedNamesStateMap(program).entries()) { const scope = getScope(target); - if (scope === undefined) { + const memberValues = new Set(scope?.members.values()); + if ( + scope === undefined || + // Workaround: exclude members that aren't actually in the scope. This can happen when types of + // properties, enum members, or union variants are cloned for one reason or another, but are not + // actually attached to the parent type. This should probably be fixed in cloning logic (mutator + // implementation) instead, but for now this workaround solves some problems with false positives + // in duplication tracking here. + !memberValues.has(target) + ) { return; } for (const [mimeType, name] of map.entries()) { diff --git a/packages/compiler/src/lib/visibility.ts b/packages/compiler/src/lib/visibility.ts index b746dd3b4e2..591919c77d9 100644 --- a/packages/compiler/src/lib/visibility.ts +++ b/packages/compiler/src/lib/visibility.ts @@ -681,7 +681,7 @@ function createVisibilityFilterMutator( realm.remove(clone); modified = true; } else { - const mutated = mutateSubgraph(program, [mpMutator], prop); + const mutated = cachedMutateSubgraph(program, mpMutator, prop); clone.properties.set(key, mutated.type as ModelProperty); From fb0002c8a6ae1ccc17d3cde6f9380455101aa26f Mon Sep 17 00:00:00 2001 From: Will Temple Date: Tue, 7 Oct 2025 15:21:45 -0400 Subject: [PATCH 2/3] chronus --- ...le-msft-fix-encodedname-dup-detect-2025-9-7-15-21-36.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .chronus/changes/witemple-msft-fix-encodedname-dup-detect-2025-9-7-15-21-36.md diff --git a/.chronus/changes/witemple-msft-fix-encodedname-dup-detect-2025-9-7-15-21-36.md b/.chronus/changes/witemple-msft-fix-encodedname-dup-detect-2025-9-7-15-21-36.md new file mode 100644 index 00000000000..88a93e23eb9 --- /dev/null +++ b/.chronus/changes/witemple-msft-fix-encodedname-dup-detect-2025-9-7-15-21-36.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/compiler" +--- + +Addressed a bug that could cause duplicate `@encodedName` applications to be detected when none actually exist. \ No newline at end of file From 18ce33d4b5c6beccd563cc2f1d6f57f681633639 Mon Sep 17 00:00:00 2001 From: Will Temple Date: Tue, 28 Oct 2025 10:50:53 -0400 Subject: [PATCH 3/3] test --- packages/compiler/test/visibility.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/compiler/test/visibility.test.ts b/packages/compiler/test/visibility.test.ts index 82a2d892dfd..5247547e08f 100644 --- a/packages/compiler/test/visibility.test.ts +++ b/packages/compiler/test/visibility.test.ts @@ -1239,6 +1239,20 @@ describe("compiler: visibility core", () => { ok(arrA.properties.has("a")); ok(!arrA.properties.has("invisible")); }); + + it("does not duplicate encodedName metadata", async () => { + const diagnostics = await runner.diagnose(` + model SomeModel { + @visibility(Lifecycle.Read) + @encodedName("application/json", "some_other_name") + someOtherName: string; + } + + alias ReadModel = Read; + `); + + expectDiagnosticEmpty(diagnostics); + }); }); function validateCreateOrUpdateTransform(