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); }
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); }