]> Cypherpunks repositories - gostls13.git/commitdiff
text/template/parse: add a mode to skip func-check on parsing
authorAriel Mashraki <ariel@mashraki.co.il>
Sun, 14 Mar 2021 17:04:31 +0000 (19:04 +0200)
committerIan Lance Taylor <iant@golang.org>
Mon, 19 Apr 2021 16:49:40 +0000 (16:49 +0000)
Following the discussion on #34652 and the proposal of #36911 (gopls),
this CL adds an option to skip the function declartion check on parsing,
in order to make it possible to parse arbitrary template text files and
get their AST.

Fixed #38627

Change-Id: Id1e0360fc726b49dcdd49716ce25563ebaae6c10
Reviewed-on: https://go-review.googlesource.com/c/go/+/301493
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Ian Lance Taylor <iant@golang.org>

src/text/template/parse/parse.go
src/text/template/parse/parse_test.go

index 5e6e512eb4314cd9aaa6c6555ba9a2bc095916a1..ff1358b0010f35fe2c406f3be526cded7eee125a 100644 (file)
@@ -38,7 +38,8 @@ type Tree struct {
 type Mode uint
 
 const (
-       ParseComments Mode = 1 << iota // parse comments and add them to AST
+       ParseComments  Mode = 1 << iota // parse comments and add them to AST
+       DeferFuncCheck                  // defer type checking functions until template is executed
 )
 
 // Copy returns a copy of the Tree. Any parsing state is discarded.
@@ -689,7 +690,8 @@ func (t *Tree) operand() Node {
 func (t *Tree) term() Node {
        switch token := t.nextNonSpace(); token.typ {
        case itemIdentifier:
-               if !t.hasFunction(token.val) {
+               checkFunc := t.Mode&DeferFuncCheck == 0
+               if checkFunc && !t.hasFunction(token.val) {
                        t.errorf("function %q not defined", token.val)
                }
                return NewIdentifier(token.val).SetTree(t).SetPos(token.pos)
index 220f984777b74ec13d4b0bd616bfb98395860cae..c4585f6912cb42a7dac1e38a189f4c7a702add3b 100644 (file)
@@ -379,6 +379,22 @@ func TestParseWithComments(t *testing.T) {
        }
 }
 
+func TestDeferFuncCheck(t *testing.T) {
+       oldTextFormat := textFormat
+       textFormat = "%q"
+       defer func() { textFormat = oldTextFormat }()
+       tr := New("defer func check")
+       tr.Mode = DeferFuncCheck
+       tmpl, err := tr.Parse("{{fn 1 2}}", "", "", make(map[string]*Tree))
+       if err != nil {
+               t.Fatalf("unexpected error: %v", err)
+       }
+       expected := "{{fn 1 2}}"
+       if result := tmpl.Root.String(); result != expected {
+               t.Errorf("got\n\t%v\nexpected\n\t%v", result, expected)
+       }
+}
+
 type isEmptyTest struct {
        name  string
        input string