Skip to content

Commit d2b14ed

Browse files
committed
BenMorris/NetArchTest#126 - Add support for structs, enums and delegates
1 parent 1a99cd4 commit d2b14ed

19 files changed

+553
-229
lines changed

src/NetArchTest.Rules/Condition.Traits.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,66 @@ public ConditionList NotBeClasses()
4444
return CreateConditionList();
4545
}
4646

47+
/// <summary>
48+
/// Selects types that are structures.
49+
/// </summary>
50+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
51+
public ConditionList BeStructures()
52+
{
53+
AddFunctionCall(x => FunctionDelegates.BeStruct(x, true));
54+
return CreateConditionList();
55+
}
56+
57+
/// <summary>
58+
/// Selects types that are not structures.
59+
/// </summary>
60+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
61+
public ConditionList NotBeStructures()
62+
{
63+
AddFunctionCall(x => FunctionDelegates.BeStruct(x, false));
64+
return CreateConditionList();
65+
}
66+
67+
/// <summary>
68+
/// Selects types that are enums.
69+
/// </summary>
70+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
71+
public ConditionList BeEnums()
72+
{
73+
AddFunctionCall(x => FunctionDelegates.BeEnum(x, true));
74+
return CreateConditionList();
75+
}
76+
77+
/// <summary>
78+
/// Selects types that are not enums.
79+
/// </summary>
80+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
81+
public ConditionList NotBeEnums()
82+
{
83+
AddFunctionCall(x => FunctionDelegates.BeEnum(x, false));
84+
return CreateConditionList();
85+
}
86+
87+
/// <summary>
88+
/// Selects types that are delegates.
89+
/// </summary>
90+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
91+
public ConditionList BeDelegates()
92+
{
93+
AddFunctionCall(x => FunctionDelegates.BeDelegate(x, true));
94+
return CreateConditionList();
95+
}
96+
97+
/// <summary>
98+
/// Selects types that are not delegates.
99+
/// </summary>
100+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
101+
public ConditionList NotBeDelegates()
102+
{
103+
AddFunctionCall(x => FunctionDelegates.BeDelegate(x, false));
104+
return CreateConditionList();
105+
}
106+
47107
/// <summary>
48108
/// Selects types that have generic parameters.
49109
/// </summary>

src/NetArchTest.Rules/Extensions/Mono.Cecil/TypeDefinitionExtensions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,16 @@ public static string GetNamespace(this TypeDefinition typeDefinition)
120120
}
121121
return typeDefinition.Namespace;
122122
}
123+
124+
125+
126+
public static bool IsDelegate(this TypeDefinition typeDefinition)
127+
{
128+
return typeDefinition.IsClass && typeDefinition.BaseType?.FullName == "System.MulticastDelegate";
129+
}
130+
public static bool IsStruct(this TypeDefinition typeDefinition)
131+
{
132+
return typeDefinition.IsValueType && typeDefinition.BaseType?.FullName == "System.ValueType";
133+
}
123134
}
124135
}

