Browse Source

XML Parser: Track offsets of syntax errors. Updated XmlDOM sample.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4680 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
3605021db0
  1. 10
      samples/XmlDOM/Window1.xaml
  2. 16
      samples/XmlDOM/Window1.xaml.cs
  3. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlObjectCollection.cs
  4. 16
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/Cache.cs

10
samples/XmlDOM/Window1.xaml

@ -1,7 +1,7 @@
<Window x:Class="XmlDOM.Window1" <Window x:Class="XmlDOM.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:clr="clr-namespace:ICSharpCode.AvalonEdit.XmlParser;assembly=ICSharpCode.AvalonEdit" xmlns:clr="clr-namespace:ICSharpCode.AvalonEdit.Xml;assembly=ICSharpCode.AvalonEdit"
xmlns:ic="http://icsharpcode.net/sharpdevelop/avalonedit" xmlns:ic="http://icsharpcode.net/sharpdevelop/avalonedit"
Title="XmlEditor" Height="450" Width="600" Title="XmlEditor" Height="450" Width="600"
> >
@ -9,20 +9,20 @@
<Storyboard x:Key="anim"> <Storyboard x:Key="anim">
<ColorAnimation Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)" To="Transparent" Duration="0:0:4"/> <ColorAnimation Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)" To="Transparent" Duration="0:0:4"/>
</Storyboard> </Storyboard>
<HierarchicalDataTemplate DataType="{x:Type clr:RawDocument}" ItemsSource="{Binding Elements}"> <HierarchicalDataTemplate DataType="{x:Type clr:AXmlDocument}" ItemsSource="{Binding Elements}">
<TextBlock Text="XML Document" Margin="2"/> <TextBlock Text="XML Document" Margin="2"/>
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type clr:RawElement}" ItemsSource="{Binding AttributesAndElements}"> <HierarchicalDataTemplate DataType="{x:Type clr:AXmlElement}" ItemsSource="{Binding AttributesAndElements}">
<TextBlock Text="{Binding StartTag.Name}" Margin="2" Initialized="BindElement"/> <TextBlock Text="{Binding StartTag.Name}" Margin="2" Initialized="BindElement"/>
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type clr:RawAttribute}"> <HierarchicalDataTemplate DataType="{x:Type clr:AXmlAttribute}">
<StackPanel Orientation="Horizontal" Margin="2"> <StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="{Binding Name}" Foreground="Blue" Initialized="BindObject"/> <TextBlock Text="{Binding Name}" Foreground="Blue" Initialized="BindObject"/>
<TextBlock Text="=" VerticalAlignment="Center"/> <TextBlock Text="=" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Value}" Foreground="Blue" Initialized="BindObject"/> <TextBlock Text="{Binding Value}" Foreground="Blue" Initialized="BindObject"/>
</StackPanel> </StackPanel>
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type clr:RawText}" ItemContainerStyle="{x:Null}"> <HierarchicalDataTemplate DataType="{x:Type clr:AXmlText}" ItemContainerStyle="{x:Null}">
<Border BorderBrush="LightGray" Height="1" BorderThickness="1"/> <Border BorderBrush="LightGray" Height="1" BorderThickness="1"/>
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
</Window.Resources> </Window.Resources>

16
samples/XmlDOM/Window1.xaml.cs

