コード例 #1
0
        /// <summary>
        /// Gets source code mapping and metadata token based on type name and line number.
        /// </summary>
        /// <param name="codeMappings">Code mappings storage.</param>
        /// <param name="typeName">Member reference name.</param>
        /// <param name="lineNumber">Line number.</param>
        /// <param name="columnNumber">Column number or 0 for any column.</param>
        /// <returns></returns>
        public static SourceCodeMapping GetInstructionByLineNumber(
            this MemberMapping codeMapping,
            int lineNumber,
            int columnNumber)
        {
            if (codeMapping == null)
            {
                throw new ArgumentException("CodeMappings storage must be valid!");
            }

            if (columnNumber != 0)
            {
                var loc = new TextLocation(lineNumber, columnNumber);
                foreach (var m in codeMapping.MemberCodeMappings.OrderBy(a => a.ILInstructionOffset.From))
                {
                    if (m.StartLocation <= loc && loc <= m.EndLocation)
                    {
                        return(m);
                    }
                }
                var list = new List <SourceCodeMapping>(codeMapping.MemberCodeMappings.FindAll(a => a.StartLocation.Line <= lineNumber && lineNumber <= a.EndLocation.Line));
                list.Sort((a, b) => {
                    var d = GetDist(a.StartLocation, lineNumber, columnNumber).CompareTo(GetDist(b.StartLocation, lineNumber, columnNumber));
                    if (d != 0)
                    {
                        return(d);
                    }
                    return(a.ILInstructionOffset.From.CompareTo(b.ILInstructionOffset.From));
                });
                if (list.Count > 0)
                {
                    return(list[0]);
                }
                return(null);
            }
            else
            {
                SourceCodeMapping map = null;
                foreach (var m in codeMapping.MemberCodeMappings)
                {
                    if (lineNumber < m.StartLocation.Line || lineNumber > m.EndLocation.Line)
                    {
                        continue;
                    }
                    if (map == null || m.ILInstructionOffset.From < map.ILInstructionOffset.From)
                    {
                        map = m;
                    }
                }
                return(map);
            }
        }
コード例 #2
0
ファイル: DebugManager.cs プロジェクト: andyhebear/dnSpy
        bool DebugGetSourceCodeMappingForSetNextStatement(DecompilerTextView textView, out string errMsg, out SourceCodeMapping mapping)
        {
            errMsg = string.Empty;
            mapping = null;

            if (ProcessState == DebuggerProcessState.Terminated) {
                errMsg = "We're not debugging";
                return false;
            }
            if (ProcessState == DebuggerProcessState.Starting || ProcessState == DebuggerProcessState.Continuing || ProcessState == DebuggerProcessState.Running) {
                errMsg = "Can't set next statement when the process is running";
                return false;
            }

            if (textView == null) {
                textView = MainWindow.Instance.ActiveTextView;
                if (textView == null) {
                    errMsg = "No tab is available. Decompile the current method!";
                    return false;
                }
            }

            Dictionary<MethodKey, MemberMapping> cm;
            if (!VerifyAndGetCurrentDebuggedMethod(textView, out cm)) {
                errMsg = "No debug information found. Make sure that only the debugged method is selected in the treeview (press 'Alt+Num *' to go to current statement)";
                return false;
            }

            var location = textView.TextEditor.TextArea.Caret.Location;
            var bps = SourceCodeMappingUtils.Find(cm, location.Line, location.Column);
            if (bps.Count == 0) {
                errMsg = "It's not possible to set the next statement here";
                return false;
            }

            if (GetCurrentMethodILFrame() == null) {
                errMsg = "There's no IL frame";
                return false;
            }

            if (currentLocation != null) {
                var currentKey = currentLocation.Value.MethodKey;

                foreach (var bp in bps) {
                    var md = bp.MemberMapping.MethodDefinition;
                    if (currentLocation.Value.Token != md.MDToken.Raw)
                        continue;
                    var serAsm = GetSerializedDnModuleWithAssembly(md);
                    if (serAsm == null)
                        continue;
                    if (serAsm != currentLocation.Value.ModuleAssembly)
                        continue;

                    mapping = bp;
                    break;
                }
            }
            if (mapping == null) {
                errMsg = "The next statement cannot be set to another method";
                return false;
            }

            return true;
        }
