コード例 #1
0
        private GraphPresentation CreateAssemblyRelationshipGraph(IList <Assembly> sources, IList <Assembly> targets, IEnumerable <AssemblyReference> assemblyReferences)
        {
            var builder = new RelaxedGraphBuilder();

            var edges = assemblyReferences
                        .Select(r => (R.AssemblyName(r.myAssembly), R.AssemblyName(r.myDependency)))
                        .Where(x => x.Item1 != x.Item2);

            foreach (var(f, t) in edges)
            {
                builder.TryAddEdge(f, t);
            }

            var sourceNodes = sources.Select(R.AssemblyName).ToList();
            var targetNodes = targets.Select(R.AssemblyName).ToList();

            foreach (var n in targetNodes)
            {
                builder.TryAddNode(n);
            }

            var targetCluster = builder.TryAddCluster("TARGET", targetNodes);

            builder.TryAddCluster("SOURCE", sourceNodes);

            return(ReduceGraph(targetCluster, builder));
        }
コード例 #2
0
        private IGraph ReadGraph()
        {
            var builder = new RelaxedGraphBuilder();

            var count = myReader.ReadInt32();

            for (int i = 0; i < count; ++i)
            {
                builder.TryAddEdge(myReader.ReadString(), myReader.ReadString());
            }

            count = myReader.ReadInt32();
            for (int i = 0; i < count; ++i)
            {
                var clusterId = myReader.ReadString();
                var nodeCount = myReader.ReadInt32();
                var nodes     = new List <string>(nodeCount);
                for (int j = 0; j < nodeCount; ++j)
                {
                    nodes.Add(myReader.ReadString());
                }
                builder.TryAddCluster(clusterId, nodes);
            }

            count = myReader.ReadInt32();
            for (int i = 0; i < count; ++i)
            {
                builder.TryAddNode(myReader.ReadString());
            }

            return(builder.Graph);
        }
コード例 #3
0
 public TypeRelationshipDocument()
 {
     myGraphBuilder = new RelaxedGraphBuilder();
     myDescriptors  = new Dictionary <string, TypeDescriptor>();
     FailedItems    = new List <FailedItem>();
     EdgeTypes      = new Dictionary <string, EdgeType>();
 }
コード例 #4
0
        public void Load(string path)
        {
            myGraphBuilder = new RelaxedGraphBuilder();
            Filename       = path;

            Load();
        }
コード例 #5
0
        private void OnInheritanceGraphCompleted(TypeRelationshipDocument document)
        {
            if (!document.Edges.Any())
            {
                MessageBox.Show("No nodes found");
                return;
            }

            var presentation = myPresentationCreationService.CreatePresentation(Path.GetDirectoryName(AssemblyToAnalyseLocation));

            var captionModule   = presentation.GetPropertySetFor <Caption>();
            var tooltipModule   = presentation.GetPropertySetFor <ToolTipContent>();
            var edgeStyleModule = presentation.GetPropertySetFor <EdgeStyle>();

            var builder = new RelaxedGraphBuilder();

            foreach (var edge in document.Edges)
            {
                var e = builder.TryAddEdge(edge.Item1, edge.Item2);
                edgeStyleModule.Add(new EdgeStyle(e.Id)
                {
                    Color = edge.Item3 == ReferenceType.DerivesFrom ? Brushes.Black : Brushes.Blue
                });
            }

            presentation.Graph = builder.Graph;

            foreach (var desc in document.Descriptors)
            {
                captionModule.Add(new Caption(desc.Id, desc.Name));
                tooltipModule.Add(new ToolTipContent(desc.Id, desc.FullName));
            }

            if (myAddToGraph && Model.Presentation != null && Model.Presentation.Graph != null)
            {
                presentation = Model.Presentation.UnionWith(presentation,
                                                            () => myPresentationCreationService.CreatePresentation(Path.GetDirectoryName(AssemblyToAnalyseLocation)));

                myAddToGraph = false;
            }

            if (document.FailedItems.Any())
            {
                foreach (var item in document.FailedItems)
                {
                    var sb = new StringBuilder();
                    sb.AppendLine("Loading failed");
                    sb.AppendFormat("Item: {0}", item.Item);
                    sb.AppendLine();
                    sb.AppendFormat("Reason: {0}", item.FailureReason);
                    myStatusMessageService.Publish(new StatusMessage(sb.ToString()));
                }
            }

            Model.Presentation = presentation;
        }
