Browse Source

AvalonEdit:

Improved caret/selection behavior on the border of read-only sections.
Fixed some FxCop warnings.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4907 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
3c3ff30a5b
  1. 135
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Editing/TextSegmentReadOnlySectionTests.cs
  2. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/ICSharpCode.AvalonEdit.Tests.csproj
  3. 14
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs
  4. 20
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
  5. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
  6. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
  7. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  8. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlAttribute.cs
  9. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlAttributeCollection.cs
  10. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlContainer.cs
  11. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlDocument.cs
  12. 13
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlElement.cs
  13. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlObject.cs
  14. 11
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs
  15. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlTag.cs
  16. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlText.cs
  17. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/CanonicalPrintAXmlVisitor.cs
  18. 49
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/InternalException.cs
  19. 10
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs
  20. 17
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagReader.cs
  21. 6
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TokenReader.cs
  22. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs

135
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/Editing/TextSegmentReadOnlySectionTests.cs

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.AvalonEdit.Document;
using System;
using System.Linq;
using NUnit.Framework;
namespace ICSharpCode.AvalonEdit.Editing.Tests
{
[TestFixture]
public class TextSegmentReadOnlySectionTests
{
TextSegmentCollection<TextSegment> segments;
TextSegmentReadOnlySectionProvider<TextSegment> provider;
[SetUp]
public void SetUp()
{
segments = new TextSegmentCollection<TextSegment>();
provider = new TextSegmentReadOnlySectionProvider<TextSegment>(segments);
}
[Test]
public void InsertionPossibleWhenNothingIsReadOnly()
{
Assert.IsTrue(provider.CanInsert(0));
Assert.IsTrue(provider.CanInsert(100));
}
[Test]
public void DeletionPossibleWhenNothingIsReadOnly()
{
var result = provider.GetDeletableSegments(new SimpleSegment(10, 20)).ToList();
Assert.AreEqual(1, result.Count);
Assert.AreEqual(10, result[0].Offset);
Assert.AreEqual(20, result[0].Length);
}
[Test]
public void InsertionPossibleBeforeReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 10, EndOffset = 15 });
Assert.IsTrue(provider.CanInsert(5));
}
[Test]
public void InsertionPossibleAtStartOfReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 10, EndOffset = 15 });
Assert.IsTrue(provider.CanInsert(10));
}
[Test]
public void InsertionImpossibleInsideReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 10, EndOffset = 15 });
Assert.IsFalse(provider.CanInsert(11));
Assert.IsFalse(provider.CanInsert(12));
Assert.IsFalse(provider.CanInsert(13));
Assert.IsFalse(provider.CanInsert(14));
}
[Test]
public void InsertionPossibleAtEndOfReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 10, EndOffset = 15 });
Assert.IsTrue(provider.CanInsert(15));
}
[Test]
public void InsertionPossibleBetweenReadOnlySegments()
{
segments.Add(new TextSegment { StartOffset = 10, EndOffset = 15 });
segments.Add(new TextSegment { StartOffset = 15, EndOffset = 20 });
Assert.IsTrue(provider.CanInsert(15));
}
[Test]
public void DeletionImpossibleInReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 10, Length = 5 });
var result = provider.GetDeletableSegments(new SimpleSegment(11, 2)).ToList();
Assert.AreEqual(0, result.Count);
}
[Test]
public void DeletionAroundReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 20, Length = 5 });
var result = provider.GetDeletableSegments(new SimpleSegment(15, 16)).ToList();
Assert.AreEqual(2, result.Count);
Assert.AreEqual(15, result[0].Offset);
Assert.AreEqual(5, result[0].Length);
Assert.AreEqual(25, result[1].Offset);
Assert.AreEqual(6, result[1].Length);
}
[Test]
public void DeleteLastCharacterInReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 20, Length = 5 });
var result = provider.GetDeletableSegments(new SimpleSegment(24, 1)).ToList();
Assert.AreEqual(0, result.Count);
/* // we would need this result for the old Backspace code so that the last character doesn't get selected:
Assert.AreEqual(1, result.Count);
Assert.AreEqual(25, result[0].Offset);
Assert.AreEqual(0, result[0].Length);*/
}
[Test]
public void DeleteFirstCharacterInReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 20, Length = 5 });
var result = provider.GetDeletableSegments(new SimpleSegment(20, 1)).ToList();
Assert.AreEqual(0, result.Count);
/* // we would need this result for the old Delete code so that the first character doesn't get selected:
Assert.AreEqual(1, result.Count);
Assert.AreEqual(2, result[0].Offset);
Assert.AreEqual(0, result[0].Length);*/
}
[Test]
public void DeleteWholeReadOnlySegment()
{
segments.Add(new TextSegment { StartOffset = 20, Length = 5 });
var result = provider.GetDeletableSegments(new SimpleSegment(20, 5)).ToList();
Assert.AreEqual(0, result.Count);
}
}
}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit.Tests/ICSharpCode.AvalonEdit.Tests.csproj

