OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package template | 5 package template |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "io" | 9 "io" |
10 "os" | 10 "os" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va
lue { | 167 func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va
lue { |
168 value := reflect.Value{} | 168 value := reflect.Value{} |
169 for _, cmd := range pipe { | 169 for _, cmd := range pipe { |
170 value = s.evalCommand(data, cmd, value) // previous value is thi
s one's final arg. | 170 value = s.evalCommand(data, cmd, value) // previous value is thi
s one's final arg. |
171 } | 171 } |
172 return value | 172 return value |
173 } | 173 } |
174 | 174 |
175 func (s *state) evalCommand(data reflect.Value, cmd *commandNode, final reflect.
Value) reflect.Value { | 175 func (s *state) evalCommand(data reflect.Value, cmd *commandNode, final reflect.
Value) reflect.Value { |
176 firstWord := cmd.args[0] | 176 firstWord := cmd.args[0] |
177 » if field, ok := firstWord.(*fieldNode); ok { | 177 » switch n := firstWord.(type) { |
178 » » return s.evalFieldNode(data, field, cmd.args, final) | 178 » case *fieldNode: |
| 179 » » return s.evalFieldNode(data, n, cmd.args, final) |
| 180 » case *identifierNode: |
| 181 » » return s.evalFieldOrCall(data, n.ident, cmd.args, final) |
179 } | 182 } |
180 if len(cmd.args) > 1 || final.IsValid() { | 183 if len(cmd.args) > 1 || final.IsValid() { |
181 // TODO: functions | 184 // TODO: functions |
182 s.errorf("can't give argument to non-method %s", cmd.args[0]) | 185 s.errorf("can't give argument to non-method %s", cmd.args[0]) |
183 } | 186 } |
184 switch word := cmd.args[0].(type) { | 187 switch word := cmd.args[0].(type) { |
185 case *dotNode: | 188 case *dotNode: |
186 return data | 189 return data |
187 case *boolNode: | 190 case *boolNode: |
188 return reflect.ValueOf(word.true) | 191 return reflect.ValueOf(word.true) |
(...skipping 19 matching lines...) Expand all Loading... |
208 panic("not reached") | 211 panic("not reached") |
209 } | 212 } |
210 | 213 |
211 func (s *state) evalFieldNode(data reflect.Value, field *fieldNode, args []node,
final reflect.Value) reflect.Value { | 214 func (s *state) evalFieldNode(data reflect.Value, field *fieldNode, args []node,
final reflect.Value) reflect.Value { |
212 // Up to the last entry, it must be a field. | 215 // Up to the last entry, it must be a field. |
213 n := len(field.ident) | 216 n := len(field.ident) |
214 for i := 0; i < n-1; i++ { | 217 for i := 0; i < n-1; i++ { |
215 data = s.evalField(data, field.ident[i]) | 218 data = s.evalField(data, field.ident[i]) |
216 } | 219 } |
217 // Now it can be a field or method and if a method, gets arguments. | 220 // Now it can be a field or method and if a method, gets arguments. |
218 » return s.evalMethodOrField(data, field.ident[n-1], args, final) | 221 » return s.evalFieldOrCall(data, field.ident[n-1], args, final) |
219 } | 222 } |
220 | 223 |
221 func (s *state) evalField(data reflect.Value, fieldName string) reflect.Value { | 224 func (s *state) evalField(data reflect.Value, fieldName string) reflect.Value { |
222 for data.Kind() == reflect.Ptr { | 225 for data.Kind() == reflect.Ptr { |
223 data = reflect.Indirect(data) | 226 data = reflect.Indirect(data) |
224 } | 227 } |
225 switch data.Kind() { | 228 switch data.Kind() { |
226 case reflect.Struct: | 229 case reflect.Struct: |
227 // Is it a field? | 230 // Is it a field? |
228 field := data.FieldByName(fieldName) | 231 field := data.FieldByName(fieldName) |
229 // TODO: look higher up the tree if we can't find it here. Also
unexported fields | 232 // TODO: look higher up the tree if we can't find it here. Also
unexported fields |
230 // might succeed higher up, as map keys. | 233 // might succeed higher up, as map keys. |
231 if field.IsValid() && field.Type().PkgPath() == "" { // valid an
d exported | 234 if field.IsValid() && field.Type().PkgPath() == "" { // valid an
d exported |
232 return field | 235 return field |
233 } | 236 } |
234 s.errorf("%s has no field %s", data.Type(), fieldName) | 237 s.errorf("%s has no field %s", data.Type(), fieldName) |
235 default: | 238 default: |
236 s.errorf("can't evaluate field %s of type %s", fieldName, data.T
ype()) | 239 s.errorf("can't evaluate field %s of type %s", fieldName, data.T
ype()) |
237 } | 240 } |
238 panic("not reached") | 241 panic("not reached") |
239 } | 242 } |
240 | 243 |
241 func (s *state) evalMethodOrField(data reflect.Value, fieldName string, args []n
ode, final reflect.Value) reflect.Value { | 244 func (s *state) evalFieldOrCall(data reflect.Value, fieldName string, args []nod
e, final reflect.Value) reflect.Value { |
| 245 » // Is it a function? |
| 246 » if function, ok := findFunction(fieldName, s.tmpl, s.set); ok { |
| 247 » » return s.evalCall(data, function, fieldName, false, args, final) |
| 248 » } |
242 ptr := data | 249 ptr := data |
243 for data.Kind() == reflect.Ptr { | 250 for data.Kind() == reflect.Ptr { |
244 ptr, data = data, reflect.Indirect(data) | 251 ptr, data = data, reflect.Indirect(data) |
245 } | 252 } |
246 // Is it a method? We use the pointer because it has value methods too. | 253 // Is it a method? We use the pointer because it has value methods too. |
247 if method, ok := ptr.Type().MethodByName(fieldName); ok { | 254 if method, ok := ptr.Type().MethodByName(fieldName); ok { |
248 » » return s.evalMethod(ptr, method, args, final) | 255 » » return s.evalCall(ptr, method.Func, fieldName, true, args, final
) |
249 } | 256 } |
250 if len(args) > 1 || final.IsValid() { | 257 if len(args) > 1 || final.IsValid() { |
251 s.errorf("%s is not a method but has arguments", fieldName) | 258 s.errorf("%s is not a method but has arguments", fieldName) |
252 } | 259 } |
253 switch data.Kind() { | 260 switch data.Kind() { |
254 case reflect.Struct: | 261 case reflect.Struct: |
255 return s.evalField(data, fieldName) | 262 return s.evalField(data, fieldName) |
256 default: | 263 default: |
257 s.errorf("can't handle evaluation of field %s of type %s", field
Name, data.Type()) | 264 s.errorf("can't handle evaluation of field %s of type %s", field
Name, data.Type()) |
258 } | 265 } |
259 panic("not reached") | 266 panic("not reached") |
260 } | 267 } |
261 | 268 |
262 var ( | 269 var ( |
263 osErrorType = reflect.TypeOf(new(os.Error)).Elem() | 270 osErrorType = reflect.TypeOf(new(os.Error)).Elem() |
264 ) | 271 ) |
265 | 272 |
266 func (s *state) evalMethod(v reflect.Value, method reflect.Method, args []node,
final reflect.Value) reflect.Value { | 273 func (s *state) evalCall(v, fun reflect.Value, name string, isMethod bool, args
[]node, final reflect.Value) reflect.Value { |
267 » typ := method.Type | 274 » typ := fun.Type() |
268 » fun := method.Func | 275 » if !isMethod && len(args) > 0 { // Args will be nil if it's a niladic ca
ll in an argument list |
| 276 » » args = args[1:] // first arg is name of function; not used in ca
ll. |
| 277 » } |
269 numIn := len(args) | 278 numIn := len(args) |
270 if final.IsValid() { | 279 if final.IsValid() { |
271 numIn++ | 280 numIn++ |
272 } | 281 } |
273 » if !typ.IsVariadic() && numIn < typ.NumIn()-1 || !typ.IsVariadic() && nu
mIn != typ.NumIn() { | 282 » numFixed := len(args) |
274 » » s.errorf("wrong number of args for %s: want %d got %d", method.N
ame, typ.NumIn(), len(args)) | 283 » if typ.IsVariadic() { |
| 284 » » numFixed = typ.NumIn() - 1 // last arg is the variadic one. |
| 285 » » if numIn < numFixed { |
| 286 » » » s.errorf("wrong number of args for %s: want at least %d
got %d", name, typ.NumIn()-1, len(args)) |
| 287 » » } |
| 288 » } else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.Num
In() { |
| 289 » » s.errorf("wrong number of args for %s: want %d got %d", name, ty
p.NumIn(), len(args)) |
275 } | 290 } |
276 » // We allow methods with 1 result or 2 results where the second is an os
.Error. | 291 » // We allow functions with 1 result or 2 results where the second is an
os.Error. |
277 switch { | 292 switch { |
278 case typ.NumOut() == 1: | 293 case typ.NumOut() == 1: |
279 case typ.NumOut() == 2 && typ.Out(1) == osErrorType: | 294 case typ.NumOut() == 2 && typ.Out(1) == osErrorType: |
280 default: | 295 default: |
281 » » s.errorf("can't handle multiple results from method %q", method.
Name) | 296 » » s.errorf("can't handle multiple results from method/function %q"
, name) |
282 } | 297 } |
283 // Build the arg list. | 298 // Build the arg list. |
284 argv := make([]reflect.Value, numIn) | 299 argv := make([]reflect.Value, numIn) |
285 // First arg is the receiver. | 300 // First arg is the receiver. |
286 » argv[0] = v | 301 » i := 0 |
287 » // Others must be evaluated. | 302 » if isMethod { |
288 » for i := 1; i < len(args); i++ { | 303 » » argv[0] = v |
| 304 » » i++ |
| 305 » } |
| 306 » // Others must be evaluated. Fixed args first. |
| 307 » for ; i < numFixed; i++ { |
289 argv[i] = s.evalArg(v, typ.In(i), args[i]) | 308 argv[i] = s.evalArg(v, typ.In(i), args[i]) |
290 } | 309 } |
| 310 // And now the ... args. |
| 311 if typ.IsVariadic() { |
| 312 argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice
. |
| 313 for ; i < len(args); i++ { |
| 314 argv[i] = s.evalArg(v, argType, args[i]) |
| 315 } |
| 316 } |
291 // Add final value if necessary. | 317 // Add final value if necessary. |
292 if final.IsValid() { | 318 if final.IsValid() { |
293 argv[len(args)] = final | 319 argv[len(args)] = final |
294 } | 320 } |
295 result := fun.Call(argv) | 321 result := fun.Call(argv) |
296 // If we have an os.Error that is not nil, stop execution and return tha
t error to the caller. | 322 // If we have an os.Error that is not nil, stop execution and return tha
t error to the caller. |
297 if len(result) == 2 && !result[1].IsNil() { | 323 if len(result) == 2 && !result[1].IsNil() { |
298 s.error(result[1].Interface().(os.Error)) | 324 s.error(result[1].Interface().(os.Error)) |
299 } | 325 } |
300 return result[0] | 326 return result[0] |
301 } | 327 } |
302 | 328 |
303 func (s *state) evalArg(data reflect.Value, typ reflect.Type, n node) reflect.Va
lue { | 329 func (s *state) evalArg(data reflect.Value, typ reflect.Type, n node) reflect.Va
lue { |
304 if field, ok := n.(*fieldNode); ok { | 330 if field, ok := n.(*fieldNode); ok { |
305 value := s.evalFieldNode(data, field, []node{n}, reflect.Value{}
) | 331 value := s.evalFieldNode(data, field, []node{n}, reflect.Value{}
) |
306 if !value.Type().AssignableTo(typ) { | 332 if !value.Type().AssignableTo(typ) { |
307 s.errorf("wrong type for value; expected %s; got %s", ty
p, value.Type()) | 333 s.errorf("wrong type for value; expected %s; got %s", ty
p, value.Type()) |
308 } | 334 } |
309 return value | 335 return value |
310 } | 336 } |
311 switch typ.Kind() { | 337 switch typ.Kind() { |
312 case reflect.Bool: | 338 case reflect.Bool: |
313 » » return s.evalBool(data, typ, n) | 339 » » return s.evalBool(typ, n) |
314 case reflect.String: | 340 case reflect.String: |
315 » » return s.evalString(data, typ, n) | 341 » » return s.evalString(typ, n) |
316 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: | 342 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: |
317 » » return s.evalInteger(data, typ, n) | 343 » » return s.evalInteger(typ, n) |
318 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflec
t.Uint64, reflect.Uintptr: | 344 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflec
t.Uint64, reflect.Uintptr: |
319 » » return s.evalUnsignedInteger(data, typ, n) | 345 » » return s.evalUnsignedInteger(typ, n) |
320 case reflect.Float32, reflect.Float64: | 346 case reflect.Float32, reflect.Float64: |
321 » » return s.evalFloat(data, typ, n) | 347 » » return s.evalFloat(typ, n) |
322 case reflect.Complex64, reflect.Complex128: | 348 case reflect.Complex64, reflect.Complex128: |
323 » » return s.evalComplex(data, typ, n) | 349 » » return s.evalComplex(typ, n) |
| 350 » case reflect.Interface: |
| 351 » » if typ.NumMethod() == 0 { |
| 352 » » » return s.evalEmptyInterface(data, typ, n) |
| 353 » » } |
324 } | 354 } |
325 » s.errorf("can't handle node %s for method arg of type %s", n, typ) | 355 » s.errorf("can't handle %s for arg of type %s", n, typ) |
326 panic("not reached") | 356 panic("not reached") |
327 } | 357 } |
328 | 358 |
329 func (s *state) evalBool(v reflect.Value, typ reflect.Type, n node) reflect.Valu
e { | 359 func (s *state) evalBool(typ reflect.Type, n node) reflect.Value { |
330 if n, ok := n.(*boolNode); ok { | 360 if n, ok := n.(*boolNode); ok { |
331 value := reflect.New(typ).Elem() | 361 value := reflect.New(typ).Elem() |
332 value.SetBool(n.true) | 362 value.SetBool(n.true) |
333 return value | 363 return value |
334 } | 364 } |
335 s.errorf("expected bool; found %s", n) | 365 s.errorf("expected bool; found %s", n) |
336 panic("not reached") | 366 panic("not reached") |
337 } | 367 } |
338 | 368 |
339 func (s *state) evalString(v reflect.Value, typ reflect.Type, n node) reflect.Va
lue { | 369 func (s *state) evalString(typ reflect.Type, n node) reflect.Value { |
340 if n, ok := n.(*stringNode); ok { | 370 if n, ok := n.(*stringNode); ok { |
341 value := reflect.New(typ).Elem() | 371 value := reflect.New(typ).Elem() |
342 value.SetString(n.text) | 372 value.SetString(n.text) |
343 return value | 373 return value |
344 } | 374 } |
345 s.errorf("expected string; found %s", n) | 375 s.errorf("expected string; found %s", n) |
346 panic("not reached") | 376 panic("not reached") |
347 } | 377 } |
348 | 378 |
349 func (s *state) evalInteger(v reflect.Value, typ reflect.Type, n node) reflect.V
alue { | 379 func (s *state) evalInteger(typ reflect.Type, n node) reflect.Value { |
350 if n, ok := n.(*numberNode); ok && n.isInt { | 380 if n, ok := n.(*numberNode); ok && n.isInt { |
351 value := reflect.New(typ).Elem() | 381 value := reflect.New(typ).Elem() |
352 value.SetInt(n.int64) | 382 value.SetInt(n.int64) |
353 return value | 383 return value |
354 } | 384 } |
355 s.errorf("expected integer; found %s", n) | 385 s.errorf("expected integer; found %s", n) |
356 panic("not reached") | 386 panic("not reached") |
357 } | 387 } |
358 | 388 |
359 func (s *state) evalUnsignedInteger(v reflect.Value, typ reflect.Type, n node) r
eflect.Value { | 389 func (s *state) evalUnsignedInteger(typ reflect.Type, n node) reflect.Value { |
360 if n, ok := n.(*numberNode); ok && n.isUint { | 390 if n, ok := n.(*numberNode); ok && n.isUint { |
361 value := reflect.New(typ).Elem() | 391 value := reflect.New(typ).Elem() |
362 value.SetUint(n.uint64) | 392 value.SetUint(n.uint64) |
363 return value | 393 return value |
364 } | 394 } |
365 s.errorf("expected unsigned integer; found %s", n) | 395 s.errorf("expected unsigned integer; found %s", n) |
366 panic("not reached") | 396 panic("not reached") |
367 } | 397 } |
368 | 398 |
369 func (s *state) evalFloat(v reflect.Value, typ reflect.Type, n node) reflect.Val
ue { | 399 func (s *state) evalFloat(typ reflect.Type, n node) reflect.Value { |
370 if n, ok := n.(*numberNode); ok && n.isFloat { | 400 if n, ok := n.(*numberNode); ok && n.isFloat { |
371 value := reflect.New(typ).Elem() | 401 value := reflect.New(typ).Elem() |
372 value.SetFloat(n.float64) | 402 value.SetFloat(n.float64) |
373 return value | 403 return value |
374 } | 404 } |
375 s.errorf("expected float; found %s", n) | 405 s.errorf("expected float; found %s", n) |
376 panic("not reached") | 406 panic("not reached") |
377 } | 407 } |
378 | 408 |
379 func (s *state) evalComplex(v reflect.Value, typ reflect.Type, n node) reflect.V
alue { | 409 func (s *state) evalComplex(typ reflect.Type, n node) reflect.Value { |
380 if n, ok := n.(*numberNode); ok && n.isComplex { | 410 if n, ok := n.(*numberNode); ok && n.isComplex { |
381 value := reflect.New(typ).Elem() | 411 value := reflect.New(typ).Elem() |
382 value.SetComplex(n.complex128) | 412 value.SetComplex(n.complex128) |
383 return value | 413 return value |
384 } | 414 } |
385 s.errorf("expected complex; found %s", n) | 415 s.errorf("expected complex; found %s", n) |
386 panic("not reached") | 416 panic("not reached") |
387 } | 417 } |
388 | 418 |
| 419 func (s *state) evalEmptyInterface(data reflect.Value, typ reflect.Type, n node)
reflect.Value { |
| 420 switch n := n.(type) { |
| 421 case *boolNode: |
| 422 return reflect.ValueOf(n.true) |
| 423 case *fieldNode: |
| 424 return s.evalFieldNode(data, n, nil, reflect.Value{}) |
| 425 case *identifierNode: |
| 426 return s.evalFieldOrCall(data, n.ident, nil, reflect.Value{}) |
| 427 case *numberNode: |
| 428 if n.isComplex { |
| 429 return reflect.ValueOf(n.complex128) |
| 430 } |
| 431 if n.isInt { |
| 432 return reflect.ValueOf(n.int64) |
| 433 } |
| 434 if n.isUint { |
| 435 return reflect.ValueOf(n.uint64) |
| 436 } |
| 437 if n.isFloat { |
| 438 return reflect.ValueOf(n.float64) |
| 439 } |
| 440 case *stringNode: |
| 441 return reflect.ValueOf(n.text) |
| 442 } |
| 443 s.errorf("can't handle assignment of %s to empty interface argument", n) |
| 444 panic("not reached") |
| 445 } |
| 446 |
389 // printValue writes the textual representation of the value to the output of | 447 // printValue writes the textual representation of the value to the output of |
390 // the template. | 448 // the template. |
391 func (s *state) printValue(n node, v reflect.Value) { | 449 func (s *state) printValue(n node, v reflect.Value) { |
392 if !v.IsValid() { | 450 if !v.IsValid() { |
393 return | 451 return |
394 } | 452 } |
395 switch v.Kind() { | 453 switch v.Kind() { |
396 case reflect.Ptr: | 454 case reflect.Ptr: |
397 if v.IsNil() { | 455 if v.IsNil() { |
398 s.errorf("%s: nil value", n) | 456 s.errorf("%s: nil value", n) |
399 } | 457 } |
400 case reflect.Chan, reflect.Func, reflect.Interface: | 458 case reflect.Chan, reflect.Func, reflect.Interface: |
401 s.errorf("can't print %s of type %s", n, v.Type()) | 459 s.errorf("can't print %s of type %s", n, v.Type()) |
402 } | 460 } |
403 fmt.Fprint(s.wr, v.Interface()) | 461 fmt.Fprint(s.wr, v.Interface()) |
404 } | 462 } |
OLD | NEW |