コード例 #3
0
ファイル: DebuggerCommands.cs プロジェクト: gsong2014/dnSpy
        public static bool DebugGetSourceCodeMappingForSetNextStatement(out string errMsg, out SourceCodeMapping mapping)
        {
            errMsg = string.Empty;
            mapping = null;

            if (DebuggerService.CurrentDebugger == null) {
                errMsg = "No debugger exists";
                return false;
            }
            if (!DebuggerService.CurrentDebugger.IsDebugging) {
                errMsg = "We're not debugging";
                return false;
            }
            if (DebuggerService.CurrentDebugger.IsProcessRunning) {
                errMsg = "Can't set next statement when the process is running";
                return false;
            }

            var textView = MainWindow.Instance.ActiveTextView;
            if (textView == null) {
                errMsg = "No tab is available. Decompile the current method!";
                return false;
            }

            Tuple<MethodKey, int, IMemberRef> info;
            MethodKey currentKey;
            Dictionary<MethodKey, MemberMapping> cm;
            if (!DebugUtils.VerifyAndGetCurrentDebuggedMethod(textView, out info, out currentKey, out cm)) {
                errMsg = "No debug information found. Make sure that only the debugged method is selected in the treeview (press 'Alt+Num *' to go to current statement)";
                return false;
            }

            var location = textView.TextEditor.TextArea.Caret.Location;
            var bps = SourceCodeMappingUtils.Find(cm, location.Line, location.Column);
            if (bps.Count == 0) {
                errMsg = "It's not possible to set the next statement here";
                return false;
            }

            // The method def could be different now if the debugged assembly was reloaded from disk
            // so use SigComparer and not object references to compare the methods.
            var flags = SigComparerOptions.CompareDeclaringTypes |
                SigComparerOptions.CompareAssemblyPublicKeyToken |
                SigComparerOptions.CompareAssemblyVersion |
                SigComparerOptions.CompareAssemblyLocale |
                SigComparerOptions.PrivateScopeIsComparable;
            foreach (var bp in bps) {
                if (new SigComparer(flags).Equals(bp.MemberMapping.MethodDefinition, info.Item3)) {
                    mapping = bp;
                    break;
                }
            }
            if (mapping == null) {
                errMsg = "The next statement cannot be set to another method";
                return false;
            }

            return true;
        }
コード例 #4
0
            public void EndNode(AstNode node)
            {
                this.nodes.Pop();

                if (this.highlightItems.Count > 0)
                {
                    TextLocation startLocation = this.startLocations.Pop();

                    if (this.currentMapping != null)
                    {
                        var ranges = node.Annotation<List<ICSharpCode.Decompiler.ILAst.ILRange>>();
                        if ((ranges != null) && (ranges.Count > 0))
                        {
                            foreach (var range in ranges)
                            {
                                SourceCodeMapping scm = null;

                                //foreach (int offset in this.HighlightOffsets)
                                foreach (HighlightItem item in this.highlightItems)
                                {
                                    if ((item.Offset >= range.From) && (item.Offset <= range.To))
                                    {
                                        if (this.CheckNode(node, item))
                                        {
                                            if (scm == null)
                                            {
                                                int adjust = 0;
                                                if (node is ThrowStatement)
                                                {
                                                    adjust = -(this.indent * tabSize + 2);
                                                }
                                                scm = new SourceCodeMapping()
                                                {
                                                    ILInstructionOffset = range,
                                                    StartLocation = startLocation,
                                                    EndLocation = new TextLocation(this.CurrentLocation.Line, this.CurrentLocation.Column + adjust),
                                                    MemberMapping = this.currentMapping
                                                };
                                            }

                                            this.HighlightMapping[item.Offset].Add(scm);
                                        }
                                    }
                                }

                                this.currentMapping.MemberCodeMappings.Add(scm);
                            }
                        }
                    }

                    if (node.Annotation<MemberMapping>() != null)
                    {
                        this.currentMapping = this.memberMapping.Pop();
                    }
                }
            }