Skip to content

Commit

Permalink
Arbitrary function argument types are now possible in function calls.
Browse files Browse the repository at this point in the history
Fixes #8 #9 #10.
  • Loading branch information
flosch committed Jul 16, 2014
1 parent 8acdc2f commit 483e45d
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 11 deletions.
4 changes: 2 additions & 2 deletions pongo2_template_test.go
Expand Up @@ -75,8 +75,8 @@ with a new line in it`,
2: "two",
5: "five",
},
"func_add": func(a, b *Value) int {
return a.Integer() + b.Integer()
"func_add": func(a, b int) int {
return a + b
},
},
"complex": map[string]interface{}{
Expand Down
3 changes: 2 additions & 1 deletion template_tests/filters-execution.err
@@ -1 +1,2 @@
{{ -(true || false) }}
{{ -(true || false) }}
{{ simple.func_add("test", 5) }}
3 changes: 2 additions & 1 deletion template_tests/filters-execution.err.out
@@ -1 +1,2 @@
.*Execution Error.*Negative sign on a non\-number expression
.*Execution Error.*Negative sign on a non\-number expression
.*Function input argument 0 of 'simple.func_add' must be of type int.
22 changes: 15 additions & 7 deletions variable.go
Expand Up @@ -218,11 +218,6 @@ func (vr *variableResolver) resolve(ctx *ExecutionContext) (*Value, error) {
t := current.Type()

// Input arguments
for i := 0; i < t.NumIn(); i++ {
if t.In(i) != reflect.TypeOf(new(Value)) {
return nil, errors.New(fmt.Sprintf("Function input argument %d of '%s' must be of type *Value.", i, vr.String()))
}
}
if len(part.calling_args) != t.NumIn() {
return nil,
errors.New(fmt.Sprintf("Function input argument count (%d) of '%s' must be equal to the calling argument count (%d).",
Expand All @@ -236,12 +231,25 @@ func (vr *variableResolver) resolve(ctx *ExecutionContext) (*Value, error) {

// Evaluate all parameters
parameters := make([]reflect.Value, 0)
for _, arg := range part.calling_args {
for idx, arg := range part.calling_args {
pv, err := arg.Evaluate(ctx)
if err != nil {
return nil, err
}
parameters = append(parameters, reflect.ValueOf(pv))

if t.In(idx) != reflect.TypeOf(new(Value)) {
// Function's argument is not a *pongo2.Value, then we have to check whether input argument is of the same type as the function's argument
if t.In(idx) != reflect.TypeOf(pv.Interface()) {
return nil, errors.New(fmt.Sprintf("Function input argument %d of '%s' must be of type %s.",
idx, vr.String(), t.In(idx).String()))
} else {
// Function's argument has another type, using the interface-value
parameters = append(parameters, reflect.ValueOf(pv.Interface()))
}
} else {
// Function's argument is a *pongo2.Value
parameters = append(parameters, reflect.ValueOf(pv))
}
}

// Call it and get first return parameter back
Expand Down

0 comments on commit 483e45d

Please sign in to comment.