github.com/senomas/gqlgen@v0.17.11-0.20220626120754-9aee61b0716a/codegen/args.go (about)

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