1
0
mirror of https://github.com/golang/go synced 2024-11-20 08:04:42 -07:00

text/template: fix pos info when trimming newlines

The lexer keeps the byte offset and the line for the rune it's currently
on. This was simple enough up until whitespace trimming was introduced.

With whitespace trimming, we might skip over newlines. In that case, the
lexer wasn't properly updating the line counter. Fix it.

Also, TestPos now checks that the line is correct too, which it was
ignoring before. This was necessary to test this scenario in the lexer.

Fixes #21778.

Change-Id: I3880f3adf02662eac8f818d5caa6935cca9cb33b
Reviewed-on: https://go-review.googlesource.com/61870
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Daniel Martí 2017-09-06 11:57:16 +02:00
parent 38ad33088c
commit 9b8964bf2d
2 changed files with 25 additions and 2 deletions

View File

@ -164,6 +164,7 @@ func (l *lexer) emit(t itemType) {
// ignore skips over the pending input before this point.
func (l *lexer) ignore() {
l.line += strings.Count(l.input[l.start:l.pos], "\n")
l.start = l.pos
}

View File

@ -404,6 +404,9 @@ func equal(i1, i2 []item, checkPos bool) bool {
if checkPos && i1[k].pos != i2[k].pos {
return false
}
if checkPos && i1[k].line != i2[k].line {
return false
}
}
return true
}
@ -452,7 +455,7 @@ func TestDelims(t *testing.T) {
}
var lexPosTests = []lexTest{
{"empty", "", []item{tEOF}},
{"empty", "", []item{{itemEOF, 0, "", 1}}},
{"punctuation", "{{,@%#}}", []item{
{itemLeftDelim, 0, "{{", 1},
{itemChar, 2, ",", 1},
@ -470,6 +473,24 @@ var lexPosTests = []lexTest{
{itemText, 13, "xyz", 1},
{itemEOF, 16, "", 1},
}},
{"trimafter", "{{x -}}\n{{y}}", []item{
{itemLeftDelim, 0, "{{", 1},
{itemIdentifier, 2, "x", 1},
{itemRightDelim, 5, "}}", 1},
{itemLeftDelim, 8, "{{", 2},
{itemIdentifier, 10, "y", 2},
{itemRightDelim, 11, "}}", 2},
{itemEOF, 13, "", 2},
}},
{"trimbefore", "{{x}}\n{{- y}}", []item{
{itemLeftDelim, 0, "{{", 1},
{itemIdentifier, 2, "x", 1},
{itemRightDelim, 3, "}}", 1},
{itemLeftDelim, 6, "{{", 2},
{itemIdentifier, 10, "y", 2},
{itemRightDelim, 11, "}}", 2},
{itemEOF, 13, "", 2},
}},
}
// The other tests don't check position, to make the test cases easier to construct.
@ -485,7 +506,8 @@ func TestPos(t *testing.T) {
if !equal(items[i:i+1], test.items[i:i+1], true) {
i1 := items[i]
i2 := test.items[i]
t.Errorf("\t#%d: got {%v %d %q} expected {%v %d %q}", i, i1.typ, i1.pos, i1.val, i2.typ, i2.pos, i2.val)
t.Errorf("\t#%d: got {%v %d %q %d} expected {%v %d %q %d}",
i, i1.typ, i1.pos, i1.val, i1.line, i2.typ, i2.pos, i2.val, i2.line)
}
}
}