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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
package common
import (
"github.com/graph-gophers/graphql-go/ast"
"github.com/graph-gophers/graphql-go/errors"
)
func ParseType(l *Lexer) ast.Type {
t := parseNullType(l)
if l.Peek() == '!' {
l.ConsumeToken('!')
return &ast.NonNull{OfType: t}
}
return t
}
func parseNullType(l *Lexer) ast.Type {
if l.Peek() == '[' {
l.ConsumeToken('[')
ofType := ParseType(l)
l.ConsumeToken(']')
return &ast.List{OfType: ofType}
}
return &ast.TypeName{Ident: l.ConsumeIdentWithLoc()}
}
type Resolver func(name string) ast.Type
// ResolveType attempts to resolve a type's name against a resolving function.
// This function is used when one needs to check if a TypeName exists in the resolver (typically a Schema).
//
// In the example below, ResolveType would be used to check if the resolving function
// returns a valid type for Dimension:
//
// type Profile {
// picture(dimensions: Dimension): Url
// }
//
// ResolveType recursively unwraps List and NonNull types until a NamedType is reached.
func ResolveType(t ast.Type, resolver Resolver) (ast.Type, *errors.QueryError) {
switch t := t.(type) {
case *ast.List:
ofType, err := ResolveType(t.OfType, resolver)
if err != nil {
return nil, err
}
return &ast.List{OfType: ofType}, nil
case *ast.NonNull:
ofType, err := ResolveType(t.OfType, resolver)
if err != nil {
return nil, err
}
return &ast.NonNull{OfType: ofType}, nil
case *ast.TypeName:
refT := resolver(t.Name)
if refT == nil {
err := errors.Errorf("Unknown type %q.", t.Name)
err.Rule = "KnownTypeNamesRule"
err.Locations = []errors.Location{t.Loc}
return nil, err
}
return refT, nil
default:
return t, nil
}
}
|