Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parse and write the default values in the input value definition #53

Merged
merged 10 commits into from
Apr 2, 2024
35 changes: 18 additions & 17 deletions lib/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,28 @@ type Type struct {
}

type Arg struct {
Name string
Type string
TypeExt *string // in case of enum e.g. admin(role: Role = ADMIN): Admin!
Null bool
IsList bool
IsListNull bool
Directives []*Directive
Descriptions *[]string
Name string
Type string
DefaultValues *[]string // in case of default values e.g. admin(role: Role = ADMIN): Admin!
Null bool
IsList bool
IsListNull bool
Directives []*Directive
Descriptions *[]string
}

type Field struct {
BaseFileInfo
Name string
Args []*Arg
Type string
Null bool
IsList bool
IsListNull bool
Directives []*Directive
Descriptions *[]string
Comments *[]string
Name string
Args []*Arg
Type string
Null bool
IsList bool
IsListNull bool
DefaultValues *[]string
Directives []*Directive
Descriptions *[]string
Comments *[]string
}

type Scalar struct {
Expand Down
35 changes: 35 additions & 0 deletions lib/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,38 @@ func (l *lexer) consumeIdent(includings ...tokenType) (*token, *[]string) {
return tok, &comments
}
}

/*
The `consumeIdent` function treats tokString as a comment.
If you want to scan the tokString for ident, you can use the consumeIdentInclString function.

e.g. scan "woonki" for ident here

test(name: String = "woonki"): Bool
*/
func (l *lexer) consumeIdentInclString(includings ...tokenType) (*token, *[]string) {
comments := []string{}
includings = append(includings, tokString)

for {
tok := l.next()
if tok.typ == tokSingleLineComment || tok.typ == tokBlockString {
comments = append(comments, tok.String())
continue
}

isIncluded := false
for _, incl := range includings {
if tok.typ == incl {
isIncluded = true
break
}
}

if tok.typ != tokIdent && !isIncluded {
errorf(`%s:%d:%d: unexpected "%s"`, l.filename, l.line, l.col, tok.String())
}
l.skipSpace()
return tok, &comments
}
}
32 changes: 26 additions & 6 deletions lib/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,43 @@ func (p *Parser) parseArgs() []*Arg {
} else {
arg.IsListNull = true
}
} else {
typ, _ := p.lex.consumeIdent()
arg.Type = typ.String()

if p.lex.peek() == '=' {
p.lex.consumeToken(tokEqual)
tex, _ := p.lex.consumeIdent()
te := tex.String()
arg.TypeExt = &te
defaultValues := []string{}
if p.lex.peek() == '[' {
p.lex.consumeIdent(tokLBracket)
for p.lex.peek() != ']' {
tex, _ := p.lex.consumeIdentInclString(tokNumber)
te := tex.String()
defaultValues = append(defaultValues, te)
if p.lex.peek() == ',' {
p.lex.consumeToken(tokComma)
}
}
p.lex.consumeIdent(tokRBracket)
arg.DefaultValues = &defaultValues
}
}
} else {
typ, _ := p.lex.consumeIdent()
arg.Type = typ.String()

if p.lex.peek() == '!' {
arg.Null = false
p.lex.consumeToken(tokBang)
} else {
arg.Null = true
}

if p.lex.peek() == '=' {
p.lex.consumeToken(tokEqual)
tex, _ := p.lex.consumeIdentInclString(tokNumber)
te := tex.String()
defaultValues := []string{}
defaultValues = append(defaultValues, te)
arg.DefaultValues = &defaultValues
}
}
arg.Directives = p.parseDirectives()

Expand Down
26 changes: 26 additions & 0 deletions lib/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,23 @@ func (s *Schema) Parse(p *Parser) {
} else {
fd.IsListNull = true
}
if p.lex.peek() == '=' {
p.lex.consumeToken(tokEqual)
defaultValues := []string{}
if p.lex.peek() == '[' {
p.lex.consumeIdent(tokLBracket)
for p.lex.peek() != ']' {
tex, _ := p.lex.consumeIdentInclString(tokNumber)
te := tex.String()
defaultValues = append(defaultValues, te)
if p.lex.peek() == ',' {
p.lex.consumeToken(tokComma)
}
}
p.lex.consumeIdent(tokRBracket)
fd.DefaultValues = &defaultValues
}
}
} else {
fd.IsList = false
fd.IsListNull = false
Expand All @@ -330,6 +347,15 @@ func (s *Schema) Parse(p *Parser) {
} else {
fd.Null = true
}

if p.lex.peek() == '=' {
p.lex.consumeToken(tokEqual)
tex, _ := p.lex.consumeIdentInclString(tokNumber)
te := tex.String()
defaultValues := []string{}
defaultValues = append(defaultValues, te)
fd.DefaultValues = &defaultValues
}
}

