Browse Source

XML Parser: Fixed some bugs. Hereby declaring code ready for use.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4717 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
551566b0c7
  1. 8
      samples/XmlDOM/Window1.xaml.cs
  2. 18
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlContainer.cs
  3. 10
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs
  4. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagMatchingHeuristics.cs
  5. 21
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs

8
samples/XmlDOM/Window1.xaml.cs

@ -72,7 +72,13 @@ namespace XmlDOM @@ -72,7 +72,13 @@ namespace XmlDOM
void Button_Click(object sender, RoutedEventArgs e)
{
if (!textDirty) return;
AXmlDocument doc = parser.Parse();
AXmlDocument doc;
parser.Lock.EnterWriteLock();
try {
doc = parser.Parse();
} finally {
parser.Lock.ExitWriteLock();
}
if (treeView.Items.Count == 0) {
treeView.Items.Add(doc);
}

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

@ -155,7 +155,6 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -155,7 +155,6 @@ namespace ICSharpCode.AvalonEdit.Xml
// item.DebugCheckConsistency(false);
// The parent (or any futher parents) can not be part of parsed document
// becuase otherwise this item would be included twice => safe to change parents
DebugAssert(item.Parent.Document == null, "Old parent is part of document as well");
// Maintain cache constraint by setting parents to null
foreach(AXmlObject ancest in item.GetAncestors().ToList()) {
ancest.Parent = null;
@ -205,9 +204,9 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -205,9 +204,9 @@ namespace ICSharpCode.AvalonEdit.Xml
Assert(child.Document != null, "Child has null document");
Assert(child.Document == this.Document, "Child is in different document");
}
Assert(myStartOffset <= child.StartOffset && child.EndOffset <= myEndOffset, "Child not within parent text range");
if (this.IsCached)
Assert(child.IsCached, "Child not in cache");
Assert(myStartOffset <= child.StartOffset && child.EndOffset <= myEndOffset, "Child not within parent text range");
if (prevChild != null)
Assert(prevChild.EndOffset <= child.StartOffset, "Overlaping childs");
child.DebugCheckConsistency(checkParentPointers);
@ -221,6 +220,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -221,6 +220,7 @@ namespace ICSharpCode.AvalonEdit.Xml
/// </remarks>
internal void UpdateTreeFrom(AXmlContainer srcContainer)
{
this.StartOffset = srcContainer.StartOffset; // Force the update
this.UpdateDataFrom(srcContainer);
RemoveChildrenNotIn(srcContainer.Children);
InsertAndUpdateChildrenFrom(srcContainer.Children);
@ -236,7 +236,8 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -236,7 +236,8 @@ namespace ICSharpCode.AvalonEdit.Xml
if (srcChildren.TryGetValue(child.StartOffset, out srcChild) && child.CanUpdateDataFrom(srcChild)) {
// Keep only one item with given offset (we might have several due to deletion)
srcChildren.Remove(child.StartOffset);
if (child is AXmlContainer)
// If contaner that needs updating
if (child is AXmlContainer && child.LastUpdatedFrom != srcChild)
((AXmlContainer)child).RemoveChildrenNotIn(((AXmlContainer)srcChild).Children);
i++;
} else {
@ -256,10 +257,13 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -256,10 +257,13 @@ namespace ICSharpCode.AvalonEdit.Xml
AXmlObject child = this.Children[i];
AXmlObject srcChild = srcList[i];
if (child.CanUpdateDataFrom(srcChild) /* includes offset test */) {
child.UpdateDataFrom(srcChild);
if (child is AXmlContainer)
((AXmlContainer)child).InsertAndUpdateChildrenFrom(((AXmlContainer)srcChild).Children);
if (child.CanUpdateDataFrom(srcChild)) { // includes offset test
// Does it need updating?
if (child.LastUpdatedFrom != srcChild) {
child.UpdateDataFrom(srcChild);
if (child is AXmlContainer)
((AXmlContainer)child).InsertAndUpdateChildrenFrom(((AXmlContainer)srcChild).Children);
}
} else {
InsertChild(i, srcChild);
}

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

@ -105,11 +105,15 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -105,11 +105,15 @@ namespace ICSharpCode.AvalonEdit.Xml
public AXmlParser(string input)
{
this.input = input;
this.userDocument = new AXmlDocument() { Parser = this };
this.userDocument.Document = this.userDocument;
this.UknonwEntityReferenceIsError = true;
this.TrackedSegments = new TrackedSegmentCollection();
this.lockObject = new ReaderWriterLockSlim();
this.userDocument = new AXmlDocument() { Parser = this };
this.userDocument.Document = this.userDocument;
// Track the document
this.TrackedSegments.AddParsedObject(this.userDocument, null);
this.userDocument.IsCached = false;
}
/// <summary>
@ -165,11 +169,11 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -165,11 +169,11 @@ namespace ICSharpCode.AvalonEdit.Xml
TagReader tagReader = new TagReader(this, input);
List<AXmlObject> tags = tagReader.ReadAllTags();
AXmlDocument parsedDocument = new TagMatchingHeuristics(this, input, tags).ReadDocument();
// parsedDocument.DebugCheckConsistency(false);
tagReader.PrintStringCacheStats();
AXmlParser.Log("Updating main DOM tree...");
userDocument.UpdateTreeFrom(parsedDocument);
userDocument.DebugCheckConsistency(true);
Assert(userDocument.GetSelfAndAllChildren().Count() == parsedDocument.GetSelfAndAllChildren().Count(), "Parsed document and updated document have different number of children");
return userDocument;
}

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

@ -35,9 +35,9 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -35,9 +35,9 @@ namespace ICSharpCode.AvalonEdit.Xml
{
AXmlDocument doc = new AXmlDocument() { Parser = parser };
AXmlParser.Log("Flat stream: {0}", PrintObjects(tags));
// AXmlParser.Log("Flat stream: {0}", PrintObjects(tags));
List<AXmlObject> valid = MatchTags(tags);
AXmlParser.Log("Fixed stream: {0}", PrintObjects(valid));
// AXmlParser.Log("Fixed stream: {0}", PrintObjects(valid));
IEnumerator<AXmlObject> validStream = valid.GetEnumerator();
validStream.MoveNext(); // Move to first
while(true) {

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

@ -58,7 +58,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -58,7 +58,7 @@ namespace ICSharpCode.AvalonEdit.Xml
public void AddParsedObject(AXmlObject obj, int? maxTouchedLocation)
{
AXmlParser.Assert(obj.Length > 0 || obj is AXmlDocument, string.Format("Invalid object {0}. It has zero length.", obj));
// Expensive check
// // Expensive check
// if (obj is AXmlContainer) {
// int objStartOffset = obj.StartOffset;
// int objEndOffset = obj.EndOffset;
@ -82,13 +82,19 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -82,13 +82,19 @@ namespace ICSharpCode.AvalonEdit.Xml
}
}
/// <summary> Removes object with all of its children </summary>
/// <summary> Removes object with all of its non-cached children </summary>
public void RemoveParsedObject(AXmlObject obj)
{
foreach(AXmlObject child in obj.GetSelfAndAllChildren()) {
bool found = segments.Remove(child);
AXmlParser.DebugAssert(found, string.Format("{0} not found", child));
RemoveSyntaxErrorsOf(child);
// Cached objects may be used in the future - do not remove them
if (obj.IsCached) return;
segments.Remove(obj);
RemoveSyntaxErrorsOf(obj);
AXmlParser.Log("Stopped tracking {0}", obj);
if (obj is AXmlContainer) {
foreach(AXmlObject child in ((AXmlContainer)obj).Children) {
RemoveParsedObject(child);
}
}
}
@ -102,8 +108,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -102,8 +108,7 @@ namespace ICSharpCode.AvalonEdit.Xml
public void RemoveSyntaxErrorsOf(AXmlObject obj)
{
foreach(SyntaxError syntaxError in obj.MySyntaxErrors) {
bool found = segments.Remove(syntaxError);
AXmlParser.DebugAssert(found, string.Format("{0} not found", syntaxError));
segments.Remove(syntaxError);
}
}

Loading…
Cancel
Save