Skip to content

Commit df1628c

Browse files
dmealingclaude
andcommitted
refactor(csharp): retire FileMetaDataLoader; migrate to MetaDataLoader.FromDirectory + Source polymorphism
Deletes the FileMetaDataLoader subclass. All CLI commands (gen/migrate/verify), tests, and the conformance adapter now use the unified MetaDataLoader.FromDirectory(...) factory. The registry-aware overload preserves the conformance adapter's provider-composition flow. Directory-read failure is still surfaced as a collected MetaError on a synthetic empty root (no throw) — mirrors the TS loadDirectory contract. Aligns the C# port with the cross-language loader architecture unification spec. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 1268084 commit df1628c

9 files changed

Lines changed: 40 additions & 123 deletions

File tree

server/csharp/MetaObjects.Cli/GenCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static IReadOnlyList<IGenerator> DefaultGenerators() =>
2424

2525
public static Outcome Run(string metadataDir, string outDir, string ns)
2626
{
27-
var load = new FileMetaDataLoader().LoadDirectory(metadataDir);
27+
var load = MetaDataLoader.FromDirectory(metadataDir);
2828
var loadErrors = load.Errors.Select(e => e.Code.ToString()).ToList();
2929
if (loadErrors.Count > 0)
3030
return new Outcome(loadErrors, null);

server/csharp/MetaObjects.Cli/MigrateCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public static async Task<IncrementalOutcome> RunIncrementalAsync(
115115

116116
private static (IReadOnlyList<string> Errors, MetaRoot? Root) LoadRoot(string metadataDir)
117117
{
118-
var load = new FileMetaDataLoader().LoadDirectory(metadataDir);
118+
var load = MetaDataLoader.FromDirectory(metadataDir);
119119
var errs = load.Errors.Select(e => e.Code.ToString()).ToList();
120120
return (errs, errs.Count == 0 ? load.Root : null);
121121
}

server/csharp/MetaObjects.Cli/VerifyCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public sealed record Outcome(
4141

4242
public static Outcome Run(string metadataDir, string templatesRoot)
4343
{
44-
var load = new FileMetaDataLoader().LoadDirectory(metadataDir);
44+
var load = MetaDataLoader.FromDirectory(metadataDir);
4545
var loadErrors = load.Errors.Select(e => e.Code.ToString()).ToList();
4646

4747
var provider = new FilesystemProvider(templatesRoot);

server/csharp/MetaObjects.Conformance.Tests/ConformanceAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static LoadOutcome LoadFixture(string inputDir, IReadOnlyList<string> pro
5252
.ToList();
5353

5454
var registry = Provider.ComposeRegistry(resolved);
55-
var result = new FileMetaDataLoader(registry).LoadDirectory(inputDir);
55+
var result = MetaDataLoader.FromDirectory(inputDir, registry);
5656

5757
return new LoadOutcome(
5858
result.Root,

server/csharp/MetaObjects.Conformance.Tests/LoaderTests.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,19 @@ public void Core_loader_consumes_MetaDataSource_units()
3434
}
3535

3636
[Fact]
37-
public void FileMetaDataLoader_discovers_and_merges_a_directory()
37+
public void FromDirectory_discovers_and_merges_a_directory()
3838
{
39-
var loader = new FileMetaDataLoader();
40-
var result = loader.LoadDirectory(
39+
var result = MetaDataLoader.FromDirectory(
4140
System.IO.Path.Combine(Corpus, "loader-basic-single-entity", "input"));
4241
Assert.Empty(result.Errors);
43-
Assert.Equal("loaded", loader.State);
42+
Assert.NotNull(result.Root);
4443
}
4544

4645
[Fact]
47-
public void FileMetaDataLoader_directory_read_failure_collects_error_and_state_is_error()
46+
public void FromDirectory_read_failure_collects_error_on_synthetic_root()
4847
{
49-
var loader = new FileMetaDataLoader();
50-
var result = loader.LoadDirectory("/nonexistent/path/that/does/not/exist");
48+
var result = MetaDataLoader.FromDirectory("/nonexistent/path/that/does/not/exist");
5149
Assert.NotEmpty(result.Errors);
52-
Assert.Equal("error", loader.State);
50+
Assert.NotNull(result.Root);
5351
}
5452
}

server/csharp/MetaObjects.Conformance.Tests/SuperResolveTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class SuperResolveTests
99
[Fact]
1010
public void Single_level_extends_resolves_and_inherits_fields()
1111
{
12-
var result = new FileMetaDataLoader().LoadDirectory(
12+
var result = MetaDataLoader.FromDirectory(
1313
System.IO.Path.Combine(CorpusRoot.Path, "extends-single-level", "input"));
1414
Assert.Empty(result.Errors);
1515
// the subtype's effective fields include the base's fields (inherited via the resolved super chain)
@@ -20,7 +20,7 @@ public void Single_level_extends_resolves_and_inherits_fields()
2020
[Fact]
2121
public void Nonexistent_extends_collects_ERR_UNRESOLVED_SUPER()
2222
{
23-
var result = new FileMetaDataLoader().LoadDirectory(
23+
var result = MetaDataLoader.FromDirectory(
2424
System.IO.Path.Combine(CorpusRoot.Path, "error-extends-nonexistent", "input"));
2525
Assert.Contains(result.Errors, e => e.Code == ErrorCode.ERR_UNRESOLVED_SUPER);
2626
}

server/csharp/MetaObjects.Conformance.Tests/ValidationTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace MetaObjects.Conformance.Tests;
1313
public class ValidationTests
1414
{
1515
private static LoadResult Load(string fixture) =>
16-
new FileMetaDataLoader().LoadDirectory(
16+
MetaDataLoader.FromDirectory(
1717
System.IO.Path.Combine(CorpusRoot.Path, fixture, "input"));
1818

1919
[Fact]

server/csharp/MetaObjects/Loader/FileMetaDataLoader.cs

Lines changed: 0 additions & 99 deletions
This file was deleted.

server/csharp/MetaObjects/Loader/MetaDataLoader.cs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,6 @@ public class MetaDataLoader
3838
private readonly bool _strict;
3939

4040
private string _state = "uninitialized";
41-
42-
/// <summary>
43-
/// Protected setter so subclasses can transition state on failure paths
44-
/// that bypass <see cref="Load"/> (e.g. directory-read failure in
45-
/// <see cref="FileMetaDataLoader.LoadDirectory"/>).
46-
/// </summary>
47-
protected void SetState(string state) => _state = state;
4841
private MetaRoot? _root;
4942

5043
// -------------------------------------------------------------------------
@@ -83,10 +76,35 @@ private static TypeRegistry DefaultRegistry() =>
8376
/// and load all discovered files in deterministic order.
8477
/// </summary>
8578
public static LoadResult FromDirectory(string directory, DirectorySource.Options? opts = null)
79+
=> FromDirectory(directory, DefaultRegistry(), opts);
80+
81+
/// <summary>
82+
/// Registry-aware overload: build a <see cref="DirectorySource"/> and load
83+
/// using the supplied <paramref name="registry"/>. A directory-read failure
84+
/// is surfaced as a collected <see cref="MetaError"/> on a synthetic empty
85+
/// root (no throw) — mirrors the TS <c>loadDirectory</c> behavior.
86+
/// </summary>
87+
public static LoadResult FromDirectory(string directory, TypeRegistry registry, DirectorySource.Options? opts = null)
8688
{
8789
var src = new DirectorySource(directory, opts);
88-
var loader = new MetaDataLoader();
89-
return loader.Load(src.Expand().Cast<IMetaDataSource>().ToList());
90+
var loader = new MetaDataLoader(registry);
91+
List<IMetaDataSource> sources;
92+
try
93+
{
94+
sources = src.Expand().Cast<IMetaDataSource>().ToList();
95+
}
96+
catch (Exception ex)
97+
{
98+
// Directory-read failure: surface as a collected error on an empty load.
99+
var empty = loader.Load(Array.Empty<IMetaDataSource>());
100+
var errors = new List<MetaError>
101+
{
102+
new($"Failed to read directory \"{directory}\": {ex.Message}", ErrorCode.ERR_UNKNOWN),
103+
};
104+
errors.AddRange(empty.Errors);
105+
return new LoadResult(empty.Root, empty.Warnings, errors.AsReadOnly());
106+
}
107+
return loader.Load(sources);
90108
}
91109

92110
/// <summary>

0 commit comments

Comments
 (0)