Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,13 @@ private static bool IsDiscriminator(InputProperty property)
return property is InputModelProperty modelProperty && modelProperty.IsDiscriminator;
}

private ModelProvider? BuildBaseModelProvider()
/// <summary>
/// Builds the <see cref="ModelProvider"/> representing the base model of this model.
/// Emitters that override <see cref="BuildBaseType"/> to redirect the generated C# base
/// class should also override this method so that <see cref="BaseType"/> and
/// <see cref="BaseModelProvider"/> stay consistent.
/// </summary>
protected virtual ModelProvider? BuildBaseModelProvider()
{
// consider models that have been customized to inherit from a different generated model
if (CustomCodeView?.BaseType != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,45 @@ public void BuildBaseType()
Assert.AreEqual(baseModel!.Type, derivedModel!.Type.BaseType);
}

// Verifies an emitter can override BuildBaseType and BuildBaseModelProvider together to
// redirect the C# base class to a custom ModelProvider, keeping BaseType and
// BaseModelProvider in agreement.
[Test]
public void OverridingBuildBaseTypeAndBuildBaseModelProvider_KeepsBaseTypeConsistent()
{
var inputBase = InputFactory.Model("baseModel", usage: InputModelTypeUsage.Input, properties: []);
var inputDerived = InputFactory.Model("derivedModel", usage: InputModelTypeUsage.Input, properties: [], baseModel: inputBase);
CodeModelGenerator.Instance.TypeFactory.CreateModel(inputBase);

var customBaseProvider = new CustomBaseModelProvider(inputBase);
var derivedProvider = new BuildBaseTypeOverridingModelProvider(inputDerived, customBaseProvider);

Assert.AreEqual(customBaseProvider.Type, derivedProvider.BaseType);
Assert.AreSame(customBaseProvider, derivedProvider.BaseModelProvider);
}

private class CustomBaseModelProvider : ModelProvider
{
public CustomBaseModelProvider(InputModelType inputModel) : base(inputModel) { }

protected override string BuildName() => "CustomBase";
}

private class BuildBaseTypeOverridingModelProvider : ModelProvider
{
private readonly ModelProvider _redirectedBaseProvider;

public BuildBaseTypeOverridingModelProvider(InputModelType inputModel, ModelProvider redirectedBaseProvider) : base(inputModel)
{
_redirectedBaseProvider = redirectedBaseProvider;
}

protected override CSharpType? BuildBaseType() => _redirectedBaseProvider?.Type;

// The emitter overrides BuildBaseModelProvider to keep it in sync with the redirected BaseType.
protected override ModelProvider? BuildBaseModelProvider() => _redirectedBaseProvider;
}

[Test]
public void BuildModelAsStruct()
{
Expand Down
Loading