コード例 #6
0
        public void SetUp()
        {
            var builder = new RelaxedGraphBuilder();

            builder.TryAddEdge("a", "b");
            builder.TryAddEdge("a", "c");
            builder.TryAddNode("d");
            builder.TryAddCluster("X17", new[] { "b", "c" });

            myPresentation       = new GraphPresentation();
            myPresentation.Graph = builder.Graph;
        }
コード例 #7
0
        // Show only nodes which can reach the target cluster
        private GraphPresentation ReduceGraph(Cluster targetCluster, RelaxedGraphBuilder builder)
        {
            var presentation = new GraphPresentation();

            presentation.Graph = builder.Graph;

            var algo = new AddRemoveTransitiveHull(presentation);

            algo.Add     = false;
            algo.Reverse = true;
            var mask = algo.Compute(targetCluster.Nodes);

            mask.Invert(presentation);

            presentation.Masks().Push(mask);

            presentation.Masks().Push(new RemoveNodesWithoutSiblings(presentation).Compute());

            return(presentation);
        }
コード例 #8
0
        public IGraphPresentation UnionWith(IGraphPresentation other, Func <IGraphPresentation> presentationCreator)
        {
            var result = presentationCreator();

            var builder = new RelaxedGraphBuilder();

            foreach (var node in GetNodes(this, other))
            {
                builder.TryAddNode(node.Id);
            }

            foreach (var edge in GetEdges(this, other))
            {
                builder.TryAddEdge(edge.Source.Id, edge.Target.Id);
            }

            foreach (var cluster in GetClusters(this, other))
            {
                builder.TryAddCluster(cluster.Id, cluster.Nodes.Select(n => n.Id));
            }

            result.Graph = builder.Graph;

            UnionWith <ToolTipContent>(this, other, result);
            UnionWith <Selection>(this, other, result);
            UnionWith <NodeStyle>(this, other, result);
            UnionWith <EdgeStyle>(this, other, result);
            UnionWith <Caption>(this, other, result);

            {
                var resultModule = result.GetModule <INodeMaskModule>();

                foreach (var item in GetModule <INodeMaskModule>().Items.Concat(other.GetModule <INodeMaskModule>().Items))
                {
                    resultModule.Push(item);
                }
            }

            return(result);
        }
コード例 #9
0
        public IGraph Transform(IGraph graph)
        {
            myGraph = graph;

            if (myFoldedClusters.Count == 0)
            {
                return(graph);
            }

            var builder = new RelaxedGraphBuilder();

            var nodesToClusterMap = new Dictionary <string, string>();

            // add unfolded clusters
            foreach (var cluster in graph.Clusters.Where(c => !myFoldedClusters.Contains(c.Id)))
            {
                var nodes = cluster.Nodes
                            .Select(n => n.Id)
                            .ToList();
                builder.TryAddCluster(cluster.Id, nodes);

                foreach (var n in nodes)
                {
                    nodesToClusterMap[n] = cluster.Id;
                }
            }

            // add folded clusters
            foreach (var clusterId in myFoldedClusters.ToList())
            {
                var clusterNodeId = GetClusterNodeId(clusterId);

                builder.TryAddNode(clusterNodeId);
                builder.TryAddCluster(clusterId, new[] { clusterNodeId });

                var foldedCluster = graph.Clusters.SingleOrDefault(c => c.Id == clusterId);
                if (foldedCluster == null)
                {
                    // this cluster was deleted
                    myFoldedClusters.Remove(clusterId);
                    continue;
                }

                var foldedNodes = foldedCluster.Nodes
                                  .Select(n => n.Id)
                                  .ToList();

                foreach (var n in foldedNodes)
                {
                    nodesToClusterMap[n] = foldedCluster.Id;
                }
            }

            // add non-clustered nodes
            foreach (var node in graph.Nodes.Select(n => n.Id).Except(nodesToClusterMap.Keys))
            {
                builder.TryAddNode(node);
            }

            // add edges
            foreach (var edge in graph.Edges)
            {
                var source = edge.Source.Id;
                var target = edge.Target.Id;

                string foldedClusterId;
                if (nodesToClusterMap.TryGetValue(source, out foldedClusterId) && myFoldedClusters.Contains(foldedClusterId))
                {
                    source = GetClusterNodeId(foldedClusterId);
                }

                if (nodesToClusterMap.TryGetValue(target, out foldedClusterId) && myFoldedClusters.Contains(foldedClusterId))
                {
                    target = GetClusterNodeId(foldedClusterId);
                }

                // ignore self-edges
                if (source != target)
                {
                    builder.TryAddEdge(source, target);
                }
            }

            return(builder.Graph);
        }
