/
types.go
47 lines (41 loc) · 1.44 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package modelgen
import (
"go/types"
"strings"
)
// buildType constructs a types.Type for the given string (using the syntax
// from the extra field config Type field).
func buildType(typeString string) types.Type {
switch {
case typeString[0] == '*':
return types.NewPointer(buildType(typeString[1:]))
case strings.HasPrefix(typeString, "[]"):
return types.NewSlice(buildType(typeString[2:]))
default:
return buildNamedType(typeString)
}
}
// buildNamedType returns the specified named or builtin type.
//
// Note that we don't look up the full types.Type object from the appropriate
// package -- gqlgen doesn't give us the package-map we'd need to do so.
// Instead we construct a placeholder type that has all the fields gqlgen
// wants. This is roughly what gqlgen itself does, anyway:
// https://github.com/niko0xdev/gqlgen/blob/master/plugin/modelgen/models.go#L119
func buildNamedType(fullName string) types.Type {
dotIndex := strings.LastIndex(fullName, ".")
if dotIndex == -1 { // builtinType
return types.Universe.Lookup(fullName).Type()
}
// type is pkg.Name
pkgPath := fullName[:dotIndex]
typeName := fullName[dotIndex+1:]
pkgName := pkgPath
slashIndex := strings.LastIndex(pkgPath, "/")
if slashIndex != -1 {
pkgName = pkgPath[slashIndex+1:]
}
pkg := types.NewPackage(pkgPath, pkgName)
// gqlgen doesn't use some of the fields, so we leave them 0/nil
return types.NewNamed(types.NewTypeName(0, pkg, typeName, nil), nil, nil)
}