v1.1.0 — Spec compliance, IEnumerable<T> support, source generator fixes#14
Merged
iamadamreed merged 14 commits intomainfrom Mar 8, 2026
Merged
v1.1.0 — Spec compliance, IEnumerable<T> support, source generator fixes#14iamadamreed merged 14 commits intomainfrom
iamadamreed merged 14 commits intomainfrom
Conversation
Use SafePropertyName instead of TypeName for generated file names. This prevents collisions when registering multiple generic types with the same base type (e.g., List<TypeA> and List<TypeB>).
- Fix duplicate local variable names in deserialization by adding unique index suffixes to pattern match variables (n0, s0, v0, etc.) - Generate serializers for all concrete context types, not just those with parameterless constructors (needed for PropertyNames, WriteRow) - Skip Deserialize method generation for non-instantiable types
- Add writer.Flush() before returning string in generated SerializeToString - Add GeneratePropertyWriteForTopLevel for AOT-compatible direct serialization - Add recursive type discovery for nested object properties and collection elements
Auto-discover element types from generic type arguments (e.g., List<T> → T) when types are registered on a context. This matches System.Text.Json behavior. - Add DiscoverTypeArguments helper method - Call from DiscoverReferencedTypes to discover types from generic arguments - Add tests for type discovery and de-duplication - Suppress nullable warnings in generated code (pre-existing generator issue)
When collection types (Dictionary, List, Array) are registered directly on a context, serialize their contents instead of CLR properties like Capacity, Count, Comparer, Keys, Values. Changes: - Add collection metadata fields to SerializableTypeInfo - Detect collections in ExtractTypeInfoFromSymbol and set empty Properties - Add collection-specific serialization code generation - Add array type support in attribute processing - Update TonlSerializer header handling for collection types - Add TonlTypeInfo collection metadata (IsCollection, IsDictionary, etc.) - Add comprehensive test coverage for root-level collections
Tests verify that IEnumerable<string> and IEnumerable<TableInfo> serialize their elements properly instead of CLR interface metadata.
…ializers GeneratePropertyWriteForTopLevel and GeneratePropertyWriteForNested now handle PropertyCategory.Collection and PropertyCategory.Object instead of falling through to default which called .ToString(). Adds 4 tests for nested collection serialization scenarios.
GenerateRowValueWrite now handles PropertyCategory.Collection and PropertyCategory.Object instead of falling through to default which called .ToString(). - Collections of primitives: joined with semicolon delimiter - Collections of objects: serialized inline using WriteRowInline - Dictionaries: serialized as key=value pairs - Nested objects: use WriteRowInline Adds 7 tests for WriteRow collection serialization scenarios.
Per TONL spec, objects containing collection or nested object properties should use block format (WriteProperties) instead of tabular format (WriteRow). This prevents incorrectly inlining collections with semicolons. - Add HasOnlyPrimitiveProperties flag to SerializableTypeInfo - Add ElementHasOnlyPrimitives/ObjectHasOnlyPrimitives to PropertyInfo - Add TypeHasOnlyPrimitiveProperties() helper to analyze type symbols - Update GenerateCollectionWriteForTopLevel() to select format based on flag - Update GenerateArrayWrite() and GenerateRootListOfObjectsWrite() similarly Simple objects (only primitives) continue using tabular format. Complex objects (has collections/objects) now use block format.
…rs, deserializer block detection Closes #10, #11, #12 Serializer (CodeGenerator.cs): - Nested objects now emit block format (key-value per line) instead of inline format. Both GenerateNestedObjectWriteForTopLevel and GenerateNestedObjectWrite now use WriteNewLine + WriteProperties instead of WriteByte(' ') + WriteRowInline. - Block-format arrays now include column headers. WritePrimitiveArrayHeader replaced with WriteArrayHeader+PropertyNames in GenerateCollectionWriteForTopLevel and GenerateArrayWrite so complex-element arrays emit key[N]{col1,col2,...}:. Deserializer (TonlSerializer.cs): - DeserializeDocument can now detect and parse block-format arrays that carry column headers (key[N]{cols}:). Peeks at the next content line to determine tabular vs block mode. Block mode tracks item boundaries by the first column name repeating at item-indent depth. Handles nested tabular arrays, nested objects, and inline primitive arrays within block-format items.
…sting, tabular-vs-block Closes #13 - Rename SPEC_002 test from NestedObjectInline to NestedObject_ProducesBlockFormat and update assertion to verify block-format output (separate lines for each field) - Add ComplexNestedExample_SerializesCorrectFormat: verifies the spec's flagship example (Project/Owner/Tasks/Assignee/Comments hierarchy) produces correct block format with tabular Comments nested inside block Tasks - Add ComplexNestedExample_RoundTrips: serialize and deserialize the complex nested structure, assert key values are preserved - Add ArrayOfAllPrimitiveObjects_UsesTabularFormat: decision test for tabular path - Add ArrayOfObjectsWithCollectionProperty_UsesBlockFormat: decision test for block path (type with List<string> property must use block format) - Add ConstraintList_BlockFormat_IncludesColumnHeader: issue #27 constraints example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SerializeToStringmissingFlush(), root-level collection serialization, nested collection properties in tabular rowsTest plan
dotnet build— clean (0 errors)dotnet test— 360/360 passing on net9.0 and net10.0