1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 // state represents the state of an execution. It's not part of the
19 // template so that multiple executions of the same template
20 // can execute in parallel.
24 node parse
.Node
// current node, for errors
25 vars
[]variable
// push-down stack of variable values.
28 // variable holds the dynamic value of a variable such as $, $x etc.
29 type variable
struct {
34 // push pushes a new variable on the stack.
35 func (s
*state
) push(name
string, value reflect
.Value
) {
36 s
.vars
= append(s
.vars
, variable
{name
, value
})
39 // mark returns the length of the variable stack.
40 func (s
*state
) mark() int {
44 // pop pops the variable stack up to the mark.
45 func (s
*state
) pop(mark
int) {
46 s
.vars
= s
.vars
[0:mark
]
49 // setVar overwrites the top-nth variable on the stack. Used by range iterations.
50 func (s
*state
) setVar(n
int, value reflect
.Value
) {
51 s
.vars
[len(s
.vars
)-n
].value
= value
54 // varValue returns the value of the named variable.
55 func (s
*state
) varValue(name
string) reflect
.Value
{
56 for i
:= s
.mark() - 1; i
>= 0; i
-- {
57 if s
.vars
[i
].name
== name
{
58 return s
.vars
[i
].value
61 s
.errorf("undefined variable: %s", name
)
65 var zero reflect
.Value
67 // at marks the state to be on node n, for error reporting.
68 func (s
*state
) at(node parse
.Node
) {
72 // doublePercent returns the string with %'s replaced by %%, if necessary,
73 // so it can be used safely inside a Printf format string.
74 func doublePercent(str
string) string {
75 if strings
.Contains(str
, "%") {
76 str
= strings
.Replace(str
, "%", "%%", -1)
81 // errorf formats the error and terminates processing.
82 func (s
*state
) errorf(format
string, args
...interface{}) {
83 name
:= doublePercent(s
.tmpl
.Name())
85 format
= fmt
.Sprintf("template: %s: %s", name
, format
)
87 location
, context
:= s
.tmpl
.ErrorContext(s
.node
)
88 format
= fmt
.Sprintf("template: %s: executing %q at <%s>: %s", location
, name
, doublePercent(context
), format
)
90 panic(fmt
.Errorf(format
, args
...))
93 // errRecover is the handler that turns panics into returns from the top
95 func errRecover(errp
*error
) {
98 switch err
:= e
.(type) {
109 // ExecuteTemplate applies the template associated with t that has the given name
110 // to the specified data object and writes the output to wr.
111 // If an error occurs executing the template or writing its output,
112 // execution stops, but partial results may already have been written to
113 // the output writer.
114 // A template may be executed safely in parallel.
115 func (t
*Template
) ExecuteTemplate(wr io
.Writer
, name
string, data
interface{}) error
{
118 return fmt
.Errorf("template: no template %q associated with template %q", name
, t
.name
)
120 return tmpl
.Execute(wr
, data
)
123 // Execute applies a parsed template to the specified data object,
124 // and writes the output to wr.
125 // If an error occurs executing the template or writing its output,
126 // execution stops, but partial results may already have been written to
127 // the output writer.
128 // A template may be executed safely in parallel.
129 func (t
*Template
) Execute(wr io
.Writer
, data
interface{}) (err error
) {
130 defer errRecover(&err
)
131 value
:= reflect
.ValueOf(data
)
135 vars
: []variable
{{"$", value
}},
138 if t
.Tree
== nil || t
.Root
== nil {
140 for name
, tmpl
:= range t
.tmpl
{
141 if tmpl
.Tree
== nil || tmpl
.Root
== nil {
147 fmt
.Fprintf(&b
, "%q", name
)
151 s
= "; defined templates are: " + b
.String()
153 state
.errorf("%q is an incomplete or empty template%s", t
.Name(), s
)
155 state
.walk(value
, t
.Root
)
159 // Walk functions step through the major pieces of the template structure,
160 // generating output as they go.
161 func (s
*state
) walk(dot reflect
.Value
, node parse
.Node
) {
163 switch node
:= node
.(type) {
164 case *parse
.ActionNode
:
165 // Do not pop variables so they persist until next end.
166 // Also, if the action declares variables, don't print the result.
167 val
:= s
.evalPipeline(dot
, node
.Pipe
)
168 if len(node
.Pipe
.Decl
) == 0 {
169 s
.printValue(node
, val
)
172 s
.walkIfOrWith(parse
.NodeIf
, dot
, node
.Pipe
, node
.List
, node
.ElseList
)
173 case *parse
.ListNode
:
174 for _
, node
:= range node
.Nodes
{
177 case *parse
.RangeNode
:
178 s
.walkRange(dot
, node
)
179 case *parse
.TemplateNode
:
180 s
.walkTemplate(dot
, node
)
181 case *parse
.TextNode
:
182 if _
, err
:= s
.wr
.Write(node
.Text
); err
!= nil {
185 case *parse
.WithNode
:
186 s
.walkIfOrWith(parse
.NodeWith
, dot
, node
.Pipe
, node
.List
, node
.ElseList
)
188 s
.errorf("unknown node: %s", node
)
192 // walkIfOrWith walks an 'if' or 'with' node. The two control structures
193 // are identical in behavior except that 'with' sets dot.
194 func (s
*state
) walkIfOrWith(typ parse
.NodeType
, dot reflect
.Value
, pipe
*parse
.PipeNode
, list
, elseList
*parse
.ListNode
) {
195 defer s
.pop(s
.mark())
196 val
:= s
.evalPipeline(dot
, pipe
)
197 truth
, ok
:= isTrue(val
)
199 s
.errorf("if/with can't use %v", val
)
202 if typ
== parse
.NodeWith
{
207 } else if elseList
!= nil {
208 s
.walk(dot
, elseList
)
212 // isTrue reports whether the value is 'true', in the sense of not the zero of its type,
213 // and whether the value has a meaningful truth value.
214 func isTrue(val reflect
.Value
) (truth
, ok
bool) {
216 // Something like var x interface{}, never set. It's a form of nil.
220 case reflect
.Array
, reflect
.Map
, reflect
.Slice
, reflect
.String
:
221 truth
= val
.Len() > 0
224 case reflect
.Complex64
, reflect
.Complex128
:
225 truth
= val
.Complex() != 0
226 case reflect
.Chan
, reflect
.Func
, reflect
.Ptr
, reflect
.Interface
:
228 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
229 truth
= val
.Int() != 0
230 case reflect
.Float32
, reflect
.Float64
:
231 truth
= val
.Float() != 0
232 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
233 truth
= val
.Uint() != 0
235 truth
= true // Struct values are always true.
242 func (s
*state
) walkRange(dot reflect
.Value
, r
*parse
.RangeNode
) {
244 defer s
.pop(s
.mark())
245 val
, _
:= indirect(s
.evalPipeline(dot
, r
.Pipe
))
246 // mark top of stack before any variables in the body are pushed.
248 oneIteration
:= func(index
, elem reflect
.Value
) {
249 // Set top var (lexically the second if there are two) to the element.
250 if len(r
.Pipe
.Decl
) > 0 {
253 // Set next var (lexically the first if there are two) to the index.
254 if len(r
.Pipe
.Decl
) > 1 {
261 case reflect
.Array
, reflect
.Slice
:
265 for i
:= 0; i
< val
.Len(); i
++ {
266 oneIteration(reflect
.ValueOf(i
), val
.Index(i
))
273 for _
, key
:= range sortKeys(val
.MapKeys()) {
274 oneIteration(key
, val
.MapIndex(key
))
283 elem
, ok
:= val
.Recv()
287 oneIteration(reflect
.ValueOf(i
), elem
)
293 case reflect
.Invalid
:
294 break // An invalid value is likely a nil map, etc. and acts like an empty map.
296 s
.errorf("range can't iterate over %v", val
)
298 if r
.ElseList
!= nil {
299 s
.walk(dot
, r
.ElseList
)
303 func (s
*state
) walkTemplate(dot reflect
.Value
, t
*parse
.TemplateNode
) {
305 tmpl
:= s
.tmpl
.tmpl
[t
.Name
]
307 s
.errorf("template %q not defined", t
.Name
)
309 // Variables declared by the pipeline persist.
310 dot
= s
.evalPipeline(dot
, t
.Pipe
)
313 // No dynamic scoping: template invocations inherit no variables.
314 newState
.vars
= []variable
{{"$", dot
}}
315 newState
.walk(dot
, tmpl
.Root
)
318 // Eval functions evaluate pipelines, commands, and their elements and extract
319 // values from the data structure by examining fields, calling methods, and so on.
320 // The printing of those values happens only through walk functions.
322 // evalPipeline returns the value acquired by evaluating a pipeline. If the
323 // pipeline has a variable declaration, the variable will be pushed on the
324 // stack. Callers should therefore pop the stack after they are finished
325 // executing commands depending on the pipeline value.
326 func (s
*state
) evalPipeline(dot reflect
.Value
, pipe
*parse
.PipeNode
) (value reflect
.Value
) {
331 for _
, cmd
:= range pipe
.Cmds
{
332 value
= s
.evalCommand(dot
, cmd
, value
) // previous value is this one's final arg.
333 // If the object has type interface{}, dig down one level to the thing inside.
334 if value
.Kind() == reflect
.Interface
&& value
.Type().NumMethod() == 0 {
335 value
= reflect
.ValueOf(value
.Interface()) // lovely!
338 for _
, variable
:= range pipe
.Decl
{
339 s
.push(variable
.Ident
[0], value
)
344 func (s
*state
) notAFunction(args
[]parse
.Node
, final reflect
.Value
) {
345 if len(args
) > 1 || final
.IsValid() {
346 s
.errorf("can't give argument to non-function %s", args
[0])
350 func (s
*state
) evalCommand(dot reflect
.Value
, cmd
*parse
.CommandNode
, final reflect
.Value
) reflect
.Value
{
351 firstWord
:= cmd
.Args
[0]
352 switch n
:= firstWord
.(type) {
353 case *parse
.FieldNode
:
354 return s
.evalFieldNode(dot
, n
, cmd
.Args
, final
)
355 case *parse
.ChainNode
:
356 return s
.evalChainNode(dot
, n
, cmd
.Args
, final
)
357 case *parse
.IdentifierNode
:
358 // Must be a function.
359 return s
.evalFunction(dot
, n
, cmd
, cmd
.Args
, final
)
360 case *parse
.PipeNode
:
361 // Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored.
362 return s
.evalPipeline(dot
, n
)
363 case *parse
.VariableNode
:
364 return s
.evalVariableNode(dot
, n
, cmd
.Args
, final
)
367 s
.notAFunction(cmd
.Args
, final
)
368 switch word
:= firstWord
.(type) {
369 case *parse
.BoolNode
:
370 return reflect
.ValueOf(word
.True
)
374 s
.errorf("nil is not a command")
375 case *parse
.NumberNode
:
376 return s
.idealConstant(word
)
377 case *parse
.StringNode
:
378 return reflect
.ValueOf(word
.Text
)
380 s
.errorf("can't evaluate command %q", firstWord
)
384 // idealConstant is called to return the value of a number in a context where
385 // we don't know the type. In that case, the syntax of the number tells us
386 // its type, and we use Go rules to resolve. Note there is no such thing as
387 // a uint ideal constant in this situation - the value must be of int type.
388 func (s
*state
) idealConstant(constant
*parse
.NumberNode
) reflect
.Value
{
389 // These are ideal constants but we don't know the type
390 // and we have no context. (If it was a method argument,
391 // we'd know what we need.) The syntax guides us to some extent.
394 case constant
.IsComplex
:
395 return reflect
.ValueOf(constant
.Complex128
) // incontrovertible.
396 case constant
.IsFloat
&& strings
.IndexAny(constant
.Text
, ".eE") >= 0:
397 return reflect
.ValueOf(constant
.Float64
)
399 n
:= int(constant
.Int64
)
400 if int64(n
) != constant
.Int64
{
401 s
.errorf("%s overflows int", constant
.Text
)
403 return reflect
.ValueOf(n
)
404 case constant
.IsUint
:
405 s
.errorf("%s overflows int", constant
.Text
)
410 func (s
*state
) evalFieldNode(dot reflect
.Value
, field
*parse
.FieldNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
412 return s
.evalFieldChain(dot
, dot
, field
, field
.Ident
, args
, final
)
415 func (s
*state
) evalChainNode(dot reflect
.Value
, chain
*parse
.ChainNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
417 // (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
418 pipe
:= s
.evalArg(dot
, nil, chain
.Node
)
419 if len(chain
.Field
) == 0 {
420 s
.errorf("internal error: no fields in evalChainNode")
422 return s
.evalFieldChain(dot
, pipe
, chain
, chain
.Field
, args
, final
)
425 func (s
*state
) evalVariableNode(dot reflect
.Value
, variable
*parse
.VariableNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
426 // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
428 value
:= s
.varValue(variable
.Ident
[0])
429 if len(variable
.Ident
) == 1 {
430 s
.notAFunction(args
, final
)
433 return s
.evalFieldChain(dot
, value
, variable
, variable
.Ident
[1:], args
, final
)
436 // evalFieldChain evaluates .X.Y.Z possibly followed by arguments.
437 // dot is the environment in which to evaluate arguments, while
438 // receiver is the value being walked along the chain.
439 func (s
*state
) evalFieldChain(dot
, receiver reflect
.Value
, node parse
.Node
, ident
[]string, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
441 for i
:= 0; i
< n
-1; i
++ {
442 receiver
= s
.evalField(dot
, ident
[i
], node
, nil, zero
, receiver
)
444 // Now if it's a method, it gets the arguments.
445 return s
.evalField(dot
, ident
[n
-1], node
, args
, final
, receiver
)
448 func (s
*state
) evalFunction(dot reflect
.Value
, node
*parse
.IdentifierNode
, cmd parse
.Node
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
451 function
, ok
:= findFunction(name
, s
.tmpl
)
453 s
.errorf("%q is not a defined function", name
)
455 return s
.evalCall(dot
, function
, cmd
, name
, args
, final
)
458 // evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
459 // The 'final' argument represents the return value from the preceding
460 // value of the pipeline, if any.
461 func (s
*state
) evalField(dot reflect
.Value
, fieldName
string, node parse
.Node
, args
[]parse
.Node
, final
, receiver reflect
.Value
) reflect
.Value
{
462 if !receiver
.IsValid() {
465 typ
:= receiver
.Type()
466 receiver
, _
= indirect(receiver
)
467 // Unless it's an interface, need to get to a value of type *T to guarantee
468 // we see all methods of T and *T.
470 if ptr
.Kind() != reflect
.Interface
&& ptr
.CanAddr() {
473 if method
:= ptr
.MethodByName(fieldName
); method
.IsValid() {
474 return s
.evalCall(dot
, method
, node
, fieldName
, args
, final
)
476 hasArgs
:= len(args
) > 1 || final
.IsValid()
477 // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
478 receiver
, isNil
:= indirect(receiver
)
480 s
.errorf("nil pointer evaluating %s.%s", typ
, fieldName
)
482 switch receiver
.Kind() {
484 tField
, ok
:= receiver
.Type().FieldByName(fieldName
)
486 field
:= receiver
.FieldByIndex(tField
.Index
)
487 if tField
.PkgPath
!= "" { // field is unexported
488 s
.errorf("%s is an unexported field of struct type %s", fieldName
, typ
)
490 // If it's a function, we must call it.
492 s
.errorf("%s has arguments but cannot be invoked as function", fieldName
)
496 s
.errorf("%s is not a field of struct type %s", fieldName
, typ
)
498 // If it's a map, attempt to use the field name as a key.
499 nameVal
:= reflect
.ValueOf(fieldName
)
500 if nameVal
.Type().AssignableTo(receiver
.Type().Key()) {
502 s
.errorf("%s is not a method but has arguments", fieldName
)
504 return receiver
.MapIndex(nameVal
)
507 s
.errorf("can't evaluate field %s in type %s", fieldName
, typ
)
512 errorType
= reflect
.TypeOf((*error
)(nil)).Elem()
513 fmtStringerType
= reflect
.TypeOf((*fmt
.Stringer
)(nil)).Elem()
516 // evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so
517 // it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0]
518 // as the function itself.
519 func (s
*state
) evalCall(dot
, fun reflect
.Value
, node parse
.Node
, name
string, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
521 args
= args
[1:] // Zeroth arg is function name/node; not passed to function.
528 numFixed
:= len(args
)
529 if typ
.IsVariadic() {
530 numFixed
= typ
.NumIn() - 1 // last arg is the variadic one.
531 if numIn
< numFixed
{
532 s
.errorf("wrong number of args for %s: want at least %d got %d", name
, typ
.NumIn()-1, len(args
))
534 } else if numIn
< typ
.NumIn()-1 ||
!typ
.IsVariadic() && numIn
!= typ
.NumIn() {
535 s
.errorf("wrong number of args for %s: want %d got %d", name
, typ
.NumIn(), len(args
))
538 // TODO: This could still be a confusing error; maybe goodFunc should provide info.
539 s
.errorf("can't call method/function %q with %d results", name
, typ
.NumOut())
541 // Build the arg list.
542 argv
:= make([]reflect
.Value
, numIn
)
543 // Args must be evaluated. Fixed args first.
545 for ; i
< numFixed
; i
++ {
546 argv
[i
] = s
.evalArg(dot
, typ
.In(i
), args
[i
])
549 if typ
.IsVariadic() {
550 argType
:= typ
.In(typ
.NumIn() - 1).Elem() // Argument is a slice.
551 for ; i
< len(args
); i
++ {
552 argv
[i
] = s
.evalArg(dot
, argType
, args
[i
])
555 // Add final value if necessary.
557 t
:= typ
.In(typ
.NumIn() - 1)
558 if typ
.IsVariadic() {
561 argv
[i
] = s
.validateType(final
, t
)
563 result
:= fun
.Call(argv
)
564 // If we have an error that is not nil, stop execution and return that error to the caller.
565 if len(result
) == 2 && !result
[1].IsNil() {
567 s
.errorf("error calling %s: %s", name
, result
[1].Interface().(error
))
572 // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
573 func canBeNil(typ reflect
.Type
) bool {
575 case reflect
.Chan
, reflect
.Func
, reflect
.Interface
, reflect
.Map
, reflect
.Ptr
, reflect
.Slice
:
581 // validateType guarantees that the value is valid and assignable to the type.
582 func (s
*state
) validateType(value reflect
.Value
, typ reflect
.Type
) reflect
.Value
{
583 if !value
.IsValid() {
584 if typ
== nil ||
canBeNil(typ
) {
585 // An untyped nil interface{}. Accept as a proper nil value.
586 return reflect
.Zero(typ
)
588 s
.errorf("invalid value; expected %s", typ
)
590 if typ
!= nil && !value
.Type().AssignableTo(typ
) {
591 if value
.Kind() == reflect
.Interface
&& !value
.IsNil() {
593 if value
.Type().AssignableTo(typ
) {
598 // Does one dereference or indirection work? We could do more, as we
599 // do with method receivers, but that gets messy and method receivers
600 // are much more constrained, so it makes more sense there than here.
601 // Besides, one is almost always all you need.
603 case value
.Kind() == reflect
.Ptr
&& value
.Type().Elem().AssignableTo(typ
):
605 if !value
.IsValid() {
606 s
.errorf("dereference of nil pointer of type %s", typ
)
608 case reflect
.PtrTo(value
.Type()).AssignableTo(typ
) && value
.CanAddr():
611 s
.errorf("wrong type for value; expected %s; got %s", typ
, value
.Type())
617 func (s
*state
) evalArg(dot reflect
.Value
, typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
619 switch arg
:= n
.(type) {
621 return s
.validateType(dot
, typ
)
624 return reflect
.Zero(typ
)
626 s
.errorf("cannot assign nil to %s", typ
)
627 case *parse
.FieldNode
:
628 return s
.validateType(s
.evalFieldNode(dot
, arg
, []parse
.Node
{n
}, zero
), typ
)
629 case *parse
.VariableNode
:
630 return s
.validateType(s
.evalVariableNode(dot
, arg
, nil, zero
), typ
)
631 case *parse
.PipeNode
:
632 return s
.validateType(s
.evalPipeline(dot
, arg
), typ
)
633 case *parse
.IdentifierNode
:
634 return s
.evalFunction(dot
, arg
, arg
, nil, zero
)
638 return s
.evalBool(typ
, n
)
639 case reflect
.Complex64
, reflect
.Complex128
:
640 return s
.evalComplex(typ
, n
)
641 case reflect
.Float32
, reflect
.Float64
:
642 return s
.evalFloat(typ
, n
)
643 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
644 return s
.evalInteger(typ
, n
)
645 case reflect
.Interface
:
646 if typ
.NumMethod() == 0 {
647 return s
.evalEmptyInterface(dot
, n
)
650 return s
.evalString(typ
, n
)
651 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
652 return s
.evalUnsignedInteger(typ
, n
)
654 s
.errorf("can't handle %s for arg of type %s", n
, typ
)
658 func (s
*state
) evalBool(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
660 if n
, ok
:= n
.(*parse
.BoolNode
); ok
{
661 value
:= reflect
.New(typ
).Elem()
662 value
.SetBool(n
.True
)
665 s
.errorf("expected bool; found %s", n
)
669 func (s
*state
) evalString(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
671 if n
, ok
:= n
.(*parse
.StringNode
); ok
{
672 value
:= reflect
.New(typ
).Elem()
673 value
.SetString(n
.Text
)
676 s
.errorf("expected string; found %s", n
)
680 func (s
*state
) evalInteger(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
682 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsInt
{
683 value
:= reflect
.New(typ
).Elem()
684 value
.SetInt(n
.Int64
)
687 s
.errorf("expected integer; found %s", n
)
691 func (s
*state
) evalUnsignedInteger(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
693 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsUint
{
694 value
:= reflect
.New(typ
).Elem()
695 value
.SetUint(n
.Uint64
)
698 s
.errorf("expected unsigned integer; found %s", n
)
702 func (s
*state
) evalFloat(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
704 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsFloat
{
705 value
:= reflect
.New(typ
).Elem()
706 value
.SetFloat(n
.Float64
)
709 s
.errorf("expected float; found %s", n
)
713 func (s
*state
) evalComplex(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
714 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsComplex
{
715 value
:= reflect
.New(typ
).Elem()
716 value
.SetComplex(n
.Complex128
)
719 s
.errorf("expected complex; found %s", n
)
723 func (s
*state
) evalEmptyInterface(dot reflect
.Value
, n parse
.Node
) reflect
.Value
{
725 switch n
:= n
.(type) {
726 case *parse
.BoolNode
:
727 return reflect
.ValueOf(n
.True
)
730 case *parse
.FieldNode
:
731 return s
.evalFieldNode(dot
, n
, nil, zero
)
732 case *parse
.IdentifierNode
:
733 return s
.evalFunction(dot
, n
, n
, nil, zero
)
735 // NilNode is handled in evalArg, the only place that calls here.
736 s
.errorf("evalEmptyInterface: nil (can't happen)")
737 case *parse
.NumberNode
:
738 return s
.idealConstant(n
)
739 case *parse
.StringNode
:
740 return reflect
.ValueOf(n
.Text
)
741 case *parse
.VariableNode
:
742 return s
.evalVariableNode(dot
, n
, nil, zero
)
743 case *parse
.PipeNode
:
744 return s
.evalPipeline(dot
, n
)
746 s
.errorf("can't handle assignment of %s to empty interface argument", n
)
750 // indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
751 // We indirect through pointers and empty interfaces (only) because
752 // non-empty interfaces have methods we might need.
753 func indirect(v reflect
.Value
) (rv reflect
.Value
, isNil
bool) {
754 for ; v
.Kind() == reflect
.Ptr || v
.Kind() == reflect
.Interface
; v
= v
.Elem() {
758 if v
.Kind() == reflect
.Interface
&& v
.NumMethod() > 0 {
765 // printValue writes the textual representation of the value to the output of
767 func (s
*state
) printValue(n parse
.Node
, v reflect
.Value
) {
769 iface
, ok
:= printableValue(v
)
771 s
.errorf("can't print %s of type %s", n
, v
.Type())
773 fmt
.Fprint(s
.wr
, iface
)
776 // printableValue returns the, possibly indirected, interface value inside v that
777 // is best for a call to formatted printer.
778 func printableValue(v reflect
.Value
) (interface{}, bool) {
779 if v
.Kind() == reflect
.Ptr
{
780 v
, _
= indirect(v
) // fmt.Fprint handles nil.
783 return "<no value>", true
786 if !v
.Type().Implements(errorType
) && !v
.Type().Implements(fmtStringerType
) {
787 if v
.CanAddr() && (reflect
.PtrTo(v
.Type()).Implements(errorType
) || reflect
.PtrTo(v
.Type()).Implements(fmtStringerType
)) {
791 case reflect
.Chan
, reflect
.Func
:
796 return v
.Interface(), true
799 // Types to help sort the keys in a map for reproducible output.
801 type rvs
[]reflect
.Value
803 func (x rvs
) Len() int { return len(x
) }
804 func (x rvs
) Swap(i
, j
int) { x
[i
], x
[j
] = x
[j
], x
[i
] }
806 type rvInts
struct{ rvs
}
808 func (x rvInts
) Less(i
, j
int) bool { return x
.rvs
[i
].Int() < x
.rvs
[j
].Int() }
810 type rvUints
struct{ rvs
}
812 func (x rvUints
) Less(i
, j
int) bool { return x
.rvs
[i
].Uint() < x
.rvs
[j
].Uint() }
814 type rvFloats
struct{ rvs
}
816 func (x rvFloats
) Less(i
, j
int) bool { return x
.rvs
[i
].Float() < x
.rvs
[j
].Float() }
818 type rvStrings
struct{ rvs
}
820 func (x rvStrings
) Less(i
, j
int) bool { return x
.rvs
[i
].String() < x
.rvs
[j
].String() }
822 // sortKeys sorts (if it can) the slice of reflect.Values, which is a slice of map keys.
823 func sortKeys(v
[]reflect
.Value
) []reflect
.Value
{
828 case reflect
.Float32
, reflect
.Float64
:
829 sort
.Sort(rvFloats
{v
})
830 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
833 sort
.Sort(rvStrings
{v
})
834 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
835 sort
.Sort(rvUints
{v
})