Skip to content

Commit

Permalink
Merge pull request #213 from AvaloniaUI/protect-transformer-exceptions
Browse files Browse the repository at this point in the history
Try/catch exceptions for override methods and events
  • Loading branch information
danipen authored Feb 22, 2022
2 parents 3e307d9 + d62fa46 commit 272a695
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 39 deletions.
18 changes: 17 additions & 1 deletion src/AvaloniaEdit.TextMate/GenericLineTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;

using Avalonia.Media;
using AvaloniaEdit.Document;
using AvaloniaEdit.Rendering;
Expand All @@ -6,9 +8,23 @@ namespace AvaloniaEdit.TextMate
{
public abstract class GenericLineTransformer : DocumentColorizingTransformer
{
private Action<Exception> _exceptionHandler;

public GenericLineTransformer(Action<Exception> exceptionHandler)
{
_exceptionHandler = exceptionHandler;
}

protected override void ColorizeLine(DocumentLine line)
{
TransformLine(line, CurrentContext);
try
{
TransformLine(line, CurrentContext);
}
catch (Exception ex)
{
_exceptionHandler?.Invoke(ex);
}
}

protected abstract void TransformLine(DocumentLine line, ITextRunConstructionContext context);
Expand Down
3 changes: 2 additions & 1 deletion src/AvaloniaEdit.TextMate/TextMate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ TextMateColoringTransformer GetOrCreateTransformer()

if (transformer is null)
{
transformer = new TextMateColoringTransformer(_editor.TextArea.TextView);
transformer = new TextMateColoringTransformer(
_editor.TextArea.TextView, _exceptionHandler);

_editor.TextArea.TextView.LineTransformers.Add(transformer);
}
Expand Down
55 changes: 39 additions & 16 deletions src/AvaloniaEdit.TextMate/TextMateColoringTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@ public class TextMateColoringTransformer :
private TMModel _model;
private TextDocument _document;
private TextView _textView;
private Action<Exception> _exceptionHandler;

private volatile int _firstVisibleLineIndex = -1;
private volatile int _lastVisibleLineIndex = -1;

private readonly Dictionary<int, IBrush> _brushes;
private TextSegmentCollection<TextTransformation> _transformations;

public TextMateColoringTransformer(TextView textView)
public TextMateColoringTransformer(
TextView textView,
Action<Exception> exceptionHandler)
: base(exceptionHandler)
{
_textView = textView;
_exceptionHandler = exceptionHandler;

_brushes = new Dictionary<int, IBrush>();
_textView.VisualLinesChanged += TextView_VisualLinesChanged;
}
Expand All @@ -51,11 +57,18 @@ public void SetModel(TextDocument document, TMModel model)

private void TextView_VisualLinesChanged(object sender, EventArgs e)
{
if (!_textView.VisualLinesValid || _textView.VisualLines.Count == 0)
return;
try
{
if (!_textView.VisualLinesValid || _textView.VisualLines.Count == 0)
return;

_firstVisibleLineIndex = _textView.VisualLines[0].FirstDocumentLine.LineNumber - 1;
_lastVisibleLineIndex = _textView.VisualLines[_textView.VisualLines.Count - 1].LastDocumentLine.LineNumber - 1;
_firstVisibleLineIndex = _textView.VisualLines[0].FirstDocumentLine.LineNumber - 1;
_lastVisibleLineIndex = _textView.VisualLines[_textView.VisualLines.Count - 1].LastDocumentLine.LineNumber - 1;
}
catch (Exception ex)
{
_exceptionHandler?.Invoke(ex);
}
}

public void Dispose()
Expand Down Expand Up @@ -103,21 +116,31 @@ IBrush ForegroundTextTransformation.IColorMap.GetBrush(int colorId)

protected override void TransformLine(DocumentLine line, ITextRunConstructionContext context)
{
int i = line.LineNumber;
try
{
if (_model == null)
return;

var tokens = _model.GetLineTokens(i - 1);
int i = line.LineNumber;

if (tokens == null)
return;
var tokens = _model.GetLineTokens(i - 1);

RemoveLineTransformations(i);
ProcessTokens(i, tokens);
if (tokens == null)
return;

var transformsInLine = _transformations.FindOverlappingSegments(line);
RemoveLineTransformations(i);
ProcessTokens(i, tokens);

foreach (var transform in transformsInLine)
var transformsInLine = _transformations.FindOverlappingSegments(line);

foreach (var transform in transformsInLine)
{
transform.Transform(this, line);
}
}
catch (Exception ex)
{
transform.Transform(this, line);
_exceptionHandler?.Invoke(ex);
}
}

Expand Down Expand Up @@ -154,7 +177,7 @@ private void ProcessTokens(int lineNumber, List<TMToken> tokens)
fontStyle = themeRule.fontStyle;
}

_transformations.Add(new ForegroundTextTransformation(this, lineOffset + startIndex,
_transformations.Add(new ForegroundTextTransformation(this, _exceptionHandler, lineOffset + startIndex,
lineOffset + endIndex, foreground, background, fontStyle));
}
}
Expand All @@ -175,7 +198,7 @@ public void ModelTokensChanged(ModelTokensChangedEvent e)
if (e.Ranges == null)
return;

if (_model.IsStopped)
if (_model == null || _model.IsStopped)
return;

int firstChangedLineIndex = int.MaxValue;
Expand Down
48 changes: 27 additions & 21 deletions src/AvaloniaEdit.TextMate/TextTransformation.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;

using Avalonia.Media;

using AvaloniaEdit.Document;

using TextMateSharp.Model;

namespace AvaloniaEdit.TextMate
{
public abstract class TextTransformation : TextSegment
Expand All @@ -27,50 +24,61 @@ public interface IColorMap
IBrush GetBrush(int color);
}

int _foreground;
int _background;
int _fontStyle;
private IColorMap _colorMap;
private Action<Exception> _exceptionHandler;
private int _foreground;
private int _background;
private int _fontStyle;

public ForegroundTextTransformation(
IColorMap colorMap,
Action<Exception> exceptionHandler,
int startOffset,
int endOffset,
int foreground,
int background,
int fontStyle) : base(startOffset, endOffset)
{
_colorMap = colorMap;
_exceptionHandler = exceptionHandler;
_foreground = foreground;
_background = background;
_fontStyle = fontStyle;
}

public override void Transform(GenericLineTransformer transformer, DocumentLine line)
{
if (Length == 0)
try
{
return;
}
if (Length == 0)
{
return;
}

var formattedOffset = 0;
var endOffset = line.EndOffset;
var formattedOffset = 0;
var endOffset = line.EndOffset;

if (StartOffset > line.Offset)
{
formattedOffset = StartOffset - line.Offset;
}
if (StartOffset > line.Offset)
{
formattedOffset = StartOffset - line.Offset;
}

if (EndOffset < line.EndOffset)
{
endOffset = EndOffset;
}
if (EndOffset < line.EndOffset)
{
endOffset = EndOffset;
}

transformer.SetTextStyle(line, formattedOffset, endOffset - line.Offset - formattedOffset,
_colorMap.GetBrush(_foreground),
_colorMap.GetBrush(_background),
GetFontStyle(),
GetFontWeight(),
IsUnderline());
}
catch(Exception ex)
{
_exceptionHandler?.Invoke(ex);
}
}

FontStyle GetFontStyle()
Expand Down Expand Up @@ -99,7 +107,5 @@ bool IsUnderline()

return false;
}

IColorMap _colorMap;
}
}

0 comments on commit 272a695

Please sign in to comment.