diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs index 971d2bebab..3fbc02c809 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs @@ -50,8 +50,8 @@ namespace ICSharpCode.XamlBinding return false; } - AXmlParser axmlParser; - ICSharpCode.SharpDevelop.ITextBuffer lastParsedContent; + AXmlParser axmlParser = new AXmlParser(); + volatile ICSharpCode.SharpDevelop.ITextBufferVersion lastParsedVersion; /// /// Parse the given text and enter read lock. @@ -59,21 +59,24 @@ namespace ICSharpCode.XamlBinding /// public IDisposable ParseAndLock(ICSharpCode.SharpDevelop.ITextBuffer fileContent) { - // Is fileContent newer? - if (lastParsedContent == null || fileContent.Version.CompareAge(lastParsedContent.Version) > 0) { + // Copy to ensure thread-safety + var lastVer = lastParsedVersion; + if (lastVer == null || // First parse + fileContent.Version == null || // Versioning not supported + fileContent.Version.CompareAge(lastVer) > 0) // Is fileContent newer? + { axmlParser.Lock.EnterWriteLock(); // Dobuble check, now that we are thread-safe - if (lastParsedContent == null) { - // First parse - axmlParser = new AXmlParser(); + if (lastParsedVersion == null || fileContent.Version == null) { + // First parse or verisoning not supported axmlParser.Parse(fileContent.Text, null); - lastParsedContent = fileContent; - } else if (fileContent.Version.CompareAge(lastParsedContent.Version) > 0) { + lastParsedVersion = fileContent.Version; + } else if (fileContent.Version.CompareAge(lastParsedVersion) > 0) { // Incremental parse - var changes = lastParsedContent.Version.GetChangesTo(fileContent.Version). + var changes = lastParsedVersion.GetChangesTo(fileContent.Version). Select(c => new DocumentChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText)); axmlParser.Parse(fileContent.Text, changes); - lastParsedContent = fileContent; + lastParsedVersion = fileContent.Version; } else { // fileContent is older - no need to parse } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs index 079f7a4013..96bc1fb4ae 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs @@ -136,8 +136,10 @@ namespace ICSharpCode.AvalonEdit.Xml /// /// Incrementaly parse the given text. /// You have to hold the write lock. - /// 'changesSinceLastParse' can be null on the first call. /// + /// + /// Changes since last parse. Null will cause full reparse. + /// public AXmlDocument Parse(string input, IEnumerable changesSinceLastParse) { if (!Lock.IsWriteLockHeld) @@ -146,6 +148,8 @@ namespace ICSharpCode.AvalonEdit.Xml // Use changes to invalidate cache if (changesSinceLastParse != null) { this.TrackedSegments.UpdateOffsetsAndInvalidate(changesSinceLastParse); + } else { + this.TrackedSegments.InvalidateAll(); } TagReader tagReader = new TagReader(this, input); diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs index 1b0055a484..767041796f 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs @@ -54,6 +54,18 @@ namespace ICSharpCode.AvalonEdit.Xml } } + /// + /// Invlidates all objects. That is, the whole document has changed. + /// + /// We still have to keep the items becuase they might be in the document + public void InvalidateAll() + { + AXmlParser.Log("Invalidating all objects"); + foreach(AXmlObject obj in segments.OfType()) { + obj.IsCached = false; + } + } + /// Add object to cache, optionally adding extra memory tracking public void AddParsedObject(AXmlObject obj, int? maxTouchedLocation) {