Commit 76466bf
[C# Generator] Populate attributes from custom code properties and fields in NamedTypeSymbolProvider (#10322)
`NamedTypeSymbolProvider.BuildProperties()` and `BuildFields()` never
passed symbol attributes to the `PropertyProvider`/`FieldProvider`
constructors, so `CustomCodeView.Properties[*].Attributes` and
`CustomCodeView.Fields[*].Attributes` were always empty. This blocked
downstream consumers (e.g., mgmt generator) from detecting attributes
like `[Obsolete]` on custom code properties and fields.
### Changes
- **`NamedTypeSymbolProvider.cs`**: Extract `AttributeData` from each
`IPropertySymbol` and `IFieldSymbol` and pass as `attributes:` parameter
when constructing `PropertyProvider` and `FieldProvider`. All attributes
(including internal CodeGen attributes) are passed through without
filtering. Uses `.ToArray()` because the constructor's `(attributes as
IReadOnlyList<AttributeStatement>) ?? []` silently drops unmaterialized
`IEnumerable`.
```csharp
new PropertyProvider(
...,
this,
attributes: propertySymbol.GetAttributes().Select(a => new AttributeStatement(a)).ToArray())
new FieldProvider(
...,
attributes: fieldSymbol.GetAttributes().Select(a => new AttributeStatement(a)).ToArray())
```
- **`FieldProvider.cs`**: Updated `InitializeParameter()` to filter out
codegen-related attributes (from the
`Microsoft.TypeSpec.Generator.Customizations` namespace) when
propagating field attributes to constructor parameters via
`AsParameter`. This ensures user-facing attributes like `[Obsolete]`
propagate to generated constructor parameters, while internal codegen
attributes like `[CodeGenMember]` do not appear in generated code. The
field itself retains all attributes for downstream consumers.
```csharp
var paramAttributes = Attributes.Where(a => a.Type.Namespace != CodeModelGenerator.CustomizationAttributeNamespace).ToArray();
_parameter = new(() => new ParameterProvider(
..., attributes: paramAttributes));
```
- **Test**: Added `CanReadPropertyAttributes` with a custom code file
declaring `[Obsolete]` (with a named argument `DiagnosticId`),
`[EditorBrowsable]`, and a custom non-system attribute on a property,
plus `[Obsolete]` on a field. The test validates attribute types using
`CSharpType.Equals`, checks argument counts, validates
`PositionalArguments`, and ensures the generator does not throw for
custom non-system attributes.
---------
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>1 parent a894bbb commit 76466bf
4 files changed
Lines changed: 75 additions & 3 deletions
File tree
- packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator
- src/Providers
- test/Providers/ModelProviders
- TestData/ModelCustomizationTests/CanReadPropertyAttributes
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
147 | 148 | | |
148 | 149 | | |
149 | 150 | | |
| 151 | + | |
150 | 152 | | |
151 | | - | |
| 153 | + | |
152 | 154 | | |
153 | 155 | | |
154 | 156 | | |
| |||
Lines changed: 4 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
125 | | - | |
| 125 | + | |
| 126 | + | |
126 | 127 | | |
127 | 128 | | |
128 | 129 | | |
| |||
146 | 147 | | |
147 | 148 | | |
148 | 149 | | |
149 | | - | |
| 150 | + | |
| 151 | + | |
150 | 152 | | |
151 | 153 | | |
152 | 154 | | |
| |||
Lines changed: 45 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
1698 | 1699 | | |
1699 | 1700 | | |
1700 | 1701 | | |
| 1702 | + | |
| 1703 | + | |
| 1704 | + | |
| 1705 | + | |
| 1706 | + | |
| 1707 | + | |
| 1708 | + | |
| 1709 | + | |
| 1710 | + | |
| 1711 | + | |
| 1712 | + | |
| 1713 | + | |
| 1714 | + | |
| 1715 | + | |
| 1716 | + | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
| 1720 | + | |
| 1721 | + | |
| 1722 | + | |
| 1723 | + | |
| 1724 | + | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
| 1728 | + | |
| 1729 | + | |
| 1730 | + | |
| 1731 | + | |
| 1732 | + | |
| 1733 | + | |
| 1734 | + | |
| 1735 | + | |
| 1736 | + | |
| 1737 | + | |
| 1738 | + | |
| 1739 | + | |
| 1740 | + | |
| 1741 | + | |
| 1742 | + | |
| 1743 | + | |
| 1744 | + | |
| 1745 | + | |
1701 | 1746 | | |
1702 | 1747 | | |
1703 | 1748 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
0 commit comments