src/NetArchTest.Rules/Functions/FunctionDelegates.Traits.cs

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,59 @@
77
namespace NetArchTest.Functions
88
{
99
internal static partial class FunctionDelegates
10-
{
11-
/// <summary> Function for finding abstract classes. </summary>
12-
internal static IEnumerable<TypeSpec> BeAbstract(IEnumerable<TypeSpec> input, bool condition)
10+
{
11+
// Types
12+
13+
internal static IEnumerable<TypeSpec> BeClass(IEnumerable<TypeSpec> input, bool condition)
1314
{
1415
if (condition)
1516
{
16-
return input.Where(c => c.Definition.IsAbstract);
17+
return input.Where(c => IsClass(c.Definition));
1718
}
1819
else
1920
{
20-
return input.Where(c => !c.Definition.IsAbstract);
21+
return input.Where(c => !IsClass(c.Definition));
2122
}
23+
24+
bool IsClass(TypeDefinition c) => c.IsClass && !c.IsValueType && !c.IsDelegate();
2225
}
2326

24-
/// <summary> Function for finding classes. </summary>
25-
internal static IEnumerable<TypeSpec> BeClass(IEnumerable<TypeSpec> input, bool condition)
27+
internal static IEnumerable<TypeSpec> BeStruct(IEnumerable<TypeSpec> input, bool condition)
2628
{
2729
if (condition)
2830
{
29-
return input.Where(c => c.Definition.IsClass);
31+
return input.Where(c => c.Definition.IsStruct());
3032
}
3133
else
3234
{
33-
return input.Where(c => !c.Definition.IsClass);
35+
return input.Where(c => !c.Definition.IsStruct());
36+
}
37+
}
38+
39+
internal static IEnumerable<TypeSpec> BeEnum(IEnumerable<TypeSpec> input, bool condition)
40+
{
41+
if (condition)
42+
{
43+
return input.Where(c => c.Definition.IsEnum);
44+
}
45+
else
46+
{
47+
return input.Where(c => !c.Definition.IsEnum);
48+
}
49+
}
50+
51+
internal static IEnumerable<TypeSpec> BeDelegate(IEnumerable<TypeSpec> input, bool condition)
52+
{
53+
if (condition)
54+
{
55+
return input.Where(c => c.Definition.IsDelegate());
56+
}
57+
else
58+
{
59+
return input.Where(c => !c.Definition.IsDelegate());
3460
}
3561
}
3662

37-
/// <summary> Function for finding interfaces. </summary>
3863
internal static IEnumerable<TypeSpec> BeInterface(IEnumerable<TypeSpec> input, bool condition)
3964
{
4065
if (condition)
@@ -47,7 +72,20 @@ internal static IEnumerable<TypeSpec> BeInterface(IEnumerable<TypeSpec> input, b
4772
}
4873
}
4974

50-
/// <summary> Function for finding static classes. </summary>
75+
// Modifiers
76+
77+
internal static IEnumerable<TypeSpec> BeAbstract(IEnumerable<TypeSpec> input, bool condition)
78+
{
79+
if (condition)
80+
{
81+
return input.Where(c => c.Definition.IsAbstract);
82+
}
83+
else
84+
{
85+
return input.Where(c => !c.Definition.IsAbstract);
86+
}
87+
}
88+
5189
internal static IEnumerable<TypeSpec> BeStatic(IEnumerable<TypeSpec> input, bool condition)
5290
{
5391
if (condition)
@@ -62,7 +100,20 @@ internal static IEnumerable<TypeSpec> BeStatic(IEnumerable<TypeSpec> input, bool
62100
bool ClassIsStatic(TypeSpec c) => c.Definition.IsAbstract && c.Definition.IsSealed && !c.Definition.IsInterface && !c.Definition.GetConstructors().Any(m => m.IsPublic);
63101
}
64102

65-
/// <summary> Function for finding types with generic parameters. </summary>
103+
internal static IEnumerable<TypeSpec> BeSealed(IEnumerable<TypeSpec> input, bool condition)
104+
{
105+
if (condition)
106+
{
107+
return input.Where(c => c.Definition.IsSealed);
108+
}
109+
else
110+
{
111+
return input.Where(c => !c.Definition.IsSealed);
112+
}
113+
}
114+
115+
// Generic
116+
66117
internal static IEnumerable<TypeSpec> BeGeneric(IEnumerable<TypeSpec> input, bool condition)
67118
{
68119
if (condition)
@@ -75,8 +126,8 @@ internal static IEnumerable<TypeSpec> BeGeneric(IEnumerable<TypeSpec> input, boo
75126
}
76127
}
77128

78-
79-
/// <summary> Function for finding nested classes. </summary>
129+
// Nested
130+
80131
internal static IEnumerable<TypeSpec> BeNested(IEnumerable<TypeSpec> input, bool condition)
81132
{
82133
if (condition)
@@ -89,7 +140,6 @@ internal static IEnumerable<TypeSpec> BeNested(IEnumerable<TypeSpec> input, bool
89140
}
90141
}
91142

92-
/// <summary> Function for finding nested public classes. </summary>
93143
internal static IEnumerable<TypeSpec> BeNestedPublic(IEnumerable<TypeSpec> input, bool condition)
94144
{
95145
if (condition)
@@ -102,7 +152,6 @@ internal static IEnumerable<TypeSpec> BeNestedPublic(IEnumerable<TypeSpec> input
102152
}
103153
}
104154

105-
/// <summary> Function for finding nested private classes. </summary>
106155
internal static IEnumerable<TypeSpec> BeNestedPrivate(IEnumerable<TypeSpec> input, bool condition)
107156
{
108157
if (condition)
@@ -115,8 +164,8 @@ internal static IEnumerable<TypeSpec> BeNestedPrivate(IEnumerable<TypeSpec> inpu
115164
}
116165
}
117166

167+
// Access Modifiers
118168

119-
/// <summary> Function for finding public classes. </summary>
120169
internal static IEnumerable<TypeSpec> BePublic(IEnumerable<TypeSpec> input, bool condition)
121170
{
122171
if (condition)
@@ -128,21 +177,9 @@ internal static IEnumerable<TypeSpec> BePublic(IEnumerable<TypeSpec> input, bool
128177
return input.Where(c => c.Definition.IsNested ? !c.Definition.IsNestedPublic : c.Definition.IsNotPublic);
129178
}
130179
}
131-
132-
/// <summary> Function for finding sealed classes. </summary>
133-
internal static IEnumerable<TypeSpec> BeSealed(IEnumerable<TypeSpec> input, bool condition)
134-
{
135-
if (condition)
136-
{
137-
return input.Where(c => c.Definition.IsSealed);
138-
}
139-
else
140-
{
141-
return input.Where(c => !c.Definition.IsSealed);
142-
}
143-
}
144-
145-
/// <summary> Function for finding immutable classes. </summary>
180+
181+
//
182+
146183
internal static IEnumerable<TypeSpec> BeImmutable(IEnumerable<TypeSpec> input, bool condition)
147184
{
148185
if (condition)
@@ -154,9 +191,7 @@ internal static IEnumerable<TypeSpec> BeImmutable(IEnumerable<TypeSpec> input, b
154191
return input.Where(c => !c.Definition.IsImmutable());
155192
}
156193
}
157-
158-
159-
/// <summary> Function for finding nullable classes. </summary>
194+
160195
internal static IEnumerable<TypeSpec> HasNullableMembers(IEnumerable<TypeSpec> input, bool condition)
161196
{
162197
if (condition)

src/NetArchTest.Rules/Predicate.Traits.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,66 @@ public PredicateList AreNotClasses()
4444
return CreatePredicateList();
4545
}
4646

47+
/// <summary>
48+
/// Selects types that are structures.
49+
/// </summary>
50+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
51+
public PredicateList AreStructures()
52+
{
53+
AddFunctionCall(x => FunctionDelegates.BeStruct(x, true));
54+
return CreatePredicateList();
55+
}
56+
57+
/// <summary>
58+
/// Selects types that are not structures.
59+
/// </summary>
60+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
61+
public PredicateList AreNotStructures()
62+
{
63+
AddFunctionCall(x => FunctionDelegates.BeStruct(x, false));
64+
return CreatePredicateList();
65+
}
66+
67+
/// <summary>
68+
/// Selects types that are delegates.
69+
/// </summary>
70+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
71+
public PredicateList AreDelegates()
72+
{
73+
AddFunctionCall(x => FunctionDelegates.BeDelegate(x, true));
74+
return CreatePredicateList();
75+
}
76+
77+
/// <summary>
78+
/// Selects types that are not delegates.
79+
/// </summary>
80+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
81+
public PredicateList AreNotDelegates()
82+
{
83+
AddFunctionCall(x => FunctionDelegates.BeDelegate(x, false));
84+
return CreatePredicateList();
85+
}
86+
87+
/// <summary>
88+
/// Selects types that are enums.
89+
/// </summary>
90+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
91+
public PredicateList AreEnums()
92+
{
93+
AddFunctionCall(x => FunctionDelegates.BeEnum(x, true));
94+
return CreatePredicateList();
95+
}
96+
97+
/// <summary>
98+
/// Selects types that are not enums.
99+
/// </summary>
100+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
101+
public PredicateList AreNotEnums()
102+
{
103+
AddFunctionCall(x => FunctionDelegates.BeEnum(x, false));
104+
return CreatePredicateList();
105+
}
106+
47107
/// <summary>
48108
/// Selects types that have generic parameters.
49109
/// </summary>

0 commit comments

Comments
 (0)