Skip to content

Commit

Permalink
[release/6.0] Treat 'abstract' properties the same as 'virtual' for s…
Browse files Browse the repository at this point in the history
…rc-gen (#59771)

* Treat 'abstract' properties the same as 'virtual' for src-gen

* Change virtual detection; move test to common

Co-authored-by: Steve Harter <[email protected]>
  • Loading branch information
github-actions[bot] and steveharter authored Sep 30, 2021
1 parent 9f66ef7 commit 8e2b607
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static MethodAttributes GetMethodAttributes(this IMethodSymbol methodSymb

if (methodSymbol.IsAbstract)
{
attributes |= MethodAttributes.Abstract;
attributes |= MethodAttributes.Abstract | MethodAttributes.Virtual;
}

if (methodSymbol.IsStatic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2653,5 +2653,94 @@ public async Task JsonIgnoreCondition_WhenWritingDefault_OnInterface()
json = await JsonSerializerWrapperForString.SerializeWrapper(obj);
Assert.Equal("{\"MyProp\":{}}", json);
}

public class ConcreteDerivedClass : AbstractBaseClass
{
// Ignored including on base class:
[JsonIgnore] public override int Abstract_Ignored_Property { get; set; }
[JsonIgnore] public override int Virtual_Ignored_Property { get; set; }

// Ignored but not specified on base class:
[JsonIgnore] public override int Abstract_IgnoredOnConcrete_Property { get; set; }
[JsonIgnore] public override int Virtual_IgnoredOnConcrete_Property { get; set; }

// Ignored specified on base class:
[JsonPropertyOrder(1)] public override int Abstract_IgnoredOnBase_Property { get; set; }
[JsonPropertyOrder(2)] public override int Virtual_IgnoredOnBase_Property { get; set; }

// Standard overrides (not ignored):
[JsonPropertyOrder(3)] public override int Abstract_Property { get; set; }
[JsonPropertyOrder(4)] public override int Virtual_Property { get; set; }
}

public abstract class AbstractBaseClass
{
[JsonIgnore] public abstract int Abstract_Ignored_Property { get; set; }
[JsonIgnore] public virtual int Virtual_Ignored_Property { get; set; }

public abstract int Abstract_IgnoredOnConcrete_Property { get; set; }
public virtual int Virtual_IgnoredOnConcrete_Property { get; set; }

[JsonIgnore] public abstract int Abstract_IgnoredOnBase_Property { get; set; }
[JsonIgnore] public virtual int Virtual_IgnoredOnBase_Property { get; set; }

public abstract int Abstract_Property { get; set; }
public virtual int Virtual_Property { get; set; }
}

[Fact]
public async Task JsonIgnoreCondition_Polymorphic()
{
ConcreteDerivedClass obj = new()
{
Abstract_Ignored_Property = -1,
Virtual_Ignored_Property = -1,
Abstract_IgnoredOnConcrete_Property = -1,
Virtual_IgnoredOnConcrete_Property = -1,
Abstract_IgnoredOnBase_Property = 1,
Virtual_IgnoredOnBase_Property = 2,
Abstract_Property = 3,
Virtual_Property = 4,
};

// Verify properties work as expected.
Assert.Equal(-1, obj.Abstract_Ignored_Property);
Assert.Equal(-1, obj.Virtual_Ignored_Property);
Assert.Equal(-1, obj.Abstract_IgnoredOnConcrete_Property);
Assert.Equal(-1, obj.Virtual_IgnoredOnConcrete_Property);
Assert.Equal(1, obj.Abstract_IgnoredOnBase_Property);
Assert.Equal(2, obj.Virtual_IgnoredOnBase_Property);
Assert.Equal(3, obj.Abstract_Property);
Assert.Equal(4, obj.Virtual_Property);

const string ExpectedJson = "{" +
"\"Abstract_IgnoredOnBase_Property\":1," +
"\"Virtual_IgnoredOnBase_Property\":2," +
"\"Abstract_Property\":3," +
"\"Virtual_Property\":4}";

string json = await JsonSerializerWrapperForString.SerializeWrapper(obj);
Assert.Equal(ExpectedJson, json);

const string Json = "{" +
"\"Abstract_Ignored_Property\":-1," +
"\"Virtual_Ignored_Property\":-1," +
"\"Abstract_IgnoredOnConcrete_Property\":-1," +
"\"Virtual_IgnoredOnConcrete_Property\":-1," +
"\"Abstract_IgnoredOnBase_Property\":1," +
"\"Virtual_IgnoredOnBase_Property\":2," +
"\"Abstract_Property\":3," +
"\"Virtual_Property\":4}";

obj = await JsonSerializerWrapperForString.DeserializeWrapper<ConcreteDerivedClass>(Json);
Assert.Equal(0, obj.Abstract_Ignored_Property);
Assert.Equal(0, obj.Virtual_Ignored_Property);
Assert.Equal(0, obj.Abstract_IgnoredOnConcrete_Property);
Assert.Equal(0, obj.Virtual_IgnoredOnConcrete_Property);
Assert.Equal(1, obj.Abstract_IgnoredOnBase_Property);
Assert.Equal(2, obj.Virtual_IgnoredOnBase_Property);
Assert.Equal(3, obj.Abstract_Property);
Assert.Equal(4, obj.Virtual_Property);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ public override async Task HonorJsonPropertyName_PrivateSetter()
[JsonSerializable(typeof(StructWithPropertiesWithJsonPropertyName_PrivateSetter))]
[JsonSerializable(typeof(ClassWithValueAndReferenceTypes))]
[JsonSerializable(typeof(ClassWithReadOnlyStringProperty_IgnoreWhenWritingDefault))]
[JsonSerializable(typeof(ConcreteDerivedClass))]
internal sealed partial class PropertyVisibilityTestsContext_Metadata : JsonSerializerContext
{
}
Expand Down Expand Up @@ -429,6 +430,7 @@ public override async Task JsonIgnoreCondition_WhenWritingNull_OnValueType_Fail_
[JsonSerializable(typeof(StructWithPropertiesWithJsonPropertyName_PrivateSetter))]
[JsonSerializable(typeof(ClassWithValueAndReferenceTypes))]
[JsonSerializable(typeof(ClassWithReadOnlyStringProperty_IgnoreWhenWritingDefault))]
[JsonSerializable(typeof(ConcreteDerivedClass))]
internal sealed partial class PropertyVisibilityTestsContext_Default : JsonSerializerContext
{
}
Expand Down

0 comments on commit 8e2b607

Please sign in to comment.