Supports https://github.com/microsoft/typespec/issues/3981

These cadl ranch tests have models which use replacement properties in
extended types that we need to handle.
This commit is contained in:
m-nash 2024-09-04 19:12:37 -07:00 коммит произвёл GitHub
Родитель 93377fd7dd
Коммит 06c0bb5dca
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
14 изменённых файлов: 292 добавлений и 24 удалений

Просмотреть файл

@ -403,9 +403,9 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
null,
[]),
// return Volatile.Read(ref _cachedClient) ?? Interlocked.CompareExchange(ref _cachedClient, new Client(_pipeline, _keyCredential, _endpoint), null) ?? _cachedClient;
Return(NullCoalescing(
Static(typeof(Volatile)).Invoke(nameof(Volatile.Read), cachedClientFieldVar),
NullCoalescing(interlockedCompareExchange, subClientInstance._clientCachingField))),
Return(
Static(typeof(Volatile)).Invoke(nameof(Volatile.Read), cachedClientFieldVar)
.NullCoalesce(interlockedCompareExchange.NullCoalesce(subClientInstance._clientCachingField))),
this);
methods.Add(factoryMethod);
}

Просмотреть файл

@ -408,7 +408,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
cases.Add(
BuildWriteObjectValueSwitchCase(new CSharpType(typeof(IJsonModel<>), _t), "jsonModel", jsonModel => new MethodBodyStatement[]
{
jsonModel.Invoke(nameof(IJsonModel<object>.Write), writer, NullCoalescing(options, ModelSerializationExtensionsSnippets.Wire)).Terminate(),
jsonModel.Invoke(nameof(IJsonModel<object>.Write), writer, options.NullCoalesce(ModelSerializationExtensionsSnippets.Wire)).Terminate(),
Break
}));
cases.AddRange(new[]

Просмотреть файл

@ -184,9 +184,8 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
var interfaceType = param.Property!.WireInfo?.IsReadOnly == true
? new CSharpType(typeof(IReadOnlyList<>), convenienceParam.Type.Arguments)
: new CSharpType(typeof(IList<>), convenienceParam.Type.Arguments);
expressions.Add(NullCoalescing(
new AsExpression(convenienceParam.NullConditional().ToList(), interfaceType),
New.Instance(convenienceParam.Type.PropertyInitializationType, [])));
expressions.Add(new AsExpression(convenienceParam.NullConditional().ToList(), interfaceType)
.NullCoalesce(New.Instance(convenienceParam.Type.PropertyInitializationType, [])));
}
else
{

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Snippets
var changeTrackingType = collection.Type.Arguments.Count == 1
? ClientModelPlugin.Instance.TypeFactory.ListInitializationType.MakeGenericType(collection.Type.Arguments)
: ClientModelPlugin.Instance.TypeFactory.DictionaryInitializationType.MakeGenericType(collection.Type.Arguments);
return NullCoalescing(collection, New.Instance(changeTrackingType));
return collection.NullCoalesce(New.Instance(changeTrackingType));
}
}
}

Просмотреть файл

