Пример #1
0
        private void BuildNode(List <TreeViewItem> items, CallTreeNode callTree, int depth)
        {
            var id = items.Count;

            items.Add(new TreeViewItem {
                id = id, depth = depth, displayName = callTree.GetPrettyName(true)
            });

            m_CallTreeDictionary.Add(id, callTree);

            // if the tree is too deep, serialization will exceed the 7 levels limit.
            if (callTree.children == null)
            {
                items.Add(new TreeViewItem {
                    id = id + 1, depth = depth + 1, displayName = "<Serialization Limit>"
                });
            }
            else
            {
                foreach (var parent in callTree.children)
                {
                    BuildNode(items, parent, depth + 1);
                }
            }
        }
Пример #2
0
        private void BuildHierarchy(CallTreeNode callee, int depth)
        {
            if (depth++ == m_MaxDepth)
            {
                return;
            }

            // let's find all callers with matching callee
            if (m_BucketedCallPairs.ContainsKey(callee.name))
            {
                var callPairs = m_BucketedCallPairs[callee.name];

                foreach (var call in callPairs)
                {
                    // ignore recursive calls
                    if (!call.caller.FullName.Equals(callee.name))
                    {
                        var callerInstance = new CallTreeNode(call.caller);
                        callerInstance.location = call.location;

                        BuildHierarchy(callerInstance, depth);
                        callee.children.Add(callerInstance);
                    }
                }
            }
        }
Пример #3
0
 public ProjectIssue(ProblemDescriptor descriptor,
                     string description,
                     IssueCategory category,
                     CallTreeNode dependenciesNode)
     : this(descriptor, description, category)
 {
     dependencies = dependenciesNode;
 }
Пример #4
0
 public ProjectIssue(ProblemDescriptor descriptor,
                     string description,
                     IssueCategory category,
                     CallTreeNode dependenciesNode)
 {
     this.descriptor  = descriptor;
     this.description = description;
     this.category    = category;
     dependencies     = dependenciesNode;
 }
Пример #5
0
 protected override void DoubleClickedItem(int id)
 {
     if (m_CallTreeDictionary.ContainsKey(id))
     {
         CallTreeNode node = m_CallTreeDictionary[id];
         if (node.location != null)
         {
             node.location.Open();
         }
     }
 }
Пример #6
0
        public CallTreeNode(string _name, CallTreeNode caller = null)
        {
            name = _name;

            typeName   = string.Empty;
            methodName = string.Empty;

            if (caller != null)
            {
                children.Add(caller);
            }
        }
Пример #7
0
        public ProjectIssue Analyze(MethodDefinition methodDefinition, Instruction inst)
        {
            var type = (TypeReference)inst.Operand;

            if (type.IsGenericParameter)
            {
                bool isValueType = true; // assume it's value type
                var  genericType = (GenericParameter)type;
                if (genericType.HasReferenceTypeConstraint)
                {
                    isValueType = false;
                }
                else
                {
                    foreach (var constraint in genericType.Constraints)
                    {
                        if (!constraint.IsValueType)
                        {
                            isValueType = false;
                        }
                    }
                }

                if (!isValueType)
                {
                    // boxing on ref types are no-ops, so not a problem
                    return(null);
                }
            }

            string typeName = type.Name;

            if (type.FullName.Equals("System.Single"))
            {
                typeName = "float";
            }
            else if (type.FullName.Equals("System.Double"))
            {
                typeName = "double";
            }

            var description = string.Format("Conversion from value type '{0}' to ref type", typeName);
            var calleeNode  = new CallTreeNode(descriptor.description);

            return(new ProjectIssue
                   (
                       descriptor,
                       description,
                       IssueCategory.ApiCalls,
                       calleeNode
                   ));
        }
Пример #8
0
        private void AnalyzeMethodBody(ProjectReport projectReport, AssemblyDefinition a, MethodDefinition caller, CallCrawler callCrawler)
        {
            if (!caller.DebugInformation.HasSequencePoints)
            {
                return;
            }

            var callerNode = new CallTreeNode(caller);

            foreach (var inst in caller.Body.Instructions.Where(i => m_OpCodes.Contains(i.OpCode)))
            {
                //var msg = string.Empty;
                SequencePoint s = null;
                for (var i = inst; i != null; i = i.Previous)
                {
                    s = caller.DebugInformation.GetSequencePoint(i);
                    if (s != null)
                    {
                        // msg = i == inst ? " exactly" : "nearby";
                        break;
                    }
                }

                var location = callerNode.location = new Location
                {
                    path = s.Document.Url.Replace("\\", "/"), line = s.StartLine
                };

                if (inst.OpCode == OpCodes.Call || inst.OpCode == OpCodes.Callvirt)
                {
                    callCrawler.Add(caller, (MethodReference)inst.Operand, location);
                }

                foreach (var analyzer in m_InstructionAnalyzers)
                {
                    if (analyzer.GetOpCodes().Contains(inst.OpCode))
                    {
                        var projectIssue = analyzer.Analyze(caller, inst);
                        if (projectIssue != null)
                        {
                            projectIssue.callTree.AddChild(callerNode);
                            projectIssue.location = location;
                            projectIssue.assembly = a.Name.Name;

                            projectReport.AddIssue(projectIssue);
                        }
                    }
                }
            }
        }
