Skip to content
Merged
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
@@ -1,4 +1,4 @@
using Dapper.CodeAnalysis;
using Dapper.CodeAnalysis;
using Dapper.Internal;
using Microsoft.CodeAnalysis;
using System;
Expand Down Expand Up @@ -56,15 +56,14 @@ public static CommandProperty Create(INamedTypeSymbol commandType, string name,
location is null ? default : new LocationSnapshot(location));
}

// note: preserved exactly from the emit-time check it replaces, quirks and all
private static bool HasPublicSettableInstanceMember(ITypeSymbol type, string name)
{
foreach (var member in type.GetMembers())
{
if (member.IsStatic || member.Name != name || member.DeclaredAccessibility != Accessibility.Public) continue;
return member.Kind switch
{
SymbolKind.Field when member is IFieldSymbol field => field.IsReadOnly,
SymbolKind.Field when member is IFieldSymbol field => !field.IsReadOnly,
SymbolKind.Property when member is IPropertySymbol prop => prop.SetMethod is not null,
_ => false,
};
Expand Down
43 changes: 43 additions & 0 deletions test/Dapper.AOT.Test/CommandPropertyMemberTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Dapper.AOT.Test.TestCommon;
using Dapper.CodeAnalysis.Model;
using Microsoft.CodeAnalysis;
using System.Linq;
using Xunit;

namespace Dapper.AOT.Test;

/// <summary>
/// The [CommandProperty] member probe: a public mutable field is assignable, a readonly
/// field is not (this was inverted for a long time - it never fired in anger because real
/// ADO.NET command types expose these knobs as properties).
/// </summary>
public class CommandPropertyMemberTests
{
const string Source = """
public class SomeCommandType
{
public int MutableField;
public readonly int ReadOnlyField;
public int SettableProperty { get; set; }
public int GetOnlyProperty { get; }
public static int StaticProperty { get; set; }
}
""";

static bool MemberExists(string name)
{
var compilation = RoslynTestHelpers.CreateCompilation(Source, "cmdprop_test", "Input.cs");
var type = (INamedTypeSymbol)compilation.GetSymbolsWithName("SomeCommandType").Single();
return CommandProperty.Create(type, name, 42, null).MemberExists;
}

[Theory]
[InlineData("MutableField", true)]
[InlineData("ReadOnlyField", false)]
[InlineData("SettableProperty", true)]
[InlineData("GetOnlyProperty", false)]
[InlineData("StaticProperty", false)]
[InlineData("DoesNotExist", false)]
public void MemberProbeReflectsAssignability(string name, bool expected)
=> Assert.Equal(expected, MemberExists(name));
}