Skip to content

Commit 9bce6be

Browse files
committed
add more target attributes to AttributeFilter.Default
1 parent 468c6fd commit 9bce6be

File tree

3 files changed

+151
-9
lines changed

3 files changed

+151
-9
lines changed

src/Smdn.Reflection.ReverseGenerating.ListApi.Core/Smdn.Reflection.ReverseGenerating.ListApi/AttributeFilter.cs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,54 @@ private static bool DefaultImpl(Type attrType, ICustomAttributeProvider attrProv
1919
return false;
2020
if ("NullableContextAttribute".Equals(attrType.Name, StringComparison.Ordinal))
2121
return false;
22+
23+
if ("CompilerGeneratedAttribute".Equals(attrType.Name, StringComparison.Ordinal)) {
24+
if (attrProvider is MethodInfo m && (m.IsPropertyAccessorMethod() || m.IsEventAccessorMethod()))
25+
return false;
26+
if (attrProvider is FieldInfo f && (f.IsPropertyBackingField() || f.IsEventBackingField()))
27+
return false;
28+
}
29+
30+
if ("IsReadOnlyAttribute".Equals(attrType.Name, StringComparison.Ordinal)) {
31+
var ignore = attrProvider switch {
32+
Type => true,
33+
MethodInfo m => m.IsPropertyAccessorMethod(),
34+
ParameterInfo => true,
35+
_ => false,
36+
};
37+
38+
if (ignore)
39+
return false;
40+
}
41+
}
42+
43+
// System.Diagnostics.DebuggerXxxAttribute
44+
if ("System.Diagnostics".Equals(attrType.Namespace, StringComparison.Ordinal)) {
45+
if (attrType.Name.StartsWith("Debugger", StringComparison.Ordinal) && attrType.Name.EndsWith("Attribute", StringComparison.Ordinal))
46+
return false;
2247
}
2348

2449
switch (attrProvider) {
25-
case Type:
50+
case Type t:
2651
if (ROCType.FullNameEquals(typeof(System.Reflection.DefaultMemberAttribute), attrType))
2752
return false;
28-
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.IsReadOnlyAttribute), attrType))
29-
return false;
3053
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.ExtensionAttribute), attrType))
3154
return false;
55+
56+
if (t.IsGenericParameter) {
57+
if ("System.Runtime.CompilerServices.IsUnmanagedAttribute".Equals(attrType.FullName, StringComparison.Ordinal))
58+
return false;
59+
}
60+
3261
break;
3362

34-
case MethodBase m:
63+
case MethodBase:
3564
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.ExtensionAttribute), attrType))
3665
return false;
3766
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.IteratorStateMachineAttribute), attrType))
3867
return false;
3968
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.AsyncStateMachineAttribute), attrType))
4069
return false;
41-
if (ROCType.FullNameEquals(typeof(System.Diagnostics.DebuggerStepThroughAttribute), attrType))
42-
// exclude DebuggerStepThroughAttribute of async methods
43-
return !m.GetCustomAttributesData().Any(static d => ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.AsyncStateMachineAttribute), d.AttributeType));
4470
break;
4571

4672
case FieldInfo:
@@ -66,8 +92,6 @@ private static bool DefaultImpl(Type attrType, ICustomAttributeProvider attrProv
6692
return false;
6793
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.TupleElementNamesAttribute), attrType))
6894
return false;
69-
if (ROCType.FullNameEquals(typeof(System.Runtime.CompilerServices.IsReadOnlyAttribute), attrType))
70-
return false;
7195
break;
7296
}
7397

tests/Smdn.Reflection.ReverseGenerating.ListApi.Core/Smdn.Reflection.ReverseGenerating.ListApi/AttributeFilter.TestCases.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,27 @@ public class DefaultMemberClass {
7070
}
7171
}
7272

