...
1 package codegen
2
3 import (
4 "fmt"
5 "go/types"
6 "strings"
7
8 "github.com/vektah/gqlparser/v2/ast"
9
10 "github.com/99designs/gqlgen/codegen/config"
11 "github.com/99designs/gqlgen/codegen/templates"
12 )
13
14 type ArgSet struct {
15 Args []*FieldArgument
16 FuncDecl string
17 }
18
19 type FieldArgument struct {
20 *ast.ArgumentDefinition
21 TypeReference *config.TypeReference
22 VarName string
23 Object *Object
24 Default interface{}
25 Directives []*Directive
26 Value interface{}
27 }
28
29
30 func (f *FieldArgument) ImplDirectives() []*Directive {
31 d := make([]*Directive, 0)
32 for i := range f.Directives {
33 if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) {
34 d = append(d, f.Directives[i])
35 }
36 }
37
38 return d
39 }
40
41 func (f *FieldArgument) DirectiveObjName() string {
42 return "rawArgs"
43 }
44
45 func (f *FieldArgument) Stream() bool {
46 return f.Object != nil && f.Object.Stream
47 }
48
49 func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) {
50 tr, err := b.Binder.TypeReference(arg.Type, nil)
51 if err != nil {
52 return nil, err
53 }
54
55 argDirs, err := b.getDirectives(arg.Directives)
56 if err != nil {
57 return nil, err
58 }
59 newArg := FieldArgument{
60 ArgumentDefinition: arg,
61 TypeReference: tr,
62 Object: obj,
63 VarName: templates.ToGoPrivate(arg.Name),
64 Directives: argDirs,
65 }
66
67 if arg.DefaultValue != nil {
68 newArg.Default, err = arg.DefaultValue.Value(nil)
69 if err != nil {
70 return nil, fmt.Errorf("default value is not valid: %w", err)
71 }
72 }
73
74 return &newArg, nil
75 }
76
77 func (b *builder) bindArgs(field *Field, sig *types.Signature, params *types.Tuple) ([]*FieldArgument, error) {
78 n := params.Len()
79 newArgs := make([]*FieldArgument, 0, len(field.Args))
80
81 if params.Len() > len(field.Args) && sig.Variadic() {
82 n = len(field.Args)
83 }
84 nextArg:
85 for j := 0; j < n; j++ {
86 param := params.At(j)
87 for _, oldArg := range field.Args {
88 if strings.EqualFold(oldArg.Name, param.Name()) {
89 tr, err := b.Binder.TypeReference(oldArg.Type, param.Type())
90 if err != nil {
91 return nil, err
92 }
93 oldArg.TypeReference = tr
94
95 newArgs = append(newArgs, oldArg)
96 continue nextArg
97 }
98 }
99
100
101 return nil, fmt.Errorf("arg %s not in schema", param.Name())
102 }
103
104 return newArgs, nil
105 }
106
107 func (d *Data) Args() map[string][]*FieldArgument {
108 ret := map[string][]*FieldArgument{}
109 for _, o := range d.Objects {
110 for _, f := range o.Fields {
111 if len(f.Args) > 0 {
112 ret[f.ArgsFunc()] = f.Args
113 }
114 }
115 }
116
117 for _, directive := range d.Directives() {
118 if len(directive.Args) > 0 {
119 ret[directive.ArgsFunc()] = directive.Args
120 }
121 }
122 return ret
123 }
124
View as plain text