internal bool TryBind(Dictionary <string, TypeSummary> types, out MonoBreakpointLocation breakpointLocation)
        {
            try
            {
                using (var stream = File.OpenRead(DocumentName))
                {
                    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(SourceText.From(stream), path: DocumentName);
                    TextLine   textLine   = syntaxTree.GetText().Lines[StartLine];
                    Location   location   = syntaxTree.GetLocation(textLine.Span);
                    SyntaxTree sourceTree = location.SourceTree;
                    SyntaxNode node       = location.SourceTree.GetRoot().FindNode(location.SourceSpan, true, true);

                    // Find the method which contains the breakpoint
                    bool isAnonymousFunctionExpression = false;
                    var  method = GetParentNode <MethodDeclarationSyntax, AnonymousFunctionExpressionSyntax>(node.Parent, ref isAnonymousFunctionExpression);

                    if (method == null)
                    {
                        breakpointLocation = null;
                        return(false);
                    }

                    string methodName = method.Identifier.Text;

                    // Find the class which contains the method
                    var    cl        = GetParentNode <ClassDeclarationSyntax>(method);
                    string className = cl.Identifier.Text;

                    // Find the namespace which contains the class
                    var    ns     = GetParentNode <NamespaceDeclarationSyntax>(method);
                    string nsname = ns.Name.ToString();

                    // Find the loaded type with name "namespace.className"
                    string      name = string.Format("{0}.{1}", nsname, className);
                    TypeSummary summary;
                    if (types.TryGetValue(name, out summary))
                    {
                        breakpointLocation = FindNearestBreakpointLocation(isAnonymousFunctionExpression, methodName, summary);
                        if (breakpointLocation != null)
                        {
                            return(true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Trace($"Exception : {ex}");
            }

            breakpointLocation = null;
            return(false);
        }
示例#2
0
        internal bool TryBind(Dictionary <string, TypeSummary> types, out MonoBreakpointLocation breakpointLocation)
        {
            try
            {
                using (var stream = File.OpenRead(DocumentName))
                {
                    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(SourceText.From(stream), path: DocumentName);
                    TextLine   textLine   = syntaxTree.GetText().Lines[StartLine];
                    Location   location   = syntaxTree.GetLocation(textLine.Span);
                    SyntaxTree sourceTree = location.SourceTree;
                    SyntaxNode node       = location.SourceTree.GetRoot().FindNode(location.SourceSpan, true, true);

                    var    method     = GetParentMethod <MethodDeclarationSyntax>(node.Parent);
                    string methodName = method.Identifier.Text;

                    var    cl        = GetParentMethod <ClassDeclarationSyntax>(method);
                    string className = cl.Identifier.Text;

                    var    ns     = GetParentMethod <NamespaceDeclarationSyntax>(method);
                    string nsname = ns.Name.ToString();

                    string      name = string.Format("{0}.{1}", nsname, className);
                    TypeSummary summary;
                    if (types.TryGetValue(name, out summary))
                    {
                        MethodMirror methodMirror = summary.Methods.FirstOrDefault(x => x.Name == methodName);

                        if (methodMirror != null)
                        {
                            breakpointLocation = new MonoBreakpointLocation
                            {
                                Method = methodMirror,
                                Offset = 0,
                            };
                            return(true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Trace($"Exception : {ex}");
            }

            breakpointLocation = null;
            return(false);
        }
        private MonoBreakpointLocation FindNearestBreakpointLocation(bool isAnonymousFunctionExpression, string methodName, TypeSummary summary)
        {
            var tempBreakpointLocation = new MonoBreakpointLocation
            {
                LineDifference = int.MinValue,
                Method         = null,
                IlOffset       = -1,
            };

            int tempIlOffset       = 0;
            int tempLineDifference = 0;

            if (isAnonymousFunctionExpression)
            {
                // TODO: Filter correct anonymous functions with Name?
                foreach (var func in summary.AnonymousFunctions.Where(x => x.Key.Contains(methodName)))
                {
                    tempIlOffset = GetILOffset(this, func.Value, out tempLineDifference);
                    if (tempBreakpointLocation.LineDifference < tempLineDifference)
                    {
                        tempBreakpointLocation.LineDifference = tempLineDifference;
                        tempBreakpointLocation.IlOffset       = tempIlOffset;
                        tempBreakpointLocation.Method         = func.Value;

                        if (tempLineDifference == 0)
                        {
                            break;
                        }
                    }
                }
            }

            if (tempBreakpointLocation.Method == null || tempBreakpointLocation.IlOffset < 0)
            {
                tempBreakpointLocation.Method   = summary.Methods.FirstOrDefault(x => x.Name == methodName);
                tempBreakpointLocation.IlOffset = GetILOffset(this, tempBreakpointLocation.Method, out tempLineDifference);
            }

            if (tempBreakpointLocation.Method != null && tempBreakpointLocation.IlOffset >= 0)
            {
                var breakpointLocation = tempBreakpointLocation;
                return(tempBreakpointLocation);
            }

            return(null);
        }