From 8f5605a1414369c7da0ee6b5e424d554a8b2e718 Mon Sep 17 00:00:00 2001 From: Richard Musiol Date: Sun, 12 Mar 2017 17:33:01 +0100 Subject: [PATCH] refactor directives --- internal/common/directive.go | 24 ++++++++++++++ internal/common/values.go | 13 ++++++++ internal/exec/exec.go | 6 ++-- internal/query/query.go | 62 ++++++------------------------------ 4 files changed, 50 insertions(+), 55 deletions(-) create mode 100644 internal/common/directive.go diff --git a/internal/common/directive.go b/internal/common/directive.go new file mode 100644 index 00000000000..e623777e769 --- /dev/null +++ b/internal/common/directive.go @@ -0,0 +1,24 @@ +package common + +import ( + "github.com/neelance/graphql-go/internal/lexer" +) + +type Directive struct { + Name string + Args map[string]interface{} +} + +func ParseDirectives(l *lexer.Lexer) map[string]*Directive { + directives := make(map[string]*Directive) + for l.Peek() == '@' { + l.ConsumeToken('@') + name := l.ConsumeIdent() + var args map[string]interface{} + if l.Peek() == '(' { + args = ParseArguments(l) + } + directives[name] = &Directive{Name: name, Args: args} + } + return directives +} diff --git a/internal/common/values.go b/internal/common/values.go index bace05f614b..144602d2e38 100644 --- a/internal/common/values.go +++ b/internal/common/values.go @@ -33,6 +33,19 @@ func ParseInputValue(l *lexer.Lexer) *InputValue { type Variable string +func ParseArguments(l *lexer.Lexer) map[string]interface{} { + args := make(map[string]interface{}) + l.ConsumeToken('(') + for l.Peek() != ')' { + name := l.ConsumeIdent() + l.ConsumeToken(':') + value := ParseValue(l, false) + args[name] = value + } + l.ConsumeToken(')') + return args +} + func ParseValue(l *lexer.Lexer, constOnly bool) interface{} { switch l.Peek() { case '$': diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 6b702df01c8..5af2ee72b1f 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -671,10 +671,10 @@ type typeAssertExec struct { typeExec iExec } -func skipByDirective(r *request, d map[string]*query.Directive) bool { +func skipByDirective(r *request, d map[string]*common.Directive) bool { if skip, ok := d["skip"]; ok { p := valuePacker{valueType: boolType} - v, err := p.pack(r, r.resolveVar(skip.Arguments["if"])) + v, err := p.pack(r, r.resolveVar(skip.Args["if"])) if err != nil { r.addError(errors.Errorf("%s", err)) } @@ -685,7 +685,7 @@ func skipByDirective(r *request, d map[string]*query.Directive) bool { if include, ok := d["include"]; ok { p := valuePacker{valueType: boolType} - v, err := p.pack(r, r.resolveVar(include.Arguments["if"])) + v, err := p.pack(r, r.resolveVar(include.Args["if"])) if err != nil { r.addError(errors.Errorf("%s", err)) } diff --git a/internal/query/query.go b/internal/query/query.go index ec25dddf663..03820ac28de 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -51,23 +51,18 @@ type Field struct { Alias string Name string Arguments map[string]interface{} - Directives map[string]*Directive + Directives map[string]*common.Directive SelSet *SelectionSet } -type Directive struct { - Name string - Arguments map[string]interface{} -} - type FragmentSpread struct { Name string - Directives map[string]*Directive + Directives map[string]*common.Directive } type InlineFragment struct { Fragment - Directives map[string]*Directive + Directives map[string]*common.Directive } func (Field) isSelection() {} @@ -180,9 +175,7 @@ func parseSelection(l *lexer.Lexer) Selection { } func parseField(l *lexer.Lexer) *Field { - f := &Field{ - Directives: make(map[string]*Directive), - } + f := &Field{} f.Alias = l.ConsumeIdent() f.Name = f.Alias if l.Peek() == ':' { @@ -190,41 +183,15 @@ func parseField(l *lexer.Lexer) *Field { f.Name = l.ConsumeIdent() } if l.Peek() == '(' { - f.Arguments = parseArguments(l) - } - for l.Peek() == '@' { - d := parseDirective(l) - f.Directives[d.Name] = d + f.Arguments = common.ParseArguments(l) } + f.Directives = common.ParseDirectives(l) if l.Peek() == '{' { f.SelSet = parseSelectionSet(l) } return f } -func parseArguments(l *lexer.Lexer) map[string]interface{} { - args := make(map[string]interface{}) - l.ConsumeToken('(') - for l.Peek() != ')' { - name := l.ConsumeIdent() - l.ConsumeToken(':') - value := common.ParseValue(l, false) - args[name] = value - } - l.ConsumeToken(')') - return args -} - -func parseDirective(l *lexer.Lexer) *Directive { - d := &Directive{} - l.ConsumeToken('@') - d.Name = l.ConsumeIdent() - if l.Peek() == '(' { - d.Arguments = parseArguments(l) - } - return d -} - func parseSpread(l *lexer.Lexer) Selection { l.ConsumeToken('.') l.ConsumeToken('.') @@ -232,25 +199,16 @@ func parseSpread(l *lexer.Lexer) Selection { ident := l.ConsumeIdent() if ident == "on" { - f := &InlineFragment{ - Directives: make(map[string]*Directive), - } + f := &InlineFragment{} f.On = l.ConsumeIdent() - for l.Peek() == '@' { - d := parseDirective(l) - f.Directives[d.Name] = d - } + f.Directives = common.ParseDirectives(l) f.SelSet = parseSelectionSet(l) return f } fs := &FragmentSpread{ - Directives: make(map[string]*Directive), - Name: ident, - } - for l.Peek() == '@' { - d := parseDirective(l) - fs.Directives[d.Name] = d + Name: ident, } + fs.Directives = common.ParseDirectives(l) return fs }