public static void AddDataFlowEdges(SourceGraph sourceGraph, IEnumerable <SyntaxNodeOrToken> tokensOfInterest)
 {
     foreach (var tokenOfInterest in tokensOfInterest)
     {
         AddDataFlowEdges(sourceGraph, tokenOfInterest);
     }
 }
示例#2
0
 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));
                    }
                }
            }
        }
示例#4
0
        public static SourceGraph Create(SourceGraph baseGraph)
        {
            var comparer = new SourceGraphComparer();

            return(new SourceGraph(baseGraph, comparer));
        }