Skip to content

Commit bf0a0cc

Browse files
committed
add types package
Part of #434 and related to #116 this change adds a new package containing all types used by graphql-go in representing the GraphQL specification. The names used in this package should match the specification as closely as possible. In order to have cohesion, all internal packages that use GraphQL types have been changed to use this new package. This change is large but mostly mechanical. I recommend starting by reading through the `types` package to build familiarity. I'll call out places in the code where I made decisions and what the tradeoffs were.
1 parent 21f7aef commit bf0a0cc

38 files changed

+1271
-1127
lines changed

graphql.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/graph-gophers/graphql-go/introspection"
1919
"github.com/graph-gophers/graphql-go/log"
2020
"github.com/graph-gophers/graphql-go/trace"
21+
"github.com/graph-gophers/graphql-go/types"
2122
)
2223

2324
// ParseSchema parses a GraphQL schema and attaches the given root resolver. It returns an error if
@@ -42,7 +43,7 @@ func ParseSchema(schemaString string, resolver interface{}, opts ...SchemaOpt) (
4243
}
4344
}
4445

45-
if err := s.schema.Parse(schemaString, s.useStringDescriptions); err != nil {
46+
if err := schema.Parse(s.schema, schemaString, s.useStringDescriptions); err != nil {
4647
return nil, err
4748
}
4849
if err := s.validateSchema(); err != nil {
@@ -69,7 +70,7 @@ func MustParseSchema(schemaString string, resolver interface{}, opts ...SchemaOp
6970

7071
// Schema represents a GraphQL schema with an optional resolver.
7172
type Schema struct {
72-
schema *schema.Schema
73+
schema *types.Schema
7374
res *resolvable.Schema
7475

7576
maxDepth int
@@ -228,7 +229,7 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str
228229
}
229230
for _, v := range op.Vars {
230231
if _, ok := variables[v.Name.Name]; !ok && v.Default != nil {
231-
variables[v.Name.Name] = v.Default.Value(nil)
232+
variables[v.Name.Name] = v.Default.Deserialize(nil)
232233
}
233234
}
234235

@@ -288,7 +289,7 @@ func (t *validationBridgingTracer) TraceValidation(context.Context) trace.TraceV
288289
return t.tracer.TraceValidation()
289290
}
290291

291-
func validateRootOp(s *schema.Schema, name string, mandatory bool) error {
292+
func validateRootOp(s *types.Schema, name string, mandatory bool) error {
292293
t, ok := s.EntryPoints[name]
293294
if !ok {
294295
if mandatory {
@@ -302,7 +303,7 @@ func validateRootOp(s *schema.Schema, name string, mandatory bool) error {
302303
return nil
303304
}
304305

305-
func getOperation(document *query.Document, operationName string) (*query.Operation, error) {
306+
func getOperation(document *types.ExecutableDefinition, operationName string) (*types.OperationDefinition, error) {
306307
if len(document.Operations) == 0 {
307308
return nil, fmt.Errorf("no operations in query document")
308309
}

internal/common/directive.go

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
11
package common
22

3-
type Directive struct {
4-
Name Ident
5-
Args ArgumentList
6-
}
3+
import "github.com/graph-gophers/graphql-go/types"
74

8-
func ParseDirectives(l *Lexer) DirectiveList {
9-
var directives DirectiveList
5+
func ParseDirectives(l *Lexer) types.DirectiveList {
6+
var directives types.DirectiveList
107
for l.Peek() == '@' {
118
l.ConsumeToken('@')
12-
d := &Directive{}
9+
d := &types.Directive{}
1310
d.Name = l.ConsumeIdentWithLoc()
1411
d.Name.Loc.Column--
1512
if l.Peek() == '(' {
16-
d.Args = ParseArguments(l)
13+
d.Arguments = ParseArgumentList(l)
1714
}
1815
directives = append(directives, d)
1916
}
2017
return directives
2118
}
22-
23-
type DirectiveList []*Directive
24-
25-
func (l DirectiveList) Get(name string) *Directive {
26-
for _, d := range l {
27-
if d.Name.Name == name {
28-
return d
29-
}
30-
}
31-
return nil
32-
}

internal/common/lexer.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"text/scanner"
99

1010
"github.com/graph-gophers/graphql-go/errors"
11+
"github.com/graph-gophers/graphql-go/types"
1112
)
1213

1314
type syntaxError string
@@ -30,7 +31,6 @@ func NewLexer(s string, useStringDescriptions bool) *Lexer {
3031
}
3132
sc.Init(strings.NewReader(s))
3233

33-
3434
l := Lexer{sc: sc, useStringDescriptions: useStringDescriptions}
3535
l.sc.Error = l.CatchScannerError
3636

@@ -119,11 +119,11 @@ func (l *Lexer) ConsumeIdent() string {
119119
return name
120120
}
121121

122-
func (l *Lexer) ConsumeIdentWithLoc() Ident {
122+
func (l *Lexer) ConsumeIdentWithLoc() types.Ident {
123123
loc := l.Location()
124124
name := l.sc.TokenText()
125125
l.ConsumeToken(scanner.Ident)
126-
return Ident{name, loc}
126+
return types.Ident{name, loc}
127127
}
128128

129129
func (l *Lexer) ConsumeKeyword(keyword string) {
@@ -133,8 +133,8 @@ func (l *Lexer) ConsumeKeyword(keyword string) {
133133
l.ConsumeWhitespace()
134134
}
135135

136-
func (l *Lexer) ConsumeLiteral() *BasicLit {
137-
lit := &BasicLit{Type: l.next, Text: l.sc.TokenText()}
136+
func (l *Lexer) ConsumeLiteral() *types.PrimitiveValue {
137+
lit := &types.PrimitiveValue{Type: l.next, Text: l.sc.TokenText()}
138138
l.ConsumeWhitespace()
139139
return lit
140140
}

internal/common/literals.go

Lines changed: 9 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,12 @@
11
package common
22

33
import (
4-
"strconv"
5-
"strings"
64
"text/scanner"
75

8-
"github.com/graph-gophers/graphql-go/errors"
6+
"github.com/graph-gophers/graphql-go/types"
97
)
108

11-
type Literal interface {
12-
Value(vars map[string]interface{}) interface{}
13-
String() string
14-
Location() errors.Location
15-
}
16-
17-
type BasicLit struct {
18-
Type rune
19-
Text string
20-
Loc errors.Location
21-
}
22-
23-
func (lit *BasicLit) Value(vars map[string]interface{}) interface{} {
24-
switch lit.Type {
25-
case scanner.Int:
26-
value, err := strconv.ParseInt(lit.Text, 10, 32)
27-
if err != nil {
28-
panic(err)
29-
}
30-
return int32(value)
31-
32-
case scanner.Float:
33-
value, err := strconv.ParseFloat(lit.Text, 64)
34-
if err != nil {
35-
panic(err)
36-
}
37-
return value
38-
39-
case scanner.String:
40-
value, err := strconv.Unquote(lit.Text)
41-
if err != nil {
42-
panic(err)
43-
}
44-
return value
45-
46-
case scanner.Ident:
47-
switch lit.Text {
48-
case "true":
49-
return true
50-
case "false":
51-
return false
52-
default:
53-
return lit.Text
54-
}
55-
56-
default:
57-
panic("invalid literal")
58-
}
59-
}
60-
61-
func (lit *BasicLit) String() string {
62-
return lit.Text
63-
}
64-
65-
func (lit *BasicLit) Location() errors.Location {
66-
return lit.Loc
67-
}
68-
69-
type ListLit struct {
70-
Entries []Literal
71-
Loc errors.Location
72-
}
73-
74-
func (lit *ListLit) Value(vars map[string]interface{}) interface{} {
75-
entries := make([]interface{}, len(lit.Entries))
76-
for i, entry := range lit.Entries {
77-
entries[i] = entry.Value(vars)
78-
}
79-
return entries
80-
}
81-
82-
func (lit *ListLit) String() string {
83-
entries := make([]string, len(lit.Entries))
84-
for i, entry := range lit.Entries {
85-
entries[i] = entry.String()
86-
}
87-
return "[" + strings.Join(entries, ", ") + "]"
88-
}
89-
90-
func (lit *ListLit) Location() errors.Location {
91-
return lit.Loc
92-
}
93-
94-
type ObjectLit struct {
95-
Fields []*ObjectLitField
96-
Loc errors.Location
97-
}
98-
99-
type ObjectLitField struct {
100-
Name Ident
101-
Value Literal
102-
}
103-
104-
func (lit *ObjectLit) Value(vars map[string]interface{}) interface{} {
105-
fields := make(map[string]interface{}, len(lit.Fields))
106-
for _, f := range lit.Fields {
107-
fields[f.Name.Name] = f.Value.Value(vars)
108-
}
109-
return fields
110-
}
111-
112-
func (lit *ObjectLit) String() string {
113-
entries := make([]string, 0, len(lit.Fields))
114-
for _, f := range lit.Fields {
115-
entries = append(entries, f.Name.Name+": "+f.Value.String())
116-
}
117-
return "{" + strings.Join(entries, ", ") + "}"
118-
}
119-
120-
func (lit *ObjectLit) Location() errors.Location {
121-
return lit.Loc
122-
}
123-
124-
type NullLit struct {
125-
Loc errors.Location
126-
}
127-
128-
func (lit *NullLit) Value(vars map[string]interface{}) interface{} {
129-
return nil
130-
}
131-
132-
func (lit *NullLit) String() string {
133-
return "null"
134-
}
135-
136-
func (lit *NullLit) Location() errors.Location {
137-
return lit.Loc
138-
}
139-
140-
type Variable struct {
141-
Name string
142-
Loc errors.Location
143-
}
144-
145-
func (v Variable) Value(vars map[string]interface{}) interface{} {
146-
return vars[v.Name]
147-
}
148-
149-
func (v Variable) String() string {
150-
return "$" + v.Name
151-
}
152-
153-
func (v *Variable) Location() errors.Location {
154-
return v.Loc
155-
}
156-
157-
func ParseLiteral(l *Lexer, constOnly bool) Literal {
9+
func ParseLiteral(l *Lexer, constOnly bool) types.Value {
15810
loc := l.Location()
15911
switch l.Peek() {
16012
case '$':
@@ -163,12 +15,12 @@ func ParseLiteral(l *Lexer, constOnly bool) Literal {
16315
panic("unreachable")
16416
}
16517
l.ConsumeToken('$')
166-
return &Variable{l.ConsumeIdent(), loc}
18+
return &types.Variable{l.ConsumeIdent(), loc}
16719

16820
case scanner.Int, scanner.Float, scanner.String, scanner.Ident:
16921
lit := l.ConsumeLiteral()
17022
if lit.Type == scanner.Ident && lit.Text == "null" {
171-
return &NullLit{loc}
23+
return &types.NullValue{loc}
17224
}
17325
lit.Loc = loc
17426
return lit
@@ -180,24 +32,24 @@ func ParseLiteral(l *Lexer, constOnly bool) Literal {
18032
return lit
18133
case '[':
18234
l.ConsumeToken('[')
183-
var list []Literal
35+
var list []types.Value
18436
for l.Peek() != ']' {
18537
list = append(list, ParseLiteral(l, constOnly))
18638
}
18739
l.ConsumeToken(']')
188-
return &ListLit{list, loc}
40+
return &types.ListValue{list, loc}
18941

19042
case '{':
19143
l.ConsumeToken('{')
192-
var fields []*ObjectLitField
44+
var fields []*types.ObjectField
19345
for l.Peek() != '}' {
19446
name := l.ConsumeIdentWithLoc()
19547
l.ConsumeToken(':')
19648
value := ParseLiteral(l, constOnly)
197-
fields = append(fields, &ObjectLitField{name, value})
49+
fields = append(fields, &types.ObjectField{name, value})
19850
}
19951
l.ConsumeToken('}')
200-
return &ObjectLit{fields, loc}
52+
return &types.ObjectValue{fields, loc}
20153

20254
default:
20355
l.SyntaxError("invalid value")

0 commit comments

Comments
 (0)