Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.

Commit 052693c

Browse files
committed
Reintroduce IsSpecialName check for properties
This is a follow-up to devlooped#712 and devlooped#713, where we added tests documenting F# and COM events not being marked with the IL `specialname` flag. But as it turns out, F# and COM *properties* are marked as `specialname`, which we document here using unit tests. Finally, we bring back checks for `method.IsSpecialName` for property accessor method recognition.
1 parent 08c5f5f commit 052693c

9 files changed

+100
-4
lines changed

src/Moq/Extensions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ public static bool IsExtensionMethod(this MethodInfo method)
4444

4545
public static bool IsPropertyGetter(this MethodInfo method)
4646
{
47-
return method.Name.StartsWith("get_", StringComparison.Ordinal);
47+
return method.IsSpecialName && method.Name.StartsWith("get_", StringComparison.Ordinal);
4848
}
4949

5050
public static bool IsPropertyIndexerGetter(this MethodInfo method)
5151
{
52-
return method.Name.StartsWith("get_Item", StringComparison.Ordinal);
52+
return method.IsSpecialName && method.Name.StartsWith("get_Item", StringComparison.Ordinal);
5353
}
5454

5555
public static bool IsPropertyIndexerSetter(this MethodInfo method)
5656
{
57-
return method.Name.StartsWith("set_Item", StringComparison.Ordinal);
57+
return method.IsSpecialName && method.Name.StartsWith("set_Item", StringComparison.Ordinal);
5858
}
5959

6060
public static bool IsPropertySetter(this MethodInfo method)
6161
{
62-
return method.Name.StartsWith("set_", StringComparison.Ordinal);
62+
return method.IsSpecialName && method.Name.StartsWith("set_", StringComparison.Ordinal);
6363
}
6464

6565
// NOTE: The following two methods used to first check whether `method.IsSpecialName` was set

tests/Moq.Tests.ComTypes/ComTypes.idl

+7
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,11 @@ library ComTypes
3232
[default] interface IButton;
3333
[default, source] interface IButtonEvents;
3434
}
35+
36+
[uuid("62a88a92-d8e5-45f7-bb7f-668a74c58749")]
37+
interface IHasProperty : IUnknown
38+
{
39+
[propget] HRESULT Property([out, retval] long *value);
40+
[propput] HRESULT Property([in] long value);
41+
}
3542
}
512 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
2+
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.
3+
4+
namespace Moq.Tests.FSharpTypes
5+
6+
open System;
7+
8+
[<AbstractClass>]
9+
type HasAbstractProperty() =
10+
abstract Property: obj with get, set
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
2+
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.
3+
4+
namespace Moq.Tests.FSharpTypes
5+
6+
open System;
7+
8+
type HasProperty() =
9+
let mutable property = new obj()
10+
abstract Property: obj with get, set
11+
default this.Property with get() = property and set(value: obj) = property <- value
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
2+
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.
3+
4+
namespace Moq.Tests.FSharpTypes
5+
6+
open System;
7+
8+
type IHasProperty =
9+
abstract member Property: obj with get, set

tests/Moq.Tests.FSharpTypes/Moq.Tests.FSharpTypes.fsproj

+3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
<ItemGroup>
1414
<Compile Include="HasAbstractActionEvent.fs" />
1515
<Compile Include="HasAbstractEventHandlerEvent.fs" />
16+
<Compile Include="HasAbstractProperty.fs" />
1617
<Compile Include="HasActionEvent.fs" />
18+
<Compile Include="HasProperty.fs" />
1719
<Compile Include="IHasActionEvent.fs" />
1820
<Compile Include="IHasEventHandlerEvent.fs" />
21+
<Compile Include="IHasProperty.fs" />
1922
</ItemGroup>
2023

2124
<Target Name="Test" DependsOnTargets="Build" />

tests/Moq.Tests/ComCompatibilityFixture.cs

+23
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,29 @@ public void Can_unsubscribe_from_COM_interop_type_event()
5656

5757
Assert.Equal(1, eventRaiseCount);
5858
}
59+
60+
[Fact]
61+
public void COM_interop_type_property_has_accessors_that_are_marked_as_specialname()
62+
{
63+
var property = typeof(IHasProperty).GetProperty(nameof(IHasProperty.Property));
64+
Assert.All(property.GetAccessors(), accessor => Assert.True(accessor.IsSpecialName, "Accessor is not marked as `specialname`."));
65+
}
66+
67+
[Fact]
68+
public void COM_interop_type_property_getter_is_recognized_as_such()
69+
{
70+
var property = typeof(IHasProperty).GetProperty(nameof(IHasProperty.Property));
71+
var getter = property.GetGetMethod(true);
72+
Assert.True(getter.IsPropertyGetter());
73+
}
74+
75+
[Fact]
76+
public void COM_interop_type_property_setter_is_recognized_as_such()
77+
{
78+
var property = typeof(IHasProperty).GetProperty(nameof(IHasProperty.Property));
79+
var setter = property.GetSetMethod(true);
80+
Assert.True(setter.IsPropertySetter());
81+
}
5982
}
6083
}
6184

tests/Moq.Tests/FSharpCompatibilityFixture.cs

+33
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,38 @@ public void Can_unsubscribe_from_FSharp_event()
7777

7878
Assert.Equal(1, eventRaiseCount);
7979
}
80+
81+
public static IEnumerable<object[]> FSharpProperties
82+
{
83+
get
84+
{
85+
yield return new object[] { typeof(IHasProperty).GetProperty(nameof(IHasProperty.Property)) };
86+
yield return new object[] { typeof(HasAbstractProperty).GetProperty(nameof(HasAbstractProperty.Property)) };
87+
yield return new object[] { typeof(HasProperty).GetProperty(nameof(HasProperty.Property)) };
88+
}
89+
}
90+
91+
[Theory]
92+
[MemberData(nameof(FSharpProperties))]
93+
public void All_FSharp_properties_have_accessors_marked_as_specialname(PropertyInfo property)
94+
{
95+
Assert.All(@property.GetAccessors(), accessor => Assert.True(accessor.IsSpecialName, "Accessor not marked as `specialname`."));
96+
}
97+
98+
[Theory]
99+
[MemberData(nameof(FSharpProperties))]
100+
public void All_FSharp_property_getters_are_recognized_as_such(PropertyInfo property)
101+
{
102+
var getter = property.GetGetMethod(true);
103+
Assert.True(getter.IsPropertyGetter());
104+
}
105+
106+
[Theory]
107+
[MemberData(nameof(FSharpProperties))]
108+
public void All_FSharp_property_setters_are_recognized_as_such(PropertyInfo property)
109+
{
110+
var setter = property.GetSetMethod(true);
111+
Assert.True(setter.IsPropertySetter());
112+
}
80113
}
81114
}

0 commit comments

Comments
 (0)