73+
public class GenericParameterAttributes {
74+
public class IsUnmanagedAttr<
75+
[TypeAttributeFilterTestCaseAttribute("")]
76+
[TypeAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
77+
TClass,
78+
[TypeAttributeFilterTestCaseAttribute("[IsUnmanaged]")]
79+
[TypeAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
80+
TUnmanaged
81+
> where TClass : class where TUnmanaged : unmanaged {
82+
public void M<
83+
[TypeAttributeFilterTestCaseAttribute("")]
84+
[TypeAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
85+
TMethodStruct,
86+
87+
[TypeAttributeFilterTestCaseAttribute("[IsUnmanaged]")]
88+
[TypeAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
89+
TMethodUnmanaged
90+
>() where TMethodStruct : struct where TMethodUnmanaged : unmanaged { }
91+
}
92+
}
93+
7394
public class MethodAttributes {
7495
public class IteratorStateMachineAttr {
7596
[MemberAttributeFilterTestCaseAttribute("")]
@@ -130,6 +151,70 @@ public class TupleElementNamesAttr {
130151
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
131152
public (int X, int Y) Named => throw null;
132153
}
154+
155+
public struct IsReadOnlyAttr {
156+
public int P {
157+
[MemberAttributeFilterTestCaseAttribute("")]
158+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
159+
get => 0;
160+
}
161+
162+
public int PReadOnlyImplicit {
163+
[MemberAttributeFilterTestCaseAttribute("[CompilerGenerated, IsReadOnly]")]
164+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
165+
get;
166+
}
167+
168+
public readonly int PReadOnlyExplicit {
169+
[MemberAttributeFilterTestCaseAttribute("[IsReadOnly]")]
170+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
171+
get => 0;
172+
}
173+
}
174+
175+
public class CompilerGeneratedAttr {
176+
public int P {
177+
[MemberAttributeFilterTestCaseAttribute("")]
178+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
179+
get => throw null;
180+
[MemberAttributeFilterTestCaseAttribute("")]
181+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
182+
set => throw null;
183+
}
184+
185+
[field: MemberAttributeFilterTestCaseAttribute("[field: DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]")]
186+
[field: MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
187+
public int PCompilerGenerated {
188+
[MemberAttributeFilterTestCaseAttribute("[CompilerGenerated]")]
189+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
190+
get;
191+
192+
[MemberAttributeFilterTestCaseAttribute("[CompilerGenerated]")]
193+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
194+
set;
195+
}
196+
}
197+
}
198+
199+
public class EventAttributes {
200+
public class CompilerGeneratedAttr {
201+
#pragma warning disable CS0067
202+
public event EventHandler E {
203+
[MemberAttributeFilterTestCaseAttribute("")]
204+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
205+
add => throw null;
206+
[MemberAttributeFilterTestCaseAttribute("")]
207+
[MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
208+
remove => throw null;
209+
}
210+
211+
[field: MemberAttributeFilterTestCaseAttribute("[field: DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]")]
212+
[field: MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
213+
[method: MemberAttributeFilterTestCaseAttribute("[CompilerGenerated]")]
214+
[method: MemberAttributeFilterTestCaseAttribute("", FilterType = typeof(AttributeFilter), FilterMemberName = nameof(AttributeFilter.Default))]
215+
public event EventHandler ECompilerGenerated;
216+
#pragma warning restore CS0067
217+
}
133218
}
134219

135220
public class ParameterAttributes {

tests/Smdn.Reflection.ReverseGenerating.ListApi.Core/Smdn.Reflection.ReverseGenerating.ListApi/AttributeFilter.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,28 @@ private static System.Collections.IEnumerable YieldTestCases_Parameters()
4444
)
4545
);
4646

47+
private static System.Collections.IEnumerable YieldTestCases_GenericParameters()
48+
{
49+
var types = FindTypes(static t => t.Namespace is not null && t.Namespace.StartsWith(typeof(ClassToDetermineNamespace).Namespace, StringComparison.Ordinal));
50+
51+
var genericTypeParameters = types
52+
//.Where(static t => t.IsGenericType)
53+
.SelectMany(static t => t.GetGenericArguments());
54+
55+
var genericMethodParameters = types
56+
.SelectMany(static t => t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
57+
//.Where(static m => m.IsGenericMethod)
58+
.SelectMany(static method => method.GetGenericArguments());
59+
60+
return genericTypeParameters
61+
.Concat(genericMethodParameters)
62+
.SelectMany(
63+
static genericParam => genericParam.GetCustomAttributes<TypeAttributeFilterTestCaseAttribute>().Select(
64+
attr => new object[] { genericParam, attr }
65+
)
66+
);
67+
}
68+
4769
private static void TestAttributeFilter(
4870
Func<string> actual,
4971
GeneratorTestCaseAttribute testCase,
@@ -100,4 +122,15 @@ GeneratorTestCaseAttribute testCase
100122
testCase: testCase,
101123
testTarget: $"{para.Member.DeclaringType!.FullName}.{para.Member.Name} {para.Name}"
102124
);
125+
126+
[TestCaseSource(nameof(YieldTestCases_GenericParameters))]
127+
public void AttributeFilter_GenericParameters(
128+
Type genericParameter,
129+
GeneratorTestCaseAttribute testCase
130+
)
131+
=> TestAttributeFilter(
132+
actual: () => string.Join(", ", Generator.GenerateAttributeList(genericParameter, null, testCase.CreateGeneratorOptions())),
133+
testCase: testCase,
134+
testTarget: $"{genericParameter.FullName}"
135+
);
103136
}

0 commit comments

Comments
 (0)