Skip to content

Commit

Permalink
fixed peek method
Browse files Browse the repository at this point in the history
  • Loading branch information
victor-pogor committed Nov 19, 2024
1 parent f17b961 commit 2b08521
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 20 deletions.
17 changes: 13 additions & 4 deletions src/OffDotNet.CodeAnalysis/Lexer/TextCursor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,21 @@ public TextCursor(in ISourceText text, IOptions<TextCursorOptions> options)
public Option<byte> Peek(int delta = 0)
{
Debug.Assert(delta >= 0, "Delta should be positive");
return !IsAtEnd
? Option<byte>.Some(_characterWindowMemoryOwner.Memory.Span[Offset + delta])
: Option<byte>.None;
var windowStart = WindowStart;
var offset = Offset;

Advance(delta);
var b = !HasMoreBytes() ? Option<byte>.None : _characterWindowMemoryOwner.Memory.Span[Offset];

SlideTextWindow(windowStart);
Advance(offset);
return b;
}

/// <summary>Advances the cursor by the specified delta.</summary>
/// <param name="delta">The delta by which to advance the cursor.</param>
public void Advance(int delta = 1)
{
Debug.Assert(delta > 0, "Delta should greater than 0");
Offset += delta;
}

Expand Down Expand Up @@ -154,6 +159,10 @@ public void SlideTextWindow(int windowStart = -1, int windowSize = -1)
if (windowStart >= SourceText.Length)
return;

// do not slide the window if the window start and size are the same
if (windowStart == WindowStart && windowSize == WindowSize)
return;

if (windowSize >= 0)
{
var oldCharacterWindowMemoryOwner = _characterWindowMemoryOwner;
Expand Down
80 changes: 64 additions & 16 deletions tests/OffDotNet.CodeAnalysis.Tests/Lexer/TextCursorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ public void SlideTextWindow_NotInitialized_ShouldShrinkWindowSize()
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 2048;
const int WindowSize = 48;
const int ExpectedWindowSize = 64;
Expand All @@ -789,7 +789,7 @@ public void SlideTextWindow_NotInitialized_ShouldShrinkWindowSize()
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart, WindowSize);
var character = cursor.Peek(delta: 0);

// Assert
Expand All @@ -803,7 +803,7 @@ public void SlideTextWindow_NotInitialized_ShouldExtendWindowSize()
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 16;
const int WindowSize = 48;
const int ExpectedWindowSize = 64;
Expand All @@ -813,7 +813,7 @@ public void SlideTextWindow_NotInitialized_ShouldExtendWindowSize()
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart, WindowSize);
var character = cursor.Peek(delta: 0);

// Assert
Expand All @@ -827,7 +827,7 @@ public void SlideTextWindow_WhenInitialized_WhenExtending_ShouldCopyOldWindowToN
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 16;
const int WindowSize = 48;
const int ExpectedWindowSize = 64;
Expand All @@ -837,12 +837,12 @@ public void SlideTextWindow_WhenInitialized_WhenExtending_ShouldCopyOldWindowToN
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(Position);
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart);
cursor.SlideTextWindow(WindowStart, WindowSize);

// Assert
Assert.Equal(ExpectedWindowSize, cursor.WindowSize);
Assert.Equal(sourceText.Source[Position..ExpectedWindowSize], cursor.Window[..ExpectedWindowSize]);
Assert.Equal(sourceText.Source[WindowStart..ExpectedWindowSize], cursor.Window[..ExpectedWindowSize]);
}

[WorkItem("https://github.com/sunt-programator/off-dotnet/issues/335")]
Expand All @@ -851,7 +851,7 @@ public void SlideTextWindow_WhenInitialized_WhenShrinking_ShouldCopyOldWindowToN
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 128;
const int WindowSize = 48;
const int ExpectedWindowSize = 64;
Expand All @@ -861,12 +861,12 @@ public void SlideTextWindow_WhenInitialized_WhenShrinking_ShouldCopyOldWindowToN
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(Position);
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart);
cursor.SlideTextWindow(WindowStart, WindowSize);

