summaryrefslogtreecommitdiff
path: root/src/text
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2018-08-30 11:02:41 -0600
committerDaniel Martí <mvdan@mvdan.cc>2018-09-05 21:27:04 +0000
commit98fd66808fafb6496caeb3e848ae277b734f8ed9 (patch)
tree3b870b5ebe5e48b06ea09ad5af65cec915264d29 /src/text
parent2524ed19946f10a9b0ecc4bf54f1a23c18faa525 (diff)
downloadgo-git-98fd66808fafb6496caeb3e848ae277b734f8ed9.tar.gz
text/template: simplify line tracking in the lexer
First, move the strings.Count logic out of emit, since only itemText requires that. Use it in those call sites. itemLeftDelim and itemRightDelim cannot contain newlines, as they're the "{{" and "}}" tokens. Secondly, introduce a startLine lexer field so that we don't have to keep track of it elsewhere. That's also a requirement to move the strings.Count out of emit, as emit modifies the start position field. Change-Id: I69175f403487607a8e5b561b3f1916ee9dc3c0c6 Reviewed-on: https://go-review.googlesource.com/132275 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/text')
-rw-r--r--src/text/template/parse/lex.go22
1 files changed, 9 insertions, 13 deletions
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
index c0843af6ed..94a676c579 100644
--- a/src/text/template/parse/lex.go
+++ b/src/text/template/parse/lex.go
@@ -117,6 +117,7 @@ type lexer struct {
items chan item // channel of scanned items
parenDepth int // nesting depth of ( ) exprs
line int // 1+number of newlines seen
+ startLine int // start line of this item
}
// next returns the next rune in the input.
@@ -152,19 +153,16 @@ func (l *lexer) backup() {
// emit passes an item back to the client.
func (l *lexer) emit(t itemType) {
- l.items <- item{t, l.start, l.input[l.start:l.pos], l.line}
- // Some items contain text internally. If so, count their newlines.
- switch t {
- case itemText, itemLeftDelim, itemRightDelim:
- l.line += strings.Count(l.input[l.start:l.pos], "\n")
- }
+ l.items <- item{t, l.start, l.input[l.start:l.pos], l.startLine}
l.start = l.pos
+ l.startLine = l.line
}
// 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
+ l.startLine = l.line
}
// accept consumes the next rune if it's from the valid set.
@@ -186,7 +184,7 @@ func (l *lexer) acceptRun(valid string) {
// errorf returns an error token and terminates the scan by passing
// back a nil pointer that will be the next state, terminating l.nextItem.
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
- l.items <- item{itemError, l.start, fmt.Sprintf(format, args...), l.line}
+ l.items <- item{itemError, l.start, fmt.Sprintf(format, args...), l.startLine}
return nil
}
@@ -218,6 +216,7 @@ func lex(name, input, left, right string) *lexer {
rightDelim: right,
items: make(chan item),
line: 1,
+ startLine: 1,
}
go l.run()
return l
@@ -252,16 +251,17 @@ func lexText(l *lexer) stateFn {
}
l.pos -= trimLength
if l.pos > l.start {
+ l.line += strings.Count(l.input[l.start:l.pos], "\n")
l.emit(itemText)
}
l.pos += trimLength
l.ignore()
return lexLeftDelim
- } else {
- l.pos = Pos(len(l.input))
}
+ l.pos = Pos(len(l.input))
// Correctly reached EOF.
if l.pos > l.start {
+ l.line += strings.Count(l.input[l.start:l.pos], "\n")
l.emit(itemText)
}
l.emit(itemEOF)
@@ -609,14 +609,10 @@ Loop:
// lexRawQuote scans a raw quoted string.
func lexRawQuote(l *lexer) stateFn {
- startLine := l.line
Loop:
for {
switch l.next() {
case eof:
- // Restore line number to location of opening quote.
- // We will error out so it's ok just to overwrite the field.
- l.line = startLine
return l.errorf("unterminated raw quoted string")
case '`':
break Loop