(f *builtin.Function, node ast.Node, arguments []ast.Node)
| 994 | } |
| 995 | |
| 996 | func (v *Checker) checkFunction(f *builtin.Function, node ast.Node, arguments []ast.Node) Nature { |
| 997 | if f.Validate != nil { |
| 998 | args := make([]reflect.Type, len(arguments)) |
| 999 | for i, arg := range arguments { |
| 1000 | argNature := v.visit(arg) |
| 1001 | if argNature.IsUnknown(&v.config.NtCache) { |
| 1002 | args[i] = anyType |
| 1003 | } else { |
| 1004 | args[i] = argNature.Type |
| 1005 | } |
| 1006 | } |
| 1007 | t, err := f.Validate(args) |
| 1008 | if err != nil { |
| 1009 | return v.error(node, "%v", err) |
| 1010 | } |
| 1011 | return v.config.NtCache.FromType(t) |
| 1012 | } else if len(f.Types) == 0 { |
| 1013 | nt, err := v.checkArguments(f.Name, v.config.NtCache.FromType(f.Type()), arguments, node) |
| 1014 | if err != nil { |
| 1015 | if v.err == nil { |
| 1016 | v.err = err |
| 1017 | } |
| 1018 | return Nature{} |
| 1019 | } |
| 1020 | // No type was specified, so we assume the function returns any. |
| 1021 | return nt |
| 1022 | } |
| 1023 | var lastErr *file.Error |
| 1024 | for _, t := range f.Types { |
| 1025 | outNature, err := v.checkArguments(f.Name, v.config.NtCache.FromType(t), arguments, node) |
| 1026 | if err != nil { |
| 1027 | lastErr = err |
| 1028 | continue |
| 1029 | } |
| 1030 | |
| 1031 | // As we found the correct function overload, we can stop the loop. |
| 1032 | // Also, we need to set the correct nature of the callee so compiler, |
| 1033 | // can correctly handle OpDeref opcode. |
| 1034 | if callNode, ok := node.(*ast.CallNode); ok { |
| 1035 | callNode.Callee.SetType(t) |
| 1036 | } |
| 1037 | |
| 1038 | return outNature |
| 1039 | } |
| 1040 | if lastErr != nil { |
| 1041 | if v.err == nil { |
| 1042 | v.err = lastErr |
| 1043 | } |
| 1044 | return Nature{} |
| 1045 | } |
| 1046 | |
| 1047 | return v.error(node, "no matching overload for %v", f.Name) |
| 1048 | } |
| 1049 | |
| 1050 | func (v *Checker) checkArguments( |
| 1051 | name string, |
no test coverage detected