@ -10,12 +10,12 @@ namespace Microsoft.Generator.CSharp.Expressions
/// </summary>
/// <param name="Variable">The variable that is being assigned.</param>
/// <param name="Value">The value that <paramref name="Variable"/> is being assigned.</param>
public sealed record AssignmentExpression(ValueExpression Variable, ValueExpression Value, bool NullCoalesce = false) : ValueExpression
public sealed record AssignmentExpression(ValueExpression Variable, ValueExpression Value, bool UseNullCoalesce = false) : ValueExpression
{
internal override void Write(CodeWriter writer)
{
Variable.Write(writer);
if (NullCoalesce)
if (UseNullCoalesce)
{
writer.Append($" ??= ");
}

Просмотреть файл

@ -120,6 +120,8 @@ namespace Microsoft.Generator.CSharp.Expressions
public AssignmentExpression Assign(ValueExpression value, bool nullCoalesce = false) => new AssignmentExpression(this, value, nullCoalesce);
public ValueExpression NullCoalesce(ValueExpression right) => new BinaryOperatorExpression("??", this, right);
public string ToDisplayString() => GetDebuggerDisplay();
private string GetDebuggerDisplay()

Просмотреть файл

@ -85,7 +85,7 @@ namespace Microsoft.Generator.CSharp.Providers
{
new IfStatement(value.NotEqual(Null))
{
ThrowArgumentException(NullCoalescing(message, Literal("Value must be null.")))
ThrowArgumentException(message.NullCoalesce(Literal("Value must be null.")))
}
},
this);

Просмотреть файл

@ -1,11 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.Collections.Generic;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Statements;
using static Microsoft.Generator.CSharp.Snippets.ArgumentSnippets;
namespace Microsoft.Generator.CSharp.Providers
{

Просмотреть файл

@ -114,7 +114,47 @@ namespace Microsoft.Generator.CSharp.Providers
/// <returns>The list of <see cref="FieldProvider"/> for the model.</returns>
protected override FieldProvider[] BuildFields()
{
return RawDataField != null ? [RawDataField] : [];
List<FieldProvider> fields = [];
if (RawDataField != null)
{
fields.Add(RawDataField);
}
foreach (var property in _inputModel.Properties)
{
if (property.IsDiscriminator)
continue;
var derivedProperty = InputDerivedProperties.FirstOrDefault(p => p.Value.ContainsKey(property.Name)).Value?[property.Name];
if (derivedProperty is not null)
{
if (!derivedProperty.Type.Equals(property.Type) || !DomainEqual(property, derivedProperty))
{
fields.Add(new FieldProvider(
FieldModifiers.Private | FieldModifiers.Protected,
CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(property.Type)!,
$"_{property.Name.ToVariableName()}",
this));
}
}
}
return [.. fields];
}
private Dictionary<InputModelType, Dictionary<string, InputModelProperty>>? _inputDerivedProperties;
private Dictionary<InputModelType, Dictionary<string, InputModelProperty>> InputDerivedProperties => _inputDerivedProperties ??= BuildDerivedProperties();
private Dictionary<InputModelType, Dictionary<string, InputModelProperty>> BuildDerivedProperties()
{
Dictionary<InputModelType, Dictionary<string, InputModelProperty>> derivedProperties = [];
foreach (var derivedModel in _inputModel.DerivedModels)
{
var derivedModelProperties = derivedModel.Properties;
if (derivedModelProperties.Count > 0)
{
derivedProperties[derivedModel] = derivedModelProperties.ToDictionary(p => p.Name);
}
}
return derivedProperties;
}
protected override PropertyProvider[] BuildProperties()
@ -122,6 +162,8 @@ namespace Microsoft.Generator.CSharp.Providers
var propertiesCount = _inputModel.Properties.Count;
var properties = new List<PropertyProvider>(propertiesCount + 1);
Dictionary<string, InputModelProperty> baseProperties = _inputModel.BaseModel?.Properties.ToDictionary(p => p.Name) ?? [];
for (int i = 0; i < propertiesCount; i++)
{
var property = _inputModel.Properties[i];
@ -132,6 +174,34 @@ namespace Microsoft.Generator.CSharp.Providers
var outputProperty = CodeModelPlugin.Instance.TypeFactory.CreatePropertyProvider(property, this);
if (outputProperty != null)
{
if (!property.IsDiscriminator)
{
var derivedProperty = InputDerivedProperties.FirstOrDefault(p => p.Value.ContainsKey(property.Name)).Value?[property.Name];
if (derivedProperty is not null)
{
if (derivedProperty.Type.Equals(property.Type) && DomainEqual(property, derivedProperty))
{
outputProperty.Modifiers |= MethodSignatureModifiers.Virtual;
}
}
var baseProperty = baseProperties.GetValueOrDefault(property.Name);
if (baseProperty is not null)
{
if (baseProperty.Type.Equals(property.Type) && DomainEqual(baseProperty, property))
{
outputProperty.Modifiers |= MethodSignatureModifiers.Override;
}
else
{
outputProperty.Modifiers |= MethodSignatureModifiers.New;
var fieldName = $"_{baseProperty.Name.ToVariableName()}";
outputProperty.Body = new ExpressionPropertyBody(
This.Property(fieldName).NullCoalesce(Default),
outputProperty.Body.HasSetter ? This.Property(fieldName).Assign(Value) : null);
}
}
}
properties.Add(outputProperty);
}
}
@ -144,6 +214,14 @@ namespace Microsoft.Generator.CSharp.Providers
return [.. properties];
}
private static bool DomainEqual(InputModelProperty baseProperty, InputModelProperty derivedProperty)
{
if (baseProperty.IsRequired != derivedProperty.IsRequired)
return false;
var baseNullable = baseProperty.Type is InputNullableType;
return baseNullable ? derivedProperty.Type is InputNullableType : derivedProperty.Type is not InputNullableType;
}
protected override ConstructorProvider[] BuildConstructors()
{
if (_inputModel.IsUnknownDiscriminatorModel)
@ -273,7 +351,7 @@ namespace Microsoft.Generator.CSharp.Providers
else
{
/* kind ?? "unknown" */
return NullCoalescing(discriminatorExpression, Literal(_inputModel.DiscriminatorValue));
return discriminatorExpression.NullCoalesce(Literal(_inputModel.DiscriminatorValue));
}
}
else

Просмотреть файл

@ -20,10 +20,10 @@ namespace Microsoft.Generator.CSharp.Providers
public FormattableString Description { get; }
public XmlDocSummaryStatement XmlDocSummary { get; }
public MethodSignatureModifiers Modifiers { get; }
public MethodSignatureModifiers Modifiers { get; internal set; }
public CSharpType Type { get; }
public string Name { get; }
public PropertyBody Body { get; private set; }
public string Name { get; internal set; }
public PropertyBody Body { get; internal set; }
public CSharpType? ExplicitInterface { get; }
public XmlDocProvider XmlDocs { get; private set; }
public PropertyWireInformation? WireInfo { get; }

Просмотреть файл

@ -20,6 +20,8 @@ namespace Microsoft.Generator.CSharp.Snippets
public static ValueExpression NullConditional(this ParameterProvider parameter) => new NullConditionalExpression(parameter);
public static ValueExpression NullCoalesce(this ParameterProvider parameter, ValueExpression value) => parameter.AsExpression.NullCoalesce(value);
public static DictionaryExpression AsDictionary(this FieldProvider field, CSharpType keyType, CSharpType valueType) => new(new KeyValuePairType(keyType, valueType), field);
public static DictionaryExpression AsDictionary(this ParameterProvider parameter, CSharpType keyType, CSharpType valueType) => new(new KeyValuePairType(keyType, valueType), parameter);
@ -56,8 +58,6 @@ namespace Microsoft.Generator.CSharp.Snippets
public static ValueExpression Nameof(ValueExpression expression) => new InvokeMethodExpression(null, "nameof", new[] { expression });
public static ValueExpression ThrowExpression(ValueExpression expression) => new KeywordExpression("throw", expression);
public static ValueExpression NullCoalescing(ValueExpression left, ValueExpression right) => new BinaryOperatorExpression("??", left, right);
// TO-DO: Migrate remaining class as part of output classes migration : https://github.com/Azure/autorest.csharp/issues/4198
//public static ValueExpression EnumValue(EnumType type, EnumTypeValue value) => new MemberExpression(new TypeReference(type.Type), value.Declaration.Name);
public static ValueExpression FrameworkEnumValue<TEnum>(TEnum value) where TEnum : struct, Enum => new MemberExpression(TypeReferenceExpression.FromType(typeof(TEnum)), Enum.GetName(value)!);

Просмотреть файл

@ -18,7 +18,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
private static readonly InputModelType _catModel = InputFactory.Model("cat", discriminatedKind: "cat", properties:
[
InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true),
InputFactory.Property("willScratchOwner", InputPrimitiveType.Boolean, isRequired: true, isDiscriminator: true)
InputFactory.Property("willScratchOwner", InputPrimitiveType.Boolean, isRequired: true)
]);
private static readonly InputModelType _dogModel = InputFactory.Model("dog", discriminatedKind: "dog", properties:
[
@ -30,6 +30,26 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
properties: [InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true)],
discriminatedModels: new Dictionary<string, InputModelType>() { { "cat", _catModel }, { "dog", _dogModel } });
private static readonly InputEnumType _petEnum = InputFactory.Enum("pet", InputPrimitiveType.String, isExtensible: true, values:
[
InputFactory.EnumMember.String("cat", "cat"),
InputFactory.EnumMember.String("dog", "dog")
]);
private static readonly InputModelType _catEnumModel = InputFactory.Model("cat", discriminatedKind: "cat", properties:
[
InputFactory.Property("kind", _petEnum, isRequired: true, isDiscriminator: true),
InputFactory.Property("willScratchOwner", InputPrimitiveType.Boolean, isRequired: true)
]);
private static readonly InputModelType _dogEnumModel = InputFactory.Model("dog", discriminatedKind: "dog", properties:
[
InputFactory.Property("kind", _petEnum, isRequired: true, isDiscriminator: true),
InputFactory.Property("likesBones", InputPrimitiveType.Boolean, isRequired: true)
]);
private static readonly InputModelType _baseEnumModel = InputFactory.Model(
"pet",
properties: [InputFactory.Property("kind", _petEnum, isRequired: true, isDiscriminator: true)],
discriminatedModels: new Dictionary<string, InputModelType>() { { "cat", _catEnumModel }, { "dog", _dogEnumModel } });
[Test]
public void BaseShouldBeAbstract()
{
@ -154,5 +174,38 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
Assert.IsNotNull(serializationCtor);
Assert.AreEqual("kind", serializationCtor!.Signature.Parameters[0].Name);
}
[Test]
public void BaseDoesNotHaveDiscriminatorField()
{
MockHelpers.LoadMockPlugin(inputModelTypes: [_baseEnumModel, _catEnumModel, _dogEnumModel]);
var outputLibrary = CodeModelPlugin.Instance.OutputLibrary;
var baseModel = outputLibrary.TypeProviders.OfType<ModelProvider>().FirstOrDefault(t => t.Name == "Pet");
Assert.IsNotNull(baseModel);
Assert.IsFalse(baseModel!.Fields.Any(f => f.Name == "_kind"));
}
[Test]
public void BaseKindPropertyIsNotVirtual()
{
MockHelpers.LoadMockPlugin(inputModelTypes: [_baseEnumModel, _catEnumModel, _dogEnumModel]);
var outputLibrary = CodeModelPlugin.Instance.OutputLibrary;
var baseModel = outputLibrary.TypeProviders.OfType<ModelProvider>().FirstOrDefault(t => t.Name == "Pet");
Assert.IsNotNull(baseModel);
var kindProperty = baseModel!.Properties.FirstOrDefault(p => p.Name == "Kind");
Assert.IsNotNull(kindProperty);
Assert.IsFalse(kindProperty!.Modifiers.HasFlag(MethodSignatureModifiers.Virtual));
}
[Test]
public void DerivedHasNoKindProperty()
{
MockHelpers.LoadMockPlugin(inputModelTypes: [_baseEnumModel, _catEnumModel, _dogEnumModel]);
var outputLibrary = CodeModelPlugin.Instance.OutputLibrary;
var catModel = outputLibrary.TypeProviders.OfType<ModelProvider>().FirstOrDefault(t => t.Name == "Cat");
Assert.IsNotNull(catModel);
var kindProperty = catModel!.Properties.FirstOrDefault(p => p.Name == "Kind");
Assert.IsNull(kindProperty);
}
}
}

