github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/old/template/execute.go (about)

     1  // Copyright 2009 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.
     4  
     5  // Code to execute a parsed template.
     6  
     7  package template
     8  
     9  import (
    10  	"bytes"
    11  	"io"
    12  	"reflect"
    13  	"strings"
    14  )
    15  
    16  // Internal state for executing a Template.  As we evaluate the struct,
    17  // the data item descends into the fields associated with sections, etc.
    18  // Parent is used to walk upwards to find variables higher in the tree.
    19  type state struct {
    20  	parent *state          // parent in hierarchy
    21  	data   reflect.Value   // the driver data for this section etc.
    22  	wr     io.Writer       // where to send output
    23  	buf    [2]bytes.Buffer // alternating buffers used when chaining formatters
    24  }
    25  
    26  func (parent *state) clone(data reflect.Value) *state {
    27  	return &state{parent: parent, data: data, wr: parent.wr}
    28  }
    29  
    30  // Evaluate interfaces and pointers looking for a value that can look up the name, via a
    31  // struct field, method, or map key, and return the result of the lookup.
    32  func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value {
    33  	for v.IsValid() {
    34  		typ := v.Type()
    35  		if n := v.Type().NumMethod(); n > 0 {
    36  			for i := 0; i < n; i++ {
    37  				m := typ.Method(i)
    38  				mtyp := m.Type
    39  				if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 {
    40  					if !isExported(name) {
    41  						t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
    42  					}
    43  					return v.Method(i).Call(nil)[0]
    44  				}
    45  			}
    46  		}
    47  		switch av := v; av.Kind() {
    48  		case reflect.Ptr:
    49  			v = av.Elem()
    50  		case reflect.Interface:
    51  			v = av.Elem()
    52  		case reflect.Struct:
    53  			if !isExported(name) {
    54  				t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type())
    55  			}
    56  			return av.FieldByName(name)
    57  		case reflect.Map:
    58  			if v := av.MapIndex(reflect.ValueOf(name)); v.IsValid() {
    59  				return v
    60  			}
    61  			return reflect.Zero(typ.Elem())
    62  		default:
    63  			return reflect.Value{}
    64  		}
    65  	}
    66  	return v
    67  }
    68  
    69  // indirectPtr returns the item numLevels levels of indirection below the value.
    70  // It is forgiving: if the value is not a pointer, it returns it rather than giving
    71  // an error.  If the pointer is nil, it is returned as is.
    72  func indirectPtr(v reflect.Value, numLevels int) reflect.Value {
    73  	for i := numLevels; v.IsValid() && i > 0; i++ {
    74  		if p := v; p.Kind() == reflect.Ptr {
    75  			if p.IsNil() {
    76  				return v
    77  			}
    78  			v = p.Elem()
    79  		} else {
    80  			break
    81  		}
    82  	}
    83  	return v
    84  }
    85  
    86  // Walk v through pointers and interfaces, extracting the elements within.
    87  func indirect(v reflect.Value) reflect.Value {
    88  loop:
    89  	for v.IsValid() {
    90  		switch av := v; av.Kind() {
    91  		case reflect.Ptr:
    92  			v = av.Elem()
    93  		case reflect.Interface:
    94  			v = av.Elem()
    95  		default:
    96  			break loop
    97  		}
    98  	}
    99  	return v
   100  }
   101  
   102  // If the data for this template is a struct, find the named variable.
   103  // Names of the form a.b.c are walked down the data tree.
   104  // The special name "@" (the "cursor") denotes the current data.
   105  // The value coming in (st.data) might need indirecting to reach
   106  // a struct while the return value is not indirected - that is,
   107  // it represents the actual named field. Leading stars indicate
   108  // levels of indirection to be applied to the value.
   109  func (t *Template) findVar(st *state, s string) reflect.Value {
   110  	data := st.data
   111  	flattenedName := strings.TrimLeft(s, "*")
   112  	numStars := len(s) - len(flattenedName)
   113  	s = flattenedName
   114  	if s == "@" {
   115  		return indirectPtr(data, numStars)
   116  	}
   117  	for _, elem := range strings.Split(s, ".") {
   118  		// Look up field; data must be a struct or map.
   119  		data = t.lookup(st, data, elem)
   120  		if !data.IsValid() {
   121  			return reflect.Value{}
   122  		}
   123  	}
   124  	return indirectPtr(data, numStars)
   125  }
   126  
   127  // Is there no data to look at?
   128  func empty(v reflect.Value) bool {
   129  	v = indirect(v)
   130  	if !v.IsValid() {
   131  		return true
   132  	}
   133  	switch v.Kind() {
   134  	case reflect.Bool:
   135  		return v.Bool() == false
   136  	case reflect.String:
   137  		return v.String() == ""
   138  	case reflect.Struct:
   139  		return false
   140  	case reflect.Map:
   141  		return false
   142  	case reflect.Array:
   143  		return v.Len() == 0
   144  	case reflect.Slice:
   145  		return v.Len() == 0
   146  	}
   147  	return false
   148  }
   149  
   150  // Look up a variable or method, up through the parent if necessary.
   151  func (t *Template) varValue(name string, st *state) reflect.Value {
   152  	field := t.findVar(st, name)
   153  	if !field.IsValid() {
   154  		if st.parent == nil {
   155  			t.execError(st, t.linenum, "name not found: %s in type %s", name, st.data.Type())
   156  		}
   157  		return t.varValue(name, st.parent)
   158  	}
   159  	return field
   160  }
   161  
   162  func (t *Template) format(wr io.Writer, fmt string, val []interface{}, v *variableElement, st *state) {
   163  	fn := t.formatter(fmt)
   164  	if fn == nil {
   165  		t.execError(st, v.linenum, "missing formatter %s for variable", fmt)
   166  	}
   167  	fn(wr, fmt, val...)
   168  }
   169  
   170  // Evaluate a variable, looking up through the parent if necessary.
   171  // If it has a formatter attached ({var|formatter}) run that too.
   172  func (t *Template) writeVariable(v *variableElement, st *state) {
   173  	// Resolve field names
   174  	val := make([]interface{}, len(v.args))
   175  	for i, arg := range v.args {
   176  		if name, ok := arg.(fieldName); ok {
   177  			val[i] = t.varValue(string(name), st).Interface()
   178  		} else {
   179  			val[i] = arg
   180  		}
   181  	}
   182  	for i, fmt := range v.fmts[:len(v.fmts)-1] {
   183  		b := &st.buf[i&1]
   184  		b.Reset()
   185  		t.format(b, fmt, val, v, st)
   186  		val = val[0:1]
   187  		val[0] = b.Bytes()
   188  	}
   189  	t.format(st.wr, v.fmts[len(v.fmts)-1], val, v, st)
   190  }
   191  
   192  // Execute element i.  Return next index to execute.
   193  func (t *Template) executeElement(i int, st *state) int {
   194  	switch elem := t.elems[i].(type) {
   195  	case *textElement:
   196  		st.wr.Write(elem.text)
   197  		return i + 1
   198  	case *literalElement:
   199  		st.wr.Write(elem.text)
   200  		return i + 1
   201  	case *variableElement:
   202  		t.writeVariable(elem, st)
   203  		return i + 1
   204  	case *sectionElement:
   205  		t.executeSection(elem, st)
   206  		return elem.end
   207  	case *repeatedElement:
   208  		t.executeRepeated(elem, st)
   209  		return elem.end
   210  	}
   211  	e := t.elems[i]
   212  	t.execError(st, 0, "internal error: bad directive in execute: %v %T\n", reflect.ValueOf(e).Interface(), e)
   213  	return 0
   214  }
   215  
   216  // Execute the template.
   217  func (t *Template) execute(start, end int, st *state) {
   218  	for i := start; i < end; {
   219  		i = t.executeElement(i, st)
   220  	}
   221  }
   222  
   223  // Execute a .section
   224  func (t *Template) executeSection(s *sectionElement, st *state) {
   225  	// Find driver data for this section.  It must be in the current struct.
   226  	field := t.varValue(s.field, st)
   227  	if !field.IsValid() {
   228  		t.execError(st, s.linenum, ".section: cannot find field %s in %s", s.field, st.data.Type())
   229  	}
   230  	st = st.clone(field)
   231  	start, end := s.start, s.or
   232  	if !empty(field) {
   233  		// Execute the normal block.
   234  		if end < 0 {
   235  			end = s.end
   236  		}
   237  	} else {
   238  		// Execute the .or block.  If it's missing, do nothing.
   239  		start, end = s.or, s.end
   240  		if start < 0 {
   241  			return
   242  		}
   243  	}
   244  	for i := start; i < end; {
   245  		i = t.executeElement(i, st)
   246  	}
   247  }
   248  
   249  // Return the result of calling the Iter method on v, or nil.
   250  func iter(v reflect.Value) reflect.Value {
   251  	for j := 0; j < v.Type().NumMethod(); j++ {
   252  		mth := v.Type().Method(j)
   253  		fv := v.Method(j)
   254  		ft := fv.Type()
   255  		// TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue.
   256  		if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 {
   257  			continue
   258  		}
   259  		ct := ft.Out(0)
   260  		if ct.Kind() != reflect.Chan ||
   261  			ct.ChanDir()&reflect.RecvDir == 0 {
   262  			continue
   263  		}
   264  		return fv.Call(nil)[0]
   265  	}
   266  	return reflect.Value{}
   267  }
   268  
   269  // Execute a .repeated section
   270  func (t *Template) executeRepeated(r *repeatedElement, st *state) {
   271  	// Find driver data for this section.  It must be in the current struct.
   272  	field := t.varValue(r.field, st)
   273  	if !field.IsValid() {
   274  		t.execError(st, r.linenum, ".repeated: cannot find field %s in %s", r.field, st.data.Type())
   275  	}
   276  	field = indirect(field)
   277  
   278  	start, end := r.start, r.or
   279  	if end < 0 {
   280  		end = r.end
   281  	}
   282  	if r.altstart >= 0 {
   283  		end = r.altstart
   284  	}
   285  	first := true
   286  
   287  	// Code common to all the loops.
   288  	loopBody := func(newst *state) {
   289  		// .alternates between elements
   290  		if !first && r.altstart >= 0 {
   291  			for i := r.altstart; i < r.altend; {
   292  				i = t.executeElement(i, newst)
   293  			}
   294  		}
   295  		first = false
   296  		for i := start; i < end; {
   297  			i = t.executeElement(i, newst)
   298  		}
   299  	}
   300  
   301  	if array := field; array.Kind() == reflect.Array || array.Kind() == reflect.Slice {
   302  		for j := 0; j < array.Len(); j++ {
   303  			loopBody(st.clone(array.Index(j)))
   304  		}
   305  	} else if m := field; m.Kind() == reflect.Map {
   306  		for _, key := range m.MapKeys() {
   307  			loopBody(st.clone(m.MapIndex(key)))
   308  		}
   309  	} else if ch := iter(field); ch.IsValid() {
   310  		for {
   311  			e, ok := ch.Recv()
   312  			if !ok {
   313  				break
   314  			}
   315  			loopBody(st.clone(e))
   316  		}
   317  	} else {
   318  		t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",
   319  			r.field, field.Type())
   320  	}
   321  
   322  	if first {
   323  		// Empty. Execute the .or block, once.  If it's missing, do nothing.
   324  		start, end := r.or, r.end
   325  		if start >= 0 {
   326  			newst := st.clone(field)
   327  			for i := start; i < end; {
   328  				i = t.executeElement(i, newst)
   329  			}
   330  		}
   331  		return
   332  	}
   333  }
   334  
   335  // A valid delimiter must contain no space and be non-empty.
   336  func validDelim(d []byte) bool {
   337  	if len(d) == 0 {
   338  		return false
   339  	}
   340  	for _, c := range d {
   341  		if isSpace(c) {
   342  			return false
   343  		}
   344  	}
   345  	return true
   346  }