Skip to content

Commit 7fd6d89

Browse files
authored
Merge branch 'master' into extensions
2 parents 857c948 + cc858c0 commit 7fd6d89

File tree

6 files changed

+280
-228
lines changed

6 files changed

+280
-228
lines changed

executor.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func Execute(p ExecuteParams) (result *Result) {
5454
go func(out chan<- *Result, done <-chan struct{}) {
5555
defer func() {
5656
if err := recover(); err != nil {
57-
result.Errors = append(result.Errors, gqlerrors.FormatError(err.(error)))
57+
result.AppendErrors(gqlerrors.FormatError(err.(error)))
5858
}
5959
select {
6060
case out <- result:
@@ -72,7 +72,7 @@ func Execute(p ExecuteParams) (result *Result) {
7272
})
7373

7474
if err != nil {
75-
result.Errors = append(result.Errors, gqlerrors.FormatError(err))
75+
result.AppendErrors(gqlerrors.FormatError(err))
7676
return
7777
}
7878

@@ -86,7 +86,7 @@ func Execute(p ExecuteParams) (result *Result) {
8686

8787
select {
8888
case <-ctx.Done():
89-
result.Errors = append(result.Errors, gqlerrors.FormatError(ctx.Err()))
89+
result.AppendErrors(gqlerrors.FormatError(ctx.Err()))
9090
case r := <-resultChannel:
9191
result = r
9292
}
@@ -995,6 +995,22 @@ func DefaultResolveFn(p ResolveParams) (interface{}, error) {
995995
return property, nil
996996
}
997997

998+
// Try accessing as map via reflection
999+
if r := reflect.ValueOf(p.Source); r.Kind() == reflect.Map && r.Type().Key().Kind() == reflect.String {
1000+
val := r.MapIndex(reflect.ValueOf(p.Info.FieldName))
1001+
if val.IsValid() {
1002+
property := val.Interface()
1003+
if val.Type().Kind() == reflect.Func {
1004+
// try type casting the func to the most basic func signature
1005+
// for more complex signatures, user have to define ResolveFn
1006+
if propertyFn, ok := property.(func() interface{}); ok {
1007+
return propertyFn(), nil
1008+
}
1009+
}
1010+
return property, nil
1011+
}
1012+
}
1013+
9981014
// last resort, return nil
9991015
return nil, nil
10001016
}

executor_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,62 @@ func TestMergesParallelFragments(t *testing.T) {
297297
}
298298
}
299299

300+
type CustomMap map[string]interface{}
301+
302+
func TestCustomMapType(t *testing.T) {
303+
query := `
304+
query Example { data { a } }
305+
`
306+
data := CustomMap{
307+
"a": "1",
308+
"b": "2",
309+
}
310+
schema, err := graphql.NewSchema(graphql.SchemaConfig{
311+
Query: graphql.NewObject(graphql.ObjectConfig{
312+
Name: "RootQuery",
313+
Fields: graphql.Fields{
314+
"data": &graphql.Field{
315+
Type: graphql.NewObject(graphql.ObjectConfig{
316+
Name: "Data",
317+
Fields: graphql.Fields{
318+
"a": &graphql.Field{
319+
Type: graphql.String,
320+
},
321+
"b": &graphql.Field{
322+
Type: graphql.String,
323+
},
324+
},
325+
}),
326+
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
327+
return data, nil
328+
},
329+
},
330+
},
331+
}),
332+
})
333+
if err != nil {
334+
t.Fatalf("Error in schema %v", err.Error())
335+
}
336+
337+
result := testutil.TestExecute(t, graphql.ExecuteParams{
338+
Schema: schema,
339+
Root: data,
340+
AST: testutil.TestParse(t, query),
341+
})
342+
if len(result.Errors) > 0 {
343+
t.Fatalf("wrong result, unexpected errors: %v", result.Errors)
344+
}
345+
346+
expected := map[string]interface{}{
347+
"data": map[string]interface{}{
348+
"a": "1",
349+
},
350+
}
351+
if !reflect.DeepEqual(result.Data, expected) {
352+
t.Fatalf("Expected context.key to equal %v, got %v", expected, result.Data)
353+
}
354+
}
355+
300356
func TestThreadsSourceCorrectly(t *testing.T) {
301357

302358
query := `

language/lexer/lexer.go

Lines changed: 56 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import (
1111
"github.com/graphql-go/graphql/language/source"
1212
)
1313

14+
type TokenKind int
15+
1416
const (
15-
EOF = iota + 1
17+
EOF TokenKind = iota + 1
1618
BANG
1719
DOLLAR
1820
PAREN_L
@@ -34,6 +36,33 @@ const (
3436
AMP
3537
)
3638

39+
var tokenDescription = map[TokenKind]string{
40+
EOF: "EOF",
41+
BANG: "!",
42+
DOLLAR: "$",
43+
PAREN_L: "(",
44+
PAREN_R: ")",
45+
SPREAD: "...",
46+
COLON: ":",
47+
EQUALS: "=",
48+
AT: "@",
49+
BRACKET_L: "[",
50+
BRACKET_R: "]",
51+
BRACE_L: "{",
52+
PIPE: "|",
53+
BRACE_R: "}",
54+
NAME: "Name",
55+
INT: "Int",
56+
FLOAT: "Float",
57+
STRING: "String",
58+
BLOCK_STRING: "BlockString",
59+
AMP: "&",
60+
}
61+
62+
func (kind TokenKind) String() string {
63+
return tokenDescription[kind]
64+
}
65+
3766
// NAME -> keyword relationship
3867
const (
3968
FRAGMENT = "fragment"
@@ -51,61 +80,10 @@ const (
5180
DIRECTIVE = "directive"
5281
)
5382

54-
var TokenKind map[int]int
55-
var tokenDescription map[int]string
56-
57-
func init() {
58-
TokenKind = make(map[int]int)
59-
{
60-
TokenKind[EOF] = EOF
61-
TokenKind[BANG] = BANG
62-
TokenKind[DOLLAR] = DOLLAR
63-
TokenKind[PAREN_L] = PAREN_L
64-
TokenKind[PAREN_R] = PAREN_R
65-
TokenKind[SPREAD] = SPREAD
66-
TokenKind[COLON] = COLON
67-
TokenKind[EQUALS] = EQUALS
68-
TokenKind[AT] = AT
69-
TokenKind[BRACKET_L] = BRACKET_L
70-
TokenKind[BRACKET_R] = BRACKET_R
71-
TokenKind[BRACE_L] = BRACE_L
72-
TokenKind[PIPE] = PIPE
73-
TokenKind[BRACE_R] = BRACE_R
74-
TokenKind[NAME] = NAME
75-
TokenKind[INT] = INT
76-
TokenKind[FLOAT] = FLOAT
77-
TokenKind[STRING] = STRING
78-
TokenKind[BLOCK_STRING] = BLOCK_STRING
79-
}
80-
tokenDescription = make(map[int]string)
81-
{
82-
tokenDescription[TokenKind[EOF]] = "EOF"
83-
tokenDescription[TokenKind[BANG]] = "!"
84-
tokenDescription[TokenKind[DOLLAR]] = "$"
85-
tokenDescription[TokenKind[PAREN_L]] = "("
86-
tokenDescription[TokenKind[PAREN_R]] = ")"
87-
tokenDescription[TokenKind[SPREAD]] = "..."
88-
tokenDescription[TokenKind[COLON]] = ":"
89-
tokenDescription[TokenKind[EQUALS]] = "="
90-
tokenDescription[TokenKind[AT]] = "@"
91-
tokenDescription[TokenKind[BRACKET_L]] = "["
92-
tokenDescription[TokenKind[BRACKET_R]] = "]"
93-
tokenDescription[TokenKind[BRACE_L]] = "{"
94-
tokenDescription[TokenKind[PIPE]] = "|"
95-
tokenDescription[TokenKind[BRACE_R]] = "}"
96-
tokenDescription[TokenKind[NAME]] = "Name"
97-
tokenDescription[TokenKind[INT]] = "Int"
98-
tokenDescription[TokenKind[FLOAT]] = "Float"
99-
tokenDescription[TokenKind[STRING]] = "String"
100-
tokenDescription[TokenKind[BLOCK_STRING]] = "BlockString"
101-
tokenDescription[TokenKind[AMP]] = "&"
102-
}
103-
}
104-
10583
// Token is a representation of a lexed Token. Value only appears for non-punctuation
10684
// tokens: NAME, INT, FLOAT, and STRING.
10785
type Token struct {
108-
Kind int
86+
Kind TokenKind
10987
Start int
11088
End int
11189
Value string
@@ -151,7 +129,7 @@ func readName(source *source.Source, position, runePosition int) Token {
151129
break
152130
}
153131
}
154-
return makeToken(TokenKind[NAME], runePosition, endRune, string(body[position:endByte]))
132+
return makeToken(NAME, runePosition, endRune, string(body[position:endByte]))
155133
}
156134

157135
// Reads a number token from the source file, either a float
@@ -207,9 +185,9 @@ func readNumber(s *source.Source, start int, firstCode rune, codeLength int) (To
207185
}
208186
position = p
209187
}
210-
kind := TokenKind[INT]
188+
kind := INT
211189
if isFloat {
212-
kind = TokenKind[FLOAT]
190+
kind = FLOAT
213191
}
214192

215193
return makeToken(kind, start, position, string(body[start:position])), nil
@@ -328,7 +306,7 @@ func readString(s *source.Source, start int) (Token, error) {
328306
stringContent := body[chunkStart:position]
329307
valueBuffer.Write(stringContent)
330308
value := valueBuffer.String()
331-
return makeToken(TokenKind[STRING], start, position+1, value), nil
309+
return makeToken(STRING, start, position+1, value), nil
332310
}
333311

334312
// readBlockString reads a block string token from the source file.
@@ -357,7 +335,7 @@ func readBlockString(s *source.Source, start int) (Token, error) {
357335
stringContent := body[chunkStart:position]
358336
valueBuffer.Write(stringContent)
359337
value := blockStringValue(valueBuffer.String())
360-
return makeToken(TokenKind[BLOCK_STRING], start, position+3, value), nil
338+
return makeToken(BLOCK_STRING, start, position+3, value), nil
361339
}
362340
}
363341

@@ -426,19 +404,13 @@ func blockStringValue(in string) string {
426404
}
427405

428406
// Remove leading blank lines.
429-
for {
430-
if isBlank := lineIsBlank(lines[0]); !isBlank {
431-
break
432-
}
407+
for len(lines) > 0 && lineIsBlank(lines[0]) {
433408
lines = lines[1:]
434409
}
435410

436411
// Remove trailing blank lines.
437-
for {
412+
for len(lines) > 0 && lineIsBlank(lines[len(lines)-1]) {
438413
i := len(lines) - 1
439-
if isBlank := lineIsBlank(lines[i]); !isBlank {
440-
break
441-
}
442414
lines = append(lines[:i], lines[i+1:]...)
443415
}
444416

@@ -490,7 +462,7 @@ func char2hex(a rune) int {
490462
return -1
491463
}
492464

493-
func makeToken(kind int, start int, end int, value string) Token {
465+
func makeToken(kind TokenKind, start int, end int, value string) Token {
494466
return Token{Kind: kind, Start: start, End: end, Value: value}
495467
}
496468

@@ -512,7 +484,7 @@ func readToken(s *source.Source, fromPosition int) (Token, error) {
512484
bodyLength := len(body)
513485
position, runePosition := positionAfterWhitespace(body, fromPosition)
514486
if position >= bodyLength {
515-
return makeToken(TokenKind[EOF], position, position, ""), nil
487+
return makeToken(EOF, position, position, ""), nil
516488
}
517489
code, codeLength := runeAt(body, position)
518490

@@ -524,51 +496,51 @@ func readToken(s *source.Source, fromPosition int) (Token, error) {
524496
switch code {
525497
// !
526498
case '!':
527-
return makeToken(TokenKind[BANG], position, position+1, ""), nil
499+
return makeToken(BANG, position, position+1, ""), nil
528500
// $
529501
case '$':
530-
return makeToken(TokenKind[DOLLAR], position, position+1, ""), nil
502+
return makeToken(DOLLAR, position, position+1, ""), nil
531503
// &
532504
case '&':
533-
return makeToken(TokenKind[AMP], position, position+1, ""), nil
505+
return makeToken(AMP, position, position+1, ""), nil
534506
// (
535507
case '(':
536-
return makeToken(TokenKind[PAREN_L], position, position+1, ""), nil
508+
return makeToken(PAREN_L, position, position+1, ""), nil
537509
// )
538510
case ')':
539-
return makeToken(TokenKind[PAREN_R], position, position+1, ""), nil
511+
return makeToken(PAREN_R, position, position+1, ""), nil
540512
// .
541513
case '.':
542514
next1, _ := runeAt(body, position+1)
543515
next2, _ := runeAt(body, position+2)
544516
if next1 == '.' && next2 == '.' {
545-
return makeToken(TokenKind[SPREAD], position, position+3, ""), nil
517+
return makeToken(SPREAD, position, position+3, ""), nil
546518
}
547519
break
548520
// :
549521
case ':':
550-
return makeToken(TokenKind[COLON], position, position+1, ""), nil
522+
return makeToken(COLON, position, position+1, ""), nil
551523
// =
552524
case '=':
553-
return makeToken(TokenKind[EQUALS], position, position+1, ""), nil
525+
return makeToken(EQUALS, position, position+1, ""), nil
554526
// @
555527
case '@':
556-
return makeToken(TokenKind[AT], position, position+1, ""), nil
528+
return makeToken(AT, position, position+1, ""), nil
557529
// [
558530
case '[':
559-
return makeToken(TokenKind[BRACKET_L], position, position+1, ""), nil
531+
return makeToken(BRACKET_L, position, position+1, ""), nil
560532
// ]
561533
case ']':
562-
return makeToken(TokenKind[BRACKET_R], position, position+1, ""), nil
534+
return makeToken(BRACKET_R, position, position+1, ""), nil
563535
// {
564536
case '{':
565-
return makeToken(TokenKind[BRACE_L], position, position+1, ""), nil
537+
return makeToken(BRACE_L, position, position+1, ""), nil
566538
// |
567539
case '|':
568-
return makeToken(TokenKind[PIPE], position, position+1, ""), nil
540+
return makeToken(PIPE, position, position+1, ""), nil
569541
// }
570542
case '}':
571-
return makeToken(TokenKind[BRACE_R], position, position+1, ""), nil
543+
return makeToken(BRACE_R, position, position+1, ""), nil
572544
// A-Z
573545
case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
574546
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':
@@ -672,11 +644,7 @@ func positionAfterWhitespace(body []byte, startPosition int) (position int, rune
672644

673645
func GetTokenDesc(token Token) string {
674646
if token.Value == "" {
675-
return GetTokenKindDesc(token.Kind)
647+
return token.Kind.String()
676648
}
677-
return fmt.Sprintf("%s \"%s\"", GetTokenKindDesc(token.Kind), token.Value)
678-
}
679-
680-
func GetTokenKindDesc(kind int) string {
681-
return tokenDescription[kind]
649+
return fmt.Sprintf("%s \"%s\"", token.Kind.String(), token.Value)
682650
}

0 commit comments

Comments
 (0)