Browse Source

Implement semantic highlighting and links in rich text tooltips.

pull/1654/head
Siegfried Pammer 6 years ago
parent
commit
b18876d087
  1. 19
      ICSharpCode.Decompiler/Xml/DocumentationElement.cs
  2. 6
      ILSpy/Languages/CSharpLanguage.cs
  3. 4
      ILSpy/MainWindow.xaml.cs
  4. 11
      ILSpy/TextView/DecompilerTextView.cs
  5. 8
      ILSpy/TextView/XmlDocRenderer.cs

19
ICSharpCode.Decompiler/Xml/DocumentationElement.cs

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
@ -184,17 +185,17 @@ namespace ICSharpCode.Decompiler.Xml
foreach (var text in childTag.Children.OfType<AXmlText>()) foreach (var text in childTag.Children.OfType<AXmlText>())
list.Add(new XmlDocumentationElement(text.Value, declaringEntity)); list.Add(new XmlDocumentationElement(text.Value, declaringEntity));
} else if (childElement != null) { } else if (childElement != null) {
if (nestingLevel < 5 && childElement.Name == "inheritdoc") { /*if (nestingLevel < 5 && childElement.Name == "inheritdoc") {
/*string cref = childElement.GetAttributeValue("cref"); string cref = childElement.GetAttributeValue("cref");
IEntity inheritedFrom = null; IEntity inheritedFrom = null;
DocumentationComment inheritedDocumentation = null; string inheritedDocumentation = null;
if (cref != null) { if (cref != null) {
inheritedFrom = crefResolver(cref); inheritedFrom = crefResolver(cref);
if (inheritedFrom != null) if (inheritedFrom != null)
inheritedDocumentation = inheritedFrom.Documentation; inheritedDocumentation = inheritedFrom.GetDocumentation();
} else { } else {
foreach (IMember baseMember in InheritanceHelper.GetBaseMembers((IMember)declaringEntity, includeImplementedInterfaces: true)) { foreach (IMember baseMember in InheritanceHelper.GetBaseMembers((IMember)declaringEntity, includeImplementedInterfaces: true)) {
inheritedDocumentation = baseMember.Documentation; inheritedDocumentation = baseMember.GetDocumentation();
if (inheritedDocumentation != null) { if (inheritedDocumentation != null) {
inheritedFrom = baseMember; inheritedFrom = baseMember;
break; break;
@ -203,7 +204,7 @@ namespace ICSharpCode.Decompiler.Xml
} }
if (inheritedDocumentation != null) { if (inheritedDocumentation != null) {
var doc = new AXmlParser().Parse(inheritedDocumentation.Xml); var doc = new AXmlParser().Parse(inheritedDocumentation);
// XPath filter not yet implemented // XPath filter not yet implemented
if (childElement.Parent is AXmlDocument && childElement.GetAttributeValue("select") == null) { if (childElement.Parent is AXmlDocument && childElement.GetAttributeValue("select") == null) {
@ -221,10 +222,10 @@ namespace ICSharpCode.Decompiler.Xml
list.AddRange(CreateElements(inheritedChildren, inheritedFrom, inheritedDocumentation.ResolveCref, nestingLevel + 1)); list.AddRange(CreateElements(inheritedChildren, inheritedFrom, inheritedDocumentation.ResolveCref, nestingLevel + 1));
} }
}*/ }
} else { } else {*/
list.Add(new XmlDocumentationElement(childElement, declaringEntity, crefResolver) { nestingLevel = nestingLevel }); list.Add(new XmlDocumentationElement(childElement, declaringEntity, crefResolver) { nestingLevel = nestingLevel });
} //}
} }
} }
if (list.Count > 0 && list[0].IsTextNode) { if (list.Count > 0 && list[0].IsTextNode) {

6
ILSpy/Languages/CSharpLanguage.cs

@ -487,7 +487,7 @@ namespace ICSharpCode.ILSpy
// HACK : UnknownType is not supported by CSharpAmbience. // HACK : UnknownType is not supported by CSharpAmbience.
} else if (type.Kind == TypeKind.Unknown) { } else if (type.Kind == TypeKind.Unknown) {
return (includeNamespace ? type.FullName : type.Name) return (includeNamespace ? type.FullName : type.Name)
+ (type.TypeParameterCount > 0 ? "<" + string.Join(",", type.TypeArguments.Select(t => t.Name)) + ">" : ""); + (type.TypeParameterCount > 0 ? "<" + string.Join(", ", type.TypeArguments.Select(t => t.Name)) + ">" : "");
} else { } else {
return ambience.ConvertType(type); return ambience.ConvertType(type);
} }
@ -633,8 +633,8 @@ namespace ICSharpCode.ILSpy
var output = new StringWriter(); var output = new StringWriter();
var decoratedWriter = new TextWriterTokenWriter(output); var decoratedWriter = new TextWriterTokenWriter(output);
var richTextOutput = new RichTextModelOutput(decoratedWriter); var richTextOutput = new RichTextModelOutput(decoratedWriter);
var writer = new CSharpHighlightingTokenWriter(decoratedWriter, richTextOutput); var writer = new CSharpHighlightingTokenWriter(new InsertRequiredSpacesDecorator(decoratedWriter), richTextOutput);
new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(entity, writer, FormattingOptionsFactory.CreateEmpty()); new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(entity, writer, new DecompilerSettings().CSharpFormattingOptions);
return new RichText(output.ToString(), richTextOutput.Model); return new RichText(output.ToString(), richTextOutput.Model);
} }

