void CollectAllIssues(Environment env, string variableName) { var fixes = QualifierDirectiveEvidentIssueProvider.GetFixes(ctx, env, variableName).ToArray(); env.IssueCollected = true; foreach (var child in env.Children) { if (child is Environment) { CollectAllIssues((Environment)child, variableName); } else { if (child.Kind != NodeKind.Modification) { AddIssue(child.AstNode, title, fixes); } // stop marking references after the variable is modified in current environment if (child.Kind != NodeKind.Reference) { break; } } } }
void CheckVariable(IVariable variable, Statement env) { if (!QualifierDirectiveEvidentIssueProvider.IsTargetVariable(variable)) { return; } var root = new Environment(env, env); var envLookup = new Dictionary <AstNode, Environment> (); envLookup [env] = root; foreach (var result in ctx.FindReferences(env, variable)) { AddNode(envLookup, new Node(result.Node, QualifierDirectiveEvidentIssueProvider.GetNodeKind(result.Node))); } root.SortChildren(); CollectIssues(root, variable.Name); }
bool CanReachModification(IEnumerable <ControlFlowNode> cfg, Environment env, IDictionary <Statement, IList <Node> > modifications) { if (modifications.Count == 0) { return(false); } var start = env.ContainingStatement; if (modifications.ContainsKey(start) && modifications [start].Any(v => v.AstNode.StartLocation > env.AstNode.EndLocation)) { return(true); } var stack = new Stack <ControlFlowNode> (cfg.Where(node => node.NextStatement == start)); var visitedNodes = new HashSet <ControlFlowNode> (stack); while (stack.Count > 0) { var node = stack.Pop(); if (QualifierDirectiveEvidentIssueProvider.CanReachModification(node, start, modifications)) { return(true); } foreach (var edge in node.Outgoing) { if (visitedNodes.Add(edge.To)) { stack.Push(edge.To); } } } return(false); }