/// <summary> /// Jumps to the definition referred to by the <see cref="ReferenceSegment"/>. /// </summary> internal void JumpToReference(ReferenceSegment referenceSegment) { object reference = referenceSegment.Reference; if (referenceSegment.IsLocal) { ClearLocalReferenceMarks(); if (references != null) { foreach (var r in references) { if (reference.Equals(r.Reference)) { var mark = textMarkerService.Create(r.StartOffset, r.Length); mark.BackgroundColor = r.IsLocalTarget ? Colors.LightSeaGreen : Colors.GreenYellow; localReferenceMarks.Add(mark); } } } return; } if (definitionLookup != null) { int pos = definitionLookup.GetDefinitionPosition(reference); if (pos >= 0) { textEditor.TextArea.Focus(); textEditor.Select(pos, 0); textEditor.ScrollTo(textEditor.TextArea.Caret.Line, textEditor.TextArea.Caret.Column); Dispatcher.Invoke(DispatcherPriority.Background, new Action( delegate { CaretHighlightAdorner.DisplayCaretHighlightAnimation(textEditor.TextArea); })); return; } } MainWindow.Instance.JumpToReference(reference); }
void TextViewMouseHover(object sender, PointerEventArgs e) { TextViewPosition?position = GetPositionFromMousePosition(); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); ToolTip.SetIsOpen(this, false); if (content != null) { ToolTip.SetTip(this, content); ToolTip.SetIsOpen(this, true); } }
private void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = GetPositionFromMousePosition(); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; }
private object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(string.Format("{0} ({1}) - ", code.Name, opCodeHex)); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return(string.Format("{0} ({1})", code.Name, opCodeHex)); } else if (segment.Reference is MemberReference) { MemberReference mr = (MemberReference)segment.Reference; // if possible, resolve the reference if (mr is TypeReference) { mr = ((TypeReference)mr).Resolve() ?? mr; } else if (mr is MethodReference) { mr = ((MethodReference)mr).Resolve() ?? mr; } XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr)); try { XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module); if (docProvider != null) { string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr)); if (documentation != null) { renderer.AppendText(Environment.NewLine); renderer.AddXmlDocumentation(documentation); } } } catch (XmlException) { // ignore } return(renderer.CreateTextBlock()); } return(null); }
public static TextViewContext Create(SharpTreeView treeView = null, DecompilerTextView textView = null, ListBox listBox = null) { ReferenceSegment reference; if (textView != null) reference = textView.GetReferenceSegmentAtMousePosition(); else if (listBox != null) reference = new ReferenceSegment { Reference = ((SearchResult)listBox.SelectedItem).Member }; else reference = null; var position = textView != null ? textView.GetPositionFromMousePosition() : null; var selectedTreeNodes = treeView != null ? treeView.GetTopLevelSelection().ToArray() : null; return new TextViewContext { TreeView = treeView, SelectedTreeNodes = selectedTreeNodes, TextView = textView, Reference = reference, Position = position }; }
/// <summary> /// Jumps to the definition referred to by the <see cref="ReferenceSegment"/>. /// </summary> internal void JumpToReference(ReferenceSegment referenceSegment) { object reference = referenceSegment.Reference; if (definitionLookup != null) { int pos = definitionLookup.GetDefinitionPosition(reference); if (pos >= 0) { textEditor.TextArea.Focus(); textEditor.Select(pos, 0); textEditor.ScrollTo(textEditor.TextArea.Caret.Line, textEditor.TextArea.Caret.Column); Dispatcher.Invoke(DispatcherPriority.Background, new Action( delegate { CaretHighlightAdorner.DisplayCaretHighlightAnimation(textEditor.TextArea); })); return; } } MainWindow.Instance.JumpToReference(reference); }
object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code) { XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText($"{code.Name} (0x{code.Code:x}) - "); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return($"{code.Name} (0x{code.Code:x})"); } else if (segment.Reference is IEntity entity) { return(CreateTextBlockForEntity(entity)); } else if (segment.Reference is ValueTuple <PEFile, System.Reflection.Metadata.EntityHandle> unresolvedEntity) { var typeSystem = new DecompilerTypeSystem(unresolvedEntity.Item1, unresolvedEntity.Item1.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached); try { IEntity resolved = typeSystem.MainModule.ResolveEntity(unresolvedEntity.Item2); if (resolved == null) { return(null); } return(CreateTextBlockForEntity(resolved)); } catch (BadImageFormatException) { return(null); } } return(null); }
object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code) { XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; DocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), MainWindow.Instance.CurrentLanguage.SyntaxHighlighting); renderer.AddSignatureBlock($"{code.Name} (0x{code.Code:x})"); if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName); if (documentation != null) { renderer.AddXmlDocumentation(documentation, null, null); } } return(new FlowDocumentTooltip(renderer.CreateDocument())); } else if (segment.Reference is IEntity entity) { return(new FlowDocumentTooltip(CreateTooltipForEntity(entity))); } else if (segment.Reference is ValueTuple <PEFile, System.Reflection.Metadata.EntityHandle> unresolvedEntity) { var typeSystem = new DecompilerTypeSystem(unresolvedEntity.Item1, unresolvedEntity.Item1.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached); try { IEntity resolved = typeSystem.MainModule.ResolveEntity(unresolvedEntity.Item2); if (resolved == null) { return(null); } return(new FlowDocumentTooltip(CreateTooltipForEntity(resolved))); } catch (BadImageFormatException) { return(null); } } return(null); }
internal void JumpToReference(ReferenceSegment referenceSegment, MouseEventArgs e) { referenceClicked(referenceSegment, e); }
internal void JumpToReference(ReferenceSegment referenceSegment, MouseEventArgs e) { referenceClicked(referenceSegment, e); }
/// <summary> /// Creates a visual line text element with the specified length. /// It uses the <see cref="ITextRunConstructionContext.VisualLine"/> and its /// <see cref="VisualLineElement.RelativeTextOffset"/> to find the actual text string. /// </summary> public VisualLineReferenceText(VisualLine parentVisualLine, int length, ReferenceElementGenerator parent, ReferenceSegment referenceSegment) : base(parentVisualLine, length) { this.parent = parent; this.referenceSegment = referenceSegment; }
internal void JumpToReference(ReferenceSegment referenceSegment) { referenceClicked(referenceSegment); }
internal void JumpToReference(ReferenceSegment referenceSegment, bool openNewWindow) { referenceClicked(referenceSegment, openNewWindow); }
/// <summary> /// Creates a visual line text element with the specified length. /// It uses the <see cref="ITextRunConstructionContext.VisualLine"/> and its /// <see cref="VisualLineElement.RelativeTextOffset"/> to find the actual text string. /// </summary> public VisualLineReferenceText(VisualLine parentVisualLine, int length, ReferenceElementGenerator parent, ReferenceSegment referenceSegment) : base(parentVisualLine, length) { this.parent = parent; this.referenceSegment = referenceSegment; }
void TextViewMouseHover(object sender, MouseEventArgs e) { if (!TryCloseExistingPopup(false)) { return; } TextViewPosition?position = GetPositionFromMousePosition(); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (content != null) { popupToolTip = content as Popup; if (popupToolTip != null) { var popupPosition = GetPopupPosition(e); popupToolTip.Closed += ToolTipClosed; popupToolTip.HorizontalOffset = popupPosition.X; popupToolTip.VerticalOffset = popupPosition.Y; popupToolTip.StaysOpen = true; // We will close it ourselves e.Handled = true; popupToolTip.IsOpen = true; distanceToPopupLimit = double.PositiveInfinity; // reset limit; we'll re-calculate it on the next mouse movement } else { if (toolTip == null) { toolTip = new ToolTip(); toolTip.Closed += ToolTipClosed; } toolTip.PlacementTarget = this; // required for property inheritance if (content is string s) { toolTip.Content = new TextBlock { Text = s, TextWrapping = TextWrapping.Wrap }; } else { toolTip.Content = content; } e.Handled = true; toolTip.IsOpen = true; } } }
void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = textEditor.TextArea.TextView.GetPosition(e.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; } object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(string.Format("{0} ({1}) - ", code.Name, opCodeHex)); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return(string.Format("{0} ({1})", code.Name, opCodeHex)); } else if (segment.Reference is MemberReference) { MemberReference mr = (MemberReference)segment.Reference; // if possible, resolve the reference if (mr is TypeReference) { mr = ((TypeReference)mr).Resolve() ?? mr; } else if (mr is MethodReference) { mr = ((MethodReference)mr).Resolve() ?? mr; } XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr)); try { XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module); if (docProvider != null) { string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr)); if (documentation != null) { renderer.AppendText(Environment.NewLine); renderer.AddXmlDocumentation(documentation); } } } catch (XmlException) { // ignore } return(renderer.CreateTextBlock()); } return(null); }
/// <summary> /// Filters all ReferenceSegments that are no real links. /// </summary> bool IsLink(ReferenceSegment referenceSegment) { return(referenceSegment.IsLocal || !referenceSegment.IsDefinition); }
internal void JumpToReference(ReferenceSegment referenceSegment) { referenceClicked(referenceSegment); }
internal void OpenReferenceInNewTab(DecompilerTextView textView, ReferenceSegment reference) { if (textView == null || reference == null) return; var tabState = TabStateDecompile.GetTabStateDecompile(textView); var clonedTabState = CloneTabMakeActive(tabState, true); clonedTabState.History.Clear(); clonedTabState.TextView.GoToTarget(reference, true, false); }
void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = GetPositionFromMousePosition(); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; } object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code) { XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText($"{code.Name} (0x{code.Code:x}) - "); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return($"{code.Name} (0x{code.Code:x})"); } else if (segment.Reference is IEntity entity) { return(CreateTextBlockForEntity(entity)); } else if (segment.Reference is ValueTuple <PEFile, System.Reflection.Metadata.EntityHandle> unresolvedEntity) { var typeSystem = new DecompilerTypeSystem(unresolvedEntity.Item1, unresolvedEntity.Item1.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached); try { IEntity resolved = typeSystem.MainModule.ResolveEntity(unresolvedEntity.Item2); if (resolved == null) { return(null); } return(CreateTextBlockForEntity(resolved)); } catch (BadImageFormatException) { return(null); } } return(null); }
internal void OpenReferenceInNewTab(DecompilerTextView textView, ReferenceSegment reference) { if (reference == null) return; if (reference.Reference is AddressReference) { GoToAddress((AddressReference)reference.Reference); return; } if (textView == null) return; var tabState = DecompileTabState.GetDecompileTabState(textView); var clonedTabState = (DecompileTabState)CloneTabMakeActive(tabState, false); if (clonedTabState == null) return; clonedTabState.History.Clear(); // Always open resources in their own window if (reference.Reference is IResourceNode) { JumpToReference(clonedTabState.TextView, reference.Reference, false); return; } DecompileNodes(clonedTabState, tabState.DecompiledNodes, false, (success, hasMovedCaret) => clonedTabState.TextView.GoToTarget(reference, true, false)); }
/// <summary> /// Filters all ReferenceSegments that are no real links. /// </summary> bool IsLink(ReferenceSegment referenceSegment) { return(true); }
void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = textEditor.TextArea.TextView.GetPosition(e.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value); ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; } object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); string documentationFile = FindDocumentation("mscorlib.xml"); string text = ""; if (documentationFile != null) { XmlDocumentationProvider provider = new XmlDocumentationProvider(documentationFile); string documentation = provider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { text = StripXml(documentation); } } return(string.Format("{0} ({1}): {2}", code.Name, opCodeHex, text)); } return(null); } string StripXml(string xmlText) { try { using (XmlTextReader xml = new XmlTextReader(new StringReader(xmlText))) { StringBuilder ret = new StringBuilder(); while (xml.Read()) { if (xml.NodeType == XmlNodeType.Element) { string elname = xml.Name.ToLowerInvariant(); switch (elname) { case "summary": break; case "br": case "para": ret.AppendLine(); break; default: xml.Skip(); break; } } else if (xml.NodeType == XmlNodeType.Text) { ret.Append(Regex.Replace(xml.Value, @"\s+", " ")); } } return(ret.ToString()); } } catch (XmlException) { return(null); // invalid XML docu } } string FindDocumentation(string fileName) { string path = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); List <string> names = new List <string>(); EnumerateCultures(CultureInfo.CurrentCulture, names); names.Add("en"); names.Add("en-US"); names.Add("en-GB"); foreach (string name in names) { string location = Path.Combine(path, name, fileName); if (File.Exists(location)) { return(location); } } path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"); string loc = Path.Combine(path, fileName); if (File.Exists(loc)) { return(loc); } return(null); } void EnumerateCultures(CultureInfo info, List <string> names) { while (info != null) { names.Add(info.Name); info = info.Parent; if (info == info.Parent) { return; } } }