@ -71,6 +71,7 @@ @@ -71,6 +71,7 @@
<Compile Include="Document\ChangeTrackingTest.cs" />
<Compile Include="Document\TextAnchorTest.cs" />
<Compile Include="Document\TextSegmentTreeTest.cs" />
<Compile Include="Editing\TextSegmentReadOnlySectionTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Document\CollapsingTests.cs" />
<Compile Include="Document\HeightTests.cs" />
@ -90,6 +91,7 @@ @@ -90,6 +91,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Document" />
<Folder Include="Editing" />
<Folder Include="Utils" />
<Folder Include="XmlParser" />
</ItemGroup>

14
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs

@ -85,7 +85,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -85,7 +85,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (PositionChanged != null) {
PositionChanged(this, EventArgs.Empty);
}
Debug.WriteLine("Caret position changed to " + value);
Log("Caret position changed to " + value);
if (visible)
Show();
}
@ -232,6 +232,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -232,6 +232,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (!visualColumnValid) {
TextDocument document = textArea.Document;
if (document != null) {
Debug.WriteLine("Explicit validation of caret column");
var documentLine = document.GetLineByNumber(position.Line);
RevalidateVisualColumn(textView.GetOrConstructVisualLine(documentLine));
}
@ -329,7 +330,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -329,7 +330,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public void Show()
{
Debug.WriteLine("Caret.Show()");
Log("Caret.Show()");
visible = true;
if (!showScheduled) {
showScheduled = true;
@ -372,7 +373,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -372,7 +373,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public void Hide()
{
Debug.WriteLine("Caret.Hide()");
Log("Caret.Hide()");
visible = false;
if (hasWin32Caret) {
Win32.DestroyCaret();
@ -383,6 +384,13 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -383,6 +384,13 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
[Conditional("DEBUG")]
static void Log(string text)
{
// commented out to make debug output less noisy - add back if there are any problems with the caret
//Debug.WriteLine(text);
}
/// <summary>
/// Gets/Sets the color of the caret.
/// </summary>

20
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs

@ -226,8 +226,23 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -226,8 +226,23 @@ namespace ICSharpCode.AvalonEdit.Editing
// call BeginUpdate before running the 'selectingCommand'
// so that undoing the delete does not select the deleted character
using (textArea.Document.RunUpdate()) {
if (textArea.Selection.IsEmpty)
if (textArea.Selection.IsEmpty) {
TextViewPosition oldCaretPosition = textArea.Caret.Position;
selectingCommand.Execute(args.Parameter, textArea);
bool hasSomethingDeletable = false;
foreach (ISegment s in textArea.Selection.Segments) {
if (textArea.GetDeletableSegments(s).Length > 0) {
hasSomethingDeletable = true;
break;
}
}
if (!hasSomethingDeletable) {
// If nothing in the selection is deletable; then reset caret+selection
// to the previous value. This prevents the caret from moving through read-only sections.
textArea.Caret.Position = oldCaretPosition;
textArea.Selection = Selection.Empty;
}
}
textArea.RemoveSelectedText();
}
textArea.Caret.BringCaretToView();
@ -362,7 +377,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -362,7 +377,8 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line);
textArea.Document.Remove(currentLine.Offset, currentLine.TotalLength);
textArea.Selection = new SimpleSelection(currentLine.Offset, currentLine.EndOffset);
textArea.RemoveSelectedText();
args.Handled = true;
}
}

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs

@ -86,7 +86,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -86,7 +86,9 @@ namespace ICSharpCode.AvalonEdit.Editing
textArea.Document.Remove(segmentsToDelete[i]);
}
}
textArea.Selection = Selection.Empty;
if (segmentsToDelete.Length != 0) {
textArea.Selection = Selection.Empty;
}
}
}
}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs

