From f83c8a226e09ea85130b4acf39e161307593545c Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 2 Apr 2024 16:24:28 +0900 Subject: [PATCH] fix parse and write the default value in arg definitions --- lib/graphql.go | 2 +- lib/lex.go | 35 ++++++++++++++++++++++++++++ lib/parse.go | 14 +++++------ lib/write.go | 7 +++--- test/default_value/generated.graphql | 12 ++++++++++ test/default_value/schema/a.graphql | 5 +++- 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 test/default_value/generated.graphql diff --git a/lib/graphql.go b/lib/graphql.go index 4b09fbe..a7f2ff8 100644 --- a/lib/graphql.go +++ b/lib/graphql.go @@ -66,7 +66,7 @@ type Type struct { type Arg struct { Name string Type string - TypeExt *string // in case of enum e.g. admin(role: Role = ADMIN): Admin! + TypeExt *string // in case of default values e.g. admin(role: Role = ADMIN): Admin! Null bool IsList bool IsListNull bool diff --git a/lib/lex.go b/lib/lex.go index 054290e..6374313 100644 --- a/lib/lex.go +++ b/lib/lex.go @@ -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 + } +} diff --git a/lib/parse.go b/lib/parse.go index 7731913..8d84d8b 100644 --- a/lib/parse.go +++ b/lib/parse.go @@ -68,19 +68,19 @@ func (p *Parser) parseArgs() []*Arg { 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 - } - 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() + arg.TypeExt = &te + } } arg.Directives = p.parseDirectives() diff --git a/lib/write.go b/lib/write.go index e95b86b..f5c6c65 100644 --- a/lib/write.go +++ b/lib/write.go @@ -280,12 +280,13 @@ func (ms *MergedSchema) stitchArgument(a *Arg, l int, i int) { } } else { ms.buf.WriteString(a.Type) - if a.TypeExt != nil { - ms.buf.WriteString(" = " + *a.TypeExt) - } if !a.Null { ms.buf.WriteString("!") } + if a.TypeExt != nil { + ms.buf.WriteString(" = " + *a.TypeExt) + } + ms.stitchDirectives(a.Directives) } if l <= 2 && i != l-1 { diff --git a/test/default_value/generated.graphql b/test/default_value/generated.graphql new file mode 100644 index 0000000..ac3064a --- /dev/null +++ b/test/default_value/generated.graphql @@ -0,0 +1,12 @@ +type Query { + test(X: Int = 20): Int + test(X: Int! = 20): Int + test1(X: Int = ADMIN): Int + test2(X: String! = "user"): Int + test3(X: String = "user" @deprecated): Int + test3(X: String = "user" @deprecated, Y: String! = "operator" @unique): Int +} + + + + diff --git a/test/default_value/schema/a.graphql b/test/default_value/schema/a.graphql index d3ddf10..e72845c 100644 --- a/test/default_value/schema/a.graphql +++ b/test/default_value/schema/a.graphql @@ -1,5 +1,8 @@ type Query { test(X: Int = 20): Int + test(X: Int! = 20): Int test1(X: Int = ADMIN): Int - test2(X: String = "user"): Int + test2(X: String! = "user"): Int + test3(X: String = "user" @deprecated): Int + test3(X: String = "user" @deprecated, Y: String! = "operator" @unique): Int }