diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go index c0843af6ede95b..94a676c579cb48 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