@ -351,7 +351,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -351,7 +351,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
ensureSelectionValidRequested = false;
if (allowCaretOutsideSelection == 0) {
if (!selection.Contains(caret.Offset)) {
if (!selection.IsEmpty && !selection.Contains(caret.Offset)) {
Debug.WriteLine("Resetting selection because caret is outside");
this.Selection = Selection.Empty;
}

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -321,6 +321,7 @@ @@ -321,6 +321,7 @@
<Compile Include="Xml\AXmlTag.cs" />
<Compile Include="Xml\AXmlText.cs" />
<Compile Include="Xml\CanonicalPrintAXmlVisitor.cs" />
<Compile Include="Xml\InternalException.cs" />
<Compile Include="Xml\TrackedSegmentCollection.cs">
<DependentUpon>AXmlParser.cs</DependentUpon>
</Compile>

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlAttribute.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -80,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -80,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.Xml
AXmlElement elem = this.ParentElement;
if (elem != null) {
return elem.ReslovePrefix(this.Prefix);
return elem.ResolvePrefix(this.Prefix);
}
return NoNamespace; // Orphaned attribute
}
@ -126,7 +127,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -126,7 +127,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("[{0} '{1}{2}{3}']", base.ToString(), this.Name, this.EqualsSign, this.Value);
return string.Format(CultureInfo.InvariantCulture, "[{0} '{1}{2}{3}']", base.ToString(), this.Name, this.EqualsSign, this.Value);
}
}
}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlAttributeCollection.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -16,7 +16,7 @@ namespace ICSharpCode.AvalonEdit.Xml
public class AXmlAttributeCollection: FilteredCollection<AXmlAttribute, AXmlObjectCollection<AXmlObject>>
{
/// <summary> Empty unbound collection </summary>
public static AXmlAttributeCollection Empty = new AXmlAttributeCollection();
public static readonly AXmlAttributeCollection Empty = new AXmlAttributeCollection();
/// <summary> Create unbound collection </summary>
protected AXmlAttributeCollection() {}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlContainer.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -28,7 +28,7 @@ namespace ICSharpCode.AvalonEdit.Xml
public AXmlObjectCollection<AXmlObject> Children { get; private set; }
/// <summary> Create new container </summary>
public AXmlContainer()
protected AXmlContainer()
{
this.Children = new AXmlObjectCollection<AXmlObject>();
}

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlDocument.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -66,7 +67,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -66,7 +67,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("[{0} Chld:{1}]", base.ToString(), this.Children.Count);
return string.Format(CultureInfo.InvariantCulture, "[{0} Chld:{1}]", base.ToString(), this.Children.Count);
}
}
}

13
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlElement.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -144,15 +145,15 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -144,15 +145,15 @@ namespace ICSharpCode.AvalonEdit.Xml
get {
string prefix = this.Prefix;
if (string.IsNullOrEmpty(prefix)) {
return FindDefaultNamesapce();
return FindDefaultNamespace();
} else {
return ReslovePrefix(prefix);
return ResolvePrefix(prefix);
}
}
}
/// <summary> Find the defualt namesapce for this context </summary>
public string FindDefaultNamesapce()
/// <summary> Find the defualt namespace for this context </summary>
public string FindDefaultNamespace()
{
AXmlElement current = this;
while(current != null) {
@ -167,7 +168,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -167,7 +168,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// Recursively resolve given prefix in this context. Prefix must have some value.
/// </summary>
/// <returns> Empty string if prefix is not found </returns>
public string ReslovePrefix(string prefix)
public string ResolvePrefix(string prefix)
{
if (string.IsNullOrEmpty(prefix)) throw new ArgumentException("No prefix given", "prefix");
@ -223,7 +224,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -223,7 +224,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("[{0} '{1}' Attr:{2} Chld:{3} Nest:{4}]", base.ToString(), this.Name, this.HasStartOrEmptyTag ? this.StartTag.Children.Count : 0, this.Children.Count, this.IsProperlyNested ? "Ok" : "Bad");
return string.Format(CultureInfo.InvariantCulture, "[{0} '{1}' Attr:{2} Chld:{3} Nest:{4}]", base.ToString(), this.Name, this.HasStartOrEmptyTag ? this.StartTag.Children.Count : 0, this.Children.Count, this.IsProperlyNested ? "Ok" : "Bad");
}
}
}

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlObject.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -45,7 +46,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -45,7 +46,7 @@ namespace ICSharpCode.AvalonEdit.Xml
internal AXmlDocument Document { get; set; }
/// <summary> Creates new object </summary>
public AXmlObject()
protected AXmlObject()
{
this.LastUpdatedFrom = this;
}
@ -129,7 +130,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -129,7 +130,7 @@ namespace ICSharpCode.AvalonEdit.Xml
protected static void Assert(bool condition, string message)
{
if (!condition) {
throw new Exception("Assertion failed: " + message);
throw new InternalException("Assertion failed: " + message);
}
}
@ -138,7 +139,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -138,7 +139,7 @@ namespace ICSharpCode.AvalonEdit.Xml
protected static void DebugAssert(bool condition, string message)
{
if (!condition) {
throw new Exception("Assertion failed: " + message);
throw new InternalException("Assertion failed: " + message);
}
}
@ -229,7 +230,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -229,7 +230,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("{0}({1}-{2})", this.GetType().Name.Remove(0, 4), this.StartOffset, this.EndOffset);
return string.Format(CultureInfo.InvariantCulture, "{0}({1}-{2})", this.GetType().Name.Remove(0, 4), this.StartOffset, this.EndOffset);
}
#region Helpper methods

