diff --git a/CHANGELOG.md b/CHANGELOG.md index 06acab6..74669ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +- Renamed `CustomLexerContext` to `CustomLexerCursor` and separated it from the + `context.Context` type. + ## [0.3.0] - 2026-01-25 - Refactored `CustomLexer` to add a new `CustomLexerContext` type that is passed diff --git a/README.md b/README.md index dc5dd6c..fed0474 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ in addition to the underlying reader's position. When the token has been fully processed it can be emitted to a channel for further processing by the `Parser`. Developers implement the token processing portion of the lexer by implementing -`LexState` interface for each relevant lexer state. A `CustomLexerContext` is +`LexState` interface for each relevant lexer state. A `CustomLexerCursor` is passed to each `LexState` during processing and includes a number of methods that can be used to advance through the input text. @@ -211,7 +211,7 @@ type LexState interface { // Run returns the next state to transition to or an error. If the returned // next state is nil or the returned error is io.EOF then the Lexer // finishes processing normally. - Run(*CustomLexerContext) (LexState, error) + Run(context.Context, *CustomLexerCursor) (LexState, error) } ``` @@ -238,23 +238,23 @@ advancing over the text. ```go // lexText tokenizes normal text. -func lexText(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexText(ctx context.Context, c *lexparse.CustomLexerCursor) (lexparse.LexState, error) { for { - p := ctx.PeekN(2) + p := c.PeekN(2) switch string(p) { case tokenBlockStart, tokenVarStart: - if ctx.Width() > 0 { - ctx.Emit(lexTypeText) + if c.Width() > 0 { + c.Emit(lexTypeText) } return lexparse.LexStateFn(lexCode), nil default: } // Advance the input. - if !ctx.Advance() { + if !c.Advance() { // End of input. Emit the text up to this point. - if ctx.Width() > 0 { - ctx.Emit(lexTypeText) + if c.Width() > 0 { + c.Emit(lexTypeText) } return nil, nil } diff --git a/custom.go b/custom.go index 8fb95f2..38ad18c 100644 --- a/custom.go +++ b/custom.go @@ -35,106 +35,112 @@ const EOF rune = -1 type LexState interface { // Run returns the next state to transition to or an error. If the returned // error is io.EOF then the Lexer finishes processing normally. - Run(ctx *CustomLexerContext) (LexState, error) + Run(ctx context.Context, cursor *CustomLexerCursor) (LexState, error) } type lexFnState struct { - f func(*CustomLexerContext) (LexState, error) + f func(context.Context, *CustomLexerCursor) (LexState, error) } // Run implements [LexState.Run]. // //nolint:ireturn // Returning interface required to satisfy [LexState.Run] -func (s *lexFnState) Run(ctx *CustomLexerContext) (LexState, error) { - return s.f(ctx) +func (s *lexFnState) Run(ctx context.Context, cursor *CustomLexerCursor) (LexState, error) { + return s.f(ctx, cursor) } // LexStateFn creates a State from the given Run function. // //nolint:ireturn // Returning interface required to satisfy [LexState.Run] -func LexStateFn(f func(*CustomLexerContext) (LexState, error)) LexState { +func LexStateFn(f func(context.Context, *CustomLexerCursor) (LexState, error)) LexState { return &lexFnState{f} } -// CustomLexerContext is a context that carries a reference to the current -// CustomLexer. It is passed to [LexState.Run] method to allow the state -// implementation to interact with the lexer. -type CustomLexerContext struct { - //nolint:containedctx // Embedding context required for interface compliance. - context.Context - +// CustomLexerCursor is a type that allows for processing the input for the +// CustomLexer. It provides methods to advance the reader, emit tokens, and +// manage the current token being processed. It is designed to be used within +// the [LexState.Run] method to allow the state implementation to interact with +// the lexer without exposing the full CustomLexer implementation. +type CustomLexerCursor struct { l *CustomLexer } +// NewCustomLexerCursor creates a new CustomLexerCursor. +func NewCustomLexerCursor(l *CustomLexer) *CustomLexerCursor { + return &CustomLexerCursor{ + l: l, + } +} + // Advance attempts to advance the underlying reader a single rune and returns // true if actually advanced. The current token cursor position is not updated. -func (ctx *CustomLexerContext) Advance() bool { - return ctx.l.advance(1, false) == 1 +func (c *CustomLexerCursor) Advance() bool { + return c.l.advance(1, false) == 1 } // AdvanceN attempts to advance the underlying reader n runes and returns the // number actually advanced. The current token cursor position is not updated. -func (ctx *CustomLexerContext) AdvanceN(n int) int { - return ctx.l.advance(n, false) +func (c *CustomLexerCursor) AdvanceN(n int) int { + return c.l.advance(n, false) } // Cursor returns the current position of the underlying cursor marking the // beginning of the current token being processed. -func (ctx *CustomLexerContext) Cursor() Position { - return ctx.l.cursor +func (c *CustomLexerCursor) Cursor() Position { + return c.l.cursor } // Discard attempts to discard the next rune, advancing the current token // cursor, and returns true if actually discarded. -func (ctx *CustomLexerContext) Discard() bool { - return ctx.l.advance(1, true) == 1 +func (c *CustomLexerCursor) Discard() bool { + return c.l.advance(1, true) == 1 } // DiscardN attempts to discard n runes, advancing the current token cursor // position, and returns the number actually discarded. -func (ctx *CustomLexerContext) DiscardN(n int) int { - return ctx.l.advance(n, true) +func (c *CustomLexerCursor) DiscardN(n int) int { + return c.l.advance(n, true) } // DiscardTo searches the input for one of the given search strings, advancing // the reader, and stopping when one of the strings is found. The token cursor // is advanced and data prior to the search string is discarded. The string // found is returned. If no match is found an empty string is returned. -func (ctx *CustomLexerContext) DiscardTo(query []string) string { - return ctx.l.discardTo(query) +func (c *CustomLexerCursor) DiscardTo(query []string) string { + return c.l.discardTo(query) } // Emit emits the token between the current cursor position and reader // position and returns the token. If the lexer is not currently active, this // is a no-op. This advances the current token cursor. -func (ctx *CustomLexerContext) Emit(typ TokenType) *Token { - return ctx.l.emit(typ) +func (c *CustomLexerCursor) Emit(typ TokenType) *Token { + return c.l.emit(typ) } // Find searches the input for one of the given search strings, advancing the // reader, and stopping when one of the strings is found. The token cursor is // not advanced. The string found is returned. If no match is found an empty // string is returned. -func (ctx *CustomLexerContext) Find(query []string) string { - return ctx.l.find(query) +func (c *CustomLexerCursor) Find(query []string) string { + return c.l.find(query) } // Ignore ignores the previous input and resets the token start position to // the current reader position. -func (ctx *CustomLexerContext) Ignore() { - ctx.l.ignore() +func (c *CustomLexerCursor) Ignore() { + c.l.ignore() } // NextRune returns the next rune of input, advancing the reader while not // advancing the token cursor. -func (ctx *CustomLexerContext) NextRune() rune { - return ctx.l.nextRune() +func (c *CustomLexerCursor) NextRune() rune { + return c.l.nextRune() } // Peek returns the next rune from the buffer without advancing the reader or // current token cursor. -func (ctx *CustomLexerContext) Peek() rune { - p := ctx.PeekN(1) +func (c *CustomLexerCursor) Peek() rune { + p := c.PeekN(1) if len(p) < 1 { return EOF } @@ -145,24 +151,24 @@ func (ctx *CustomLexerContext) Peek() rune { // PeekN returns the next n runes from the buffer without advancing the reader // or current token cursor. PeekN may return fewer runes than requested if an // error occurs or at end of input. -func (ctx *CustomLexerContext) PeekN(n int) []rune { - return ctx.l.peekN(n) +func (c *CustomLexerCursor) PeekN(n int) []rune { + return c.l.peekN(n) } // Pos returns the current position of the underlying reader. -func (ctx *CustomLexerContext) Pos() Position { - return ctx.l.pos +func (c *CustomLexerCursor) Pos() Position { + return c.l.pos } // Token returns the current token value. -func (ctx *CustomLexerContext) Token() string { - return ctx.l.b.String() +func (c *CustomLexerCursor) Token() string { + return c.l.b.String() } // Width returns the current width of the token being processed. It is // equivalent to l.Pos().Offset - l.Cursor().Offset. -func (ctx *CustomLexerContext) Width() int { - return ctx.l.pos.Offset - ctx.l.cursor.Offset +func (c *CustomLexerCursor) Width() int { + return c.l.pos.Offset - c.l.cursor.Offset } // CustomLexer lexically processes a byte stream. It is implemented as a @@ -240,10 +246,7 @@ func (l *CustomLexer) NextToken(ctx context.Context) *Token { return l.newToken(TokenTypeEOF) } - lexerCtx := &CustomLexerContext{ - Context: ctx, - l: l, - } + cursor := NewCustomLexerCursor(l) // If we have no tokens to return, we need to run the current state. for len(l.buf) == 0 && l.state != nil { @@ -258,7 +261,7 @@ func (l *CustomLexer) NextToken(ctx context.Context) *Token { var err error - l.state, err = l.state.Run(lexerCtx) + l.state, err = l.state.Run(ctx, cursor) l.setErr(err) if l.err != nil { diff --git a/custom_test.go b/custom_test.go index e335799..99ab9fa 100644 --- a/custom_test.go +++ b/custom_test.go @@ -33,31 +33,30 @@ const ( type lexWordState struct{} //nolint:ireturn // Returning interface required to satisfy [LexState.Run] -func (w *lexWordState) Run(ctx *CustomLexerContext) (LexState, error) { - rn := ctx.Peek() +func (w *lexWordState) Run(_ context.Context, c *CustomLexerCursor) (LexState, error) { + rn := c.Peek() if unicode.IsSpace(rn) || rn == EOF { // NOTE: This can emit empty words. - ctx.Emit(wordType) + c.Emit(wordType) // Discard the space - if !ctx.Discard() { + if !c.Discard() { return nil, io.EOF } } - ctx.Advance() + c.Advance() return w, nil } -func TestCustomLexerContext_Peek(t *testing.T) { +func TestCustomLexerCursor_Peek(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\nWorld!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\nWorld!"), &lexWordState{}), + ) - rn := ctx.Peek() + rn := cursor.Peek() if diff := cmp.Diff('H', rn); diff != "" { t.Errorf("Peek (-want +got):\n%s", diff) @@ -69,8 +68,8 @@ func TestCustomLexerContext_Peek(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { - t.Errorf("Cursor (-want +got):\n%s", diff) + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { + t.Errorf("Pos (-want +got):\n%s", diff) } expectedCursor := Position{ @@ -79,28 +78,27 @@ func TestCustomLexerContext_Peek(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } } -func TestCustomLexerContext_PeekN(t *testing.T) { +func TestCustomLexerCursor_PeekN(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\nWorld!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\nWorld!"), &lexWordState{}), + ) - if diff := cmp.Diff("Hello\n", string(ctx.PeekN(6))); diff != "" { + if diff := cmp.Diff("Hello\n", string(cursor.PeekN(6))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\nWorld!", string(ctx.PeekN(16))); diff != "" { + if diff := cmp.Diff("Hello\nWorld!", string(cursor.PeekN(16))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -110,7 +108,7 @@ func TestCustomLexerContext_PeekN(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -120,32 +118,31 @@ func TestCustomLexerContext_PeekN(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } } //nolint:dupl // Tests are testing different methods. -func TestCustomLexerContext_Advance(t *testing.T) { +func TestCustomLexerCursor_Advance(t *testing.T) { t.Parallel() t.Run("success", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), + ) - if diff := cmp.Diff(true, ctx.Advance()); diff != "" { + if diff := cmp.Diff(true, cursor.Advance()); diff != "" { t.Errorf("Advance (-want +got):\n%s", diff) } - if diff := cmp.Diff("ello\n!Adva", string(ctx.PeekN(10))); diff != "" { + if diff := cmp.Diff("ello\n!Adva", string(cursor.PeekN(10))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -155,7 +152,7 @@ func TestCustomLexerContext_Advance(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -165,19 +162,19 @@ func TestCustomLexerContext_Advance(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(1, ctx.Width()); diff != "" { + if diff := cmp.Diff(1, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("H", ctx.Token()); diff != "" { + if diff := cmp.Diff("H", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) @@ -185,12 +182,11 @@ func TestCustomLexerContext_Advance(t *testing.T) { t.Run("end of input", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader(""), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader(""), &lexWordState{}), + ) - if diff := cmp.Diff(false, ctx.Advance()); diff != "" { + if diff := cmp.Diff(false, cursor.Advance()); diff != "" { t.Errorf("Advance (-want +got):\n%s", diff) } @@ -200,7 +196,7 @@ func TestCustomLexerContext_Advance(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -210,40 +206,39 @@ func TestCustomLexerContext_Advance(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) } -func TestCustomLexerContext_AdvanceN(t *testing.T) { +func TestCustomLexerCursor_AdvanceN(t *testing.T) { t.Parallel() t.Run("basic", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), + ) - if diff := cmp.Diff(5, ctx.AdvanceN(5)); diff != "" { + if diff := cmp.Diff(5, cursor.AdvanceN(5)); diff != "" { t.Errorf("AdvanceN (-want +got):\n%s", diff) } - if diff := cmp.Diff("\n!Advance!", string(ctx.PeekN(10))); diff != "" { + if diff := cmp.Diff("\n!Advance!", string(cursor.PeekN(10))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -253,7 +248,7 @@ func TestCustomLexerContext_AdvanceN(t *testing.T) { Column: 6, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -263,19 +258,19 @@ func TestCustomLexerContext_AdvanceN(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(5, ctx.Width()); diff != "" { + if diff := cmp.Diff(5, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) @@ -283,12 +278,11 @@ func TestCustomLexerContext_AdvanceN(t *testing.T) { t.Run("past end", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), + ) - if diff := cmp.Diff(15, ctx.AdvanceN(16)); diff != "" { + if diff := cmp.Diff(15, cursor.AdvanceN(16)); diff != "" { t.Errorf("AdvanceN (-want +got):\n%s", diff) } @@ -298,7 +292,7 @@ func TestCustomLexerContext_AdvanceN(t *testing.T) { Column: 10, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -308,41 +302,40 @@ func TestCustomLexerContext_AdvanceN(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(15, ctx.Width()); diff != "" { + if diff := cmp.Diff(15, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\n!Advance!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello\n!Advance!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) } //nolint:dupl // Tests are testing different methods. -func TestCustomLexerContext_Discard(t *testing.T) { +func TestCustomLexerCursor_Discard(t *testing.T) { t.Parallel() t.Run("success", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Advance!"), &lexWordState{}), + ) - if diff := cmp.Diff(true, ctx.Discard()); diff != "" { + if diff := cmp.Diff(true, cursor.Discard()); diff != "" { t.Errorf("Discard (-want +got):\n%s", diff) } - if diff := cmp.Diff("ello\n!Adva", string(ctx.PeekN(10))); diff != "" { + if diff := cmp.Diff("ello\n!Adva", string(cursor.PeekN(10))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -352,7 +345,7 @@ func TestCustomLexerContext_Discard(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -362,19 +355,19 @@ func TestCustomLexerContext_Discard(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) @@ -382,12 +375,11 @@ func TestCustomLexerContext_Discard(t *testing.T) { t.Run("end of input", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader(""), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader(""), &lexWordState{}), + ) - if diff := cmp.Diff(false, ctx.Discard()); diff != "" { + if diff := cmp.Diff(false, cursor.Discard()); diff != "" { t.Errorf("Discard (-want +got):\n%s", diff) } @@ -397,7 +389,7 @@ func TestCustomLexerContext_Discard(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -407,40 +399,39 @@ func TestCustomLexerContext_Discard(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) } -func TestCustomLexerContext_DiscardN(t *testing.T) { +func TestCustomLexerCursor_DiscardN(t *testing.T) { t.Parallel() t.Run("basic", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Discard!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Discard!"), &lexWordState{}), + ) - if diff := cmp.Diff(7, ctx.DiscardN(7)); diff != "" { + if diff := cmp.Diff(7, cursor.DiscardN(7)); diff != "" { t.Errorf("DiscardN (-want +got):\n%s", diff) } - if diff := cmp.Diff("Discard!", string(ctx.PeekN(8))); diff != "" { + if diff := cmp.Diff("Discard!", string(cursor.PeekN(8))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -450,7 +441,7 @@ func TestCustomLexerContext_DiscardN(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -460,19 +451,19 @@ func TestCustomLexerContext_DiscardN(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) @@ -480,12 +471,11 @@ func TestCustomLexerContext_DiscardN(t *testing.T) { t.Run("past end", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Discard!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Discard!"), &lexWordState{}), + ) - if diff := cmp.Diff(15, ctx.DiscardN(16)); diff != "" { + if diff := cmp.Diff(15, cursor.DiscardN(16)); diff != "" { t.Errorf("DiscardN (-want +got):\n%s", diff) } @@ -495,7 +485,7 @@ func TestCustomLexerContext_DiscardN(t *testing.T) { Column: 10, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -505,38 +495,37 @@ func TestCustomLexerContext_DiscardN(t *testing.T) { Column: 10, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) } //nolint:dupl // Similar to TestLexer_DiscardTo/match -func TestCustomLexerContext_Find_match(t *testing.T) { +func TestCustomLexerCursor_Find_match(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), + ) - if diff := cmp.Diff("Find", ctx.Find([]string{"Find"})); diff != "" { + if diff := cmp.Diff("Find", cursor.Find([]string{"Find"})); diff != "" { t.Errorf("Find (-want +got):\n%s", diff) } - if diff := cmp.Diff("Find!", string(ctx.PeekN(5))); diff != "" { + if diff := cmp.Diff("Find!", string(cursor.PeekN(5))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -546,7 +535,7 @@ func TestCustomLexerContext_Find_match(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -556,32 +545,31 @@ func TestCustomLexerContext_Find_match(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(7, ctx.Width()); diff != "" { + if diff := cmp.Diff(7, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\n!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello\n!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } } -func TestCustomLexerContext_Find_short_match(t *testing.T) { +func TestCustomLexerCursor_Find_short_match(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), + ) - if diff := cmp.Diff("Find!", ctx.Find([]string{"no match", "Find!"})); diff != "" { + if diff := cmp.Diff("Find!", cursor.Find([]string{"no match", "Find!"})); diff != "" { t.Errorf("Find (-want +got):\n%s", diff) } @@ -591,7 +579,7 @@ func TestCustomLexerContext_Find_short_match(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -601,33 +589,32 @@ func TestCustomLexerContext_Find_short_match(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(7, ctx.Width()); diff != "" { + if diff := cmp.Diff(7, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\n!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello\n!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } } //nolint:dupl // Similar to TestLexer_DiscardTo/no_match -func TestCustomLexerContext_Find_no_match(t *testing.T) { +func TestCustomLexerCursor_Find_no_match(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), + ) - if diff := cmp.Diff("", ctx.Find([]string{"no match"})); diff != "" { + if diff := cmp.Diff("", cursor.Find([]string{"no match"})); diff != "" { t.Errorf("Find (-want +got):\n%s", diff) } @@ -637,7 +624,7 @@ func TestCustomLexerContext_Find_no_match(t *testing.T) { Column: 7, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -647,39 +634,38 @@ func TestCustomLexerContext_Find_no_match(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(12, ctx.Width()); diff != "" { + if diff := cmp.Diff(12, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\n!Find!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello\n!Find!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } } -func TestCustomLexerContext_Ignore(t *testing.T) { +func TestCustomLexerCursor_Ignore(t *testing.T) { t.Parallel() t.Run("basic", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Ignore!\n"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Ignore!\n"), &lexWordState{}), + ) - if diff := cmp.Diff(7, ctx.AdvanceN(7)); diff != "" { + if diff := cmp.Diff(7, cursor.AdvanceN(7)); diff != "" { t.Errorf("AdvanceN (-want +got):\n%s", diff) } - if diff := cmp.Diff("Ignore!", string(ctx.PeekN(7))); diff != "" { + if diff := cmp.Diff("Ignore!", string(cursor.PeekN(7))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -689,7 +675,7 @@ func TestCustomLexerContext_Ignore(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -699,25 +685,25 @@ func TestCustomLexerContext_Ignore(t *testing.T) { Column: 1, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(7, ctx.Width()); diff != "" { + if diff := cmp.Diff(7, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Hello\n!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Hello\n!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - ctx.Ignore() + cursor.Ignore() - if diff := cmp.Diff(7, ctx.AdvanceN(7)); diff != "" { + if diff := cmp.Diff(7, cursor.AdvanceN(7)); diff != "" { t.Errorf("AdvanceN (-want +got):\n%s", diff) } - if diff := cmp.Diff("\n", string(ctx.PeekN(1))); diff != "" { + if diff := cmp.Diff("\n", string(cursor.PeekN(1))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -727,7 +713,7 @@ func TestCustomLexerContext_Ignore(t *testing.T) { Column: 9, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -737,41 +723,40 @@ func TestCustomLexerContext_Ignore(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(7, ctx.Width()); diff != "" { + if diff := cmp.Diff(7, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("Ignore!", ctx.Token()); diff != "" { + if diff := cmp.Diff("Ignore!", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) } -func TestCustomLexerContext_DiscardTo(t *testing.T) { +func TestCustomLexerCursor_DiscardTo(t *testing.T) { t.Parallel() //nolint:dupl // Similar to TestLexer_Find_match t.Run("match", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), + ) - if diff := cmp.Diff("Find", ctx.DiscardTo([]string{"Find"})); diff != "" { + if diff := cmp.Diff("Find", cursor.DiscardTo([]string{"Find"})); diff != "" { t.Errorf("DiscardTo (-want +got):\n%s", diff) } - if diff := cmp.Diff("Find!", string(ctx.PeekN(5))); diff != "" { + if diff := cmp.Diff("Find!", string(cursor.PeekN(5))); diff != "" { t.Errorf("PeekN (-want +got):\n%s", diff) } @@ -781,7 +766,7 @@ func TestCustomLexerContext_DiscardTo(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -791,19 +776,19 @@ func TestCustomLexerContext_DiscardTo(t *testing.T) { Column: 2, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) @@ -812,12 +797,11 @@ func TestCustomLexerContext_DiscardTo(t *testing.T) { t.Run("no match", func(t *testing.T) { t.Parallel() - ctx := CustomLexerContext{ - Context: context.Background(), - l: NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), - } + cursor := NewCustomLexerCursor( + NewCustomLexer(strings.NewReader("Hello\n!Find!"), &lexWordState{}), + ) - if diff := cmp.Diff("", ctx.DiscardTo([]string{"no match"})); diff != "" { + if diff := cmp.Diff("", cursor.DiscardTo([]string{"no match"})); diff != "" { t.Errorf("DiscardTo (-want +got):\n%s", diff) } @@ -827,7 +811,7 @@ func TestCustomLexerContext_DiscardTo(t *testing.T) { Column: 7, } - if diff := cmp.Diff(expectedPos, ctx.Pos()); diff != "" { + if diff := cmp.Diff(expectedPos, cursor.Pos()); diff != "" { t.Errorf("Pos (-want +got):\n%s", diff) } @@ -837,19 +821,19 @@ func TestCustomLexerContext_DiscardTo(t *testing.T) { Column: 7, } - if diff := cmp.Diff(expectedCursor, ctx.Cursor()); diff != "" { + if diff := cmp.Diff(expectedCursor, cursor.Cursor()); diff != "" { t.Errorf("Cursor (-want +got):\n%s", diff) } - if diff := cmp.Diff(0, ctx.Width()); diff != "" { + if diff := cmp.Diff(0, cursor.Width()); diff != "" { t.Errorf("Width (-want +got):\n%s", diff) } - if diff := cmp.Diff("", ctx.Token()); diff != "" { + if diff := cmp.Diff("", cursor.Token()); diff != "" { t.Errorf("Token (-want +got):\n%s", diff) } - if diff := cmp.Diff(nil, ctx.l.Err(), cmpopts.EquateErrors()); diff != "" { + if diff := cmp.Diff(nil, cursor.l.Err(), cmpopts.EquateErrors()); diff != "" { t.Errorf("Err (-want +got):\n%s", diff) } }) diff --git a/ini_example_test.go b/ini_example_test.go index 02b456b..15be90e 100644 --- a/ini_example_test.go +++ b/ini_example_test.go @@ -87,12 +87,12 @@ var ( // lexINI is the initial lexer state for INI files. // //nolint:ireturn // returning the generic interface is needed to return the previous value. -func lexINI(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexINI(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { for { - rn := ctx.Peek() + rn := cursor.Peek() switch rn { case ' ', '\t', '\r', '\n': - ctx.Discard() + cursor.Discard() case '[', ']', '=': return lexparse.LexStateFn(lexINIOper), nil case ';', '#': @@ -108,9 +108,9 @@ func lexINI(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexINIOper lexes an operator token. // //nolint:ireturn // returning the generic interface is needed to return the previous value. -func lexINIOper(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { - oper := ctx.NextRune() - ctx.Emit(lexINITypeOper) +func lexINIOper(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { + oper := cursor.NextRune() + cursor.Emit(lexINITypeOper) if oper == '=' { return lexparse.LexStateFn(lexINIValue), nil @@ -122,9 +122,9 @@ func lexINIOper(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexINIIden lexes an identifier token (section name or property key). // //nolint:ireturn // returning the generic interface is needed to return the previous value. -func lexINIIden(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { - if next := ctx.Find([]string{"]", "="}); next != "" { - ctx.Emit(lexINITypeIden) +func lexINIIden(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { + if next := cursor.Find([]string{"]", "="}); next != "" { + cursor.Emit(lexINITypeIden) return lexparse.LexStateFn(lexINIOper), nil } @@ -134,9 +134,9 @@ func lexINIIden(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexINIValue lexes a property value token. // //nolint:ireturn // returning the generic interface is needed to return the previous value. -func lexINIValue(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { - ctx.Find([]string{";", "\n"}) - ctx.Emit(lexINITypeValue) +func lexINIValue(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { + cursor.Find([]string{";", "\n"}) + cursor.Emit(lexINITypeValue) return lexparse.LexStateFn(lexINI), nil } @@ -144,9 +144,9 @@ func lexINIValue(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexINIComment lexes a comment token. // //nolint:ireturn // returning the generic interface is needed to return the previous value. -func lexINIComment(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { - ctx.Find([]string{"\n"}) - ctx.Emit(lexINITypeComment) +func lexINIComment(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { + cursor.Find([]string{"\n"}) + cursor.Emit(lexINITypeComment) return lexparse.LexStateFn(lexINI), nil } diff --git a/lexparse_test.go b/lexparse_test.go index 20e33ca..83c756a 100644 --- a/lexparse_test.go +++ b/lexparse_test.go @@ -15,6 +15,7 @@ package lexparse import ( + "context" "errors" "strings" "testing" @@ -114,7 +115,7 @@ var ( type lexErrState struct{} //nolint:ireturn // returning interface is required to satisfy LexState. -func (e *lexErrState) Run(*CustomLexerContext) (LexState, error) { +func (e *lexErrState) Run(context.Context, *CustomLexerCursor) (LexState, error) { return nil, errState } diff --git a/template_example_test.go b/template_example_test.go index 23e16b3..9fff1eb 100644 --- a/template_example_test.go +++ b/template_example_test.go @@ -106,22 +106,22 @@ func lexTokenErr(err error, t *lexparse.Token) error { // lexText tokenizes normal text. // //nolint:ireturn // returning interface is required to satisfy lexparse.LexState. -func lexText(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexText(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { for { - p := string(ctx.PeekN(2)) + p := string(cursor.PeekN(2)) if p == tokenBlockStart || p == tokenVarStart { - if ctx.Width() > 0 { - ctx.Emit(lexTypeText) + if cursor.Width() > 0 { + cursor.Emit(lexTypeText) } return lexparse.LexStateFn(lexCode), nil } // Advance the input. - if !ctx.Advance() { + if !cursor.Advance() { // End of input. Emit the text up to this point. - if ctx.Width() > 0 { - ctx.Emit(lexTypeText) + if cursor.Width() > 0 { + cursor.Emit(lexTypeText) } return nil, io.EOF @@ -132,17 +132,17 @@ func lexText(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexCode tokenizes template code. // //nolint:ireturn // returning interface is required to satisfy lexparse.LexState. -func lexCode(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexCode(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { // Consume whitespace and discard it. // TODO(#94): use backtracking - for unicode.IsSpace(ctx.Peek()) { - if !ctx.Discard() { + for unicode.IsSpace(cursor.Peek()) { + if !cursor.Discard() { // End of input return nil, io.EOF } } - rn := ctx.Peek() + rn := cursor.Peek() switch { case idenRegexp.MatchString(string(rn)): return lexparse.LexStateFn(lexIden), nil @@ -150,21 +150,21 @@ func lexCode(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { return lexparse.LexStateFn(lexSymbol), nil default: return nil, fmt.Errorf("%w: %q; line: %d, column: %d", errRune, - rn, ctx.Pos().Line, ctx.Pos().Column) + rn, cursor.Pos().Line, cursor.Pos().Column) } } // lexIden tokenizes identifiers (e.g. variable names). // //nolint:ireturn // returning interface is required to satisfy lexparse.LexState. -func lexIden(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexIden(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { for { - if rn := ctx.Peek(); !idenRegexp.MatchString(string(rn)) { - ctx.Emit(lexTypeIdentifier) + if rn := cursor.Peek(); !idenRegexp.MatchString(string(rn)) { + cursor.Emit(lexTypeIdentifier) return lexparse.LexStateFn(lexCode), nil } - if !ctx.Advance() { + if !cursor.Advance() { return nil, io.EOF } } @@ -173,29 +173,29 @@ func lexIden(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { // lexSymbol tokenizes template symbols (e.g. {%, {{, }}, %}). // //nolint:ireturn // returning interface is required to satisfy lexparse.LexState. -func lexSymbol(ctx *lexparse.CustomLexerContext) (lexparse.LexState, error) { +func lexSymbol(_ context.Context, cursor *lexparse.CustomLexerCursor) (lexparse.LexState, error) { for { - switch ctx.Token() { + switch cursor.Token() { case tokenVarStart: - ctx.Emit(lexTypeVarStart) + cursor.Emit(lexTypeVarStart) return lexparse.LexStateFn(lexCode), nil case tokenVarEnd: - ctx.Emit(lexTypeVarEnd) + cursor.Emit(lexTypeVarEnd) return lexparse.LexStateFn(lexText), nil case tokenBlockStart: - ctx.Emit(lexTypeBlockStart) + cursor.Emit(lexTypeBlockStart) return lexparse.LexStateFn(lexCode), nil case tokenBlockEnd: - ctx.Emit(lexTypeBlockEnd) + cursor.Emit(lexTypeBlockEnd) return lexparse.LexStateFn(lexText), nil default: - if rn := ctx.Peek(); !symbolRegexp.MatchString(string(rn)) { + if rn := cursor.Peek(); !symbolRegexp.MatchString(string(rn)) { return nil, fmt.Errorf("symbol: %w: %q; line: %d, column: %d", - errRune, rn, ctx.Pos().Line, ctx.Pos().Column) + errRune, rn, cursor.Pos().Line, cursor.Pos().Column) } } - if !ctx.Advance() { + if !cursor.Advance() { return nil, io.EOF } }