Skip to content

Commit 8797338

Browse files
authored
Merge pull request #174 from ianlewis/169-bug-positionfilename-is-never-set
feat: set filename
2 parents 973930e + f20666d commit 8797338

4 files changed

Lines changed: 109 additions & 10 deletions

File tree

custom.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"io"
24+
"os"
2425
"strings"
2526

2627
"github.com/ianlewis/runeio"
@@ -87,25 +88,34 @@ type CustomLexer struct {
8788
// NewCustomLexer creates a new Lexer initialized with the given starting
8889
// [LexState]. The Lexer takes ownership of the tokens channel and closes it
8990
// when lexing is completed.
90-
func NewCustomLexer(r io.Reader, startingState LexState) *CustomLexer {
91+
func NewCustomLexer(reader io.Reader, startingState LexState) *CustomLexer {
92+
var fileName string
93+
94+
file, isFile := reader.(*os.File)
95+
if isFile {
96+
fileName = file.Name()
97+
}
98+
9199
customLexer := &CustomLexer{
92100
state: startingState,
93101
pos: Position{
94-
Offset: 0,
95-
Line: 1,
96-
Column: 1,
102+
Filename: fileName,
103+
Offset: 0,
104+
Line: 1,
105+
Column: 1,
97106
},
98107
cursor: Position{
99-
Offset: 0,
100-
Line: 1,
101-
Column: 1,
108+
Filename: fileName,
109+
Offset: 0,
110+
Line: 1,
111+
Column: 1,
102112
},
103113
}
104114

105115
// If already a *bufio.Reader, use it directly.
106-
br, ok := r.(*bufio.Reader)
107-
if !ok {
108-
br = bufio.NewReader(r)
116+
br, isBufReader := reader.(*bufio.Reader)
117+
if !isBufReader {
118+
br = bufio.NewReader(reader)
109119
}
110120

111121
customLexer.r = runeio.NewReader(br)
@@ -464,3 +474,9 @@ func (l *CustomLexer) setErr(err error) {
464474
l.err = err
465475
}
466476
}
477+
478+
// SetFilename sets the filename in the lexer's positional information.
479+
func (l *CustomLexer) SetFilename(name string) {
480+
l.pos.Filename = name
481+
l.cursor.Filename = name
482+
}

custom_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,3 +953,36 @@ func TestCustomLexer_NextToken(t *testing.T) {
953953
}
954954
})
955955
}
956+
957+
func TestCustomLexer_SetFilename(t *testing.T) {
958+
t.Parallel()
959+
960+
t.Run("SetFilename", func(t *testing.T) {
961+
t.Parallel()
962+
963+
customLexer := NewCustomLexer(strings.NewReader("Hello World!"), &lexWordState{})
964+
customLexer.SetFilename("testfile.txt")
965+
966+
expectedPos := Position{
967+
Offset: 0,
968+
Line: 1,
969+
Column: 1,
970+
Filename: "testfile.txt",
971+
}
972+
973+
if diff := cmp.Diff(expectedPos, customLexer.Pos()); diff != "" {
974+
t.Errorf("Pos (-want +got):\n%s", diff)
975+
}
976+
977+
expectedCursor := Position{
978+
Offset: 0,
979+
Line: 1,
980+
Column: 1,
981+
Filename: "testfile.txt",
982+
}
983+
984+
if diff := cmp.Diff(expectedCursor, customLexer.Cursor()); diff != "" {
985+
t.Errorf("Cursor (-want +got):\n%s", diff)
986+
}
987+
})
988+
}

scanner.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"errors"
2020
"fmt"
2121
"io"
22+
"os"
2223
"text/scanner"
2324
)
2425

@@ -62,13 +63,23 @@ type ScanningLexer struct {
6263
// NewScanningLexer creates a new ScanningLexer that reads from the given
6364
// [io.Reader].
6465
func NewScanningLexer(r io.Reader) *ScanningLexer {
66+
var fileName string
67+
68+
file, ok := r.(*os.File)
69+
if ok {
70+
fileName = file.Name()
71+
}
72+
6573
l := ScanningLexer{}
6674
l.s = &scanner.Scanner{
6775
Error: func(s *scanner.Scanner, msg string) {
6876
if l.err == nil {
6977
l.err = fmt.Errorf("%w: %s: %s", errScanner, s.Position, msg)
7078
}
7179
},
80+
Position: scanner.Position{
81+
Filename: fileName,
82+
},
7283
}
7384
l.s = l.s.Init(r)
7485
// Configure the scanner to be more generic and to not skip Go comments.
@@ -102,3 +113,8 @@ func (l *ScanningLexer) newToken(typ TokenType) *Token {
102113
End: Position(l.s.Pos()),
103114
}
104115
}
116+
117+
// SetFilename sets the filename in the lexer's positional information.
118+
func (l *ScanningLexer) SetFilename(name string) {
119+
l.s.Filename = name
120+
}

scanner_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,37 @@ func TestScannerLexer_NextToken(t *testing.T) {
160160
})
161161
}
162162
}
163+
164+
func TestScanningLexer_SetFilename(t *testing.T) {
165+
t.Parallel()
166+
167+
t.Run("SetFilename", func(t *testing.T) {
168+
t.Parallel()
169+
170+
customLexer := NewScanningLexer(strings.NewReader("Hello World!"))
171+
customLexer.SetFilename("testfile.txt")
172+
173+
expectedToken := &Token{
174+
Type: TokenType(scanner.Ident),
175+
Value: "Hello",
176+
Start: Position{
177+
Offset: 0,
178+
Line: 1,
179+
Column: 1,
180+
Filename: "testfile.txt",
181+
},
182+
End: Position{
183+
Offset: 5,
184+
Line: 1,
185+
Column: 6,
186+
Filename: "testfile.txt",
187+
},
188+
}
189+
190+
token := customLexer.NextToken(context.Background())
191+
192+
if diff := cmp.Diff(expectedToken, token); diff != "" {
193+
t.Errorf("Pos (-want +got):\n%s", diff)
194+
}
195+
})
196+
}

0 commit comments

Comments
 (0)