Skip to content

Commit c54721e

Browse files
committed
Add TomlSerializable source-gen roots
Fix #113 Warn when JsonSerializable is used on TomlSerializerContext and switch the repo, tests, and docs to the dedicated TomlSerializable root attribute. Also add TypeInfoPropertyName parity and remove the SYSLIB1224 suppressions that are no longer needed.
1 parent b30d070 commit c54721e

18 files changed

+267
-77
lines changed

readme.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Tomlyn is a high-performance .NET TOML 1.1 parser, round-trippable syntax tree,
1212

1313
- **`System.Text.Json`-style API**: familiar surface with `TomlSerializer`, `TomlSerializerOptions`, `TomlTypeInfo<T>`
1414
- **TOML 1.1.0 only**: Tomlyn v1 targets TOML 1.1.0 and does **not** support TOML 1.0
15-
- **Source generation**: NativeAOT / trimming friendly via `TomlSerializerContext` - reuses `[JsonSerializable]` attributes
15+
- **Source generation**: NativeAOT / trimming friendly via `TomlSerializerContext` and `[TomlSerializable]` roots
1616
- **`System.Text.Json` attribute interop**: reuse `[JsonPropertyName]`, `[JsonIgnore]`, `[JsonRequired]`, `[JsonConstructor]`, polymorphism attributes
1717
- **Allocation-free parsing pipeline**: incremental `TomlLexer``TomlParser` with precise spans for errors
1818
- **Low-level access**: full lexer/parser API plus a lossless, trivia-preserving syntax tree (`SyntaxParser``DocumentSyntax`)
@@ -97,13 +97,11 @@ public sealed class MyConfig
9797
public string? Global { get; set; }
9898
}
9999

