Commit b48efe2
Fix malformed namespace generation for unresolved types in customization code (#9578)
## Fix for Malformed Namespace Generation in Customization Code
- [x] Understand root cause: Roslyn cannot resolve generated types in
customization code, leading to malformed namespaces
- [x] Move fix from TypeSymbolExtensions to
CSharpTypeExtensions.EnsureNamespace per code review feedback
- [x] Enhanced EnsureNamespace to look up types by name when spec
property is null
- [x] Handle edge case where types are renamed with CodeGenType
attribute
- [x] Add TypeProvidersByName dictionary for efficient name-based lookup
- [x] Remove redundant code and unnecessary variables
- [x] Add comprehensive tests validating the fix
- [x] Validate with existing test suite - all 2260 tests pass (including
2 new tests)
### Changes Made
**Modified:** `TypeFactory.cs`
- Added `TypeProvidersByName` dictionary mapping C# type names to
TypeProviders for efficient O(1) lookup
- Populated dictionary when adding types to CSharpTypeMap in CreateModel
and CreateEnum
**Modified:** `CSharpTypeExtensions.cs`
- Enhanced `EnsureNamespace` method to handle custom properties without
corresponding spec properties
- Added `TryFindCSharpTypeByName` with inline TypeFactory access for
cleaner code
- Returns properly qualified CSharpType by resolving through
TypeProvidersByName
**Added Tests:** `ModelCustomizationTests.cs`
- `CanAddPropertyReferencingGeneratedType`: Validates custom property
`IList<Bar>` gets proper namespace "Sample.Models"
- `CanAddPropertyReferencingRenamedGeneratedType`: Validates custom
property referencing CodeGenType renamed type gets proper namespace
- Both tests confirm namespaces are correctly resolved instead of being
empty or malformed
### Testing
All tests pass, confirming the fix resolves malformed namespace
generation for customization code.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[http-client-csharp] malformed code is generated on some
kind of customization code</issue_title>
> <issue_description>Sometimes, in customized code, roslyn cannot
analyze the correct namespace of some symbols (or maybe not?), and code
like this is generated:
> <img width="1850" height="878" alt="Image"
src="https://github.com/user-attachments/assets/1630f69a-b9c1-49f6-8073-386152826431"
/>
>
> We need to fix this.
> The above code was generated when we have the following customization:
> <img width="1613" height="694" alt="Image"
src="https://github.com/user-attachments/assets/f1df4239-5382-4acd-8e76-13dcd72c707f"
/>
>
> To reproduce:
> Prepare typespec:
> ```
> model Foo {
> bar?: Bar;
> }
>
> model Bar {
> b?: string;
> }
> ```
> In the generated code, add the following:
> ```
> [CodeGenSerialization(nameof(Bars), "bars"]
> public partial class Foo
> {
> public IList<Bar> Bars {get;}
> }
> ```
> then generate the code.</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@JoshLove-msft</author><body>
> @ArcturusZhang can you please add repro
instructions?</body></comment_new>
> <comment_new><author>@ArcturusZhang</author><body>
> > [@ArcturusZhang](https://github.com/ArcturusZhang) can you please
add repro instructions?
>
> added some reproduction steps.</body></comment_new>
> <comment_new><author>@jorgerangel-msft</author><body>
> The root cause of this may be that we are not successfully reading the
namespace of "non-primitive" generated types in the symbols therefore
when we write them out, there are no namespaces.</body></comment_new>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #9403
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>1 parent 5799e1b commit b48efe2
File tree
6 files changed
+124
-0
lines changed- packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator
- src
- Utilities
- test/Providers/ModelProviders
- TestData/ModelCustomizationTests
- CanAddPropertyReferencingGeneratedType
- CanAddPropertyReferencingRenamedGeneratedType
6 files changed
+124
-0
lines changedLines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
26 | 30 | | |
27 | 31 | | |
28 | 32 | | |
| |||
197 | 201 | | |
198 | 202 | | |
199 | 203 | | |
| 204 | + | |
200 | 205 | | |
201 | 206 | | |
202 | 207 | | |
| |||
255 | 260 | | |
256 | 261 | | |
257 | 262 | | |
| 263 | + | |
258 | 264 | | |
259 | 265 | | |
260 | 266 | | |
| |||
Lines changed: 24 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
50 | 62 | | |
51 | 63 | | |
52 | 64 | | |
| |||
64 | 76 | | |
65 | 77 | | |
66 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
67 | 91 | | |
68 | 92 | | |
69 | 93 | | |
| |||
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1475 | 1475 | | |
1476 | 1476 | | |
1477 | 1477 | | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
| 1527 | + | |
| 1528 | + | |
| 1529 | + | |
| 1530 | + | |
| 1531 | + | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
1478 | 1541 | | |
1479 | 1542 | | |
1480 | 1543 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
0 commit comments