Skip to content

Commit

Permalink
Aggressively avoid TrackTrivia work and allocations when not requeste…
Browse files Browse the repository at this point in the history
…d for Inlines
  • Loading branch information
MihaZupan committed Mar 13, 2022
1 parent 61452c9 commit 6f75b51
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 16 deletions.
10 changes: 8 additions & 2 deletions src/Markdig/Parsers/Inlines/CodeInlineParser.cs
Expand Up @@ -113,15 +113,21 @@ public override bool Match(InlineProcessor processor, ref StringSlice slice)
int delimiterCount = Math.Min(openSticks, closeSticks);
var spanStart = processor.GetSourcePosition(startPosition, out int line, out int column);
var spanEnd = processor.GetSourcePosition(slice.Start - 1);
processor.Inline = new CodeInline(content)
var codeInline = new CodeInline(content)
{
Delimiter = match,
ContentWithTrivia = new StringSlice(slice.Text, contentStart, contentEnd - 1),
Span = new SourceSpan(spanStart, spanEnd),
Line = line,
Column = column,
DelimiterCount = delimiterCount,
};

if (processor.TrackTrivia)
{
codeInline.ContentWithTrivia = new StringSlice(slice.Text, contentStart, contentEnd - 1);
}

processor.Inline = codeInline;
isMatching = true;
}

Expand Down
11 changes: 8 additions & 3 deletions src/Markdig/Parsers/Inlines/LinkInlineParser.cs
Expand Up @@ -79,18 +79,23 @@ public override bool Match(InlineProcessor processor, ref StringSlice slice)

// Else we insert a LinkDelimiter
slice.SkipChar();
var labelWithTrivia = new StringSlice(slice.Text, labelWithTriviaSpan.Start, labelWithTriviaSpan.End);
processor.Inline = new LinkDelimiterInline(this)
var linkDelimiter = new LinkDelimiterInline(this)
{
Type = DelimiterType.Open,
Label = label,
LabelWithTrivia = labelWithTrivia,
LabelSpan = processor.GetSourcePositionFromLocalSpan(labelSpan),
IsImage = isImage,
Span = new SourceSpan(startPosition, processor.GetSourcePosition(slice.Start - 1)),
Line = line,
Column = column
};

if (processor.TrackTrivia)
{
linkDelimiter.LabelWithTrivia = new StringSlice(slice.Text, labelWithTriviaSpan.Start, labelWithTriviaSpan.End);
}

processor.Inline = linkDelimiter;
return true;

case ']':
Expand Down
18 changes: 9 additions & 9 deletions src/Markdig/Syntax/Inlines/CodeInline.cs
Expand Up @@ -14,6 +14,9 @@ namespace Markdig.Syntax.Inlines
[DebuggerDisplay("`{Content}`")]
public class CodeInline : LeafInline
{
private TriviaProperties? _trivia;
private TriviaProperties Trivia => _trivia ??= new();

public CodeInline(string content)
{
Content = content;
Expand All @@ -37,16 +40,13 @@ public CodeInline(string content)
/// <summary>
/// Gets or sets the content with trivia and whitespace.
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// <see cref="StringSlice.Empty"/>.
/// </summary>
public StringSlice ContentWithTrivia { get; set; }
public StringSlice ContentWithTrivia { get => _trivia?.ContentWithTrivia ?? StringSlice.Empty; set => Trivia.ContentWithTrivia = value; }

/// <summary>
/// True if the first and last character of the content enclosed in a backtick `
/// is a space.
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// false.
/// </summary>
public bool FirstAndLastWasSpace { get; set; }
private sealed class TriviaProperties
{
public StringSlice ContentWithTrivia;
}
}
}
12 changes: 10 additions & 2 deletions src/Markdig/Syntax/Inlines/LinkDelimiterInline.cs
Expand Up @@ -13,6 +13,9 @@ namespace Markdig.Syntax.Inlines
/// <seealso cref="DelimiterInline" />
public class LinkDelimiterInline : DelimiterInline
{
private TriviaProperties? _trivia;
private TriviaProperties Trivia => _trivia ??= new();

public LinkDelimiterInline(InlineParser parser) : base(parser)
{
}
Expand All @@ -35,13 +38,18 @@ public LinkDelimiterInline(InlineParser parser) : base(parser)
/// <summary>
/// Gets or sets the <see cref="Label"/> with trivia.
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// <see cref="StringSlice.Empty"/>.
/// </summary>
public StringSlice LabelWithTrivia { get; set; }
public StringSlice LabelWithTrivia { get => _trivia?.LabelWithTrivia ?? StringSlice.Empty; set => Trivia.LabelWithTrivia = value; }

public override string ToLiteral()
{
return IsImage ? "![" : "[";
}

private sealed class TriviaProperties
{
public StringSlice LabelWithTrivia;
}
}
}

0 comments on commit 6f75b51

Please sign in to comment.