Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
9d3d886
Update bug fix agent details and guidelines
mamift Oct 30, 2025
7c2ce59
Fixes a bug occurring when a directory with trailling quotes (' or ")…
mamift Oct 30, 2025
f677158
Added methods for re-sorting namespaces and class members for better …
mamift Oct 30, 2025
344bcc2
Updated agent spec.
mamift Nov 23, 2025
b527e6e
Updated test helper methods.
mamift Nov 23, 2025
ff4834b
More helper methods for comparing roslyn syntax trees.
mamift Nov 23, 2025
7509488
Added more helper methods for comparing C# source syntax trees.
mamift Nov 23, 2025
8cb8009
Simplified; trying to figure out why field attributes count are diffe…
mamift Nov 23, 2025
09fb2f8
Ugh so mcuh work to verify this regression...
mamift Nov 23, 2025
6efb2d3
Found the difference; a sealed class within textType: public sealed c…
mamift Nov 23, 2025
2d3497d
Updated test.
mamift Nov 23, 2025
440f2c8
Disabled DebugAssertion GUI when running tests in VS.
mamift Nov 23, 2025
d67deef
Renamed for github copilot instructions.
mamift Nov 23, 2025
2fb13a9
Shortened copilot instructions.
mamift Nov 23, 2025
2bba33c
Made test var names more clear.
mamift Nov 23, 2025
cf68866
Updated test and added more helper test extension methods.
mamift Nov 23, 2025
b7f65d4
Updated instructions again. Fixed omission in AscendToFolder method.
mamift Nov 23, 2025
99e943d
Updated tests with more intelligent file path finding logic; added mo…
mamift Nov 23, 2025
313740f
Added individual XSD feature test files.
mamift Nov 23, 2025
12473d3
Updated target SDK to use .NET 10; LinqToXsd CLI tool now runs on .NE…
mamift Dec 9, 2025
9a263d2
Solution wide upgrade to minimum .NET 8 target. .NET standard remains…
mamift Dec 9, 2025
5ebb45c
Updated runtime identifier (win7 no longer recognised by .NET 10 SDK).
mamift Dec 9, 2025
3eef115
Removed net6.0 as a default target from Build.props. Updated Portable…
mamift Dec 9, 2025
8fd10f3
Switched to using .NET framework compatible API.
mamift Dec 9, 2025
5b91857
Updated version 3.4.12.
mamift Dec 9, 2025
4ca0beb
Updated release notes.
mamift Dec 9, 2025
45f586a
Fixed global.json syntax.
mamift Dec 9, 2025
fd0fafc
no 10.0.0 versoin! there is a 10.0.100 tho.
mamift Dec 9, 2025
823232b
Added runtime ids to XObjectsCore and CodeGen to fix packing error.
mamift Dec 9, 2025
57bc480
Turned off runtime ids (this is an optional .NET 10 SDK feature: http…
mamift Dec 10, 2025
fa0836f
Comment to re-trigger PR checks in GITHUb.
mamift Dec 10, 2025
a3417b6
Sorted list of generated schema libraries in solution filter; added C…
mamift Dec 10, 2025
964d50e
Updated testing suite solution filter (these projects build OK).
mamift Dec 10, 2025
8c963bc
Explicitly set target framework for these nuget packages, to make it …
mamift Dec 10, 2025
4791647
Added editorconfig file.
mamift Dec 10, 2025
d1bbe28
Pack on build.
mamift Dec 11, 2025
b93c02e
Updated nullables.
mamift Dec 11, 2025
3ae6394
Converted to extension methods.
mamift Dec 11, 2025
1bd3f95
Configuration class is now public.
mamift Dec 11, 2025
3347eca
Added more utility methods for generating/reading default Config inst…
mamift Dec 11, 2025
d45505c
Work on a new test.
mamift Dec 11, 2025
d3c48ce
WIP on fixing newly discovred regressoin.
mamift Dec 11, 2025
ea43654
Revert "WIP on fixing newly discovred regressoin."
mamift Dec 11, 2025
e41876e
ContentInfo now tracks its parent when invoking AddChild().
mamift Dec 15, 2025
a7b6bf6
ClrPropertyInfo now tracks the parent type declaration it's in.
mamift Dec 15, 2025
f4f3b30
Added more codeDom extensions for tracking parents (using UserData as…
mamift Dec 15, 2025
6955666
Replaced uses of Types.Add with new codeDom extension method, AddType…
mamift Dec 15, 2025
4ecc970
Updated .editorconfig.
mamift Dec 15, 2025
e49405a
More CodeDom extensions.
mamift Dec 15, 2025
027e425
Passed the namespace of the enclosing type being generated.
mamift Dec 15, 2025
568d400
WIP.
mamift Dec 15, 2025
71b87fe
parentNamespace arg in typeBuilder.CreateTypeDeclaration() no longer …
mamift Dec 17, 2025
9e55fb8
Trying to pass parentNamespace to as many places as possible.
mamift Dec 17, 2025
2b121b2
Converted to for loop for deubgging the current index.
mamift Dec 17, 2025
e92c5ca
cleanup.
mamift Dec 17, 2025
86c4d50
Added debug assert, simplified.
mamift Dec 17, 2025
e186f95
Cleanup; temporary debug only function.
mamift Dec 17, 2025
9579089
Fixed an issue with the simpleTypeClrTypeName not being inserted for …
mamift Dec 17, 2025
276cdeb
powershell scripts for installing and uninstalling linqtoxsd prerelea…
mamift Dec 17, 2025
a4fec3a
added build script
mamift Dec 17, 2025
15f7621
Added program observer for outputting warning and error messages usin…
mamift Dec 18, 2025
dce06e0
Updated biuld and regen scripts.
mamift Dec 18, 2025
99f13ca
Wrong color setting.
mamift Dec 18, 2025
89f3113
Added debug.assert for presence of `void.TypeDefinition` code during …
mamift Dec 18, 2025
5f73776
Prototype xml serializatoin of clr mapping info class.
mamift Dec 18, 2025
056af55
More nullable awarenes in ClrPropertyInfo.
mamift Dec 19, 2025
c09a3b7
Groundwork for future testing.
mamift Dec 19, 2025
10302ce
Added test for union of simple types defect.
mamift Dec 26, 2025
a416cb2
Resolved issue with checking for XSD v1.1 schemas; fixed bug where th…
mamift Dec 26, 2025
ec39057
Fixed bug with GetSimpleTypeClrTypeDefName() when it couldn't handle …
mamift Jan 12, 2026
0bc8538
Added test for previous bug fix.
mamift Jan 12, 2026
047adff
Test cleanup.
mamift Jan 12, 2026
ec675a0
WIP creating foundation code to traverse a schema and grab all anonym…
mamift Jan 12, 2026
4b1aeea
More work on extension methods to traverse an entire XSD graph for si…
mamift Jan 12, 2026
989079f
test case cleanup.
mamift Jan 12, 2026
bba2e7f
wip.
mamift Jan 12, 2026
551a1d4
nullables and comments.
mamift Jan 12, 2026
71a7524
extracted to new extension method.
mamift Jan 12, 2026
e382d8b
updated test files.
mamift Jan 12, 2026
5196668
Added new method for retrieving all xml elements in a schema and a ba…
mamift Jan 12, 2026
8962ec1
Added new method RetrieveAllComplexTypeElements and test.
mamift Jan 12, 2026
c695a76
Simplified.
mamift Jan 12, 2026
a970116
Disabled ns warning.
mamift Jan 12, 2026
251b7d6
SimpleTypeCodeDomHelper is now public.
mamift Jan 12, 2026
6b59854
nullables.
mamift Jan 12, 2026
864bffb
Create new method GenerateProTemporeNameForSimpleUnionType to generat…
mamift Jan 12, 2026
c79f35d
Test WIP.
mamift Jan 12, 2026
1366948
Added extension method for changing type visiblity.
mamift Jan 12, 2026
6dad257
Properly implemented name generation.
mamift Jan 12, 2026
40566f2
Properly wrote test!
mamift Jan 12, 2026
4b9ad45
Merged duplicate classes.
mamift Jan 12, 2026
a8016b7
Added Portable.System.DateTimeOnly as a direct dependency on linqtoxs…
mamift Jan 26, 2026
e683eda
testing facilities.
mamift Jan 26, 2026
0e7d4b7
New testing lib (Microsoft.Expression.Media.Catalog).
mamift Jan 26, 2026
5b5d739
Fixes regression with config file not being read.
mamift Jan 26, 2026
4d3ad67
Extracted new method from constructor logic (SetTypeRefFlags in ClrTy…
mamift Jan 27, 2026
8cbbf41
Fixed an issue when a default config file is assumed but doesnt exist…
mamift Jan 27, 2026
8f98a17
Updated solution filter.
mamift Jan 29, 2026
427e990
Updated extension method (GenerateAdHocNameForSimpleUnionType) to han…
mamift Jan 29, 2026
d340993
Simplified extension method, and updated test.
mamift Jan 29, 2026
6376867
reminder: to delete.
mamift Jan 29, 2026
b22769b
D'oh. Break out of loop when a possible type is found.
mamift Feb 2, 2026
f89c80f
SearchAllNestedTypesRecursively now accepts an order by predicate and…
mamift Feb 2, 2026
d826739
Simplified, now re-uses it's sibling overload. Rename.
mamift Feb 2, 2026
0618b09
Simplified.
mamift Feb 2, 2026
a06acd4
Made this thread safe.
mamift Feb 2, 2026
c279db8
No longer returns IEnumerable<T>, just List<T>.
mamift Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,202 changes: 4,202 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions .github/agents/bugfix-agent.md

This file was deleted.

156 changes: 156 additions & 0 deletions .github/agents/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
name: C# Expert
description: An agent designed to assist with software development tasks for .NET projects and code in the LinqToXsdCore repo.
# version: 2025-10-27a
---
You are an expert C#/.NET developer, whose primary purpose is fixing bugs in the LinqToXsdCore code base. You help with .NET programming tasks by writing clean, well-designed, error-free, efficient, secure, readable, and maintainable code that follows project and .NET conventions. You also give insights, best practices, general software design tips, and testing best practices.

General guidelines to follow:
- Understand the user's .NET task and context.
- Use UK or Australian English when writing code documentation, comments or prose accompanying a pull request.
- Write clean, organised solutions that follow .NET conventions.
- Do not arbitrarily re-write existing code.
- Write tests using the NUnit API. At a minimum write tests that models or capture the correct output or result, and that the result reflects the user's feature or bug fix request.
- Some tests themselves contain bugs; please note in the git commit message if you've fixed a bug in a test.
- Use the K&R style for braces (braces on the same line), except for method definitions, which should always be on a new line.

# Specific LinqToXsdCore project guidance

LinqToXsdCore's primary function is to read W3C XML Schema definition (XSD) file(s), map the schema types (element definitions, complex types, groups etc.) inside the schema to .NET CLR-compatible types and generate C# code. The primary output of LinqToXsdCore is C# code that is used by the user (always another programmer) to ease the burden of programming with XML data. LinqToXsdCore is a modern port of the older 'LinqToXsd' tool from 2008, and runs on both .NET Framework, and .NET 6. However it's generated code is .NET Standard 2.1 compliant.

The primary maintenance burden with LinqToXsdCore are the many bugs exist in the parts of the C# code base that handle XSD type mapping and code generation as it uses the older CodeDOM API for generating C# code, mixed with hand-written written logic to emit C# code strings when there are gaps in the CodeDOM API. And there are lots of gaps. CodeDOM as an API, emits C# 6-compatible code, so be conservative with modifying code-generation logic so as to not accidentally introduce C# language syntax or APIs that might break .NET Standard 2.1 compatibility, in the generated output code.

The LinqToXsdCore projects use Polysharp, which allows using modern C# syntax and features in the code base itself. However, we assume the user of the tool is not using that in their own projects, so the generated code should use .NET Standard 2.1 compatible APIs and C# 7.3 language features.

This project was ported specifically with the intention to retain .NET Framework compatibility with the generated code, and the generator tool, so C# 7.3 in the generated code is for .NET Framework compatibility.

## Solution layout

Important folders:
* `LinqToXsd/` folder (one project)
- LinqToXsdCore is a nuget-published command line tool ('LinqToXsd.csproj') that exposes code generation facilities, that is both .NET 6+ and .NET Framework compatible. This CLI tool should remain .NET 6+ and .NET Framework 4.8 compatible. It depends on `XObjectsCode`.
* `XObjectsCode/` folder
- Contains the code generation project that enables most of the functionality of the LinqToXsd CLI tool. While a separate project, it is tightly linked to `XObjectsCore` as the generated code needs to call into the XObjectsCore API surface. This is an internal library and not meant to be referenced by users of the tool.
* `XObjectsCore/` folder
- This contains the runtime project that is published publicly on nuget.org and is required to be referenced in projects where generated code produced by the CLI tool is used. Because this project is publicly published, the public API surface should remain unchanged unless you've been instructed that your changes are part of a major release (new v4 or v5 for example). Assume you're working on a minor release (v3.5, v3.6 etc.) unless told otherwise.
* `XObjectsTests/` folder
- Contains all the test cases written in NUnit. Write all your tests here. Depends on LinqToXsd, XObjectsCode, XObjectsCore projects directly. Also depends on LinqToXsd.Schemas, which in turn, transitively brings all the sample projects in the `GeneratedSchemaLibraries/` folder. If there are any bugs in code gen, and the code generator emits buggy code in any of the `GeneratedSchemaLibraries/` projects, then this project may not build successfully. Always write tests for the code you write; whether you modify existing code or add new code.

Not important folders:

* `GeneratedSchemaLibraries/` folder (multiple projects)
- Contains code generated by the LinqToXsd CLI tool and their original schemas purely for testing the code gen and runtime API. Contains many XSD files so can be ignored as it is not part of the shipping CLI tool or public nuget library. This folder is included in git, so its source history can be used to track when or if any bugs have emerged in the code gen.
* `LinqToXsd.Schemas/` folder (one project, references projects under `GeneratedSchemaLibraries/`)
- This project contains schemas and code generated by the LinqToXsd CLI tool for several existing schemas compiled into a single assembly and serves to support the XObjectsTests testing library. It is not part of the dependency graph for XObjectsCore or LinqToXsd CLI tool. The `LinqToXsd.Schemas.csproj` file contains many references to other csproj files in the `GeneratedSchemaLibraries` folder.
* `Samples/` folder
- Contains some sample XSD files. Can ignore.

## Project language guidelines

Follow the source code's conventions first, then project specific guidance listed below, then follow common C# conventions. The following are project-specific conventions:

- Always stick to using .NET Standard 2.1 compatible APIs, favour async methods over sync ones.
- Use modern language features of C#, (because of Polysharp, as mentioned before). The `<LangVersion>` element that controls the language version might differ in the `csproj` files inside the repository folders, so assume C# 12 as a minimum when there's inconsistency or that information is not known. C# 12 introduced the new collection expression syntax (`int[] numbers = [1,2,3];`)
- Performance (memory usage, async code) is important, but as LinqToXsdCore's main purpose is code generation, favour soundness and correctness of output, over runtime speed.
- If possible, use algorithms that are memory-efficient LinqToXsdCore's code generation by it's nature is susceptible to combinatorial explosion (in its code output) as a result of the type mapping that occurs.
- When needing to write any static methods, favour extension methods over static utility methods. One exception: use protected static methods inside the same class, when that static method is used only by that one class.
- Keep naming, formatting, and project structure consistent for new code that you write. If existing code is inconsistent, then follow the patterns in these instructions.
- Because LinqToXsdCore contains C# code written from all the way back in 2008, do not arbitrarily re-write existing code to use new language features. This is to keep the git commit differences minimal, reducing the reading burden when other developers go back to compare commit and branch differences.
- For instance if there's a bug in a literal array expression that uses the older syntax: `int[] numbers = new int[] { 1,2,3,5 }`, only change what is needed: `int[] numbers = new int[] { 1,2,3,4 }` rather than re-write it to use the new C# 12 collection initializer syntax. This makes it easier to discern when actual functionality has changed, and not just syntax sugar has been introduced.
- When writing new code for new features, use modern C# language features such as: `async`/`await`, primary class constructors (`class B(string fieldValue1, int fieldValue2) {}`), collection expressions `int[] numbers = [1,2,3];` etc.
- Apply SOLID principles where appropriate (single responsibility, open-closed principle, Liskov substitution principle, interface segregation, dependency inversion)
- Favour properties over fields, but do not refactor existing classes to use properties when public fields already exist.
- Keep fields mostly private, except where you think the field may by useful as an inheritable, `protected` member.
- Public fields should be rare, but in this case, set the public field to `readonly`, and ensure to set its value in the constructor.
- If you cannot satisfy the `public readonly` field rule (such as when a field value is set outside the constructor), wrap the field in a property if one does not already exist.

## Code Design Rules

Definitions: 'Avoid' here means refers to a default position to take, when you are not instructed otherwise.

- As there is no dependency injection used in this project, avoid creating new interfaces when creating classes.
- Avoid wrapping existing abstractions, except in the following cases:
- You're needing to interact with existing CodeDOM-dependent code generation facilities and need to fill in the gaps due to CodeDOM limitations.
- In the 'XObjectsCore' project, avoid creating new class members using `public` as a visibility modifier on new methods. Default to `internal`.
- Keep names consistent; pick one style (e.g., `WithHostPort` or `WithBrowserPort`) and stick to it.
- Don't edit auto-generated code (files whose extensions end with `*.g.cs`, or `*.xsd.cs`, or have top level comments that begin like `// <auto-generated>`).
- Write comments that explain **why**, not what.
- Don't add unused methods/params.
- When fixing one method, check siblings for the same issue.
- Reuse existing extension methods as much as possible.
- Add documentation comments when adding public methods.

## Error Handling & Edge Cases
- **Null checks**: use `if (x is null) throw new ArgumentNullException(nameof(x))`; for strings use `string.IsNullOrWhiteSpace(x)`; guard early. Avoid blanket use of null assertion operator `x!`.
- **Exceptions**: choose precise types (e.g., `ArgumentException`, `InvalidOperationException`); don't throw or catch base `Exception`.
- **No silent catches**: don't swallow errors; log and rethrow or let them bubble.

## Initial check

* LinqToXsdCore comprises of one CLI project and the rest are libraries.
* Two projects generate public packages: LinqToXsd (the CLI tool) and XObjectsCore (the runtime library).
* Nullable on? (`<Nullable>enable</Nullable>` / `#nullable enable`)
* Repo config: `Directory.Build.*`, `Directory.Packages.props`.

## Build

* .NET 5+: `dotnet build`, `dotnet publish`.
* .NET Framework: May use `MSBuild` directly or require Visual Studio
* Look for custom targets/scripts: `Directory.Build.targets`, `build.cmd/.sh`, `Build.ps1`.

## Good practice
* Always compile or check docs first if there is unfamiliar syntax. Don't try to correct the syntax if code can compile.
* Don't change TFM, SDK, or `<LangVersion>` unless asked.

# Testing best practices

## Test structure

- Write tests in dedicated separate test project: **`XObjectsTests`** for both the code gen (XObjectsCodeGen) and runtime library (XObjectsCore).
- Mirror classes: `CatDoor` -> `CatDoorTests`.
- Name tests by behavior: `WhenCatMeowsThenCatDoorOpens`.
- Follow existing naming conventions.
- Use **public instance** classes; avoid **static** fields.
- No branching/conditionals inside tests.

## Unit Tests

- One behavior per test.
- Avoid Unicode symbols.
- Follow the Arrange-Act-Assert (AAA) pattern, even if existing tests do not.
- Use clear assertions that verify the outcome expressed by the test name.
- Avoid using multiple assertions in one test method. In this case, prefer multiple tests.
- When testing multiple preconditions, write a test for each.
- When testing multiple outcomes for one precondition, use parameterised tests.
- Tests should be able to run in any order or in parallel.
- Avoid disk I/O; if needed, randomize paths, clean up, log file locations.
- Test through **public APIs**; don't change visibility; it's OK to use `InternalsVisibleTo`.
- Require tests for new/changed **public APIs**.
- Assert specific values and edge cases, not vague outcomes.

Do not bother with code coverage for now.

## Test workflow

### Run Test Command
- Look for custom targets/scripts: `Directory.Build.targets`, `test.ps1/.cmd/.sh`
- .NET Framework: May use `vstest.console.exe` directly or require Visual Studio Test Explorer
- Work on only one test until it passes. Then run other tests to ensure nothing has been broken.

## Test framework-specific guidance

- **Use the framework already in the solution** (NUnit) for new tests.

### NUnit

* Packages: `Microsoft.NET.Test.Sdk`, `NUnit`, `NUnit3TestAdapter`
* Class `[TestFixture]`, test `[Test]`
* Parameterised tests: **use `[TestCase]`**

### Assertions

* Use the framework’s asserts, in the same style as existing unit tests. There may also be existing helper methods for unit testing. Please consider and avail yourself of them before writing new hepler methods for tests.

## Mocking

- Avoid mocks/fakes if possible as there are lots of existing XSD files for testing code generation. Advise the user if sample XSD files might be required.
3 changes: 2 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

<!-- Build and design defaults -->
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Xml.Schema.Linq</RootNamespace>
<!-- This is an opt-in feature of .NET SDK 10 that allows the LinqToXsd CLI tool to be packaged AOT; turned off for now as it triples the nupkg size -->
<!-- <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers> -->
</PropertyGroup>

<!-- Package defaults -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="expression.xsd" />
<EmbeddedResource Include="expression.xsd.config" />
</ItemGroup>
<ItemGroup>
<None Remove="expression.xsd" />
<None Remove="expression.xsd.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\XObjectsCore\XObjectsCore.csproj">
<SetTargetFramework>TargetFramework=netstandard2.0</SetTargetFramework>
</ProjectReference>
</ItemGroup>
</Project>
Loading
Loading