コード例 #10
0
        private GraphPresentation BuildCallTree(List <Assembly> sources, List <MethodDesc> targets, GraphPresentation assemblyGraphPresentation)
        {
            var relevantNodes = assemblyGraphPresentation.Graph.Nodes
                                .Where(n => assemblyGraphPresentation.Picking.Pick(n))
                                .ToList();

            var interfaceImplementationsMap = new InterfaceImplementationsMap();

            interfaceImplementationsMap.Build(relevantNodes, targets.Select(t => t.myDeclaringType));

            var calls = TraceCalles(relevantNodes, interfaceImplementationsMap, targets, sources);

            Console.WriteLine();
            Console.WriteLine("NOT analyzed assemblies:");

            foreach (var x in myMonoLoader.SkippedAssemblies)
            {
                Shell.Warn($"    {x}");
            }

            return(Shell.Profile("Generating call graph ...", () =>
            {
                var builder = new RelaxedGraphBuilder();
                var edges = calls
                            .Select(call => (CreateMethodNode(call.From), CreateMethodNode(call.To)))
                            // we assume that usages within same class are not relevant
                            .Where(x => x.Item1.myDeclaringType != x.Item2.myDeclaringType)
                            .ToList();

                foreach (var edge in edges)
                {
                    builder.TryAddEdge(edge.Item1.myId, edge.Item2.myId);
                }

                var nodes = edges
                            .SelectMany(e => new[] { e.Item1, e.Item2 })
                            .Distinct(new MethodNodeComparer())
                            .ToList();

                var clusters = nodes
                               .GroupBy(n => n.myDeclaringType)
                               .Select(x => (R.TypeFullName(x.Key), x.Key.Name, x.Select(n => n.myId).ToList()))
                               .ToList();

                foreach (var cluster in clusters)
                {
                    builder.TryAddCluster(cluster.Item1, cluster.Item3);
                }

                builder.Freeze();

                var presentation = new GraphPresentation();
                presentation.Graph = builder.Graph;

                // add captions for readability
                var captions = presentation.GetModule <ICaptionModule>();

                foreach (var n in nodes)
                {
                    captions.Add(new Caption(n.myId, n.myCaption));
                }

                foreach (var cluster in clusters)
                {
                    captions.Add(new Caption(cluster.Item1, cluster.Item2));
                }

                return presentation;
            }));
コード例 #11
0
        private void BuildGraph(AnalysisDocument response)
        {
            if (!response.Nodes.Any() && !response.Edges.Any())
            {
                MessageBox.Show("Neither nodes nor edges found");
                return;
            }

            var presentation = myPresentationCreationService.CreatePresentation(Path.GetTempPath());

            var builder = new RelaxedGraphBuilder();

            foreach (var edge in response.Edges)
            {
                builder.TryAddEdge(edge.Item1, edge.Item2);
            }

            foreach (var node in response.Nodes)
            {
                builder.TryAddNode(node);
            }

            foreach (var cluster in response.Clusters)
            {
                builder.TryAddCluster(cluster.Key, cluster.Value);
            }

            var captionModule = presentation.GetPropertySetFor <Caption>();

            // add potentially empty clusters
            {
                var spec          = SpecUtils.Deserialize(Document.Text);
                var emptyClusters = spec.Packages
                                    .Where(p => PackagesToAnalyze == null || PackagesToAnalyze.Contains(p.Name))
                                    .SelectMany(p => p.Clusters)
                                    .Where(cluster => !response.Clusters.Any(c => c.Key == cluster.Id));

                foreach (var cluster in emptyClusters)
                {
                    builder.TryAddCluster(cluster.Id, Enumerable.Empty <string>());
                    captionModule.Add(new Caption(cluster.Id, cluster.Name));
                }
            }

            presentation.Graph = builder.Graph;

            foreach (var caption in response.Captions)
            {
                captionModule.Add(new Caption(caption.Key, caption.Value));
            }

            var converter = new BrushConverter();

            var nodeStyles = presentation.GetPropertySetFor <NodeStyle>();

            foreach (var style in response.NodeStyles)
            {
                var brush = (Brush)converter.ConvertFromString(style.Value);
                brush.Freeze();
                nodeStyles.Add(new NodeStyle(style.Key)
                {
                    FillColor = brush
                });
            }

            var edgeStyles = presentation.GetPropertySetFor <EdgeStyle>();

            foreach (var style in response.EdgeStyles)
            {
                var brush = (Brush)converter.ConvertFromString(style.Value);
                brush.Freeze();
                edgeStyles.Add(new EdgeStyle(style.Key)
                {
                    Color = brush
                });
            }

            Model.Presentation = presentation;

            // only synchronize our own presentation
            myGraphToSpecSynchronizer.Presentation = presentation;
        }
コード例 #12
0
 public InheritanceAnalyzer()
 {
     myBuilder     = new RelaxedGraphBuilder();
     myIdToTypeMap = new Dictionary <string, TypeDescriptor>();
     myEdgeTypes   = new Dictionary <string, ReferenceType>();
 }
コード例 #13
0
 protected AbstractGraphDocument()
 {
     myGraphBuilder = new RelaxedGraphBuilder();
     myFailedItems  = new List <FailedItem>();
 }
コード例 #14
0
        private IGraph BuildGraph(IGraph graph)
        {
            var builder = new RelaxedGraphBuilder();

            var nodesToClusterMap = new Dictionary <string, string>();

            // add unfolded clusters
            foreach (var cluster in graph.Clusters.Where(c => !myFoldedClusters.Contains(c.Id)))
            {
                var nodes = cluster.Nodes
                            .Select(n => n.Id)
                            .ToList();
                builder.TryAddCluster(cluster.Id, nodes);

                foreach (var n in nodes)
                {
                    nodesToClusterMap[n] = cluster.Id;
                }
            }

            // add folded clusters
            var clusterMap = new Dictionary <string, Cluster>();

            foreach (var cluster in graph.Clusters)
            {
                clusterMap.Add(cluster.Id, cluster);
            }

            foreach (var clusterId in myFoldedClusters.ToList())
            {
                var clusterNodeId = GetClusterNodeId(clusterId);

                builder.TryAddNode(clusterNodeId);
                builder.TryAddCluster(clusterId, new[] { clusterNodeId });

                Cluster cluster = null;
                if (!clusterMap.TryGetValue(clusterId, out cluster))
                {
                    // this cluster was deleted
                    myFoldedClusters.Remove(clusterId);
                    continue;
                }

                // we can safely handle all nodes here as visibility is handled below on "edge-level"
                foreach (var n in cluster.Nodes)
                {
                    nodesToClusterMap[n.Id] = cluster.Id;
                }
            }

            // add non-clustered nodes
            foreach (var node in graph.Nodes.Select(n => n.Id).Except(nodesToClusterMap.Keys))
            {
                builder.TryAddNode(node);
            }

            // "redirect" source/target in case source/target is inside folded cluster
            string GetNodeId(Node node)
            {
                return(nodesToClusterMap.TryGetValue(node.Id, out var clusterId) && myFoldedClusters.Contains(clusterId)
                    ? GetClusterNodeId(clusterId)
                    : node.Id);
            }

            // add edges
            foreach (var edge in graph.Edges)
            {
                var sourceId = GetNodeId(edge.Source);
                var targetId = GetNodeId(edge.Target);

                // 1. Add all edges which are not folded (visibility of those is handled with masks)
                //    Otherwise these edges are not "seen" when trying to extend the graph with "add" algorithms
                if (sourceId == edge.Source.Id && targetId == edge.Target.Id)
                {
                    // edge between two unfolded nodes
                    // -> add it
                    builder.TryAddEdge(sourceId, targetId);

                    // nothing more to be done with this edge
                    continue;
                }

                // skip edges within a folded cluster
                if (sourceId == targetId)
                {
                    continue;
                }

                var isEdgeVisible = myPresentation.Picking.Pick(edge);

                // 2. Only add redirected edges if original edge was visible
                //    Otherwise we would draw an edge which should not exist based on actual node visibility.
                //    This makes the folding respect node visibility.
                if (isEdgeVisible)
                {
                    // add redirected edge
                    builder.TryAddEdge(sourceId, targetId);
                }

                // ALWAYS remember based on what we computed the redirected Remember "decision" for when visibility of nodes/edges changes so that
                // we can check whether transformation has to be triggered again
                {
                    var redirectedEdgeId = Edge.CreateId(sourceId, targetId);
                    if (!myComputedEdges.TryGetValue(redirectedEdgeId, out var originalEdges))
                    {
                        originalEdges = new ComputedEdge();
                        myComputedEdges.Add(redirectedEdgeId, originalEdges);
                    }

                    originalEdges.IsVisible |= isEdgeVisible;
                    originalEdges.Originals.Add(edge);
                }
            }

            return(builder.Graph);
        }