100-
#pragma warning disable SYSLIB1224
101100
[TomlSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
102-
[JsonSerializable(typeof(MyConfig))]
101+
[TomlSerializable(typeof(MyConfig))]
103102
internal partial class MyTomlContext : TomlSerializerContext
104103
{
105104
}
106-
#pragma warning restore SYSLIB1224
107105

108106
var config = TomlSerializer.Deserialize(toml, MyTomlContext.Default.MyConfig);
109107
var tomlOut = TomlSerializer.Serialize(config, MyTomlContext.Default.MyConfig);

site/docs/compatibility.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ See [Source generation and NativeAOT](source-generation.md) for details.
4444

4545
## System.Text.Json interop
4646

47-
Tomlyn reuses [`System.Text.Json`](xref:System.Text.Json) types in two areas:
47+
Tomlyn reuses [`System.Text.Json`](xref:System.Text.Json) types in several areas:
4848

4949
- **Naming policies** - [`TomlSerializerOptions.PropertyNamingPolicy`](xref:Tomlyn.TomlSerializerOptions.PropertyNamingPolicy) accepts any [`JsonNamingPolicy`](xref:System.Text.Json.JsonNamingPolicy).
5050
- **Attributes** - most common [`System.Text.Json.Serialization`](xref:System.Text.Json.Serialization) attributes work out of the box.
51-
- **Source generation** - [`[JsonSerializable]`](xref:System.Text.Json.Serialization.JsonSerializableAttribute) roots and [`JsonKnownNamingPolicy`](xref:System.Text.Json.JsonKnownNamingPolicy) are used for context declaration.
51+
- **Source generation** - [`[TomlSerializable]`](xref:Tomlyn.Serialization.TomlSerializableAttribute) roots declare TOML contexts, while [`JsonKnownNamingPolicy`](xref:System.Text.Json.JsonKnownNamingPolicy) remains available for compile-time naming options.
5252

5353
> [!NOTE]
5454
> This allows you to share model classes between JSON and TOML serializers. TOML-specific attributes take precedence when both are present.

site/docs/getting-started.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,10 @@ See [DOM model](dom.md) for more details.
164164
For NativeAOT / trimming, declare a [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext) and use generated metadata:
165165

166166
```csharp
167-
using System.Text.Json.Serialization;
168167
using Tomlyn;
169168
using Tomlyn.Serialization;
170169

171-
[JsonSerializable(typeof(ServerConfig))]
170+
[TomlSerializable(typeof(ServerConfig))]
172171
internal partial class MyTomlContext : TomlSerializerContext { }
173172

174173
var toml = TomlSerializer.Serialize(config, MyTomlContext.Default.ServerConfig);

site/docs/migration.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ This page summarizes the major breaking changes when migrating from Tomlyn v0.x.
1919
| `Toml.Parse(...)` | [`SyntaxParser.Parse(...)`](xref:Tomlyn.Parsing.SyntaxParser) / `ParseStrict(...)` |
2020
| `DocumentSyntax.Tokens()` | [`TomlLexer`](xref:Tomlyn.Parsing.TomlLexer) |
2121
| `ITomlMetadataProvider` (on your types) | [`TomlSerializerOptions.MetadataStore`](xref:Tomlyn.TomlSerializerOptions.MetadataStore) (external store) |
22-
| `[TomlModel]` source gen roots | [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext) + [`JsonSerializable`](xref:System.Text.Json.Serialization.JsonSerializableAttribute) |
22+
| `[TomlModel]` source gen roots | [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext) + [`TomlSerializable`](xref:Tomlyn.Serialization.TomlSerializableAttribute) |
2323

2424
## Main API shape (TomlSerializer)
2525

@@ -68,17 +68,16 @@ v0.x source generation required referencing an analyzer and marking a root model
6868
Tomlyn v1 uses a `System.Text.Json`-style source generation model based on:
6969

7070
- [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext)
71-
- [`JsonSerializableAttribute`](xref:System.Text.Json.Serialization.JsonSerializableAttribute) roots
71+
- [`TomlSerializableAttribute`](xref:Tomlyn.Serialization.TomlSerializableAttribute) roots
7272

7373
> [!NOTE]
7474
> The Tomlyn v1 source generator ships with the main `Tomlyn` NuGet package (as a compiler analyzer).
7575
> You typically only need to add a `TomlSerializerContext` to your project.
7676
7777
```csharp
78-
using System.Text.Json.Serialization;
7978
using Tomlyn.Serialization;
8079

81-
[JsonSerializable(typeof(MyType))]
80+
[TomlSerializable(typeof(MyType))]
8281
internal partial class MyTomlContext : TomlSerializerContext
8382
{
8483
}

site/docs/serialization.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,10 @@ See [Source generation and NativeAOT](source-generation.md) for full details.
5656
## Using a source-generated context
5757

5858
```csharp
59-
using System.Text.Json.Serialization;
6059
using Tomlyn;
6160
using Tomlyn.Serialization;
6261

63-
[JsonSerializable(typeof(MyConfig))]
62+
[TomlSerializable(typeof(MyConfig))]
6463
internal partial class MyTomlContext : TomlSerializerContext { }
6564

6665
var context = MyTomlContext.Default;
@@ -317,7 +316,7 @@ public sealed class Config
317316

318317
```csharp
319318
[TomlSourceGenerationOptions(Converters = [typeof(UpperCaseStringConverter)])]
320-
[JsonSerializable(typeof(Config))]
319+
[TomlSerializable(typeof(Config))]
321320
internal partial class MyTomlContext : TomlSerializerContext { }
322321
```
323322

site/docs/source-generation.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ It follows the same patterns as [`System.Text.Json`](xref:System.Text.Json) sour
1818

1919
## Define a context
2020

21-
Declare a `partial` class that inherits from [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext) and annotate it with [`[JsonSerializable]`](xref:System.Text.Json.Serialization.JsonSerializableAttribute) for each root type:
21+
Declare a `partial` class that inherits from [`TomlSerializerContext`](xref:Tomlyn.Serialization.TomlSerializerContext) and annotate it with [`[TomlSerializable]`](xref:Tomlyn.Serialization.TomlSerializableAttribute) for each root type:
2222

2323
```csharp
24-
using System.Text.Json.Serialization;
2524
using Tomlyn.Serialization;
2625

2726
public sealed class ServerConfig
@@ -30,12 +29,13 @@ public sealed class ServerConfig
3029
public int Port { get; set; } = 8080;
3130
}
3231

33-
[JsonSerializable(typeof(ServerConfig))]
32+
[TomlSerializable(typeof(ServerConfig))]
3433
internal partial class MyTomlContext : TomlSerializerContext { }
3534
```
3635

3736
The generator produces a `Default` singleton and a typed [`TomlTypeInfo<T>`](xref:Tomlyn.TomlTypeInfo`1) property for each root.
3837
Nested types referenced by the root are discovered transitively - you only need to annotate top-level types.
38+
Set [`TomlSerializableAttribute.TypeInfoPropertyName`](xref:Tomlyn.Serialization.TomlSerializableAttribute.TypeInfoPropertyName) when you want to customize the generated property name exposed by the context.
3939

