Span?IDotNetSpanMap.ToSpan(ModuleId module, uint token, uint ilOffset)
        {
            if (toMethodDebugInfo == null)
            {
                toMethodDebugInfo = new Dictionary <ModuleTokenId, MethodDebugInfo>(methodDebugInfos.Count);
                foreach (var info in methodDebugInfos)
                {
                    var tokenId = new ModuleTokenId(moduleIdProvider.Create(info.Method.Module), info.Method.MDToken);
                    if (toMethodDebugInfo.TryGetValue(tokenId, out var otherInfo))
                    {
                        if (info.Statements.Length < otherInfo.Statements.Length)
                        {
                            continue;
                        }
                    }
                    toMethodDebugInfo[tokenId] = info;
                }
            }
            if (!toMethodDebugInfo.TryGetValue(new ModuleTokenId(module, token), out var info2))
            {
                return(null);
            }
            var statement = info2.GetSourceStatementByCodeOffset(ilOffset);

            if (statement == null)
            {
                return(null);
            }
            var textSpan = statement.Value.TextSpan;

            return(new Span(textSpan.Start, textSpan.Length));
        }
Пример #2
0
		public static bool GoToIL(IModuleIdProvider moduleIdProvider, IDocumentTabService documentTabService, IDsDocument document, uint token, uint ilOffset, bool newTab) {
			if (document == null)
				return false;

			var method = document.ModuleDef.ResolveToken(token) as MethodDef;
			if (method == null)
				return false;

			var modId = moduleIdProvider.Create(method.Module);
			var key = new ModuleTokenId(modId, method.MDToken);

			bool found = documentTabService.DocumentTreeView.FindNode(method.Module) != null;
			if (found) {
				documentTabService.FollowReference(method, newTab, true, e => {
					Debug.Assert(e.Tab.UIContext is IDocumentViewer);
					if (e.Success && !e.HasMovedCaret) {
						MoveCaretTo(e.Tab.UIContext as IDocumentViewer, key, ilOffset);
						e.HasMovedCaret = true;
					}
				});
				return true;
			}

			Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => {
				documentTabService.FollowReference(method, newTab, true, e => {
					Debug.Assert(e.Tab.UIContext is IDocumentViewer);
					if (e.Success && !e.HasMovedCaret) {
						MoveCaretTo(e.Tab.UIContext as IDocumentViewer, key, ilOffset);
						e.HasMovedCaret = true;
					}
				});
			}));
			return true;
		}
Пример #3
0
        public IEnumerable <ITagSpan <ITextMarkerTag> > GetTags(ActiveStatementTagger tagger, NormalizedSnapshotSpanCollection spans)
        {
            if (activeStatements.Count == 0 || spans.Count == 0)
            {
                yield break;
            }

            //TODO: This code shouldn't depend on IDocumentViewer
            var docViewer = tagger.TextView.TextBuffer.TryGetDocumentViewer();

            if (docViewer == null)
            {
                yield break;
            }

            var methodDebugService = docViewer.TryGetMethodDebugService();

            if (methodDebugService == null)
            {
                yield break;
            }

            var         snapshot  = spans[0].Snapshot;
            MethodDef   method    = null;
            List <uint> ilOffsets = null;

            foreach (var span in spans)
            {
                foreach (var info in methodDebugService.GetStatementsByTextSpan(span.Span))
                {
                    if (info.Method != method)
                    {
                        method = info.Method;
                        var moduleTokenId = new ModuleTokenId(moduleIdProvider.Create(method.Module), method.MDToken);
                        if (!activeStatements.TryGetValue(moduleTokenId, out ilOffsets))
                        {
                            continue;
                        }
                    }
                    else if (ilOffsets == null)
                    {
                        continue;
                    }
                    var textSpan = info.Statement.TextSpan;
                    if (textSpan.End > snapshot.Length)
                    {
                        yield break;                        // Old data, but we'll get called again
                    }
                    var binSpan = info.Statement.BinSpan;
                    foreach (uint ilOffset in ilOffsets)
                    {
                        if (ilOffset >= binSpan.Start && ilOffset < binSpan.End)
                        {
                            yield return(new TagSpan <ITextMarkerTag>(new SnapshotSpan(snapshot, textSpan.Start, textSpan.Length), activeStatementTextMarkerTag));
                        }
                    }
                }
            }
        }