4
ILSpy/MainWindow.xaml.cs

@ -373,7 +373,7 @@ namespace ICSharpCode.ILSpy
} }
} }
private IEntity FindEntityInRelevantAssemblies(string navigateTo, IEnumerable<LoadedAssembly> relevantAssemblies) internal static IEntity FindEntityInRelevantAssemblies(string navigateTo, IEnumerable<LoadedAssembly> relevantAssemblies)
{ {
ITypeReference typeRef = null; ITypeReference typeRef = null;
IMemberReference memberRef = null; IMemberReference memberRef = null;
@ -397,7 +397,7 @@ namespace ICSharpCode.ILSpy
return null; return null;
} }
private bool CanResolveTypeInPEFile(PEFile module, ITypeReference typeRef, out EntityHandle typeHandle) static bool CanResolveTypeInPEFile(PEFile module, ITypeReference typeRef, out EntityHandle typeHandle)
{ {
switch (typeRef) { switch (typeRef) {
case GetPotentiallyNestedClassTypeReference topLevelType: case GetPotentiallyNestedClassTypeReference topLevelType:

11
ILSpy/TextView/DecompilerTextView.cs

@ -340,7 +340,7 @@ namespace ICSharpCode.ILSpy.TextView
if (docProvider != null) { if (docProvider != null) {
string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName); string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName);
if (documentation != null) { if (documentation != null) {
renderer.AddXmlDocumentation(documentation); renderer.AddXmlDocumentation(documentation, null, null);
} }
} }
return new FlowDocumentTooltip(renderer.CreateDocument()); return new FlowDocumentTooltip(renderer.CreateDocument());
@ -373,13 +373,18 @@ namespace ICSharpCode.ILSpy.TextView
if (docProvider != null) { if (docProvider != null) {
string documentation = docProvider.GetDocumentation(resolved.GetIdString()); string documentation = docProvider.GetDocumentation(resolved.GetIdString());
if (documentation != null) { if (documentation != null) {
renderer.AddXmlDocumentation(documentation); renderer.AddXmlDocumentation(documentation, resolved, ResolveReference);
} }
} }
} catch (XmlException) { } catch (XmlException) {
// ignore // ignore
} }
return renderer.CreateDocument(); return renderer.CreateDocument();
IEntity ResolveReference(string idString)
{
return MainWindow.FindEntityInRelevantAssemblies(idString, MainWindow.Instance.CurrentAssemblyList.GetAssemblies());
}
} }
sealed class FlowDocumentTooltip : Popup sealed class FlowDocumentTooltip : Popup
@ -389,7 +394,7 @@ namespace ICSharpCode.ILSpy.TextView
public FlowDocumentTooltip(FlowDocument document) public FlowDocumentTooltip(FlowDocument document)
{ {
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display); TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
viewer = new FlowDocumentScrollViewer(); viewer = new FlowDocumentScrollViewer() { HorizontalScrollBarVisibility = ScrollBarVisibility.Visible };
viewer.Document = document; viewer.Document = document;
Border border = new Border { Border border = new Border {
Background = SystemColors.ControlBrush, Background = SystemColors.ControlBrush,

8
ILSpy/TextView/XmlDocRenderer.cs

@ -115,14 +115,14 @@ namespace ICSharpCode.ILSpy.TextView
AddBlock(block); AddBlock(block);
} }
public void AddXmlDocumentation(string xmlDocumentation) public void AddXmlDocumentation(string xmlDocumentation, IEntity declaringEntity, Func<string, IEntity> resolver)
{ {
if (xmlDocumentation == null) if (xmlDocumentation == null)
return; return;
Debug.WriteLine(xmlDocumentation); Debug.WriteLine(xmlDocumentation);
AXmlParser parser = new AXmlParser(); AXmlParser parser = new AXmlParser();
var doc = parser.Parse(new Decompiler.Xml.StringTextSource(xmlDocumentation)); var doc = parser.Parse(new Decompiler.Xml.StringTextSource(xmlDocumentation));
AddDocumentationElement(new XmlDocumentationElement(doc, null, null)); AddDocumentationElement(new XmlDocumentationElement(doc, declaringEntity, resolver));
} }
@ -319,7 +319,9 @@ namespace ICSharpCode.ILSpy.TextView
Inline ConvertReference(IEntity referencedEntity) Inline ConvertReference(IEntity referencedEntity)
{ {
var h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity))); var h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity)));
//h.Click += CreateNavigateOnClickHandler(referencedEntity); h.Click += (sender, e) => {
MainWindow.Instance.JumpToReference(referencedEntity);
};
return h; return h;
} }

Loading…
Cancel
Save