11
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs

@ -6,12 +6,13 @@ @@ -6,12 +6,13 @@
// </file>
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using ICSharpCode.AvalonEdit.Document;
using System.Threading;
namespace ICSharpCode.AvalonEdit.Xml
{
@ -115,7 +116,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -115,7 +116,7 @@ namespace ICSharpCode.AvalonEdit.Xml
internal static void Assert(bool condition, string message)
{
if (!condition) {
throw new Exception("Assertion failed: " + message);
throw new InternalException("Assertion failed: " + message);
}
}
@ -124,14 +125,14 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -124,14 +125,14 @@ namespace ICSharpCode.AvalonEdit.Xml
internal static void DebugAssert(bool condition, string message)
{
if (!condition) {
throw new Exception("Assertion failed: " + message);
throw new InternalException("Assertion failed: " + message);
}
}
[Conditional("DEBUG")]
internal static void Log(string text, params object[] pars)
{
System.Diagnostics.Debug.WriteLine(string.Format("XML: " + text, pars));
System.Diagnostics.Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "XML: " + text, pars));
}
/// <summary>

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlTag.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -22,7 +23,9 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -22,7 +23,9 @@ namespace ICSharpCode.AvalonEdit.Xml
public class AXmlTag: AXmlContainer
{
/// <summary> These identify the start of DTD elements </summary>
public static readonly string[] DTDNames = new string[] {"<!DOCTYPE", "<!NOTATION", "<!ELEMENT", "<!ATTLIST", "<!ENTITY"};
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="ReadOnlyCollection is immutable")]
public static readonly ReadOnlyCollection<string> DtdNames = new ReadOnlyCollection<string>(
new string[] {"<!DOCTYPE", "<!NOTATION", "<!ELEMENT", "<!ATTLIST", "<!ENTITY" } );
/// <summary> Opening bracket - usually "&lt;" </summary>
public string OpeningBracket { get; internal set; }
@ -46,7 +49,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -46,7 +49,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <summary> True if tag starts with "&lt;![CDATA[" </summary>
public bool IsCData { get { return OpeningBracket == "<![CDATA["; } }
/// <summary> True if tag starts with one of the DTD starts </summary>
public bool IsDocumentType { get { return DTDNames.Contains(OpeningBracket); } }
public bool IsDocumentType { get { return DtdNames.Contains(OpeningBracket); } }
/// <summary> True if tag starts with "&lt;!" </summary>
public bool IsUnknownBang { get { return OpeningBracket == "<!"; } }
@ -103,7 +106,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -103,7 +106,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("[{0} '{1}{2}{3}' Attr:{4}]", base.ToString(), this.OpeningBracket, this.Name, this.ClosingBracket, this.Children.Count);
return string.Format(CultureInfo.InvariantCulture, "[{0} '{1}{2}{3}' Attr:{4}]", base.ToString(), this.OpeningBracket, this.Name, this.ClosingBracket, this.Children.Count);
}
}
}

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlText.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -28,6 +29,8 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -28,6 +29,8 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <summary> The text with all entity references resloved </summary>
public string Value { get; set; }
/// <summary> True if the text contains only whitespace characters </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace",
Justification = "System.Xml also uses 'Whitespace'")]
public bool ContainsOnlyWhitespace { get; set; }
/// <inheritdoc/>
@ -57,7 +60,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -57,7 +60,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <inheritdoc/>
public override string ToString()
{
return string.Format("[{0} Text.Length={1}]", base.ToString(), this.EscapedValue.Length);
return string.Format(CultureInfo.InvariantCulture, "[{0} Text.Length={1}]", base.ToString(), this.EscapedValue.Length);
}
}
}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/CanonicalPrintAXmlVisitor.cs

