diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 8c95cf49c..90607e652 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -226,8 +226,7 @@
-
-
+
diff --git a/ILSpy/TextView/DocumentationUIBuilder.cs b/ILSpy/TextView/DocumentationUIBuilder.cs
index 4451ba51a..14cd8c421 100644
--- a/ILSpy/TextView/DocumentationUIBuilder.cs
+++ b/ILSpy/TextView/DocumentationUIBuilder.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
+// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@@ -18,16 +18,21 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
using System.Windows;
+using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
+using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
-using ICSharpCode.Decompiler.CSharp.OutputVisitor;
+using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.Output;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Options;
@@ -35,20 +40,22 @@ using ICSharpCode.ILSpy.Options;
namespace ICSharpCode.ILSpy.TextView
{
///
- /// Builds a FlowDocument for XML documentation.
+ /// Renders XML documentation into a WPF .
///
public class DocumentationUIBuilder
{
- FlowDocument flowDocument;
+ readonly IAmbience ambience;
+ readonly IHighlightingDefinition highlightingDefinition;
+ readonly FlowDocument document;
BlockCollection blockCollection;
InlineCollection inlineCollection;
- IAmbience ambience;
- public DocumentationUIBuilder(IAmbience ambience)
+ public DocumentationUIBuilder(IAmbience ambience, IHighlightingDefinition highlightingDefinition)
{
this.ambience = ambience;
- this.flowDocument = new FlowDocument();
- this.blockCollection = flowDocument.Blocks;
+ this.highlightingDefinition = highlightingDefinition;
+ this.document = new FlowDocument();
+ this.blockCollection = document.Blocks;
this.ShowSummary = true;
this.ShowAllParameters = true;
@@ -65,11 +72,10 @@ namespace ICSharpCode.ILSpy.TextView
this.ShowRemarks = true;
}
- public FlowDocument CreateFlowDocument()
+ public FlowDocument CreateDocument()
{
FlushAddedText(true);
- flowDocument.FontSize = DisplaySettingsPanel.CurrentDisplaySettings.SelectedFontSize;
- return flowDocument;
+ return document;
}
public bool ShowExceptions { get; set; }
@@ -85,33 +91,76 @@ namespace ICSharpCode.ILSpy.TextView
public bool ShowValue { get; set; }
public bool ShowAllParameters { get; set; }
+ public void AddCodeBlock(string textContent, bool keepLargeMargin = false)
+ {
+ var document = new TextDocument(textContent);
+ var highlighter = new DocumentHighlighter(document, highlightingDefinition);
+ var richText = DocumentPrinter.ConvertTextDocumentToRichText(document, highlighter).ToRichTextModel();
+
+ var block = new Paragraph();
+ block.Inlines.AddRange(richText.CreateRuns(document));
+ block.FontFamily = GetCodeFont();
+ if (!keepLargeMargin)
+ block.Margin = new Thickness(0, 6, 0, 6);
+ AddBlock(block);
+ }
+
+ public void AddSignatureBlock(string signature, RichTextModel highlighting = null)
+ {
+ var document = new TextDocument(signature);
+ var richText = highlighting ?? DocumentPrinter.ConvertTextDocumentToRichText(document, new DocumentHighlighter(document, highlightingDefinition)).ToRichTextModel();
+ var block = new Paragraph();
+ // HACK: measure width of signature using a TextBlock
+ // Paragraph sadly does not support TextWrapping.NoWrap
+ var text = new TextBlock {
+ FontFamily = GetCodeFont(),
+ FontSize = DisplaySettingsPanel.CurrentDisplaySettings.SelectedFontSize,
+ TextAlignment = TextAlignment.Left
+ };
+ text.Inlines.AddRange(richText.CreateRuns(document));
+ text.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
+ this.document.MinPageWidth = Math.Min(text.DesiredSize.Width, MainWindow.Instance.ActualWidth);
+ block.Inlines.AddRange(richText.CreateRuns(document));
+ block.FontFamily = GetCodeFont();
+ block.TextAlignment = TextAlignment.Left;
+ AddBlock(block);
+ }
+
+ public void AddXmlDocumentation(string xmlDocumentation, IEntity declaringEntity, Func resolver)
+ {
+ if (xmlDocumentation == null)
+ return;
+ Debug.WriteLine(xmlDocumentation);
+ var xml = XElement.Parse("" + xmlDocumentation + "");
+ AddDocumentationElement(new XmlDocumentationElement(xml, declaringEntity, resolver));
+ }
+
+
///
/// Gets/Sets the name of the parameter that should be shown.
///
public string ParameterName { get; set; }
- public void AddDocumentationElement(XNode node)
+ public void AddDocumentationElement(XmlDocumentationElement element)
{
- if (node == null)
- throw new ArgumentNullException(nameof(node));
- if (node is XText text) {
- AddText(text.Value);
+ if (element == null)
+ throw new ArgumentNullException("element");
+ if (element.IsTextNode) {
+ AddText(element.TextContent);
return;
}
- if (!(node is XElement element))
- throw new NotImplementedException();
- switch (element.Name.ToString()) {
+ switch (element.Name) {
case "b":
- AddSpan(new Bold(), element.Elements());
+ AddSpan(new Bold(), element.Children);
break;
case "i":
- AddSpan(new Italic(), element.ele);
+ AddSpan(new Italic(), element.Children);
break;
case "c":
AddSpan(new Span { FontFamily = GetCodeFont() }, element.Children);
break;
case "code":
- AddCodeBlock(element.Value);
+ AddCodeBlock(element.TextContent);
break;
case "example":
if (ShowExample)
@@ -195,7 +244,7 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- void AddList(string type, IEnumerable items)
+ void AddList(string type, IEnumerable items)
{
List list = new List();
AddBlock(list);
@@ -223,43 +272,15 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- public void AddCodeBlock(string textContent, bool keepLargeMargin = false)
- {
- var document = new ReadOnlyDocument(textContent);
- var highlightingDefinition = HighlightingManager.Instance.GetDefinition("C#");
-
- var block = DocumentPrinter.ConvertTextDocumentToBlock(document, highlightingDefinition);
- block.FontFamily = GetCodeFont();
- if (!keepLargeMargin)
- block.Margin = new Thickness(0, 6, 0, 6);
- AddBlock(block);
- }
-
- public void AddSignatureBlock(string signature, int currentParameterOffset, int currentParameterLength, string currentParameterName)
- {
- ParameterName = currentParameterName;
- var document = new ReadOnlyDocument(signature);
- var highlightingDefinition = HighlightingManager.Instance.GetDefinition("C#");
-
- var richText = DocumentPrinter.ConvertTextDocumentToRichText(document, highlightingDefinition).ToRichTextModel();
- richText.SetFontWeight(currentParameterOffset, currentParameterLength, FontWeights.Bold);
- var block = new Paragraph();
- block.Inlines.AddRange(richText.CreateRuns(document));
- block.FontFamily = GetCodeFont();
- block.TextAlignment = TextAlignment.Left;
- AddBlock(block);
- }
-
bool? ParseBool(string input)
{
- bool result;
- if (bool.TryParse(input, out result))
+ if (bool.TryParse(input, out bool result))
return result;
else
return null;
}
- void AddThreadSafety(bool? staticThreadSafe, bool? instanceThreadSafe, IEnumerable children)
+ void AddThreadSafety(bool? staticThreadSafe, bool? instanceThreadSafe, IEnumerable children)
{
AddSection(
new Run("Thread-safety: "),
@@ -279,12 +300,7 @@ namespace ICSharpCode.ILSpy.TextView
});
}
- FontFamily GetCodeFont()
- {
- return new FontFamily(SD.EditorControlService.GlobalOptions.FontFamily);
- }
-
- void AddException(IEntity referencedEntity, IList children)
+ void AddException(IEntity referencedEntity, IList children)
{
Span span = new Span();
if (referencedEntity != null)
@@ -296,7 +312,7 @@ namespace ICSharpCode.ILSpy.TextView
}
- void AddPermission(IEntity referencedEntity, IList children)
+ void AddPermission(IEntity referencedEntity, IList children)
{
Span span = new Span();
span.Inlines.Add("Permission");
@@ -311,11 +327,13 @@ namespace ICSharpCode.ILSpy.TextView
Inline ConvertReference(IEntity referencedEntity)
{
var h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity)));
- h.Click += CreateNavigateOnClickHandler(referencedEntity);
+ h.Click += (sender, e) => {
+ MainWindow.Instance.JumpToReference(referencedEntity);
+ };
return h;
}
- void AddParam(string name, IEnumerable children)
+ void AddParam(string name, IEnumerable children)
{
Span span = new Span();
span.Inlines.Add(new Run(name ?? string.Empty) { FontStyle = FontStyles.Italic });
@@ -330,7 +348,7 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- void AddPreliminary(IEnumerable children)
+ void AddPreliminary(IEnumerable children)
{
if (children.Any()) {
foreach (var child in children)
@@ -340,13 +358,15 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- void AddSee(XNode element)
+ void AddSee(XmlDocumentationElement element)
{
IEntity referencedEntity = element.ReferencedEntity;
if (referencedEntity != null) {
if (element.Children.Any()) {
Hyperlink link = new Hyperlink();
- link.Click += CreateNavigateOnClickHandler(referencedEntity);
+ link.Click += (sender, e) => {
+ MainWindow.Instance.JumpToReference(referencedEntity);
+ };
AddSpan(link, element.Children);
} else {
AddInline(ConvertReference(referencedEntity));
@@ -368,30 +388,44 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- RoutedEventHandler CreateNavigateOnClickHandler(IEntity referencedEntity)
+ static string GetCref(string cref)
{
- // Don't let the anonymous method capture the referenced entity
- // (we don't want to keep the whole compilation in memory)
- // Use the IEntityModel instead.
- var model = referencedEntity.GetModel();
- return delegate (object sender, RoutedEventArgs e) {
- IEntity resolvedEntity = model != null ? model.Resolve() : null;
- if (resolvedEntity != null) {
- bool shouldDisplayHelp = CodeCompletionOptions.TooltipLinkTarget == TooltipLinkTarget.Documentation
- && resolvedEntity.ParentAssembly.IsPartOfDotnetFramework();
- if (!shouldDisplayHelp || !HelpProvider.ShowHelp(resolvedEntity))
- NavigationService.NavigateTo(resolvedEntity);
- }
- e.Handled = true;
- };
+ if (cref == null || cref.Trim().Length==0) {
+ return "";
+ }
+ if (cref.Length < 2) {
+ return cref;
+ }
+ if (cref.Substring(1, 1) == ":") {
+ return cref.Substring(2, cref.Length - 2);
+ }
+ return cref;
+ }
+
+ FontFamily GetCodeFont()
+ {
+ return DisplaySettingsPanel.CurrentDisplaySettings.SelectedFont;
+ }
+
+ public void AddInline(Inline inline)
+ {
+ FlushAddedText(false);
+ if (inlineCollection == null) {
+ var para = new Paragraph();
+ para.Margin = new Thickness(0, 0, 0, 5);
+ inlineCollection = para.Inlines;
+ AddBlock(para);
+ }
+ inlineCollection.Add(inline);
+ ignoreWhitespace = false;
}
- void AddSection(string title, IEnumerable children)
+ void AddSection(string title, IEnumerable children)
{
AddSection(new Run(title), children);
}
- void AddSection(Inline title, IEnumerable children)
+ void AddSection(Inline title, IEnumerable children)
{
AddSection(
title, delegate {
@@ -420,7 +454,7 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- void AddParagraph(Paragraph para, IEnumerable children)
+ void AddParagraph(Paragraph para, IEnumerable children)
{
AddBlock(para);
try {
@@ -434,7 +468,7 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- void AddSpan(Span span, IEnumerable children)
+ void AddSpan(Span span, IEnumerable children)
{
AddInline(span);
var oldInlineCollection = inlineCollection;
@@ -448,19 +482,6 @@ namespace ICSharpCode.ILSpy.TextView
}
}
- public void AddInline(Inline inline)
- {
- FlushAddedText(false);
- if (inlineCollection == null) {
- var para = new Paragraph();
- para.Margin = new Thickness(0, 0, 0, 5);
- inlineCollection = para.Inlines;
- AddBlock(para);
- }
- inlineCollection.Add(inline);
- ignoreWhitespace = false;
- }
-
public void AddBlock(Block block)
{
FlushAddedText(true);
diff --git a/ILSpy/TextView/ReadOnlyDocument.cs b/ILSpy/TextView/ReadOnlyDocument.cs
deleted file mode 100644
index 5a11ee298..000000000
--- a/ILSpy/TextView/ReadOnlyDocument.cs
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using ICSharpCode.AvalonEdit.Document;
-
-namespace ICSharpCode.ILSpy.TextView
-{
- ///
- /// Read-only implementation of .
- ///
- [Serializable]
- public sealed class ReadOnlyDocument : IDocument
- {
- readonly ITextSource textSource;
- readonly string fileName;
- int[] lines;
-
- static readonly char[] newline = { '\r', '\n' };
-
- ///
- /// Creates a new ReadOnlyDocument from the given text source.
- ///
- public ReadOnlyDocument(ITextSource textSource)
- {
- if (textSource == null)
- throw new ArgumentNullException("textSource");
- // ensure that underlying buffer is immutable
- this.textSource = textSource.CreateSnapshot();
- List lines = new List();
- lines.Add(0);
- int offset = 0;
- int textLength = textSource.TextLength;
- while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0) {
- offset++;
- if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n') {
- offset++;
- }
- lines.Add(offset);
- }
- this.lines = lines.ToArray();
- }
-
- ///
- /// Creates a new ReadOnlyDocument from the given string.
- ///
- public ReadOnlyDocument(string text)
- : this(new StringTextSource(text))
- {
- }
-
- ///
- /// Creates a new ReadOnlyDocument from the given text source;
- /// and sets IDocument.FileName to the specified file name.
- ///
- public ReadOnlyDocument(ITextSource textSource, string fileName)
- : this(textSource)
- {
- this.fileName = fileName;
- }
-
- ///
- public IDocumentLine GetLineByNumber(int lineNumber)
- {
- if (lineNumber < 1 || lineNumber > lines.Length)
- throw new ArgumentOutOfRangeException("lineNumber", lineNumber, "Value must be between 1 and " + lines.Length);
- return new ReadOnlyDocumentLine(this, lineNumber);
- }
-
- sealed class ReadOnlyDocumentLine : IDocumentLine
- {
- readonly ReadOnlyDocument doc;
- readonly int lineNumber;
- readonly int offset, endOffset;
-
- public ReadOnlyDocumentLine(ReadOnlyDocument doc, int lineNumber)
- {
- this.doc = doc;
- this.lineNumber = lineNumber;
- this.offset = doc.GetStartOffset(lineNumber);
- this.endOffset = doc.GetEndOffset(lineNumber);
- }
-
- public override int GetHashCode()
- {
- return doc.GetHashCode() ^ lineNumber;
- }
-
- public override bool Equals(object obj)
- {
- ReadOnlyDocumentLine other = obj as ReadOnlyDocumentLine;
- return other != null && doc == other.doc && lineNumber == other.lineNumber;
- }
-
- public int Offset {
- get { return offset; }
- }
-
- public int Length {
- get { return endOffset - offset; }
- }
-
- public int EndOffset {
- get { return endOffset; }
- }
-
- public int TotalLength {
- get {
- return doc.GetTotalEndOffset(lineNumber) - offset;
- }
- }
-
- public int DelimiterLength {
- get {
- return doc.GetTotalEndOffset(lineNumber) - endOffset;
- }
- }
-
- public int LineNumber {
- get { return lineNumber; }
- }
-
- public IDocumentLine PreviousLine {
- get {
- if (lineNumber == 1)
- return null;
- else
- return new ReadOnlyDocumentLine(doc, lineNumber - 1);
- }
- }
-
- public IDocumentLine NextLine {
- get {
- if (lineNumber == doc.LineCount)
- return null;
- else
- return new ReadOnlyDocumentLine(doc, lineNumber + 1);
- }
- }
-
- public bool IsDeleted {
- get { return false; }
- }
- }
-
- int GetStartOffset(int lineNumber)
- {
- return lines[lineNumber - 1];
- }
-
- int GetTotalEndOffset(int lineNumber)
- {
- return lineNumber < lines.Length ? lines[lineNumber] : textSource.TextLength;
- }
-
- int GetEndOffset(int lineNumber)
- {
- if (lineNumber == lines.Length)
- return textSource.TextLength;
- int off = lines[lineNumber] - 1;
- if (off > 0 && textSource.GetCharAt(off - 1) == '\r' && textSource.GetCharAt(off) == '\n')
- off--;
- return off;
- }
-
- ///
- public IDocumentLine GetLineByOffset(int offset)
- {
- return GetLineByNumber(GetLineNumberForOffset(offset));
- }
-
- int GetLineNumberForOffset(int offset)
- {
- int r = Array.BinarySearch(lines, offset);
- return r < 0 ? ~r : r + 1;
- }
-
- ///
- public int GetOffset(int line, int column)
- {
- if (line < 1 || line > lines.Length)
- throw new ArgumentOutOfRangeException("line", line, "Value must be between 1 and " + lines.Length);
- int lineStart = GetStartOffset(line);
- if (column <= 1)
- return lineStart;
- int lineEnd = GetEndOffset(line);
- if (column - 1 >= lineEnd - lineStart)
- return lineEnd;
- return lineStart + column - 1;
- }
-
- ///
- public int GetOffset(TextLocation location)
- {
- return GetOffset(location.Line, location.Column);
- }
-
- ///
- public TextLocation GetLocation(int offset)
- {
- if (offset < 0 || offset > textSource.TextLength)
- throw new ArgumentOutOfRangeException("offset", offset, "Value must be between 0 and " + textSource.TextLength);
- int line = GetLineNumberForOffset(offset);
- return new TextLocation(line, offset - GetStartOffset(line) + 1);
- }
-
- ///
- public string Text {
- get { return textSource.Text; }
- set {
- throw new NotSupportedException();
- }
- }
-
- ///
- public int LineCount {
- get { return lines.Length; }
- }
-
- ///
- public ITextSourceVersion Version {
- get { return textSource.Version; }
- }
-
- ///
- public int TextLength {
- get { return textSource.TextLength; }
- }
-
- event EventHandler IDocument.TextChanging { add { } remove { } }
-
- event EventHandler IDocument.TextChanged { add { } remove { } }
-
- event EventHandler IDocument.ChangeCompleted { add { } remove { } }
-
- void IDocument.Insert(int offset, string text)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Remove(int offset, int length)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Replace(int offset, int length, string newText)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Insert(int offset, ITextSource text)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.Replace(int offset, int length, ITextSource newText)
- {
- throw new NotSupportedException();
- }
-
- void IDocument.StartUndoableAction()
- {
- }
-
- void IDocument.EndUndoableAction()
- {
- }
-
- IDisposable IDocument.OpenUndoGroup()
- {
- return null;
- }
-
- ///
- public ITextAnchor CreateAnchor(int offset)
- {
- return new ReadOnlyDocumentTextAnchor(GetLocation(offset), offset);
- }
-
- sealed class ReadOnlyDocumentTextAnchor : ITextAnchor
- {
- readonly TextLocation location;
- readonly int offset;
-
- public ReadOnlyDocumentTextAnchor(TextLocation location, int offset)
- {
- this.location = location;
- this.offset = offset;
- }
-
- public event EventHandler Deleted { add { } remove { } }
-
- public TextLocation Location {
- get { return location; }
- }
-
- public int Offset {
- get { return offset; }
- }
-
- public AnchorMovementType MovementType { get; set; }
-
- public bool SurviveDeletion { get; set; }
-
- public bool IsDeleted {
- get { return false; }
- }
-
- public int Line {
- get { return location.Line; }
- }
-
- public int Column {
- get { return location.Column; }
- }
- }
-
- ///
- public ITextSource CreateSnapshot()
- {
- return textSource; // textBuffer is immutable
- }
-
- ///
- public ITextSource CreateSnapshot(int offset, int length)
- {
- return textSource.CreateSnapshot(offset, length);
- }
-
- ///
- public IDocument CreateDocumentSnapshot()
- {
- return this; // ReadOnlyDocument is immutable
- }
-
- ///
- public System.IO.TextReader CreateReader()
- {
- return textSource.CreateReader();
- }
-
- ///
- public System.IO.TextReader CreateReader(int offset, int length)
- {
- return textSource.CreateReader(offset, length);
- }
-
- ///
- public void WriteTextTo(System.IO.TextWriter writer)
- {
- textSource.WriteTextTo(writer);
- }
-
- ///
- public void WriteTextTo(System.IO.TextWriter writer, int offset, int length)
- {
- textSource.WriteTextTo(writer, offset, length);
- }
-
- ///
- public char GetCharAt(int offset)
- {
- return textSource.GetCharAt(offset);
- }
-
- ///
- public string GetText(int offset, int length)
- {
- return textSource.GetText(offset, length);
- }
-
- ///
- public string GetText(ISegment segment)
- {
- return textSource.GetText(segment);
- }
-
- ///
- public int IndexOf(char c, int startIndex, int count)
- {
- return textSource.IndexOf(c, startIndex, count);
- }
-
- ///
- public int IndexOfAny(char[] anyOf, int startIndex, int count)
- {
- return textSource.IndexOfAny(anyOf, startIndex, count);
- }
-
- ///
- public int IndexOf(string searchText, int startIndex, int count, StringComparison comparisonType)
- {
- return textSource.IndexOf(searchText, startIndex, count, comparisonType);
- }
-
- ///
- public int LastIndexOf(char c, int startIndex, int count)
- {
- return textSource.LastIndexOf(c, startIndex, count);
- }
-
- ///
- public int LastIndexOf(string searchText, int startIndex, int count, StringComparison comparisonType)
- {
- return textSource.LastIndexOf(searchText, startIndex, count, comparisonType);
- }
-
- object IServiceProvider.GetService(Type serviceType)
- {
- return null;
- }
-
- ///
- /// Will never be raised on .
- public event EventHandler FileNameChanged { add { } remove { } }
-
- ///
- public string FileName {
- get { return fileName; }
- }
- }
-}
diff --git a/ILSpy/TextView/XmlDocFormatter.cs b/ILSpy/TextView/XmlDocFormatter.cs
deleted file mode 100644
index 37b80ab9b..000000000
--- a/ILSpy/TextView/XmlDocFormatter.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Windows.Documents;
-using ICSharpCode.Decompiler.Output;
-using ICSharpCode.Decompiler.TypeSystem;
-using ICSharpCode.NRefactory.TypeSystem;
-using ICSharpCode.NRefactory.Xml;
-
-namespace ICSharpCode.ILSpy.TextView
-{
- ///
- /// Provides helper methods to create nicely formatted FlowDocuments from NRefactory XmlDoc.
- ///
- public static class XmlDocFormatter
- {
- public static FlowDocument CreateTooltip(IType type, bool useFullyQualifiedMemberNames = true)
- {
- var ambience = AmbienceService.GetCurrentAmbience();
- ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType;
- if (useFullyQualifiedMemberNames)
- ambience.ConversionFlags |= ConversionFlags.UseFullyQualifiedEntityNames;
- string header;
- if (type is ITypeDefinition)
- header = ambience.ConvertSymbol((ITypeDefinition)type);
- else
- header = ambience.ConvertType(type);
-
- ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
- DocumentationUIBuilder b = new DocumentationUIBuilder(ambience);
- b.AddCodeBlock(header, keepLargeMargin: true);
-
- ITypeDefinition entity = type.GetDefinition();/*
- if (entity != null) {
- var documentation = XmlDocumentationElement.Get(entity);
- if (documentation != null) {
- foreach (var child in documentation.Children) {
- b.AddDocumentationElement(child);
- }
- }
- }*/
- return b.CreateFlowDocument();
- }
-
- public static FlowDocument CreateTooltip(IEntity entity, bool useFullyQualifiedMemberNames = true)
- {
- var ambience = AmbienceService.GetCurrentAmbience();
- ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType;
- if (useFullyQualifiedMemberNames)
- ambience.ConversionFlags |= ConversionFlags.UseFullyQualifiedEntityNames;
- string header = ambience.ConvertSymbol(entity);
- var documentation = XmlDocumentationElement.Get(entity);
-
- ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
- DocumentationUIBuilder b = new DocumentationUIBuilder(ambience);
- b.AddCodeBlock(header, keepLargeMargin: true);
- if (documentation != null) {
- foreach (var child in documentation.Children) {
- b.AddDocumentationElement(child);
- }
- }
- return b.CreateFlowDocument();
- }
-
- public static FlowDocument CreateTooltip(ISymbol symbol)
- {
- var ambience = AmbienceService.GetCurrentAmbience();
- ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType;
- string header = ambience.ConvertSymbol(symbol);
-
- if (symbol is IParameter) {
- header = "parameter " + header;
- } else if (symbol is IVariable) {
- header = "local variable " + header;
- }
-
- ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
- DocumentationUIBuilder b = new DocumentationUIBuilder(ambience);
- b.AddCodeBlock(header, keepLargeMargin: true);
- return b.CreateFlowDocument();
- }
- }
-}
diff --git a/ILSpy/TextView/XmlDocRenderer.cs b/ILSpy/TextView/XmlDocRenderer.cs
deleted file mode 100644
index 14cd8c421..000000000
--- a/ILSpy/TextView/XmlDocRenderer.cs
+++ /dev/null
@@ -1,551 +0,0 @@
-// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Media;
-using System.Xml;
-using System.Xml.Linq;
-using ICSharpCode.AvalonEdit.Document;
-using ICSharpCode.AvalonEdit.Highlighting;
-using ICSharpCode.AvalonEdit.Utils;
-using ICSharpCode.Decompiler.Documentation;
-using ICSharpCode.Decompiler.Output;
-using ICSharpCode.Decompiler.TypeSystem;
-using ICSharpCode.ILSpy.Options;
-
-namespace ICSharpCode.ILSpy.TextView
-{
- ///
- /// Renders XML documentation into a WPF .
- ///
- public class DocumentationUIBuilder
- {
- readonly IAmbience ambience;
- readonly IHighlightingDefinition highlightingDefinition;
- readonly FlowDocument document;
- BlockCollection blockCollection;
- InlineCollection inlineCollection;
-
- public DocumentationUIBuilder(IAmbience ambience, IHighlightingDefinition highlightingDefinition)
- {
- this.ambience = ambience;
- this.highlightingDefinition = highlightingDefinition;
- this.document = new FlowDocument();
- this.blockCollection = document.Blocks;
-
- this.ShowSummary = true;
- this.ShowAllParameters = true;
- this.ShowReturns = true;
- this.ShowThreadSafety = true;
- this.ShowExceptions = true;
- this.ShowTypeParameters = true;
-
- this.ShowExample = true;
- this.ShowPreliminary = true;
- this.ShowSeeAlso = true;
- this.ShowValue = true;
- this.ShowPermissions = true;
- this.ShowRemarks = true;
- }
-
- public FlowDocument CreateDocument()
- {
- FlushAddedText(true);
- return document;
- }
-
- public bool ShowExceptions { get; set; }
- public bool ShowPermissions { get; set; }
- public bool ShowExample { get; set; }
- public bool ShowPreliminary { get; set; }
- public bool ShowRemarks { get; set; }
- public bool ShowSummary { get; set; }
- public bool ShowReturns { get; set; }
- public bool ShowSeeAlso { get; set; }
- public bool ShowThreadSafety { get; set; }
- public bool ShowTypeParameters { get; set; }
- public bool ShowValue { get; set; }
- public bool ShowAllParameters { get; set; }
-
- public void AddCodeBlock(string textContent, bool keepLargeMargin = false)
- {
- var document = new TextDocument(textContent);
- var highlighter = new DocumentHighlighter(document, highlightingDefinition);
- var richText = DocumentPrinter.ConvertTextDocumentToRichText(document, highlighter).ToRichTextModel();
-
- var block = new Paragraph();
- block.Inlines.AddRange(richText.CreateRuns(document));
- block.FontFamily = GetCodeFont();
- if (!keepLargeMargin)
- block.Margin = new Thickness(0, 6, 0, 6);
- AddBlock(block);
- }
-
- public void AddSignatureBlock(string signature, RichTextModel highlighting = null)
- {
- var document = new TextDocument(signature);
- var richText = highlighting ?? DocumentPrinter.ConvertTextDocumentToRichText(document, new DocumentHighlighter(document, highlightingDefinition)).ToRichTextModel();
- var block = new Paragraph();
- // HACK: measure width of signature using a TextBlock
- // Paragraph sadly does not support TextWrapping.NoWrap
- var text = new TextBlock {
- FontFamily = GetCodeFont(),
- FontSize = DisplaySettingsPanel.CurrentDisplaySettings.SelectedFontSize,
- TextAlignment = TextAlignment.Left
- };
- text.Inlines.AddRange(richText.CreateRuns(document));
- text.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
- this.document.MinPageWidth = Math.Min(text.DesiredSize.Width, MainWindow.Instance.ActualWidth);
- block.Inlines.AddRange(richText.CreateRuns(document));
- block.FontFamily = GetCodeFont();
- block.TextAlignment = TextAlignment.Left;
- AddBlock(block);
- }
-
- public void AddXmlDocumentation(string xmlDocumentation, IEntity declaringEntity, Func resolver)
- {
- if (xmlDocumentation == null)
- return;
- Debug.WriteLine(xmlDocumentation);
- var xml = XElement.Parse("" + xmlDocumentation + "");
- AddDocumentationElement(new XmlDocumentationElement(xml, declaringEntity, resolver));
- }
-
-
- ///
- /// Gets/Sets the name of the parameter that should be shown.
- ///
- public string ParameterName { get; set; }
-
- public void AddDocumentationElement(XmlDocumentationElement element)
- {
- if (element == null)
- throw new ArgumentNullException("element");
- if (element.IsTextNode) {
- AddText(element.TextContent);
- return;
- }
- switch (element.Name) {
- case "b":
- AddSpan(new Bold(), element.Children);
- break;
- case "i":
- AddSpan(new Italic(), element.Children);
- break;
- case "c":
- AddSpan(new Span { FontFamily = GetCodeFont() }, element.Children);
- break;
- case "code":
- AddCodeBlock(element.TextContent);
- break;
- case "example":
- if (ShowExample)
- AddSection("Example: ", element.Children);
- break;
- case "exception":
- if (ShowExceptions)
- AddException(element.ReferencedEntity, element.Children);
- break;
- case "list":
- AddList(element.GetAttribute("type"), element.Children);
- break;
- //case "note":
- // throw new NotImplementedException();
- case "para":
- AddParagraph(new Paragraph { Margin = new Thickness(0, 5, 0, 5) }, element.Children);
- break;
- case "param":
- if (ShowAllParameters || (ParameterName != null && ParameterName == element.GetAttribute("name")))
- AddParam(element.GetAttribute("name"), element.Children);
- break;
- case "paramref":
- AddParamRef(element.GetAttribute("name"));
- break;
- case "permission":
- if (ShowPermissions)
- AddPermission(element.ReferencedEntity, element.Children);
- break;
- case "preliminary":
- if (ShowPreliminary)
- AddPreliminary(element.Children);
- break;
- case "remarks":
- if (ShowRemarks)
- AddSection("Remarks: ", element.Children);
- break;
- case "returns":
- if (ShowReturns)
- AddSection("Returns: ", element.Children);
- break;
- case "see":
- AddSee(element);
- break;
- case "seealso":
- if (inlineCollection != null)
- AddSee(element);
- else if (ShowSeeAlso)
- AddSection(new Run("See also: "), () => AddSee(element));
- break;
- case "summary":
- if (ShowSummary)
- AddSection("Summary: ", element.Children);
- break;
- case "threadsafety":
- if (ShowThreadSafety)
- AddThreadSafety(ParseBool(element.GetAttribute("static")), ParseBool(element.GetAttribute("instance")), element.Children);
- break;
- case "typeparam":
- if (ShowTypeParameters)
- AddSection("Type parameter " + element.GetAttribute("name") + ": ", element.Children);
- break;
- case "typeparamref":
- AddText(element.GetAttribute("name"));
- break;
- case "value":
- if (ShowValue)
- AddSection("Value: ", element.Children);
- break;
- case "exclude":
- case "filterpriority":
- case "overloads":
- // ignore children
- break;
- case "br":
- AddLineBreak();
- break;
- default:
- foreach (var child in element.Children)
- AddDocumentationElement(child);
- break;
- }
- }
-
- void AddList(string type, IEnumerable items)
- {
- List list = new List();
- AddBlock(list);
- list.Margin = new Thickness(0, 5, 0, 5);
- if (type == "number")
- list.MarkerStyle = TextMarkerStyle.Decimal;
- else if (type == "bullet")
- list.MarkerStyle = TextMarkerStyle.Disc;
- var oldBlockCollection = blockCollection;
- try {
- foreach (var itemElement in items) {
- if (itemElement.Name == "listheader" || itemElement.Name == "item") {
- ListItem item = new ListItem();
- blockCollection = item.Blocks;
- inlineCollection = null;
- foreach (var prop in itemElement.Children) {
- AddDocumentationElement(prop);
- }
- FlushAddedText(false);
- list.ListItems.Add(item);
- }
- }
- } finally {
- blockCollection = oldBlockCollection;
- }
- }
-
- bool? ParseBool(string input)
- {
- if (bool.TryParse(input, out bool result))
- return result;
- else
- return null;
- }
-
- void AddThreadSafety(bool? staticThreadSafe, bool? instanceThreadSafe, IEnumerable children)
- {
- AddSection(
- new Run("Thread-safety: "),
- delegate {
- if (staticThreadSafe == true)
- AddText("Any public static members of this type are thread safe. ");
- else if (staticThreadSafe == false)
- AddText("The static members of this type are not thread safe. ");
-
- if (instanceThreadSafe == true)
- AddText("Any public instance members of this type are thread safe. ");
- else if (instanceThreadSafe == false)
- AddText("Any instance members are not guaranteed to be thread safe. ");
-
- foreach (var child in children)
- AddDocumentationElement(child);
- });
- }
-
- void AddException(IEntity referencedEntity, IList children)
- {
- Span span = new Span();
- if (referencedEntity != null)
- span.Inlines.Add(ConvertReference(referencedEntity));
- else
- span.Inlines.Add("Exception");
- span.Inlines.Add(": ");
- AddSection(span, children);
- }
-
-
- void AddPermission(IEntity referencedEntity, IList children)
- {
- Span span = new Span();
- span.Inlines.Add("Permission");
- if (referencedEntity != null) {
- span.Inlines.Add(" ");
- span.Inlines.Add(ConvertReference(referencedEntity));
- }
- span.Inlines.Add(": ");
- AddSection(span, children);
- }
-
- Inline ConvertReference(IEntity referencedEntity)
- {
- var h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity)));
- h.Click += (sender, e) => {
- MainWindow.Instance.JumpToReference(referencedEntity);
- };
- return h;
- }
-
- void AddParam(string name, IEnumerable children)
- {
- Span span = new Span();
- span.Inlines.Add(new Run(name ?? string.Empty) { FontStyle = FontStyles.Italic });
- span.Inlines.Add(": ");
- AddSection(span, children);
- }
-
- void AddParamRef(string name)
- {
- if (name != null) {
- AddInline(new Run(name) { FontStyle = FontStyles.Italic });
- }
- }
-
- void AddPreliminary(IEnumerable children)
- {
- if (children.Any()) {
- foreach (var child in children)
- AddDocumentationElement(child);
- } else {
- AddText("[This is preliminary documentation and subject to change.]");
- }
- }
-
- void AddSee(XmlDocumentationElement element)
- {
- IEntity referencedEntity = element.ReferencedEntity;
- if (referencedEntity != null) {
- if (element.Children.Any()) {
- Hyperlink link = new Hyperlink();
- link.Click += (sender, e) => {
- MainWindow.Instance.JumpToReference(referencedEntity);
- };
- AddSpan(link, element.Children);
- } else {
- AddInline(ConvertReference(referencedEntity));
- }
- } else if (element.GetAttribute("langword") != null) {
- AddInline(new Run(element.GetAttribute("langword")) { FontFamily = GetCodeFont() });
- } else if (element.GetAttribute("href") != null) {
- Uri uri;
- if (Uri.TryCreate(element.GetAttribute("href"), UriKind.Absolute, out uri)) {
- if (element.Children.Any()) {
- AddSpan(new Hyperlink { NavigateUri = uri }, element.Children);
- } else {
- AddInline(new Hyperlink(new Run(element.GetAttribute("href"))) { NavigateUri = uri });
- }
- }
- } else {
- // Invalid reference: print the cref value
- AddText(element.GetAttribute("cref"));
- }
- }
-
- static string GetCref(string cref)
- {
- if (cref == null || cref.Trim().Length==0) {
- return "";
- }
- if (cref.Length < 2) {
- return cref;
- }
- if (cref.Substring(1, 1) == ":") {
- return cref.Substring(2, cref.Length - 2);
- }
- return cref;
- }
-
- FontFamily GetCodeFont()
- {
- return DisplaySettingsPanel.CurrentDisplaySettings.SelectedFont;
- }
-
- public void AddInline(Inline inline)
- {
- FlushAddedText(false);
- if (inlineCollection == null) {
- var para = new Paragraph();
- para.Margin = new Thickness(0, 0, 0, 5);
- inlineCollection = para.Inlines;
- AddBlock(para);
- }
- inlineCollection.Add(inline);
- ignoreWhitespace = false;
- }
-
- void AddSection(string title, IEnumerable children)
- {
- AddSection(new Run(title), children);
- }
-
- void AddSection(Inline title, IEnumerable children)
- {
- AddSection(
- title, delegate {
- foreach (var child in children)
- AddDocumentationElement(child);
- });
- }
-
- void AddSection(Inline title, Action addChildren)
- {
- var section = new Section();
- AddBlock(section);
- var oldBlockCollection = blockCollection;
- try {
- blockCollection = section.Blocks;
- inlineCollection = null;
-
- if (title != null)
- AddInline(new Bold(title));
-
- addChildren();
- FlushAddedText(false);
- } finally {
- blockCollection = oldBlockCollection;
- inlineCollection = null;
- }
- }
-
- void AddParagraph(Paragraph para, IEnumerable children)
- {
- AddBlock(para);
- try {
- inlineCollection = para.Inlines;
-
- foreach (var child in children)
- AddDocumentationElement(child);
- FlushAddedText(false);
- } finally {
- inlineCollection = null;
- }
- }
-
- void AddSpan(Span span, IEnumerable children)
- {
- AddInline(span);
- var oldInlineCollection = inlineCollection;
- try {
- inlineCollection = span.Inlines;
- foreach (var child in children)
- AddDocumentationElement(child);
- FlushAddedText(false);
- } finally {
- inlineCollection = oldInlineCollection;
- }
- }
-
- public void AddBlock(Block block)
- {
- FlushAddedText(true);
- blockCollection.Add(block);
- }
-
- StringBuilder addedText = new StringBuilder();
- bool ignoreWhitespace;
-
- public void AddLineBreak()
- {
- TrimEndOfAddedText();
- addedText.AppendLine();
- ignoreWhitespace = true;
- }
-
- public void AddText(string textContent)
- {
- if (string.IsNullOrEmpty(textContent))
- return;
- for (int i = 0; i < textContent.Length; i++) {
- char c = textContent[i];
- if (c == '\n' && IsEmptyLineBefore(textContent, i)) {
- AddLineBreak(); // empty line -> line break
- } else if (char.IsWhiteSpace(c)) {
- // any whitespace sequence gets converted to a single space (like HTML)
- if (!ignoreWhitespace) {
- addedText.Append(' ');
- ignoreWhitespace = true;
- }
- } else {
- addedText.Append(c);
- ignoreWhitespace = false;
- }
- }
- }
-
- bool IsEmptyLineBefore(string text, int i)
- {
- // Skip previous whitespace
- do {
- i--;
- } while (i >= 0 && (text[i] == ' ' || text[i] == '\r'));
- // Check if previous non-whitespace char is \n
- return i >= 0 && text[i] == '\n';
- }
-
- void TrimEndOfAddedText()
- {
- while (addedText.Length > 0 && addedText[addedText.Length - 1] == ' ') {
- addedText.Length--;
- }
- }
-
- void FlushAddedText(bool trim)
- {
- if (trim) // trim end of current text element
- TrimEndOfAddedText();
- if (addedText.Length == 0)
- return;
- string text = addedText.ToString();
- addedText.Length = 0;
- AddInline(new Run(text));
- ignoreWhitespace = trim; // trim start of next text element
- }
- }
-}