fd.Directives = p.parseDirectives()
Expand Down
42 changes: 38 additions & 4 deletions lib/write.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lib

import (
"sort"
"strings"
)

Expand Down Expand Up @@ -237,7 +238,17 @@ func (ms *MergedSchema) WriteSchema(s *Schema) string {
if p.IsList && !p.IsListNull {
ms.buf.WriteString("!")
}

if p.DefaultValues != nil {
if p.IsList {
ms.buf.WriteString(" = ")
ms.buf.WriteString("[")
ms.stitchDefaultValues(p.DefaultValues)
ms.buf.WriteString("]")
} else {
ms.buf.WriteString(" = ")
ms.stitchDefaultValues(p.DefaultValues)
}
}
ms.stitchDirectives(p.Directives)

ms.buf.WriteString("\n")
Expand Down Expand Up @@ -278,14 +289,23 @@ func (ms *MergedSchema) stitchArgument(a *Arg, l int, i int) {
if !a.IsListNull {
ms.buf.WriteString("!")
}
if a.DefaultValues != nil {
ms.buf.WriteString(" = ")
ms.buf.WriteString("[")
ms.stitchDefaultValues(a.DefaultValues)
ms.buf.WriteString("]")
}
ms.stitchDirectives(a.Directives)
} else {
ms.buf.WriteString(a.Type)
if a.TypeExt != nil {
ms.buf.WriteString(" = " + *a.TypeExt)
}
if !a.Null {
ms.buf.WriteString("!")
}
if a.DefaultValues != nil {
ms.buf.WriteString(" = ")
ms.stitchDefaultValues(a.DefaultValues)
}
ms.stitchDirectives(a.Directives)
}

if l <= 2 && i != l-1 {
Expand All @@ -297,6 +317,9 @@ func (ms *MergedSchema) stitchArgument(a *Arg, l int, i int) {
}

func (ms *MergedSchema) stitchDirectives(a []*Directive) {
sort.SliceStable(a, func(i, j int) bool {
return a[i].Name > a[j].Name
})
if l := len(a); l > 0 {
for _, a := range a {
ms.buf.WriteString(" @" + a.Name)
Expand All @@ -311,6 +334,17 @@ func (ms *MergedSchema) stitchDirectives(a []*Directive) {
}
}

func (ms *MergedSchema) stitchDefaultValues(a *[]string) {
if l := len(*a); l > 0 {
for i, v := range *a {
ms.buf.WriteString(v)
if i < l-1 {
ms.buf.WriteString(", ")
}
}
}
}

func (ms *MergedSchema) stitchDirectiveArgument(a *DirectiveArg, l int, i int) {
if l > 2 {
ms.addIndent(2)
Expand Down
22 changes: 22 additions & 0 deletions test/default_value/generated.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
type Query {
test1(X: Int = 20): Int
test2(X: Int! = 20): Int
test3(X: User = ADMIN): Int
test4(X: String! = "user"): Int
test5(X: String = "user" @deprecated): Int
test6(X: String = "user" @deprecated, Y: String! = "operator" @unique): Int
test7(X: [Int] = [20]): Int
test8(X: [Int] = [20, 30]): Int
test9(X: [User!]! = [ADMIN]): Int
test10(X: [String!] = ["user"]): Int
test11(X: [String] = ["user", "user1"] @deprecated): Int
test12(X: [String] = ["user", "user1"] @deprecated, Y: String! = "operator" @unique): Int
}




input User {
name: String! = "woonki"
nicknames: [String!]! = ["mununki", "arnold"]
}
19 changes: 19 additions & 0 deletions test/default_value/schema/a.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
type Query {
test1(X: Int = 20): Int
test2(X: Int! = 20): Int
test3(X: User = ADMIN): Int
test4(X: String! = "user"): Int
test5(X: String = "user" @deprecated): Int
test6(X: String = "user" @deprecated, Y: String! = "operator" @unique): Int
test7(X: [Int] = [20]): Int
test8(X: [Int] = [20, 30]): Int
test9(X: [User!]! = [ADMIN]): Int
test10(X: [String!] = ["user"]): Int
test11(X: [String] = ["user", "user1"] @deprecated): Int
test12(X: [String] = ["user", "user1"] @deprecated, Y: String! = "operator" @unique): Int
}

input User {
name: String! = "woonki"
nicknames: [String!]! = ["mununki", "arnold"]
}
2 changes: 1 addition & 1 deletion test/object_extension/generated.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type Person implements Node @talkable @walkable {
type Person implements Node @walkable @talkable {
id: ID!
createTime: Time!
updateTime: Time!
Expand Down
Loading