@ -104,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -104,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.Xml
sb.Append(Escape(text.Value));
}
string Escape(string text)
static string Escape(string text)
{
return text
.Replace("&", "&amp;")

49
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/InternalException.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.AvalonEdit.Xml
{
/// <summary>
/// Exception used for internal errors in XML parser.
/// This exception indicates a bug in AvalonEdit.
/// </summary>
[Serializable()]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic", Justification = "This exception is not public because it is not supposed to be caught by user code - it indicates a bug in AvalonEdit.")]
class InternalException : Exception
{
/// <summary>
/// Creates a new InternalException instance.
/// </summary>
public InternalException() : base()
{
}
/// <summary>
/// Creates a new InternalException instance.
/// </summary>
public InternalException(string message) : base(message)
{
}
/// <summary>
/// Creates a new InternalException instance.
/// </summary>
public InternalException(string message, Exception innerException) : base(message, innerException)
{
}
/// <summary>
/// Creates a new InternalException instance.
/// </summary>
protected InternalException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

10
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -56,7 +56,7 @@ namespace ICSharpCode.AvalonEdit.Xml
}
// Check well formed
foreach(AXmlTag xmlDeclaration in doc.Children.OfType<AXmlTag>().Where(t => t.IsProcessingInstruction && t.Name.ToLower() == "xml")) {
foreach(AXmlTag xmlDeclaration in doc.Children.OfType<AXmlTag>().Where(t => t.IsProcessingInstruction && string.Equals(t.Name, "xml", StringComparison.OrdinalIgnoreCase))) {
if (xmlDeclaration.StartOffset != 0)
TagReader.OnSyntaxError(doc, xmlDeclaration.StartOffset, xmlDeclaration.StartOffset + 5,
"XML declaration must be at the start of document");
@ -87,7 +87,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -87,7 +87,7 @@ namespace ICSharpCode.AvalonEdit.Xml
return doc;
}
AXmlObject ReadSingleObject(IEnumerator<AXmlObject> objStream)
static AXmlObject ReadSingleObject(IEnumerator<AXmlObject> objStream)
{
AXmlObject obj = objStream.Current;
objStream.MoveNext();
@ -407,7 +407,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -407,7 +407,7 @@ namespace ICSharpCode.AvalonEdit.Xml
}
#region Helper methods
/*
string PrintObjects(IEnumerable<AXmlObject> objs)
{
StringBuilder sb = new StringBuilder();
@ -429,12 +429,12 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -429,12 +429,12 @@ namespace ICSharpCode.AvalonEdit.Xml
} else if (obj is AXmlText) {
sb.Append('~');
} else {
throw new Exception("Should not be here: " + obj);
throw new InternalException("Should not be here: " + obj);
}
}
return sb.ToString();
}
*/
#endregion
}
}

17
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagReader.cs

@ -149,7 +149,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -149,7 +149,7 @@ namespace ICSharpCode.AvalonEdit.Xml
} else if (tag.IsUnknownBang) {
text = ReadText(TextType.UnknownBang);
} else {
throw new Exception(string.Format("Unknown opening bracket '{0}'", tag.OpeningBracket));
throw new InternalException(string.Format(CultureInfo.InvariantCulture, "Unknown opening bracket '{0}'", tag.OpeningBracket));
}
// Enumerate
text = text.ToList();
@ -186,7 +186,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -186,7 +186,7 @@ namespace ICSharpCode.AvalonEdit.Xml
} else if (tag.IsDocumentType) {
if (tag.ClosingBracket != ">") OnSyntaxError(tag, brStart, brEnd, "'>' expected");
} else {
throw new Exception(string.Format("Unknown opening bracket '{0}'", tag.OpeningBracket));
throw new InternalException(string.Format(CultureInfo.InvariantCulture, "Unknown opening bracket '{0}'", tag.OpeningBracket));
}
// Attribute name may not apper multiple times
@ -220,7 +220,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -220,7 +220,7 @@ namespace ICSharpCode.AvalonEdit.Xml
} else if (TryRead("[CDATA[")) {
return "<![CDATA[";
} else {
foreach(string dtdName in AXmlTag.DTDNames) {
foreach(string dtdName in AXmlTag.DtdNames) {
// the dtdName includes "<!"
if (TryRead(dtdName.Remove(0, 2))) return dtdName;
}
@ -230,7 +230,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -230,7 +230,7 @@ namespace ICSharpCode.AvalonEdit.Xml
return "<";
}
} else {
throw new Exception("'<' expected");
throw new InternalException("'<' expected");
}
}
@ -579,12 +579,13 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -579,12 +579,13 @@ namespace ICSharpCode.AvalonEdit.Xml
public static void OnSyntaxError(AXmlObject obj, int start, int end, string message, params object[] args)
{
if (end <= start) end = start + 1;
AXmlParser.Log("Syntax error ({0}-{1}): {2}", start, end, string.Format(message, args));
string formattedMessage = string.Format(CultureInfo.InvariantCulture, message, args);
AXmlParser.Log("Syntax error ({0}-{1}): {2}", start, end, formattedMessage);
obj.AddSyntaxError(new SyntaxError() {
Object = obj,
StartOffset = start,
EndOffset = end,
Message = string.Format(message, args),
Message = formattedMessage,
});
}
@ -624,7 +625,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -624,7 +625,7 @@ namespace ICSharpCode.AvalonEdit.Xml
}
}
string NormalizeEndOfLine(string text)
static string NormalizeEndOfLine(string text)
{
return text.Replace("\r\n", "\n").Replace("\r", "\n");
}
@ -678,7 +679,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -678,7 +679,7 @@ namespace ICSharpCode.AvalonEdit.Xml
// Resolve the name
string replacement;
if (name == "") {
if (name.Length == 0) {
replacement = null;
OnSyntaxError(owner, errorLoc + 1, errorLoc + 1, "Entity name expected");
} else if (name == "amp") {

6
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TokenReader.cs

@ -66,13 +66,13 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -66,13 +66,13 @@ namespace ICSharpCode.AvalonEdit.Xml
protected void Skip(int count)
{
if (currentLocation + count > inputLength) throw new Exception("Skipping after the end of file");
AXmlParser.Assert(currentLocation + count <= inputLength, "Skipping after the end of file");
currentLocation += count;
}
protected void GoBack(int oldLocation)
{
if (oldLocation > currentLocation) throw new Exception("Trying to move forward");
AXmlParser.Assert(oldLocation <= currentLocation, "Trying to move forward");
maxTouchedLocation = Math.Max(maxTouchedLocation, currentLocation);
currentLocation = oldLocation;
}
@ -269,7 +269,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -269,7 +269,7 @@ namespace ICSharpCode.AvalonEdit.Xml
protected string GetText(int start, int end)
{
if (end > currentLocation) throw new Exception("Reading ahead of current location");
AXmlParser.Assert(end <= currentLocation, "Reading ahead of current location");
if (start == inputLength && end == inputLength) {
return string.Empty;
} else {

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs

@ -7,7 +7,9 @@ @@ -7,7 +7,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Xml
@ -70,7 +72,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -70,7 +72,7 @@ namespace ICSharpCode.AvalonEdit.Xml
public void AddParsedObject(AXmlObject obj, int? maxTouchedLocation)
{
if (!(obj.Length > 0 || obj is AXmlDocument))
AXmlParser.Assert(false, string.Format("Invalid object {0}. It has zero length.", obj));
AXmlParser.Assert(false, string.Format(CultureInfo.InvariantCulture, "Invalid object {0}. It has zero length.", obj));
// // Expensive check
// if (obj is AXmlContainer) {
// int objStartOffset = obj.StartOffset;

Loading…
Cancel
Save