Пример #4
0
 public IGlyphTextMethodMarker AddMarker(MethodDef method, uint ilOffset, ImageReference?glyphImage, string markerTypeName, string selectedMarkerTypeName, IClassificationType classificationType, int zIndex, object tag, IGlyphTextMarkerHandler handler, Func <ITextView, bool> textViewFilter)
 {
     if (method == null)
     {
         throw new ArgumentNullException(nameof(method));
     }
     return(AddMarker(new ModuleTokenId(moduleIdProvider.Create(method.Module), method.MDToken), ilOffset, glyphImage, markerTypeName, selectedMarkerTypeName, classificationType, zIndex, tag, handler, textViewFilter));
 }
        public override IEnumerable <SnapshotSpan> GetFrameSpans(ITextView textView, NormalizedSnapshotSpanCollection spans)
        {
            if (activeStatements.Count == 0)
            {
                yield break;
            }

            var docViewer = textView.TextBuffer.TryGetDocumentViewer();

            if (docViewer == null)
            {
                yield break;
            }

            var methodDebugService = docViewer.TryGetMethodDebugService();

            if (methodDebugService == null)
            {
                yield break;
            }

            var         snapshot  = spans[0].Snapshot;
            MethodDef   method    = null;
            List <uint> ilOffsets = null;

            foreach (var span in spans)
            {
                foreach (var info in methodDebugService.GetStatementsByTextSpan(span.Span))
                {
                    if (info.Method != method)
                    {
                        method = info.Method;
                        var moduleTokenId = new ModuleTokenId(moduleIdProvider.Create(method.Module), method.MDToken);
                        if (!activeStatements.TryGetValue(moduleTokenId, out ilOffsets))
                        {
                            continue;
                        }
                    }
                    else if (ilOffsets == null)
                    {
                        continue;
                    }
                    var textSpan = info.Statement.TextSpan;
                    if (textSpan.End > snapshot.Length)
                    {
                        yield break;                        // Old data, but we'll get called again
                    }
                    var ilSpan = info.Statement.ILSpan;
                    foreach (uint ilOffset in ilOffsets)
                    {
                        if (ilOffset >= ilSpan.Start && ilOffset < ilSpan.End)
                        {
                            yield return(new SnapshotSpan(snapshot, textSpan.Start, textSpan.Length));
                        }
                    }
                }
            }
        }
Пример #6
0
        void DocumentTabService_FileCollectionChanged(object sender, NotifyDocumentCollectionChangedEventArgs e)
        {
            switch (e.Type)
            {
            case NotifyDocumentCollectionType.Clear:
            case NotifyDocumentCollectionType.Remove:
                var existing = new HashSet <ModuleId>(documentTabService.DocumentTreeView.GetAllModuleNodes().Select(a => moduleIdProvider.Create(a.Document.ModuleDef)));
                var removed  = new HashSet <ModuleId>(e.Documents.Select(a => moduleIdProvider.Create(a.ModuleDef)));
                existing.Remove(new ModuleId());
                removed.Remove(new ModuleId());
                object orbArg = null;
                if (OnRemoveBreakpoints != null)
                {
                    orbArg = OnRemoveBreakpoints(orbArg);
                }
                foreach (var ilbp in GetILCodeBreakpoints())
                {
                    // Don't auto-remove BPs in dynamic modules since they have no disk file. The
                    // user must delete these him/herself.
                    if (ilbp.MethodToken.Module.IsDynamic)
                    {
                        continue;
                    }

                    // If the file is still in the TV, don't delete anything. This can happen if
                    // we've loaded an in-memory module and the node just got removed.
                    if (existing.Contains(ilbp.MethodToken.Module))
                    {
                        continue;
                    }

                    if (removed.Contains(ilbp.MethodToken.Module))
                    {
                        Remove(ilbp);
                    }
                }
                OnRemoveBreakpoints?.Invoke(orbArg);
                break;

            case NotifyDocumentCollectionType.Add:
                break;
            }
        }
