public static void AddDataFlowEdges(SourceGraph sourceGraph, IEnumerable <SyntaxNodeOrToken> tokensOfInterest) { foreach (var tokenOfInterest in tokensOfInterest) { AddDataFlowEdges(sourceGraph, tokenOfInterest); } }
private SourceGraph(SourceGraph baseGraph, SourceGraphComparer comparer) : base(comparer, comparer) { SemanticModel = baseGraph.SemanticModel; _nodeToTypeStringCache = baseGraph._nodeToTypeStringCache; _usedVariableNodes = new HashSet <SyntaxNodeOrToken>(baseGraph._usedVariableNodes); _writtenVariableNodes = new HashSet <SyntaxNodeOrToken>(baseGraph._writtenVariableNodes); _declarationNodes = new HashSet <SyntaxNodeOrToken>(baseGraph._declarationNodes); _aliasedVariableNodes = new Dictionary <SyntaxToken, ISet <ISymbol> >(); foreach (var kvp in baseGraph._aliasedVariableNodes) { _aliasedVariableNodes.Add(kvp.Key, new HashSet <ISymbol>(kvp.Value)); } }
public static void AddDataFlowEdges(SourceGraph sourceGraph, SyntaxNodeOrToken tokenOfInterest, ICollection <SyntaxNodeOrToken> forbiddenNodes = null, ICollection <Edge <SyntaxNodeOrToken, SourceGraphEdge> > addedEdges = null) { //There's nothing before the declaration, so we don't need to bother: if (sourceGraph.DeclarationNodes.Contains(tokenOfInterest)) { return; } //We only ever need to visit each node once, so collect visited nodes here: var visitedNodes = new HashSet <(SyntaxNodeOrToken, bool)>(); //Start from all predecessors of the token of interest: var toVisit = new Stack <(SyntaxNodeOrToken node, bool haveFoundUse)>(); foreach (var(_, label, target) in sourceGraph.GetOutEdges(tokenOfInterest)) { if (label != SourceGraphEdge.LastUsedVariable || (forbiddenNodes?.Contains(target) ?? false)) { continue; } if (visitedNodes.Add((target, false))) { toVisit.Push((target, false)); } } string nodeLabelToLookFor = tokenOfInterest.ToString(); while (toVisit.Count > 0) { var(node, haveFoundUse) = toVisit.Pop(); if (node.ToString().Equals(nodeLabelToLookFor)) { if (!haveFoundUse) { var lastUseEdge = new Edge <SyntaxNodeOrToken, SourceGraphEdge>(tokenOfInterest, SourceGraphEdge.LastUse, node); if (sourceGraph.AddEdge(lastUseEdge)) { addedEdges?.Add(lastUseEdge); } haveFoundUse = true; } if (sourceGraph.WrittenVariableNodes.Contains(node)) { var lastWriteEdge = new Edge <SyntaxNodeOrToken, SourceGraphEdge>(tokenOfInterest, SourceGraphEdge.LastWrite, node); if (sourceGraph.AddEdge(lastWriteEdge)) { addedEdges?.Add(lastWriteEdge); } //We are done with this path -- we found a use and a write! continue; } //There's nothing before the declaration, so we don't need to bother to recurse further: if (sourceGraph.DeclarationNodes.Contains(node)) { continue; } } foreach (var(_, label, target) in sourceGraph.GetOutEdges(node)) { if (label != SourceGraphEdge.LastUsedVariable || (forbiddenNodes?.Contains(target) ?? false)) { continue; } if (visitedNodes.Add((target, haveFoundUse))) { toVisit.Push((target, haveFoundUse)); } } } }
public static SourceGraph Create(SourceGraph baseGraph) { var comparer = new SourceGraphComparer(); return(new SourceGraph(baseGraph, comparer)); }