Просмотреть файл

@ -303,7 +303,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
var param = constructorSignature?.Parameters[0];
Assert.IsNotNull(param);
Assert.AreEqual("serializedAdditionalRawData", param?.Name);
}
}
}
[Test]
@ -403,5 +403,142 @@ namespace Microsoft.Generator.CSharp.Tests.Providers.ModelProviders
yield return new TestCaseData(InputFactory.Model("foo"), true);
}
}
[Test]
public void DuplicatePropertyHasVirtualAndOverrideKeyword()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.String)]);
var baseInputModel = InputFactory.Model("baseModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.String)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var derivedProp = derivedModel!.Properties[0];
var baseProp = baseModel!.Properties[0];
Assert.AreEqual(baseProp.Name, derivedProp.Name);
Assert.AreEqual(baseProp.Type, derivedProp.Type);
Assert.IsNotNull(baseProp.WireInfo);
Assert.IsNotNull(derivedProp.WireInfo);
Assert.AreEqual(baseProp.WireInfo!.IsRequired, derivedProp.WireInfo!.IsRequired);
Assert.IsTrue(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.Virtual));
Assert.IsTrue(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.Override));
Assert.IsFalse(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.Override));
Assert.IsFalse(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.Virtual));
}
[Test]
public void OptionalityChangeNarrowPropertyHasNewKeyword()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.String, isRequired: true)]);
var baseInputModel = InputFactory.Model("baseModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.String)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var derivedProp = derivedModel!.Properties[0];
var baseProp = baseModel!.Properties[0];
Assert.AreEqual(baseProp.Name, derivedProp.Name);
Assert.IsTrue(baseProp.Type.Equals(derivedProp.Type, ignoreNullable: true));
Assert.IsNotNull(baseProp.WireInfo);
Assert.IsNotNull(derivedProp.WireInfo);
Assert.IsFalse(baseProp.WireInfo!.IsRequired);
Assert.IsTrue(derivedProp.WireInfo!.IsRequired);
Assert.IsTrue(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.New));
Assert.IsFalse(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.Virtual));
Assert.IsFalse(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.New));
Assert.IsFalse(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.Override));
}
[Test]
public void TypeChangeNarrowPropertyHasNewKeyWord()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int32)]);
var baseInputModel = InputFactory.Model("baseModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int64)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var derivedProp = derivedModel!.Properties[0];
var baseProp = baseModel!.Properties[0];
Assert.AreEqual(baseProp.Name, derivedProp.Name);
Assert.IsFalse(baseProp.Type.Equals(derivedProp.Type, ignoreNullable: true));
Assert.IsNotNull(baseProp.WireInfo);
Assert.IsNotNull(derivedProp.WireInfo);
Assert.AreEqual(baseProp.WireInfo!.IsRequired, derivedProp.WireInfo!.IsRequired);
Assert.IsTrue(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.New));
Assert.IsFalse(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.Virtual));
Assert.IsFalse(baseProp.Modifiers.HasFlag(MethodSignatureModifiers.New));
Assert.IsFalse(derivedProp.Modifiers.HasFlag(MethodSignatureModifiers.Override));
}
[Test]
public void BaseHasFieldWhenPropertyIsNarrowed()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int32)]);
var baseInputModel = InputFactory.Model("baseModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int64)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var baseField = baseModel!.Fields.FirstOrDefault(f => f.Name == "_prop1");
Assert.IsNotNull(baseField);
Assert.AreEqual(new CSharpType(typeof(long)), baseField!.Type);
Assert.AreEqual(FieldModifiers.Private | FieldModifiers.Protected, baseField.Modifiers);
}
[Test]
public void DerivedUsesExpressionBodyPropertyWhenNarrowed()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int32)]);
var baseInputModel = InputFactory.Model("baseModel", properties: [InputFactory.Property("prop1", InputPrimitiveType.Int64)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var derivedProp = derivedModel!.Properties[0];
Assert.IsNotNull(derivedProp);
var expressionBody = derivedProp.Body as ExpressionPropertyBody;
Assert.IsNotNull(expressionBody);
Assert.IsTrue(expressionBody!.Getter.ToDisplayString().Contains("_prop1 ?? default"));
Assert.IsTrue(expressionBody.HasSetter);
Assert.IsTrue(expressionBody.Setter!.ToDisplayString().Contains("_prop1 = value"));
}
[Test]
public void DerivedExpressionBodyDoesNotHaveSetterWhenNarrowed()
{
MockHelpers.LoadMockPlugin();
var derivedInputModel = InputFactory.Model("derivedModel", usage: InputModelTypeUsage.Output, properties: [InputFactory.Property("prop1", InputPrimitiveType.Int32, isReadOnly: true)]);
var baseInputModel = InputFactory.Model("baseModel", usage: InputModelTypeUsage.Output, properties: [InputFactory.Property("prop1", InputPrimitiveType.Int64, isReadOnly: true)], derivedModels: [derivedInputModel]);
var derivedModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(derivedInputModel);
var baseModel = CodeModelPlugin.Instance.TypeFactory.CreateModel(baseInputModel);
Assert.IsNotNull(derivedModel);
Assert.IsNotNull(baseModel);
var derivedProp = derivedModel!.Properties[0];
Assert.IsNotNull(derivedProp);
var expressionBody = derivedProp.Body as ExpressionPropertyBody;
Assert.IsNotNull(expressionBody);
Assert.IsTrue(expressionBody!.Getter.ToDisplayString().Contains("_prop1 ?? default"));
Assert.IsFalse(expressionBody.HasSetter);
Assert.IsNull(expressionBody.Setter);
}
}
}

Просмотреть файл

@ -121,12 +121,13 @@ namespace Microsoft.Generator.CSharp.Tests.Common
bool isRequired = false,
bool isReadOnly = false,
bool isDiscriminator = false,
string? wireName = null)
string? wireName = null,
string? description = null)
{
return new InputModelProperty(
name,
wireName ?? name.ToVariableName(),
$"Description for {name}",
description ?? $"Description for {name}",
type,
isRequired,
isReadOnly,