Пример #7
0
        IDsDocument LoadExisting(ModuleId moduleId)
        {
            foreach (var file in AllActiveDocuments)
            {
                var otherId = moduleIdProvider.Create(file.ModuleDef);
                if (otherId.Equals(moduleId))
                {
                    return(file);
                }
            }

            foreach (var file in AllDocuments)
            {
                var moduleIdFile = moduleIdProvider.Create(file.ModuleDef);
                if (moduleIdFile.Equals(moduleId))
                {
                    return(file);
                }
            }

            return(null);
        }
Пример #8
0
        public MethodDebugService(IReadOnlyList <MethodDebugInfo> methodDebugInfos, ITextSnapshot snapshot, IModuleIdProvider moduleIdProvider)
        {
            if (methodDebugInfos == null)
            {
                throw new ArgumentNullException(nameof(methodDebugInfos));
            }
            if (snapshot == null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }
            if (moduleIdProvider == null)
            {
                throw new ArgumentNullException(nameof(moduleIdProvider));
            }

            this.dict             = new Dictionary <ModuleTokenId, MethodDebugInfo>(methodDebugInfos.Count);
            this.snapshot         = snapshot;
            this.moduleIdProvider = moduleIdProvider;

            var modIdDict = new Dictionary <ModuleDef, ModuleId>();

            foreach (var info in methodDebugInfos)
            {
                var module = info.Method.Module;
                if (module == null)
                {
                    continue;
                }

                ModuleId moduleId;
                if (!modIdDict.TryGetValue(module, out moduleId))
                {
                    moduleId = moduleIdProvider.Create(module);
                    modIdDict.Add(module, moduleId);
                }
                var             key = new ModuleTokenId(moduleId, info.Method.MDToken);
                MethodDebugInfo oldDebugInfo;
                if (this.dict.TryGetValue(key, out oldDebugInfo))
                {
                    if (info.Statements.Length < oldDebugInfo.Statements.Length)
                    {
                        continue;
                    }
                }
                this.dict[key] = info;
            }
        }
        public static bool GoToIL(IModuleIdProvider moduleIdProvider, IDocumentTabService documentTabService, IDsDocument document, uint token, uint ilOffset, bool newTab)
        {
            if (document == null)
            {
                return(false);
            }

            var method = document.ModuleDef.ResolveToken(token) as MethodDef;

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

            var modId = moduleIdProvider.Create(method.Module);
            var key   = new ModuleTokenId(modId, method.MDToken);

            bool found = documentTabService.DocumentTreeView.FindNode(method.Module) != null;

            if (found)
            {
                documentTabService.FollowReference(method, newTab, true, e =>
                {
                    Debug.Assert(e.Tab.UIContext is IDocumentViewer);
                    if (e.Success && !e.HasMovedCaret)
                    {
                        MoveCaretTo(e.Tab.UIContext as IDocumentViewer, key, ilOffset);
                        e.HasMovedCaret = true;
                    }
                });
                return(true);
            }

            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
            {
                documentTabService.FollowReference(method, newTab, true, e =>
                {
                    Debug.Assert(e.Tab.UIContext is IDocumentViewer);
                    if (e.Success && !e.HasMovedCaret)
                    {
                        MoveCaretTo(e.Tab.UIContext as IDocumentViewer, key, ilOffset);
                        e.HasMovedCaret = true;
                    }
                });
            }));
            return(true);
        }
Пример #10
0
 public MethodDebugInfoMethodOffsetSpanMap(IModuleIdProvider moduleIdProvider, ReadOnlyCollection <MethodDebugInfo> methodDebugInfos)
 {
     if (methodDebugInfos == null)
     {
         throw new ArgumentNullException(nameof(methodDebugInfos));
     }
     this.moduleIdProvider = moduleIdProvider;
     toMethodDebugInfo     = new Dictionary <ModuleTokenId, MethodDebugInfo>(methodDebugInfos.Count);
     foreach (var info in methodDebugInfos)
     {
         var             token = new ModuleTokenId(moduleIdProvider.Create(info.Method.Module), info.Method.MDToken);
         MethodDebugInfo otherInfo;
         if (toMethodDebugInfo.TryGetValue(token, out otherInfo))
         {
             if (info.Statements.Length < otherInfo.Statements.Length)
             {
                 continue;
             }
         }
         toMethodDebugInfo[token] = info;
     }
 }