// Assert
Assert.Equal(ExpectedWindowSize, cursor.WindowSize);
Assert.Equal(sourceText.Source[Position..ExpectedWindowSize], cursor.Window[..ExpectedWindowSize]);
Assert.Equal(sourceText.Source[WindowStart..ExpectedWindowSize], cursor.Window[..ExpectedWindowSize]);
}

[WorkItem("https://github.com/sunt-programator/off-dotnet/issues/335")]
Expand All @@ -875,7 +875,7 @@ public void SlideTextWindow_WhenSliding_ShouldSetOffsetToZero()
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 128;
const int WindowSize = 48;
const int ExpectedOffset = 0;
Expand All @@ -887,7 +887,7 @@ public void SlideTextWindow_WhenSliding_ShouldSetOffsetToZero()
// Act
cursor.Peek();
cursor.Advance(5);
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart, WindowSize);

// Assert
Assert.Equal(ExpectedOffset, cursor.Offset);
Expand All @@ -899,7 +899,7 @@ public void SlideTextWindow_WhenSliding_ShouldSetLexemeStartToZero()
{
// Arrange
const int TextLength = 256;
const int Position = 0;
const int WindowStart = 0;
const int DefaultWindowSize = 128;
const int WindowSize = 48;
const int ExpectedLexemeStart = 0;
Expand All @@ -911,13 +911,61 @@ public void SlideTextWindow_WhenSliding_ShouldSetLexemeStartToZero()
// Act
cursor.Peek();
cursor.Advance(5);
cursor.SlideTextWindow(Position, WindowSize);
cursor.SlideTextWindow(WindowStart, WindowSize);

// Assert
Assert.Equal(ExpectedLexemeStart, cursor.LexemeStart);
Assert.False(cursor.IsLexemeMode);
}

[WorkItem("https://github.com/sunt-programator/off-dotnet/issues/335")]
[Fact(DisplayName = $"{nameof(TextCursor.SlideTextWindow)} method should not slide the window if the start position and size are the same")]
public void SlideTextWindow_WhenStartAndSizeAreTheSame_ShouldNotSlideWindow()
{
// Arrange
const int TextLength = 256;
const int WindowStart = 0;
const int DefaultWindowSize = 128;
const int WindowSize = 128;

var sourceText = GetSourceText(GenerateIncrementingString(TextLength));
_options.Value.Returns(new TextCursorOptions { WindowSize = DefaultWindowSize });
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(WindowStart, WindowSize);
cursor.SlideTextWindow();

// Assert
Assert.Equal(DefaultWindowSize, cursor.WindowSize);
}

[WorkItem("https://github.com/sunt-programator/off-dotnet/issues/335")]
[Theory(DisplayName = $"{nameof(TextCursor.Peek)} method should restore the {nameof(TextCursor.WindowStart)} if the delta is outside window")]
[InlineData(16, (byte)'s')]
[InlineData(17, (byte)'t')]
[InlineData(18, (byte)'u')]
[InlineData(19, (byte)'v')]
public void Peek_CustomWindowStart_WhenDeltaIsOutsideWindow_ShouldRestoreWindowStart(int peekDelta, byte expectedByte)
{
// Arrange
const int TextLength = 256;
const int WindowStart = 2;
const int DefaultWindowSize = 16;

var sourceText = GetSourceText(GenerateIncrementingString(TextLength));
_options.Value.Returns(new TextCursorOptions { WindowSize = DefaultWindowSize });
ITextCursor cursor = new TextCursor(sourceText, _options);

// Act
cursor.SlideTextWindow(WindowStart);
var actual = cursor.Peek(peekDelta);

// Assert
Assert.Equal(WindowStart, cursor.WindowStart);
Assert.Equal(expectedByte, actual);
}

private static ISourceText GetSourceText(string text) => new StringText(Encoding.ASCII.GetBytes(text));

private static string GenerateIncrementingString(int n)
Expand Down

0 comments on commit 2b08521

Please sign in to comment.