@@ -37,11 +37,13 @@ public class UseShouldProcessCorrectly : IScriptRule
37
37
private FunctionReferenceDigraph funcDigraph ;
38
38
private List < DiagnosticRecord > diagnosticRecords ;
39
39
private readonly Vertex shouldProcessVertex ;
40
+ private readonly Vertex implicitShouldProcessVertex ;
40
41
41
42
public UseShouldProcessCorrectly ( )
42
43
{
43
44
diagnosticRecords = new List < DiagnosticRecord > ( ) ;
44
45
shouldProcessVertex = new Vertex ( "ShouldProcess" , null ) ;
46
+ implicitShouldProcessVertex = new Vertex ( "implicitShouldProcessVertex" , null ) ;
45
47
}
46
48
47
49
/// <summary>
@@ -150,10 +152,12 @@ private DiagnosticRecord GetViolation(Vertex v)
150
152
return null ;
151
153
}
152
154
153
- bool callsShouldProcess = funcDigraph . IsConnected ( v , shouldProcessVertex ) ;
154
155
if ( DeclaresSupportsShouldProcess ( fast ) )
155
156
{
156
- if ( ! callsShouldProcess )
157
+ bool callsShouldProcess = funcDigraph . IsConnected ( v , shouldProcessVertex ) ;
158
+ bool callsCommandWithShouldProcess = funcDigraph . IsConnected ( v , implicitShouldProcessVertex ) ;
159
+ if ( ! callsShouldProcess
160
+ && ! callsCommandWithShouldProcess )
157
161
{
158
162
return new DiagnosticRecord (
159
163
string . Format (
@@ -168,12 +172,12 @@ private DiagnosticRecord GetViolation(Vertex v)
168
172
}
169
173
else
170
174
{
171
- if ( callsShouldProcess )
175
+ if ( callsShouldProcessDirectly ( v ) )
172
176
{
173
177
// check if upstream function declares SupportShouldProcess
174
178
// if so, this might just be a helper function
175
179
// do not flag this case
176
- if ( UpstreamDeclaresShouldProcess ( v ) )
180
+ if ( v . IsNestedFunctionDefinition && UpstreamDeclaresShouldProcess ( v ) )
177
181
{
178
182
return null ;
179
183
}
@@ -193,6 +197,11 @@ private DiagnosticRecord GetViolation(Vertex v)
193
197
return null ;
194
198
}
195
199
200
+ private bool callsShouldProcessDirectly ( Vertex vertex )
201
+ {
202
+ return funcDigraph . GetNeighbors ( vertex ) . Contains ( shouldProcessVertex ) ;
203
+ }
204
+
196
205
/// <summary>
197
206
/// Checks if an upstream function declares SupportsShouldProcess
198
207
/// </summary>
@@ -344,10 +353,10 @@ private void CheckForSupportShouldProcess()
344
353
345
354
if ( commandsWithSupportShouldProcess . Count > 0 )
346
355
{
347
- funcDigraph . AddVertex ( shouldProcessVertex ) ;
356
+ funcDigraph . AddVertex ( implicitShouldProcessVertex ) ;
348
357
foreach ( var v in commandsWithSupportShouldProcess )
349
358
{
350
- funcDigraph . AddEdge ( v , shouldProcessVertex ) ;
359
+ funcDigraph . AddEdge ( v , implicitShouldProcessVertex ) ;
351
360
}
352
361
}
353
362
}
@@ -359,10 +368,23 @@ private void CheckForSupportShouldProcess()
359
368
class Vertex
360
369
{
361
370
public string Name { get { return name ; } }
362
- public Ast Ast { get { return ast ; } }
371
+ public Ast Ast
372
+ {
373
+ get
374
+ {
375
+ return ast ;
376
+ }
377
+ set
378
+ {
379
+ ast = value ;
380
+ }
381
+ }
382
+
383
+ public bool IsNestedFunctionDefinition { get { return isNestedFunctionDefinition ; } }
363
384
364
385
private string name ;
365
386
private Ast ast ;
387
+ private bool isNestedFunctionDefinition ;
366
388
367
389
public Vertex ( )
368
390
{
@@ -379,6 +401,12 @@ public Vertex (string name, Ast ast)
379
401
this . ast = ast ;
380
402
}
381
403
404
+ public Vertex ( String name , Ast ast , bool isNestedFunctionDefinition )
405
+ : this ( name , ast )
406
+ {
407
+ this . isNestedFunctionDefinition = isNestedFunctionDefinition ;
408
+ }
409
+
382
410
/// <summary>
383
411
/// Returns string representation of a Vertex instance
384
412
/// </summary>
@@ -460,11 +488,30 @@ public FunctionReferenceDigraph()
460
488
/// <summary>
461
489
/// Add a vertex to the graph
462
490
/// </summary>
463
- public void AddVertex ( Vertex name )
491
+ public void AddVertex ( Vertex vertex )
464
492
{
465
- if ( ! digraph . ContainsVertex ( name ) )
493
+ bool containsVertex = false ;
494
+
495
+ // if the graph contains a vertex with name equal to that
496
+ // of the input vertex, then update the vertex's ast if the
497
+ // input vertex's ast is of FunctionDefinitionAst type
498
+ foreach ( Vertex v in digraph . GetVertices ( ) )
499
+ {
500
+ if ( v . Equals ( vertex ) )
501
+ {
502
+ containsVertex = true ;
503
+ if ( vertex . Ast != null
504
+ && vertex . Ast is FunctionDefinitionAst )
505
+ {
506
+ v . Ast = vertex . Ast ;
507
+ }
508
+ break ;
509
+ }
510
+ }
511
+
512
+ if ( ! containsVertex )
466
513
{
467
- digraph . AddVertex ( name ) ;
514
+ digraph . AddVertex ( vertex ) ;
468
515
}
469
516
}
470
517
@@ -491,7 +538,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst ast
491
538
return AstVisitAction . SkipChildren ;
492
539
}
493
540
494
- var functionVertex = new Vertex ( ast . Name , ast ) ;
541
+ var functionVertex = new Vertex ( ast . Name , ast , IsWithinFunctionDefinition ( ) ) ;
495
542
functionVisitStack . Push ( functionVertex ) ;
496
543
AddVertex ( functionVertex ) ;
497
544
ast . Body . Visit ( this ) ;
@@ -549,18 +596,15 @@ public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressio
549
596
}
550
597
551
598
// Suppose we find <Expression>.<Member>, we split it up and create
552
- // and edge from <Expression>-> <Member>. Even though <Expression> is not
599
+ // and edge only to <Member>. Even though <Expression> is not
553
600
// necessarily a function, we do it because we are mainly interested in
554
601
// finding connection between a function and ShouldProcess and this approach
555
602
// prevents any unnecessary complexity.
556
- var exprVertex = new Vertex ( expr , ast . Expression ) ;
557
603
var memberVertex = new Vertex ( memberExprAst . Value , memberExprAst ) ;
558
- AddVertex ( exprVertex ) ;
559
604
AddVertex ( memberVertex ) ;
560
- AddEdge ( exprVertex , memberVertex ) ;
561
605
if ( IsWithinFunctionDefinition ( ) )
562
606
{
563
- AddEdge ( GetCurrentFunctionContext ( ) , exprVertex ) ;
607
+ AddEdge ( GetCurrentFunctionContext ( ) , memberVertex ) ;
564
608
}
565
609
566
610
return AstVisitAction . Continue ;
@@ -597,5 +641,10 @@ public int GetOutDegree(Vertex v)
597
641
{
598
642
return digraph . GetOutDegree ( v ) ;
599
643
}
644
+
645
+ public IEnumerable < Vertex > GetNeighbors ( Vertex v )
646
+ {
647
+ return digraph . GetNeighbors ( v ) ;
648
+ }
600
649
}
601
650
}
0 commit comments