diff options
author | Daniel Martí <mvdan@mvdan.cc> | 2018-08-30 11:02:41 -0600 |
---|---|---|
committer | Daniel Martí <mvdan@mvdan.cc> | 2018-09-05 21:27:04 +0000 |
commit | 98fd66808fafb6496caeb3e848ae277b734f8ed9 (patch) | |
tree | 3b870b5ebe5e48b06ea09ad5af65cec915264d29 /src/text | |
parent | 2524ed19946f10a9b0ecc4bf54f1a23c18faa525 (diff) | |
download | go-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.go | 22 |
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 |