aboutsummaryrefslogtreecommitdiff
path: root/src/text/template/parse/parse.go
diff options
context:
space:
mode:
authorTim Cooper <tim.cooper@layeh.com>2017-09-26 21:14:03 -0300
committerRob Pike <r@golang.org>2017-10-17 02:06:15 +0000
commit3be5d551801a97a76e236a2a53489b1c9c22e665 (patch)
tree99281e70b044f736eef5def74773045673392747 /src/text/template/parse/parse.go
parent0b2cb89196967030ae005076f0166ad7d6024083 (diff)
downloadgo-3be5d551801a97a76e236a2a53489b1c9c22e665.tar.xz
text/template: add break, continue actions in ranges
Adds the two range control actions "break" and "continue". They act the same as the Go keywords break and continue, but are simplified in that only the innermost range statement can be broken out of or continued. Fixes #20531 Change-Id: I4412b3bbfd4dadb0ab74ae718e308c1ac7a0a1e9 Reviewed-on: https://go-review.googlesource.com/66410 Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/text/template/parse/parse.go')
-rw-r--r--src/text/template/parse/parse.go44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
index a91a544ce0..ad9c051978 100644
--- a/src/text/template/parse/parse.go
+++ b/src/text/template/parse/parse.go
@@ -23,12 +23,13 @@ type Tree struct {
Root *ListNode // top-level root of the tree.
text string // text parsed to create the template (or its parent)
// Parsing only; cleared after parse.
- funcs []map[string]interface{}
- lex *lexer
- token [3]item // three-token lookahead for parser.
- peekCount int
- vars []string // variables defined at the moment.
- treeSet map[string]*Tree
+ funcs []map[string]interface{}
+ lex *lexer
+ token [3]item // three-token lookahead for parser.
+ peekCount int
+ vars []string // variables defined at the moment.
+ treeSet map[string]*Tree
+ rangeDepth int // nesting level of range loops.
}
// Copy returns a copy of the Tree. Any parsing state is discarded.
@@ -219,6 +220,7 @@ func (t *Tree) stopParse() {
t.vars = nil
t.funcs = nil
t.treeSet = nil
+ t.rangeDepth = 0
}
// Parse parses the template definition string to construct a representation of
@@ -373,6 +375,10 @@ func (t *Tree) action() (n Node) {
return t.templateControl()
case itemWith:
return t.withControl()
+ case itemBreak:
+ return t.breakControl()
+ case itemContinue:
+ return t.continueControl()
}
t.backup()
token := t.peek()
@@ -453,7 +459,13 @@ func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int
defer t.popVars(len(t.vars))
pipe = t.pipeline(context)
var next Node
+ if context == "range" {
+ t.rangeDepth++
+ }
list, next = t.itemList()
+ if context == "range" {
+ t.rangeDepth--
+ }
switch next.Type() {
case nodeEnd: //done
case nodeElse:
@@ -498,6 +510,26 @@ func (t *Tree) rangeControl() Node {
return t.newRange(t.parseControl(false, "range"))
}
+// Break:
+// {{break}}
+// Break keyword is past.
+func (t *Tree) breakControl() Node {
+ if t.rangeDepth == 0 {
+ t.errorf("unexpected break outside of range")
+ }
+ return t.newBreak(t.expect(itemRightDelim, "break").pos)
+}
+
+// Continue:
+// {{continue}}
+// Continue keyword is past.
+func (t *Tree) continueControl() Node {
+ if t.rangeDepth == 0 {
+ t.errorf("unexpected continue outside of range")
+ }
+ return t.newContinue(t.expect(itemRightDelim, "continue").pos)
+}
+
// With:
// {{with pipeline}} itemList {{end}}
// {{with pipeline}} itemList {{else}} itemList {{end}}