@ -18,7 +18,7 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Threading; using System.Windows.Threading;
using ICSharpCode.AvalonEdit.XmlParser; using ICSharpCode.AvalonEdit.Xml;
namespace XmlDOM namespace XmlDOM
{ {
@ -27,7 +27,7 @@ namespace XmlDOM
/// </summary> /// </summary>
public partial class Window1 : Window public partial class Window1 : Window
{ {
XmlParser parser; AXmlParser parser;
bool textDirty = true; bool textDirty = true;
@ -45,7 +45,7 @@ namespace XmlDOM
editor.TextArea.TextView.MouseMove += new MouseEventHandler(editor_TextArea_TextView_MouseMove); editor.TextArea.TextView.MouseMove += new MouseEventHandler(editor_TextArea_TextView_MouseMove);
editor.Document.Changed += delegate { textDirty = true; }; editor.Document.Changed += delegate { textDirty = true; };
parser = new XmlParser(editor.Document); parser = new AXmlParser(editor.Document);
DispatcherTimer timer = new DispatcherTimer(); DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(0.5); timer.Interval = TimeSpan.FromSeconds(0.5);
@ -72,18 +72,18 @@ namespace XmlDOM
void Button_Click(object sender, RoutedEventArgs e) void Button_Click(object sender, RoutedEventArgs e)
{ {
if (!textDirty) return; if (!textDirty) return;
RawDocument doc = parser.Parse(); AXmlDocument doc = parser.Parse();
if (treeView.Items.Count == 0) { if (treeView.Items.Count == 0) {
treeView.Items.Add(doc); treeView.Items.Add(doc);
} }
PrettyPrintXmlVisitor visitor = new PrettyPrintXmlVisitor(); PrettyPrintAXmlVisitor visitor = new PrettyPrintAXmlVisitor();
visitor.VisitDocument(doc); visitor.VisitDocument(doc);
string prettyPrintedText = visitor.Output; string prettyPrintedText = visitor.Output;
if (prettyPrintedText != editor.Document.Text) { if (prettyPrintedText != editor.Document.Text) {
MessageBox.Show("Error - Original and pretty printed version of XML differ"); MessageBox.Show("Error - Original and pretty printed version of XML differ");
} }
markerService.RemoveAll(m => true); markerService.RemoveAll(m => true);
foreach(var error in doc.SyntaxErrors) { foreach(var error in doc.GetSelfAndAllChildren().SelectMany(c => c.SyntaxErrors)) {
var marker = markerService.Create(error.StartOffset, error.EndOffset - error.StartOffset); var marker = markerService.Create(error.StartOffset, error.EndOffset - error.StartOffset);
marker.Tag = error.Message; marker.Tag = error.Message;
marker.BackgroundColor = Color.FromRgb(255, 150, 150); marker.BackgroundColor = Color.FromRgb(255, 150, 150);
@ -94,7 +94,7 @@ namespace XmlDOM
void BindObject(object sender, EventArgs e) void BindObject(object sender, EventArgs e)
{ {
TextBlock textBlock = (TextBlock)sender; TextBlock textBlock = (TextBlock)sender;
RawObject node = (RawObject)textBlock.DataContext; AXmlObject node = (AXmlObject)textBlock.DataContext;
node.Changed += delegate { node.Changed += delegate {
BindingOperations.GetBindingExpression(textBlock, TextBlock.TextProperty).UpdateTarget(); BindingOperations.GetBindingExpression(textBlock, TextBlock.TextProperty).UpdateTarget();
textBlock.Background = new SolidColorBrush(Colors.LightGreen); textBlock.Background = new SolidColorBrush(Colors.LightGreen);
@ -107,7 +107,7 @@ namespace XmlDOM
void BindElement(object sender, EventArgs e) void BindElement(object sender, EventArgs e)
{ {
TextBlock textBlock = (TextBlock)sender; TextBlock textBlock = (TextBlock)sender;
RawElement node = (RawElement)textBlock.DataContext; AXmlElement node = (AXmlElement)textBlock.DataContext;
node.StartTag.Changed += delegate { node.StartTag.Changed += delegate {
BindingOperations.GetBindingExpression(textBlock, TextBlock.TextProperty).UpdateTarget(); BindingOperations.GetBindingExpression(textBlock, TextBlock.TextProperty).UpdateTarget();
textBlock.Background = new SolidColorBrush(Colors.LightGreen); textBlock.Background = new SolidColorBrush(Colors.LightGreen);

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlObjectCollection.cs

@ -18,7 +18,6 @@ namespace ICSharpCode.AvalonEdit.Xml
/// Collection that is publicly read-only and has support /// Collection that is publicly read-only and has support
/// for adding/removing multiple items at a time. /// for adding/removing multiple items at a time.
/// </summary> /// </summary>
// TODO: Specialize
public class AXmlObjectCollection<T>: Collection<T>, INotifyCollectionChanged public class AXmlObjectCollection<T>: Collection<T>, INotifyCollectionChanged
{ {
/// <summary> Occurs when the collection is changed </summary> /// <summary> Occurs when the collection is changed </summary>

16
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/Cache.cs

@ -26,6 +26,12 @@ namespace ICSharpCode.AvalonEdit.Xml
/// </summary> /// </summary>
TextSegmentCollection<TouchedMemoryRange> touchedMemoryRanges = new TextSegmentCollection<TouchedMemoryRange>(); TextSegmentCollection<TouchedMemoryRange> touchedMemoryRanges = new TextSegmentCollection<TouchedMemoryRange>();
/// <summary>
/// Track offsets of syntax errors as well.
/// Objects can not change in the cache, so not need to update it.
/// </summary>
TextSegmentCollection<SyntaxError> syntaxErrors = new TextSegmentCollection<SyntaxError>();
class TouchedMemoryRange: TextSegment class TouchedMemoryRange: TextSegment
{ {
public AXmlObject TouchedByObject { get; set; } public AXmlObject TouchedByObject { get; set; }
@ -37,6 +43,7 @@ namespace ICSharpCode.AvalonEdit.Xml
// Update offsets of all items // Update offsets of all items
parsedItems.UpdateOffsets(change); parsedItems.UpdateOffsets(change);
touchedMemoryRanges.UpdateOffsets(change); touchedMemoryRanges.UpdateOffsets(change);
syntaxErrors.UpdateOffsets(change);
// Remove any items affected by the change // Remove any items affected by the change
AXmlParser.Log("Changed offset {0}", change.Offset); AXmlParser.Log("Changed offset {0}", change.Offset);
@ -66,6 +73,9 @@ namespace ICSharpCode.AvalonEdit.Xml
} }
} }
parsedItems.Add(obj); parsedItems.Add(obj);
foreach(SyntaxError syntaxError in obj.SyntaxErrors) {
syntaxErrors.Add(syntaxError);
}
obj.IsInCache = true; obj.IsInCache = true;
if (maxTouchedLocation != null) { if (maxTouchedLocation != null) {
// location is assumed to be read so the range ends at (location + 1) // location is assumed to be read so the range ends at (location + 1)
@ -100,6 +110,9 @@ namespace ICSharpCode.AvalonEdit.Xml
foreach(AXmlObject r in parents) { foreach(AXmlObject r in parents) {
if (parsedItems.Remove(r)) { if (parsedItems.Remove(r)) {
foreach(SyntaxError syntaxError in r.SyntaxErrors) {
syntaxErrors.Remove(syntaxError);
}
r.IsInCache = false; r.IsInCache = false;
AXmlParser.Log("Removing cached item {0} (it is parent)", r); AXmlParser.Log("Removing cached item {0} (it is parent)", r);
} }
@ -107,6 +120,9 @@ namespace ICSharpCode.AvalonEdit.Xml
} }
if (parsedItems.Remove(obj)) { if (parsedItems.Remove(obj)) {
foreach(SyntaxError syntaxError in obj.SyntaxErrors) {
syntaxErrors.Remove(syntaxError);
}
obj.IsInCache = false; obj.IsInCache = false;
AXmlParser.Log("Removed cached item {0}", obj); AXmlParser.Log("Removed cached item {0}", obj);
} }

Loading…
Cancel
Save