diff --git a/Shortcodes.sln b/Shortcodes.sln index e4ecfe3..71dc30d 100644 --- a/Shortcodes.sln +++ b/Shortcodes.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30107.140 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35111.106 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shortcodes.Tests", "tests\Shortcodes.Tests\Shortcodes.Tests.csproj", "{7ECF5D62-FDDF-4A6E-A6DD-8B4EDFB5CB4E}" EndProject diff --git a/src/Shortcodes/RawText.cs b/src/Shortcodes/RawText.cs index cc9a13c..4a32ccb 100644 --- a/src/Shortcodes/RawText.cs +++ b/src/Shortcodes/RawText.cs @@ -1,16 +1,17 @@ -namespace Shortcodes +using Parlot; +using System; + +namespace Shortcodes { public class RawText : Node { - public RawText(string buffer, int offset, int count) + private readonly TextSpan _textSpan; + + public RawText(TextSpan textSpan) { - Buffer = buffer; - Offset = offset; - Count = count; + _textSpan = textSpan; } - public string Buffer { get; } - public int Offset { get; } - public int Count { get; } + public ReadOnlySpan Span => _textSpan.Span; } } diff --git a/src/Shortcodes/Shortcodes.csproj b/src/Shortcodes/Shortcodes.csproj index a75bff9..4c13669 100644 --- a/src/Shortcodes/Shortcodes.csproj +++ b/src/Shortcodes/Shortcodes.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/src/Shortcodes/ShortcodesParser.cs b/src/Shortcodes/ShortcodesParser.cs index b5d089c..29b729e 100644 --- a/src/Shortcodes/ShortcodesParser.cs +++ b/src/Shortcodes/ShortcodesParser.cs @@ -51,9 +51,9 @@ private List ParseNodes() private RawText ParseRawText() { - if (_scanner.ReadRawText(out var _result)) + if (_scanner.ReadRawText(out var result)) { - return new RawText(_scanner.Buffer, _result.Start, _result.Length); + return new RawText(result); } return null; @@ -110,7 +110,7 @@ private Shortcode ParseShortcode() return null; } - var identifier = _result.GetText(); + var identifier = _result.ToString(); _scanner.SkipWhiteSpace(); @@ -128,7 +128,7 @@ private Shortcode ParseShortcode() { arguments ??= CreateArgumentsDictionary(); - arguments[argumentIndex.ToString()] = Character.DecodeString(new TextSpan(_scanner.Buffer, _result.Start + 1, _result.Length - 2)).ToString(); + arguments[argumentIndex.ToString()] = Character.DecodeString(_result)[1..^1].ToString(); argumentIndex += 1; } @@ -136,8 +136,9 @@ private Shortcode ParseShortcode() { _scanner.SkipWhiteSpace(); - var argumentName = _result.GetText(); - + var argumentName = _result.ToString(); + var valueStart = _scanner.Cursor.Offset; + // It might just be a value if (_scanner.ReadChar('=')) { @@ -147,13 +148,13 @@ private Shortcode ParseShortcode() { arguments ??= CreateArgumentsDictionary(); - arguments[argumentName] = Character.DecodeString(new TextSpan(_scanner.Buffer, _result.Start + 1, _result.Length - 2)).ToString(); + arguments[argumentName] = Character.DecodeString(_result)[1..^1].ToString(); } - else if (_scanner.ReadValue(out _result)) + else if (_scanner.ReadValue(out var textSpan)) { arguments ??= CreateArgumentsDictionary(); - arguments[argumentName] = _result.GetText(); + arguments[argumentName] = textSpan.ToString(); } else { @@ -168,11 +169,11 @@ private Shortcode ParseShortcode() _scanner.Cursor.ResetPosition(argumentStart); - if (_scanner.ReadValue(out _result)) + if (_scanner.ReadValue(out var textSpan)) { arguments ??= CreateArgumentsDictionary(); - arguments[argumentIndex.ToString()] = _result.GetText(); + arguments[argumentIndex.ToString()] = textSpan.ToString(); argumentIndex += 1; } @@ -184,11 +185,11 @@ private Shortcode ParseShortcode() } } } - else if (_scanner.ReadValue(out _result)) + else if (_scanner.ReadValue(out var textSpan)) { arguments ??= CreateArgumentsDictionary(); - arguments[argumentIndex.ToString()] = _result.GetText(); + arguments[argumentIndex.ToString()] = textSpan.ToString(); argumentIndex += 1; } diff --git a/src/Shortcodes/ShortcodesProcessor.cs b/src/Shortcodes/ShortcodesProcessor.cs index f7936ba..d50ce64 100644 --- a/src/Shortcodes/ShortcodesProcessor.cs +++ b/src/Shortcodes/ShortcodesProcessor.cs @@ -104,7 +104,7 @@ private async ValueTask FoldClosingTagsAsync(string input, List no { var text = node as RawText; - sb.Builder.Append(text.Buffer, text.Offset, text.Count); + sb.Builder.Append(text.Span); } cursor += 1; @@ -271,7 +271,7 @@ private async Task AppendAsync(StringBuilder builder, string source, Node start, switch (start) { case RawText raw: - builder.Append(raw.Buffer, raw.Offset, raw.Count); + builder.Append(raw.Span); return; case Shortcode code: diff --git a/src/Shortcodes/ShortcodesScanner.cs b/src/Shortcodes/ShortcodesScanner.cs index 5c4d81c..b5c71cf 100644 --- a/src/Shortcodes/ShortcodesScanner.cs +++ b/src/Shortcodes/ShortcodesScanner.cs @@ -1,4 +1,5 @@ using Parlot; +using System; namespace Shortcodes { @@ -9,7 +10,7 @@ public ShortcodesScanner(string buffer) : base(buffer) } - public bool ReadRawText(out TokenResult result) + public bool ReadRawText(out TextSpan result) { var start = Cursor.Offset; @@ -27,26 +28,26 @@ public bool ReadRawText(out TokenResult result) if (length == 0) { - result = TokenResult.Fail(); + result = null; return false; } - result = TokenResult.Succeed(Buffer, start, Cursor.Offset); + result = new TextSpan(Buffer, start, length); return true; } - public bool ReadValue(out TokenResult result) + public bool ReadValue(out TextSpan result) { if (Cursor.Match(']') || Cursor.Match('\'') || Cursor.Match('"') || Character.IsWhiteSpaceOrNewLine(Cursor.Current)) { - result = TokenResult.Fail(); + result = null; return false; } if (Cursor.Match("/]")) { - result = TokenResult.Fail(); + result = null; return false; } @@ -56,14 +57,14 @@ public bool ReadValue(out TokenResult result) { if (Cursor.Eof) { - result = TokenResult.Fail(); + result = null; return false; } Cursor.Advance(); } - result = TokenResult.Succeed(Buffer, start, Cursor.Offset); + result = new TextSpan(Buffer, start, Cursor.Offset - start); return true; } diff --git a/tests/Shortcodes.Benchmarks/Shortcodes.Benchmarks.csproj b/tests/Shortcodes.Benchmarks/Shortcodes.Benchmarks.csproj index 277b653..6686f75 100644 --- a/tests/Shortcodes.Benchmarks/Shortcodes.Benchmarks.csproj +++ b/tests/Shortcodes.Benchmarks/Shortcodes.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net8.0 false true @@ -14,7 +14,7 @@ - + diff --git a/tests/Shortcodes.Tests/Shortcodes.Tests.csproj b/tests/Shortcodes.Tests/Shortcodes.Tests.csproj index f6d2d5f..732c9b2 100644 --- a/tests/Shortcodes.Tests/Shortcodes.Tests.csproj +++ b/tests/Shortcodes.Tests/Shortcodes.Tests.csproj @@ -1,7 +1,7 @@ - + - net5.0 + net8.0 false true @@ -9,10 +9,16 @@ - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/Shortcodes.Tests/ShortcodesParserTests.cs b/tests/Shortcodes.Tests/ShortcodesParserTests.cs index bae0923..92f16a0 100644 --- a/tests/Shortcodes.Tests/ShortcodesParserTests.cs +++ b/tests/Shortcodes.Tests/ShortcodesParserTests.cs @@ -43,7 +43,7 @@ private string EncodeNodes(IEnumerable nodes) break; case RawText raw: - _builder.Append($"R({raw.Count})"); + _builder.Append($"R({raw.Span.Length})"); break; } } @@ -118,7 +118,8 @@ public void ShouldScanArguments(string input, string encoded) [Theory] [InlineData("[hello a='b]", "R(12)")] - [InlineData("[hello '\\a']", "R(12)")] + // \z is not a valid escape sequence + [InlineData("[hello '\\z']", "R(12)")] public void ShouldIgnoreMalformedArguments(string input, string encoded) { var nodes = new ShortcodesParser().Parse(input); @@ -131,8 +132,8 @@ public void ShouldIgnoreMalformedArguments(string input, string encoded) [InlineData("[h a='\\u03A9']", "[h a=Ω]")] [InlineData("[h a='\\xe9']", "[h a=é]")] [InlineData("[h a='\\xE9']", "[h a=é]")] - // This is not a valid string (invalid escape sequence), and not a valid value as it start with ' - [InlineData("[h a='\\a']", "R(10)")] + // This is not a valid string (invalid escape sequence), and not a valid value as it starts with ' + [InlineData("[h a='\\z']", "R(10)")] [InlineData("[h a='\\\\']", "[h a=\\]")] [InlineData("[h a='\\\"']", "[h a=\"]")] [InlineData("[h a='\\\'']", "[h a=']")]