github.com/matiasanaya/gqlgen@v0.6.0/codegen/type_build.go (about)

     1  package codegen
     2  
     3  import (
     4  	"go/types"
     5  	"strings"
     6  
     7  	"github.com/vektah/gqlparser/ast"
     8  	"golang.org/x/tools/go/loader"
     9  )
    10  
    11  // namedTypeFromSchema objects for every graphql type, including scalars. There should only be one instance of Type for each thing
    12  func (cfg *Config) buildNamedTypes() NamedTypes {
    13  	types := map[string]*NamedType{}
    14  	for _, schemaType := range cfg.schema.Types {
    15  		t := namedTypeFromSchema(schemaType)
    16  
    17  		if userEntry, ok := cfg.Models[t.GQLType]; ok && userEntry.Model != "" {
    18  			t.IsUserDefined = true
    19  			t.Package, t.GoType = pkgAndType(userEntry.Model)
    20  		} else if t.IsScalar {
    21  			t.Package = "github.com/99designs/gqlgen/graphql"
    22  			t.GoType = "String"
    23  		}
    24  
    25  		types[t.GQLType] = t
    26  	}
    27  	return types
    28  }
    29  
    30  func (cfg *Config) bindTypes(imports *Imports, namedTypes NamedTypes, destDir string, prog *loader.Program) {
    31  	for _, t := range namedTypes {
    32  		if t.Package == "" {
    33  			continue
    34  		}
    35  
    36  		def, _ := findGoType(prog, t.Package, "Marshal"+t.GoType)
    37  		switch def := def.(type) {
    38  		case *types.Func:
    39  			sig := def.Type().(*types.Signature)
    40  			cpy := t.Ref
    41  			t.Marshaler = &cpy
    42  
    43  			t.Package, t.GoType = pkgAndType(sig.Params().At(0).Type().String())
    44  			t.Import = imports.add(t.Package)
    45  		}
    46  	}
    47  }
    48  
    49  // namedTypeFromSchema objects for every graphql type, including primitives.
    50  // don't recurse into object fields or interfaces yet, lets make sure we have collected everything first.
    51  func namedTypeFromSchema(schemaType *ast.Definition) *NamedType {
    52  	switch schemaType.Kind {
    53  	case ast.Scalar, ast.Enum:
    54  		return &NamedType{GQLType: schemaType.Name, IsScalar: true}
    55  	case ast.Interface, ast.Union:
    56  		return &NamedType{GQLType: schemaType.Name, IsInterface: true}
    57  	case ast.InputObject:
    58  		return &NamedType{GQLType: schemaType.Name, IsInput: true}
    59  	default:
    60  		return &NamedType{GQLType: schemaType.Name}
    61  	}
    62  }
    63  
    64  // take a string in the form github.com/package/blah.Type and split it into package and type
    65  func pkgAndType(name string) (string, string) {
    66  	parts := strings.Split(name, ".")
    67  	if len(parts) == 1 {
    68  		return "", name
    69  	}
    70  
    71  	return normalizeVendor(strings.Join(parts[:len(parts)-1], ".")), parts[len(parts)-1]
    72  }
    73  
    74  func (n NamedTypes) getType(t *ast.Type) *Type {
    75  	orig := t
    76  	var modifiers []string
    77  	for {
    78  		if t.Elem != nil {
    79  			modifiers = append(modifiers, modList)
    80  			t = t.Elem
    81  		} else {
    82  			if !t.NonNull {
    83  				modifiers = append(modifiers, modPtr)
    84  			}
    85  			if n[t.NamedType] == nil {
    86  				panic("missing type " + t.NamedType)
    87  			}
    88  			res := &Type{
    89  				NamedType: n[t.NamedType],
    90  				Modifiers: modifiers,
    91  				ASTType:   orig,
    92  			}
    93  
    94  			if res.IsInterface {
    95  				res.StripPtr()
    96  			}
    97  
    98  			return res
    99  		}
   100  	}
   101  }