4040
## Use generated metadata
4141

@@ -72,7 +72,7 @@ using Tomlyn.Serialization;
7272
WriteIndented = true,
7373
IndentSize = 2,
7474
DefaultIgnoreCondition = TomlIgnoreCondition.WhenWritingNull)]
75-
[JsonSerializable(typeof(ServerConfig))]
75+
[TomlSerializable(typeof(ServerConfig))]
7676
internal partial class MyTomlContext : TomlSerializerContext { }
7777
```
7878

@@ -81,7 +81,7 @@ internal partial class MyTomlContext : TomlSerializerContext { }
8181
```csharp
8282
[TomlSourceGenerationOptions(
8383
Converters = [typeof(MyCustomConverter)])]
84-
[JsonSerializable(typeof(ServerConfig))]
84+
[TomlSerializable(typeof(ServerConfig))]
8585
internal partial class MyTomlContext : TomlSerializerContext { }
8686
```
8787

@@ -140,10 +140,10 @@ You can also disable reflection via MSBuild in your project file:
140140
You can define multiple contexts for different parts of your application:
141141

142142
```csharp
143-
[JsonSerializable(typeof(ServerConfig))]
143+
[TomlSerializable(typeof(ServerConfig))]
144144
internal partial class ServerContext : TomlSerializerContext { }
145145

146-
[JsonSerializable(typeof(DatabaseConfig))]
146+
[TomlSerializable(typeof(DatabaseConfig))]
147147
internal partial class DatabaseContext : TomlSerializerContext { }
148148
```
149149

@@ -153,6 +153,6 @@ internal partial class DatabaseContext : TomlSerializerContext { }
153153
| --- | --- |
154154
| Generated properties are missing | Ensure the project references the `Tomlyn` NuGet package (the generator is shipped under `analyzers/dotnet/cs`). |
155155
| Compilation errors on context | Ensure the context class is `partial`. |
156-
| Type not found on context | Ensure root types are declared via `[JsonSerializable(typeof(...))]`. |
156+
| Type not found on context | Ensure root types are declared via `[TomlSerializable(typeof(...))]`. |
157157
| Nested types not serialized | Nested types are discovered transitively - verify they're reachable from a root type. |
158158
| Converter not applied | Use `TomlSourceGenerationOptionsAttribute.Converters` instead of `TomlConverterAttribute` for source-generated contexts. |

src/Tomlyn.AotTests/Program.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,9 @@ internal sealed class PlatformConfig
318318
}
319319
}
320320

321-
#pragma warning disable SYSLIB1224
322321
[TomlSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower)]
323-
[JsonSerializable(typeof(Program.RootConfig))]
324-
[JsonSerializable(typeof(TomlTable))]
322+
[TomlSerializable(typeof(Program.RootConfig))]
323+
[TomlSerializable(typeof(TomlTable))]
325324
internal partial class AotTomlSerializerContext : TomlSerializerContext
326325
{
327326
}
328-
#pragma warning restore SYSLIB1224

src/Tomlyn.AotTests/Tomlyn.AotTests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8-
<NoWarn>$(NoWarn);SYSLIB1224</NoWarn>
98
<PublishAot>true</PublishAot>
109
<InvariantGlobalization>true</InvariantGlobalization>
1110
<IsPackable>false</IsPackable>

src/Tomlyn.Benchmarks.SourceGen/Tomlyn.Benchmarks.SourceGen.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<Nullable>enable</Nullable>
88
<IsPackable>false</IsPackable>
99
<LangVersion>latest</LangVersion>
10-
<NoWarn>$(NoWarn);SYSLIB1224</NoWarn>
1110
</PropertyGroup>
1211

1312
<ItemGroup>

src/Tomlyn.Benchmarks.SourceGen/TomlynBenchmarkContext.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using System.Text.Json.Serialization;
21
using Tomlyn.Serialization;
32

43
namespace Tomlyn.Benchmarks;
54

6-
[JsonSerializable(typeof(BenchmarkDocument))]
5+
[TomlSerializable(typeof(BenchmarkDocument))]
76
internal partial class TomlynBenchmarkContext : TomlSerializerContext
87
{
98
}

0 commit comments

Comments
 (0)