Skip to content

Commit 14ec9c3

Browse files
author
Kapil Borle
committed
Update UseShouldProcessCorrectly rule
* Flag a function if it calls shouldprocess but supports shouldprocess * Do not flag a function if it does not support shouldprocess and calls commands that support shouldprocess
1 parent 5d0ff03 commit 14ec9c3

File tree

1 file changed

+65
-16
lines changed

1 file changed

+65
-16
lines changed

Rules/UseShouldProcessCorrectly.cs

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ public class UseShouldProcessCorrectly : IScriptRule
3737
private FunctionReferenceDigraph funcDigraph;
3838
private List<DiagnosticRecord> diagnosticRecords;
3939
private readonly Vertex shouldProcessVertex;
40+
private readonly Vertex implicitShouldProcessVertex;
4041

4142
public UseShouldProcessCorrectly()
4243
{
4344
diagnosticRecords = new List<DiagnosticRecord>();
4445
shouldProcessVertex = new Vertex("ShouldProcess", null);
46+
implicitShouldProcessVertex = new Vertex("implicitShouldProcessVertex", null);
4547
}
4648

4749
/// <summary>
@@ -150,10 +152,12 @@ private DiagnosticRecord GetViolation(Vertex v)
150152
return null;
151153
}
152154

153-
bool callsShouldProcess = funcDigraph.IsConnected(v, shouldProcessVertex);
154155
if (DeclaresSupportsShouldProcess(fast))
155156
{
156-
if (!callsShouldProcess)
157+
bool callsShouldProcess = funcDigraph.IsConnected(v, shouldProcessVertex);
158+
bool callsCommandWithShouldProcess = funcDigraph.IsConnected(v, implicitShouldProcessVertex);
159+
if (!callsShouldProcess
160+
&& !callsCommandWithShouldProcess)
157161
{
158162
return new DiagnosticRecord(
159163
string.Format(
@@ -168,12 +172,12 @@ private DiagnosticRecord GetViolation(Vertex v)
168172
}
169173
else
170174
{
171-
if (callsShouldProcess)
175+
if (callsShouldProcessDirectly(v))
172176
{
173177
// check if upstream function declares SupportShouldProcess
174178
// if so, this might just be a helper function
175179
// do not flag this case
176-
if (UpstreamDeclaresShouldProcess(v))
180+
if (v.IsNestedFunctionDefinition && UpstreamDeclaresShouldProcess(v))
177181
{
178182
return null;
179183
}
@@ -193,6 +197,11 @@ private DiagnosticRecord GetViolation(Vertex v)
193197
return null;
194198
}
195199

200+
private bool callsShouldProcessDirectly(Vertex vertex)
201+
{
202+
return funcDigraph.GetNeighbors(vertex).Contains(shouldProcessVertex);
203+
}
204+
196205
/// <summary>
197206
/// Checks if an upstream function declares SupportsShouldProcess
198207
/// </summary>
@@ -344,10 +353,10 @@ private void CheckForSupportShouldProcess()
344353

345354
if (commandsWithSupportShouldProcess.Count > 0)
346355
{
347-
funcDigraph.AddVertex(shouldProcessVertex);
356+
funcDigraph.AddVertex(implicitShouldProcessVertex);
348357
foreach(var v in commandsWithSupportShouldProcess)
349358
{
350-
funcDigraph.AddEdge(v, shouldProcessVertex);
359+
funcDigraph.AddEdge(v, implicitShouldProcessVertex);
351360
}
352361
}
353362
}
@@ -359,10 +368,23 @@ private void CheckForSupportShouldProcess()
359368
class Vertex
360369
{
361370
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;}}
363384

364385
private string name;
365386
private Ast ast;
387+
private bool isNestedFunctionDefinition;
366388

367389
public Vertex()
368390
{
@@ -379,6 +401,12 @@ public Vertex (string name, Ast ast)
379401
this.ast = ast;
380402
}
381403

404+
public Vertex (String name, Ast ast, bool isNestedFunctionDefinition)
405+
: this(name, ast)
406+
{
407+
this.isNestedFunctionDefinition = isNestedFunctionDefinition;
408+
}
409+
382410
/// <summary>
383411
/// Returns string representation of a Vertex instance
384412
/// </summary>
@@ -460,11 +488,30 @@ public FunctionReferenceDigraph()
460488
/// <summary>
461489
/// Add a vertex to the graph
462490
/// </summary>
463-
public void AddVertex(Vertex name)
491+
public void AddVertex(Vertex vertex)
464492
{
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)
466513
{
467-
digraph.AddVertex(name);
514+
digraph.AddVertex(vertex);
468515
}
469516
}
470517

@@ -491,7 +538,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst ast
491538
return AstVisitAction.SkipChildren;
492539
}
493540

494-
var functionVertex = new Vertex (ast.Name, ast);
541+
var functionVertex = new Vertex(ast.Name, ast, IsWithinFunctionDefinition());
495542
functionVisitStack.Push(functionVertex);
496543
AddVertex(functionVertex);
497544
ast.Body.Visit(this);
@@ -549,18 +596,15 @@ public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressio
549596
}
550597

551598
// 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
553600
// necessarily a function, we do it because we are mainly interested in
554601
// finding connection between a function and ShouldProcess and this approach
555602
// prevents any unnecessary complexity.
556-
var exprVertex = new Vertex (expr, ast.Expression);
557603
var memberVertex = new Vertex (memberExprAst.Value, memberExprAst);
558-
AddVertex(exprVertex);
559604
AddVertex(memberVertex);
560-
AddEdge(exprVertex, memberVertex);
561605
if (IsWithinFunctionDefinition())
562606
{
563-
AddEdge(GetCurrentFunctionContext(), exprVertex);
607+
AddEdge(GetCurrentFunctionContext(), memberVertex);
564608
}
565609

566610
return AstVisitAction.Continue;
@@ -597,5 +641,10 @@ public int GetOutDegree(Vertex v)
597641
{
598642
return digraph.GetOutDegree(v);
599643
}
644+
645+
public IEnumerable<Vertex> GetNeighbors(Vertex v)
646+
{
647+
return digraph.GetNeighbors(v);
648+
}
600649
}
601650
}

0 commit comments

Comments
 (0)