@@ -10,16 +10,16 @@ namespace NetArchTest.Rules
1010 /// </summary>
1111 internal sealed class FunctionSequence
1212 {
13- private readonly List < List < FunctionCall > > _groups ;
13+ private readonly List < List < IFunctionCall > > _groups ;
1414
1515
1616 /// <summary>
1717 /// Initializes a new instance of the <see cref="FunctionSequence"/> class.
1818 /// </summary>
1919 internal FunctionSequence ( )
2020 {
21- _groups = new List < List < FunctionCall > > ( ) ;
22- _groups . Add ( new List < FunctionCall > ( ) ) ;
21+ _groups = new List < List < IFunctionCall > > ( ) ;
22+ _groups . Add ( new List < IFunctionCall > ( ) ) ;
2323 }
2424
2525
@@ -36,7 +36,7 @@ internal void AddFunctionCall<T>(FunctionDelegates.FunctionDelegate<T> method, T
3636 /// </summary>
3737 internal void CreateGroup ( )
3838 {
39- _groups . Add ( new List < FunctionCall > ( ) ) ;
39+ _groups . Add ( new List < IFunctionCall > ( ) ) ;
4040 }
4141
4242 /// <summary>
@@ -45,65 +45,39 @@ internal void CreateGroup()
4545 /// <returns>A list of types that are selected by the predicates (or not selected if optional reversing flag is passed).</returns>
4646 public IReadOnlyList < TypeSpec > ExecuteExtended ( IEnumerable < TypeSpec > inputTypes , bool selected = true )
4747 {
48- var resultSets = new List < List < TypeSpec > > ( ) ;
48+ MarkPassingTypes ( inputTypes ) ;
4949
50- // Execute each group of calls - each group represents a separate "or"
51- foreach ( var group in _groups )
52- {
53- var passingTypes = new List < TypeSpec > ( inputTypes ) ;
54-
55- // Invoke the functions iteratively - functions within a group are treated as "and" statements
56- foreach ( var func in group )
57- {
58- var funcResults = func . FunctionDelegate . DynamicInvoke ( passingTypes , func . Value , func . Condition ) as IEnumerable < TypeSpec > ;
59- passingTypes = funcResults . ToList ( ) ;
60- }
61-
62- if ( passingTypes . Count > 0 )
63- {
64- resultSets . Add ( passingTypes ) ;
65- }
66- }
67-
68- if ( selected )
69- {
70- // Return all the types that appear in at least one of the result sets
71- return resultSets . SelectMany ( list => list . Select ( def => def ) ) . Distinct ( ) . ToList ( ) ;
72- }
73- else
74- {
75- // Return all the types that *do not* appear in at least one of the result sets
76- var selectedTypes = resultSets . SelectMany ( list => list . Select ( def => def ) ) . Distinct ( ) . Select ( t => t . Definition . FullName ) ;
77- var notSelected = inputTypes . Where ( t => ! selectedTypes . Contains ( t . Definition . FullName ) ) . ToList ( ) ;
78- return notSelected ;
79- }
50+ return inputTypes . Where ( x => x . IsSelected == selected ) . ToList ( ) ;
8051 }
8152
8253 public IReadOnlyList < TypeSpec > Execute ( IEnumerable < TypeSpec > inputTypes )
8354 {
84- var resultSets = new List < IEnumerable < TypeSpec > > ( ) ;
85-
55+ MarkPassingTypes ( inputTypes ) ;
56+
57+ return inputTypes . Where ( x => x . IsSelected == true ) . ToList ( ) ;
58+ }
59+ private void MarkPassingTypes ( IEnumerable < TypeSpec > inputTypes )
60+ {
61+ inputTypes . ForEach ( x => x . IsSelected = false ) ;
62+
8663 foreach ( var group in _groups )
8764 {
8865 IEnumerable < TypeSpec > passingTypes = inputTypes ;
89-
66+
9067 foreach ( var func in group )
9168 {
92- var funcResults = func . FunctionDelegate . DynamicInvoke ( passingTypes , func . Value , func . Condition ) as IEnumerable < TypeSpec > ;
69+ var funcResults = func . Execute ( passingTypes ) ;
9370 passingTypes = funcResults ;
9471 }
9572
96- resultSets . Add ( passingTypes ) ;
73+ passingTypes . ForEach ( x => x . IsSelected = true ) ;
9774 }
98-
99- return resultSets . SelectMany ( list => list . Select ( def => def ) ) . Distinct ( ) . ToList ( ) ;
10075 }
10176
102-
10377 /// <summary>
10478 /// Represents a single function call.
10579 /// </summary>
106- internal class FunctionCall
80+ internal class FunctionCall : IFunctionCall
10781 {
10882 /// <summary>
10983 /// Initializes a new instance of the <see cref="FunctionCall"/> class.
@@ -115,6 +89,13 @@ internal FunctionCall(Delegate func, object value, bool condition)
11589 this . Condition = condition ;
11690 }
11791
92+
93+ public IEnumerable < TypeSpec > Execute ( IEnumerable < TypeSpec > inputTypes )
94+ {
95+ return FunctionDelegate . DynamicInvoke ( inputTypes , Value , Condition ) as IEnumerable < TypeSpec > ;
96+ }
97+
98+
11899 /// <summary>
119100 /// A delegate for a function call.
120101 /// </summary>
@@ -131,5 +112,10 @@ internal FunctionCall(Delegate func, object value, bool condition)
131112 public bool Condition { get ; private set ; }
132113
133114 }
115+
116+ internal interface IFunctionCall
117+ {
118+ IEnumerable < TypeSpec > Execute ( IEnumerable < TypeSpec > inputTypes ) ;
119+ }
134120 }
135121}
0 commit comments