]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: fix pos info when trimming newlines
authorDaniel Martí <mvdan@mvdan.cc>
Wed, 6 Sep 2017 09:57:16 +0000 (11:57 +0200)
committerDaniel Martí <mvdan@mvdan.cc>
Thu, 7 Sep 2017 14:50:23 +0000 (14:50 +0000)
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>

src/text/template/parse/lex.go
src/text/template/parse/lex_test.go

index cdecd412eea6234679b266069850e899408689ae..2cde4a2ca1f8e443cdf28dea695324241031c570 100644 (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
 }
 
index 2c73bb623aebeac676b21cb8ebf9a2424b577429..cb01cd98b6ab2263618a5feec888e8bfc58807d5 100644 (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)
                                        }
                                }
                        }