Пример #11
0
        public override TextViewBookmarkLocationResult?CreateLocation(IDocumentTab tab, ITextView textView, VirtualSnapshotPoint position)
        {
            var documentViewer = tab.TryGetDocumentViewer();

            if (documentViewer == null)
            {
                return(null);
            }

            // A bookmark should be set on the current line if possible, and the current position
            // isn't necessarily at the start of the line.
            int startPos = position.Position.GetContainingLine().Start.Position;

            foreach (var data in documentViewer.ReferenceCollection.FindFrom(startPos))
            {
                if (!data.Data.IsDefinition)
                {
                    continue;
                }
                var def = data.Data.Reference as IMemberDef;
                if (def == null)
                {
                    continue;
                }
                var span = data.Span;

                var snapshot = textView.TextSnapshot;
                if (span.End > snapshot.Length)
                {
                    return(null);
                }

                var moduleId = moduleIdProvider.Create(def.Module);
                var location = dotNetBookmarkLocationFactory.Value.CreateTokenLocation(moduleId, def.MDToken.Raw);
                return(new TextViewBookmarkLocationResult(location, new SnapshotSpan(snapshot, span)));
            }

            return(null);
        }
        public override TextViewBookmarkLocationResult?CreateLocation(IDocumentTab tab, ITextView textView, VirtualSnapshotPoint position)
        {
            var documentViewer = tab.TryGetDocumentViewer();

            if (documentViewer == null)
            {
                return(null);
            }
            var methodDebugService = documentViewer.GetMethodDebugService();

            if (methodDebugService == null)
            {
                return(null);
            }
            // A bookmark should be set on the current line if possible, and the current position
            // isn't necessarily at the start of the line.
            var startPos         = position.Position.GetContainingLine().Start;
            var methodStatements = methodDebugService.FindByTextPosition(startPos, FindByTextPositionOptions.None);

            if (methodStatements.Count == 0)
            {
                return(null);
            }
            var textSpan = methodStatements[0].Statement.TextSpan;
            var snapshot = textView.TextSnapshot;

            if (textSpan.End > snapshot.Length)
            {
                return(null);
            }
            var span = new VirtualSnapshotSpan(new SnapshotSpan(snapshot, new Span(textSpan.Start, textSpan.Length)));

            var statement = methodStatements[0];
            var moduleId  = moduleIdProvider.Create(statement.Method.Module);
            var location  = dotNetBookmarkLocationFactory.Value.CreateMethodBodyLocation(moduleId, statement.Method.MDToken.Raw, statement.Statement.ILSpan.Start);

            return(new TextViewBookmarkLocationResult(location, span));
        }
        public override DbgTextViewBreakpointLocationResult?CreateLocation(IDocumentTab tab, ITextView textView, VirtualSnapshotPoint position)
        {
            var documentViewer = tab.TryGetDocumentViewer();

            if (documentViewer == null)
            {
                return(null);
            }
            var methodDebugService = documentViewer.GetMethodDebugService();

            if (methodDebugService == null)
            {
                return(null);
            }
            var methodStatements = methodDebugService.FindByTextPosition(position.Position, FindByTextPositionOptions.None);

            if (methodStatements.Count == 0)
            {
                return(null);
            }
            var textSpan = methodStatements[0].Statement.TextSpan;
            var snapshot = textView.TextSnapshot;

            if (textSpan.End > snapshot.Length)
            {
                return(null);
            }
            var span      = new VirtualSnapshotSpan(new SnapshotSpan(snapshot, new Span(textSpan.Start, textSpan.Length)));
            var locations = new DbgCodeLocation[methodStatements.Count];

            for (int i = 0; i < methodStatements.Count; i++)
            {
                var statement = methodStatements[i];
                var moduleId  = moduleIdProvider.Create(statement.Method.Module);
                locations[i] = dbgDotNetCodeLocationFactory.Value.Create(moduleId, statement.Method.MDToken.Raw, statement.Statement.ILSpan.Start);
            }
            return(new DbgTextViewBreakpointLocationResult(locations, span));
        }