Fixes a code gen bug, fixes false positives with NoVoidTypeOfExpressionsInGeneratedCode test - #96
Conversation
…s another schema that contains a global attribute whose schema type was anonymous and had enums, LinqToXsd will now properly generate the C# enum definition.
…atedSchemaLibraries)
…solve all appropriate entry point XSD files in a given folder.
…tchInfo.Capture to preserve exception stack trace.
…ressionsInGeneratedCode
35613ef to
d03d8aa
Compare
…NoVoidTypeOfExpressionsInGeneratedCode test.
NoVoidTypeOfExpressionsInGeneratedCode test
There was a problem hiding this comment.
🟡 Changes recommended
Several newly introduced graph/schema utilities have concrete correctness issues (null-safety, path normalisation, stubbed/empty implementations) that can cause runtime exceptions or silently incorrect results.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates LinqToXsdCore’s schema-processing and test tooling to better handle multi-XSD import/include graphs (including cycles), fixes a codegen edge case around anonymous-enum attribute types, and reduces false positives in the NoVoidTypeOfExpressionsInGeneratedCode test by selecting more appropriate entry-point XSDs.
Changes:
- Fix anonymous-type detection for referenced global attributes so enum definitions are generated correctly.
- Add SCC-based entry-point selection for XSD sets (plus an import/include report utility) and new tests around path resolution / GitHub Issue 71.
- Introduce an XSD-backed
Graphmodel (generated + partial) and supporting test/script updates for regenerating schema libraries.
File summaries
| File | Description |
|---|---|
| XObjectsTests/XObjectsTests.csproj | Adds System.Text.Json for new tests reading .slnf JSON. |
| XObjectsTests/Utilities.cs | Adds schema-set preloading/compilation path and preserves exception stack traces via ExceptionDispatchInfo. |
| XObjectsTests/MockXmlUrlResolver.cs | Improves resolver matching for absolute vs filename-only URIs; tweaks ResolveUri matching logic. |
| XObjectsTests/GraphTests.cs | Adds coverage for building/serialising the new Graph and basic entry-point detection. |
| XObjectsTests/FileSystemUtilitiesTests.cs | Adds tests for SCC-based schema entry-point selection and import/include reporting. |
| XObjectsTests/Extensions/MockFileSystemExtensions.cs | Updates test helper to use SCC-based entry-point detection; adds BuildGraph helper. |
| XObjectsTests/Extensions/DirectoryExtensions.cs | Adds AscendByLevel helper used by filesystem-based tests. |
| XObjectsTests/CodeGenerationTests.cs | Switches void-type checks to graph-derived entry points; adds (currently empty) regression test placeholder. |
| XObjectsCore/XAttributeValueEqualityComparer.cs | Adds Default singleton for consistent comparer usage. |
| XObjectsCore/FileSystemUtilities.cs | Renames/reshapes filtering parameters; replaces previous heuristic with SCC-based entry-point detection; adds report generator. |
| XObjectsCore/Extensions/XDocumentExtensions.cs | Adds include/import helpers and SCC-based entry-point selection (Tarjan) for file-path→XDocument inputs. |
| XObjectsCore/Extensions/StringExtensionMethods.cs | Adds ignore-case equality helpers used by new graph logic. |
| XObjectsCore/Extensions/GeneralExtensionMethods.cs | Adds ValueForPossibleKeys for dictionary lookups with fallback keys. |
| XObjectsCode/XObjectsCodeGen.csproj | Adds System.IO.Abstractions dependency used by graph building from an IFileSystem. |
| XObjectsCode/XImportGraph.xsd.config | Adds config for generating the Graph type model. |
| XObjectsCode/XImportGraph.xsd-g.cs | Adds generated types for Graph/Schema model used by tests/code. |
| XObjectsCode/XImportGraph.xsd | Adds the schema defining the Graph/Schema XML model. |
| XObjectsCode/Graph.cs | Adds partial implementation for building/traversing XSD dependency graphs and choosing SCC-based entry points. |
| XObjectsCode/Extensions/XmlSchemaExtensions.cs | Fixes anonymous-type detection for attribute references with anonymous resolved types. |
| XObjectsCode/Extensions/GraphExtensions.cs | Adds (currently stubbed) traversal extension. |
| Version.props | Bumps version to 3.4.20. |
| Regenerate-TestingSuite.ps1 | Adds script to regenerate generated schema libraries from the solution filter list. |
| LinqToXsd/Properties/launchSettings.json | Adds launch profiles for new schemas/tests. |
| LinqToXsd.Schemas/XsdFeatureTests/ImportsXmlNamespace/ImportsXmlAttributes.xsd.config | Enables AlwaysPrefixGlobal to reduce naming collisions in generated code. |
| LinqToXsd.Schemas/XsdFeatureTests/ImportsXmlNamespace/ImportsXmlAttributes.xsd-g.cs | Updates generated output for import/xml namespace attribute enum scenario. |
| LinqToXsd.Schemas/Tests/GithubIssue71/xmldsig-core-schema.xsd.config | Adds config for Issue 71 test schema set. |
| LinqToXsd.Schemas/Tests/GithubIssue71/xmldsig-core-schema.xsd | Adds Issue 71 dependency XSD fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_MsgHeader.xsd | Adds Issue 71 cyclic-import graph fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_MsgDef.xsd | Adds Issue 71 cyclic-import graph fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_MsgDataTypes.xsd.config | Adds config for Issue 71 cyclic-import graph fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_MsgDataTypes.xsd | Adds Issue 71 cyclic-import graph fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_MsgBody.xsd | Adds Issue 71 cyclic-import graph fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_AppProtocol.xsd.config | Adds config for standalone schema fixture. |
| LinqToXsd.Schemas/Tests/GithubIssue71/V2G_CI_AppProtocol.xsd | Adds standalone schema fixture for Issue 71. |
| LinqToXsd.Schemas/LinqToXsd.Schemas.csproj | Adjusts embedded resource handling for ImportsXmlAttributes XSD. |
| GeneratedSchemaLibraries/1707_ISYBAU_XML_Schema/1707-metadaten.xsd.config | Normalises config (adds CodeGeneration section; updates XMLSchema CLR namespace mapping). |
| fuse.json | Adds Fuse workspace config file. |
| Directory.Build.props | Adds NETSDK1138 to NoWarn. |
| CLAUDE.md | Adds Fuse workflow guidance block. |
| AGENTS.md | Adds Fuse workflow guidance block. |
| .mcp.json | Adds MCP server entries for code-review-graph and fuse. |
| .gitignore | Ignores .fuse/ directory. |
| .github/copilot-instructions.md | Adds Fuse workflow guidance for Copilot. |
Review details
Suppressed comments (3)
XObjectsCore/Extensions/XDocumentExtensions.cs:37
- Same as GetXsdIncludeElements: matching only by LocalName can include elements from other namespaces. Prefer using ImportXName to ensure you only capture xs:import elements.
XObjectsCode/Graph.cs:236 - FindEntryPointSchemas accesses SchemaField directly; on Graph instances created via Parse/Load, SchemaField can still be null until the Schema property is accessed, leading to NullReferenceException. Use the Schema property instead of the backing field.
public List<Schema> FindEntryPointSchemas()
{
List<string> entryPointNames = FindEntryPointSchemaNames();
return this.SchemaField
.Where(sc => entryPointNames.Any(e => e.EqualsIgnoreCase(sc.Name)))
.ToList();
}
XObjectsCode/Graph.cs:447
- GetDependencies assumes include/import Schema.Name matches the root schema Name exactly and uses Single(), but BuildFromFolder stores schemaLocation values (often relative paths). This can cause InvalidOperationException (no match) even when the dependency exists. Normalise to Path.GetFileName and skip/raise a clearer error when the dependency isn’t present in the graph.
public IEnumerable<Schema> GetDependencies()
{
// since this Schema represents a <Schema> XML element under the <Graph> XML element,
// we can conveniently navigate to the parent by casting to the right type!
Graph graph = (Graph)this.Untyped.Parent;
if (Includes?.Schema != null && Includes.Schema.Any())
{
foreach (Schema include in Includes.Schema)
{
var schemaByNameFromGraphRoot = graph.Schema.Single(s => s.Name.EqualsIgnoreCase(include.Name));
yield return schemaByNameFromGraphRoot;
}
}
if (Imports?.Schema != null && Imports.Schema.Any())
{
foreach (Schema import in Imports.Schema)
{
var schemaByNameFromGraphRoot = graph.Schema.Single(s => s.Name.EqualsIgnoreCase(import.Name));
yield return schemaByNameFromGraphRoot;
}
}
}
- Files reviewed: 42/43 changed files
- Comments generated: 10
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
committed suggestion: GetSchemasThatAreImportedByOthers uses SchemaField directly (can be null) and does a case-sensitive Contains on schema names, which can miss matches. Also i.Name can include relative paths, so comparing raw strings can fail; normalise to Path.GetFileName and compare ordinal-ignore-case. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…nly; within an XSD it’s safer to match the full XName (namespace + localname) to avoid accidentally picking up unrelated elements from other namespaces."
…cationAttr.Value directly to file names. If schemaLocation contains a relative path (e.g. "subdir/foo.xsd"), the edge won’t be recorded and entry-point detection becomes incorrect. Normalise to Path.GetFileName(schemaLocation).
…l, files.Except(filteredOut) will throw (ArgumentNullException). The previous implementation guarded against null; this should continue to be null-safe to avoid surprising runtime failures from custom filters."
…zureDevOps clones the repo into a folder NOT called "LinqToXsdCore" - it's usually a random single char folder name (like 'a', 'b' ... i've seen all the way up to 's').
ResolveFileAndFolderPathsToJustFiles, added tests forResolvePossibleFileAndFolderPathsToProcessableSchemasNoVoidTypeOfExpressionsInGeneratedCodetestGraphthat can more easily model the connections between a bunch of XSDs that include or import each other. Usable only in unit tests for now.v3.4.20