Пример #9
0
        public CallTreeNode(MethodReference methodReference, CallTreeNode caller = null)
        {
            name       = methodReference.FullName;
            methodName = "(anonymous)"; // default value

            // check if it's a coroutine
            if (methodReference.DeclaringType.FullName.IndexOf("/<") >= 0)
            {
                var fullName         = methodReference.DeclaringType.FullName;
                var methodStartIndex = fullName.IndexOf("<") + 1;
                if (methodStartIndex > 0)
                {
                    var length = fullName.IndexOf(">") - methodStartIndex;
                    typeName = fullName.Substring(0, fullName.IndexOf("/"));
                    if (length > 0)
                    {
                        methodName = fullName.Substring(methodStartIndex, length);
                    }
                    else
                    {
                        // handle example: System.Int32 DelegateTest/<>c::<Update>b__1_0()
                        methodStartIndex = name.LastIndexOf("<") + 1;
                        if (methodStartIndex > 0)
                        {
                            length     = name.LastIndexOf(">") - methodStartIndex;
                            methodName = name.Substring(methodStartIndex, length) + ".(anonymous)";
                        }
                    }
                }
                else
                {
                    // for some reason, some generated types don't have the same syntax
                    typeName = fullName;
                }
            }
            else
            {
                typeName   = methodReference.DeclaringType.Name;
                methodName = methodReference.Name;
            }

            if (caller != null)
            {
                children.Add(caller);
            }
        }
Пример #10
0
        private void DrawCallHierarchy(CallTreeNode callTree)
        {
            EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.FoldoutWidth), GUILayout.MinHeight(LayoutSize.FoldoutMinHeight * 2));

            m_ShowCallTree = BoldFoldout(m_ShowCallTree, Styles.CallTreeFoldout);
            if (m_ShowCallTree)
            {
                if (callTree != null)
                {
                    Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(400));

                    m_CallHierarchyView.OnGUI(r);
                }
                else
                {
                    EditorGUILayout.LabelField(NoIssueSelectedText);
                }
            }
            EditorGUILayout.EndVertical();
        }
Пример #11
0
        public ProjectIssue Analyze(MethodDefinition methodDefinition, Instruction inst)
        {
            var callee = ((MethodReference)inst.Operand);

            // replace root with callee node
            var calleeNode = new CallTreeNode(callee);

            var description = string.Empty;
            var descriptor  = m_Descriptors.SingleOrDefault(c => c.type == callee.DeclaringType.FullName &&
                                                            (c.method == callee.Name ||
                                                             ("get_" + c.method) == callee.Name));

            if (descriptor != null)
            {
                // by default use descriptor issue description
                description = descriptor.description;
            }
            else
            {
                // Are we trying to warn about a whole namespace?
                descriptor = m_Descriptors.SingleOrDefault(c =>
                                                           c.type == callee.DeclaringType.Namespace && c.method == "*");
                if (descriptor == null)
                {
                    // no issue found
                    return(null);
                }

                // use callee name since it's more informative
                description = calleeNode.prettyName;
            }

            return(new ProjectIssue
                   (
                       descriptor,
                       description,
                       IssueCategory.ApiCalls,
                       calleeNode
                   ));
        }
Пример #12
0
        private void DrawFoldouts()
        {
            ProblemDescriptor problemDescriptor = null;
            var selectedItems       = m_ActiveIssueTable.GetSelectedItems();
            var selectedDescriptors = selectedItems.Select(i => i.ProblemDescriptor);
            var selectedIssues      = selectedItems.Select(i => i.ProjectIssue);
            // find out if all descriptors are the same
            var firstDescriptor = selectedDescriptors.FirstOrDefault();

            if (selectedDescriptors.Count() == selectedDescriptors.Count(d => d.id == firstDescriptor.id))
            {
                problemDescriptor = firstDescriptor;
            }

            DrawDetailsFoldout(problemDescriptor);
            DrawRecommendationFoldout(problemDescriptor);
            if (m_ActiveAnalysisView.desc.showInvertedCallTree)
            {
                CallTreeNode callTree = null;
                if (selectedIssues.Count() == 1)
                {
                    var issue = selectedIssues.First();
                    if (issue != null)
                    {
                        // get caller sub-tree
                        callTree = issue.callTree.GetChild();
                    }
                }

                if (m_CurrentCallTree != callTree)
                {
                    m_CallHierarchyView.SetCallTree(callTree);
                    m_CallHierarchyView.Reload();
                    m_CurrentCallTree = callTree;
                }

                DrawCallHierarchy(callTree);
            }
        }
Пример #13
0
 public void AddChild(CallTreeNode child)
 {
     children.Add(child);
 }
Пример #14
0
 public void SetCallTree(CallTreeNode callTree)
 {
     m_CallTree = callTree;
 }