8000 normalization of type extensions by jobergner · Pull Request #108 · wundergraph/graphql-go-tools · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

normalization of type extensions #108 8000

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

Merged
merged 20 commits into from
Nov 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 103 additions & 14 deletions pkg/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,20 @@ func (d *Document) FieldDefinitionTypeNode(ref int) Node {
return d.Index.Nodes[xxhash.Sum64(typeName)]
}

func (d *Document) ExtendInterfaceTypeDefinitionByInterfaceTypeExtension(interfaceTypeDefinitionRef, interfaceTypeExtensionRef int) {
if d.InterfaceTypeExtensionHasFieldDefinitions(interfaceTypeExtensionRef) {
d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].FieldsDefinition.Refs = append(d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].FieldsDefinition.Refs, d.InterfaceTypeExtensions[interfaceTypeExtensionRef].FieldsDefinition.Refs...)
d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].HasFieldDefinitions = true
}

if d.InterfaceTypeExtensionHasDirectives(interfaceTypeExtensionRef) {
d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].Directives.Refs = append(d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].Directives.Refs, d.InterfaceTypeExtensions[interfaceTypeExtensionRef].Directives.Refs...)
d.InterfaceTypeDefinitions[interfaceTypeDefinitionRef].HasDirectives = true
}

d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: interfaceTypeExtensionRef, Kind: NodeKindInterfaceTypeExtension})
}

func (d *Document) ExtendObjectTypeDefinitionByObjectTypeExtension(objectTypeDefinitionRef, objectTypeExtensionRef int) {
if d.ObjectTypeExtensionHasFieldDefinitions(objectTypeExtensionRef) {
d.ObjectTypeDefinitions[objectTypeDefinitionRef].FieldsDefinition.Refs = append(d.ObjectTypeDefinitions[objectTypeDefinitionRef].FieldsDefinition.Refs, d.ObjectTypeExtensions[objectTypeExtensionRef].FieldsDefinition.Refs...)
Expand All @@ -470,6 +484,57 @@ func (d *Document) ExtendObjectTypeDefinitionByObjectTypeExtension(objectTypeDef
d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: objectTypeExtensionRef, Kind: NodeKindObjectTypeExtension})
}

func (d *Document) ExtendScalarTypeDefinitionByScalarTypeExtension(scalarTypeDefinitionRef, scalarTypeExtensionRef int) {
if d.ScalarTypeExtensionHasDirectives(scalarTypeExtensionRef) {
d.ScalarTypeDefinitions[scalarTypeDefinitionRef].Directives.Refs = append(d.ScalarTypeDefinitions[scalarTypeDefinitionRef].Directives.Refs, d.ScalarTypeExtensions[scalarTypeExtensionRef].Directives.Refs...)
d.ScalarTypeDefinitions[scalarTypeDefinitionRef].HasDirectives = true
}

d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: scalarTypeExtensionRef, Kind: NodeKindScalarTypeExtension})
}

func (d *Document) ExtendUnionTypeDefinitionByUnionTypeExtension(unionTypeDefinitionRef, unionTypeExtensionRef int) {
if d.UnionTypeExtensionHasDirectives(unionTypeExtensionRef) {
d.UnionTypeDefinitions[unionTypeDefinitionRef].Directives.Refs = append(d.UnionTypeDefinitions[unionTypeDefinitionRef].Directives.Refs, d.UnionTypeExtensions[unionTypeExtensionRef].Directives.Refs...)
d.UnionTypeDefinitions[unionTypeDefinitionRef].HasDirectives = true
}

if d.UnionTypeExtensionHasUnionMemberTypes(unionTypeExtensionRef) {
d.UnionTypeDefinitions[unionTypeDefinitionRef].UnionMemberTypes.Refs = append(d.UnionTypeDefinitions[unionTypeDefinitionRef].UnionMemberTypes.Refs, d.UnionTypeExtensions[unionTypeExtensionRef].UnionMemberTypes.Refs...)
d.UnionTypeDefinitions[unionTypeDefinitionRef].HasUnionMemberTypes = true
}

d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: unionTypeExtensionRef, Kind: NodeKindUnionTypeExtension})
}

func (d *Document) ExtendEnumTypeDefinitionByEnumTypeExtension(enumTypeDefinitionRef, enumTypeExtensionRef int) {
if d.EnumTypeExtensionHasDirectives(enumTypeExtensionRef) {
d.EnumTypeDefinitions[enumTypeDefinitionRef].Directives.Refs = append(d.EnumTypeDefinitions[enumTypeDefinitionRef].Directives.Refs, d.EnumTypeExtensions[enumTypeExtensionRef].Directives.Refs...)
d.EnumTypeDefinitions[enumTypeDefinitionRef].HasDirectives = true
}

if d.EnumTypeDefinitionHasEnumValueDefinition(enumTypeExtensionRef) {
d.EnumTypeDefinitions[enumTypeDefinitionRef].EnumValuesDefinition.Refs = append(d.EnumTypeDefinitions[enumTypeDefinitionRef].EnumValuesDefinition.Refs, d.EnumTypeExtensions[enumTypeExtensionRef].EnumValuesDefinition.Refs...)
d.EnumTypeDefinitions[enumTy 8000 peDefinitionRef].HasEnumValuesDefinition = true
}

d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: enumTypeExtensionRef, Kind: NodeKindEnumTypeExtension})
}

func (d *Document) ExtendInputObjectTypeDefinitionByInputObjectTypeExtension(inputObjectTypeDefinitionRef, inputObjectTypeExtensionRef int) {
if d.InputObjectTypeExtensionHasDirectives(inputObjectTypeExtensionRef) {
d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].Directives.Refs = append(d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].Directives.Refs, d.InputObjectTypeExtensions[inputObjectTypeExtensionRef].Directives.Refs...)
d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].HasDirectives = true
}

if d.InputObjectTypeExtensionHasInputFieldsDefinition(inputObjectTypeExtensionRef) {
d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].InputFieldsDefinition.Refs = append(d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].InputFieldsDefinition.Refs, d.InputObjectTypeExtensions[inputObjectTypeExtensionRef].InputFieldsDefinition.Refs...)
d.InputObjectTypeDefinitions[inputObjectTypeDefinitionRef].HasInputFieldsDefinition = true
}

d.Index.MergedTypeExtensions = append(d.Index.MergedTypeExtensions, Node{Ref: inputObjectTypeExtensionRef, Kind: NodeKindInputObjectTypeExtension})
}

func (d *Document) RemoveMergedTypeExtensions() {
for _, node := range d.Index.MergedTypeExtensions {
d.RemoveRootNode(node)
Expand Down Expand Up @@ -1846,13 +1911,21 @@ type DefaultValue struct {
}

type InputObjectTypeDefinition struct {
Description Description // optional, describes the input type
InputLiteral position.Position // input
Name ByteSliceReference // name of the input type
HasDirectives bool
Directives DirectiveList // optional, e.g. @foo
HasInputFieldsDefinitions bool
InputFieldsDefinition InputValueDefinitionList // e.g. x:Float
Description Description // optional, describes the input type
InputLiteral position.Position // input
Name ByteSliceReference // name of the input type
HasDirectives bool
Directives DirectiveList // optional, e.g. @foo
HasInputFieldsDefinition bool
InputFieldsDefinition InputValueDefinitionList // e.g. x:Float
}

func (d *Document) InputObjectTypeExtensionHasDirectives(ref int) bool {
return d.InputObjectTypeExtensions[ref].HasDirectives
}

func (d *Document) InputObjectTypeExtensionHasInputFieldsDefinition(ref int) bool {
return d.InputObjectTypeDefinitions[ref].HasInputFieldsDefinition
}
< 8000 span class='blob-code-inner blob-code-marker ' data-code-marker=" ">
func (d *Document) InputObjectTypeDefinitionNameBytes(ref int) ByteSlice {
Expand Down Expand Up @@ -1942,6 +2015,14 @@ type InterfaceTypeDefinition struct {
FieldsDefinition FieldDefinitionList // optional, e.g. { name: String }
}

func (d *Document) InterfaceTypeExtensionHasDirectives(ref int) bool {
return d.InterfaceTypeExtensions[ref].HasDirectives
}

func (d *Document) InterfaceTypeExtensionHasFieldDefinitions(ref int) bool {
return d.InterfaceTypeExtensions[ref].HasFieldDefinitions
}

func (d *Document) InterfaceTypeDefinitionNameBytes(ref int) ByteSlice {
return d.Input.ByteSlice(d.InterfaceTypeDefinitions[ref].Name)
}
Expand Down Expand Up @@ -2046,6 +2127,10 @@ func (d *Document) UnionTypeExtensionHasDirectives(ref int) bool {
return d.UnionTypeExtensions[ref].HasDirectives
}

func (d *Document) UnionTypeExtensionHasUnionMemberTypes(ref int) bool {
return d.UnionTypeExtensions[ref].HasUnionMemberTypes
}

func (d *Document) UnionTypeExtensionNameBytes(ref int) ByteSlice {
return d.Input.ByteSlice(d.UnionTypeExtensions[ref].Name)
}
Expand All @@ -2063,19 +2148,23 @@ func (d *Document) UnionTypeExtensionNameString(ref int) string {
// WEST
//}
type EnumTypeDefinition struct {
Description Description // optional, describes enum
EnumLiteral position.Position // enum
Name ByteSliceReference // e.g. Direction
HasDirectives bool
Directives DirectiveList // optional, e.g. @foo
HasEnumValuesDefinitions bool
EnumValuesDefinition EnumValueDefinitionList // optional, e.g. { NORTH EAST }
Description Description // optional, describes enum
EnumLiteral position.Position // enum
Name ByteSliceReference // e.g. Direction
HasDirectives bool
Directives DirectiveList // optional, e.g. @foo
HasEnumValuesDefinition bool
EnumValuesDefinition EnumValueDefinitionList // optional, e.g. { NORTH EAST }
}

func (d *Document) EnumTypeDefinitionHasDirectives(ref int) bool {
return d.EnumTypeDefinitions[ref].HasDirectives
}

func (d *Document) EnumTypeDefinitionHasEnumValueDefinition(ref int) bool {
return d.EnumTypeDefinitions[ref].HasEnumValuesDefinition
}

func (d *Document) EnumTypeDefinitionNameBytes(ref int) ByteSlice {
return d.Input.ByteSlice(d.EnumTypeDefinitions[ref].Name)
}
Expand Down
38 changes: 38 additions & 0 deletions pkg/astnormalization/enum_type_extending.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package astnormalization

import (
"github.com/cespare/xxhash"
"github.com/jensneuse/graphql-go-tools/pkg/ast"
"github.com/jensneuse/graphql-go-tools/pkg/astvisitor"
)

func extendEnumTypeDefinition(walker *astvisitor.Walker) {
visitor := extendEnumTypeDefinitionVisitor{
Walker: walker,
}
walker.RegisterEnterDocumentVisitor(&visitor)
walker.RegisterEnterEnumTypeExtensionVisitor(&visitor)
}

type extendEnumTypeDefinitionVisitor struct {
*astvisitor.Walker
operation *ast.Document
}

func (e *extendEnumTypeDefinitionVisitor) EnterDocument(operation, definition *ast.Document) {
e.operation = operation
}

func (e *extendEnumTypeDefinitionVisitor) EnterEnumTypeExtension(ref int) {

baseNode, exists := e.operation.Index.Nodes[xxhash.Sum64(e.operation.EnumTypeExtensionNameBytes(ref))]
if !exists {
return
}

if baseNode.Kind != ast.NodeKindEnumTypeDefinition {
return
}

e.operation.ExtendEnumTypeDefinitionByEnumTypeExtension(baseNode.Ref, ref)
}
33 changes: 33 additions & 0 deletions pkg/astnormalization/enum_type_extending_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package astnormalization

import "testing"

func TestExtendEnumType(t *testing.T) {
t.Run("extend enum type by directive", func(t *testing.T) {
run(extendEnumTypeDefinition, testDefinition, `
enum Countries {DE ES NL}
extend enum Countries @deprecated(reason: "some reason")
`, `
enum Countries @deprecated(reason: "some reason") {DE ES NL}
extend enum Countries @deprecated(reason: "some reason")
`)
})
t.Run("extend enum type by enum values", func(t *testing.T) {
run(extendEnumTypeDefinition, testDefinition, `
enum Countries {DE ES NL}
extend enum Countries {EN}
`, `
enum Countries {DE ES NL EN}
extend enum Countries {EN}
`)
})
t.Run("extend enum type by multiple enum values and directives", func(t *testing.T) {
run(extendEnumTypeDefinition, testDefinition, `
enum Countries {DE ES NL}
extend enum Countries @deprecated(reason: "some reason") @skip(if: false) {EN IT}
`, `
enum Countries @deprecated(reason: "some reason") @skip(if: false) {DE ES NL EN IT}
extend enum Countries @deprecated(reason: "some reason") @skip(if: false) {EN IT}
`)
})
}
38 changes: 38 additions & 0 deletions pkg/astnormalization/input_object_type_extending.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package astnormalization

import (
"github.com/cespare/xxhash"
"github.com/jensneuse/graphql-go-tools/pkg/ast"
"github.com/jensneuse/graphql-go-tools/pkg/astvisitor"
)

func extendInputObjectTypeDefinition(walker *astvisitor.Walker) {
visitor := extendInputObjectTypeDefinitionVisitor{
Walker: walker,
}
walker.RegisterEnterDocumentVisitor(&visitor)
walker.RegisterEnterInputObjectTypeExtensionVisitor(&visitor)
}

type extendInputObjectTypeDefinitionVisitor struct {
*astvisitor.Walker
operation *ast.Document
}

func (e *extendInputObjectTypeDefinitionVisitor) EnterDocument(operation, definition *ast.Document) {
e.operation = operation
}

func (e *extendInputObjectTypeDefinitionVisitor) EnterInputObjectTypeExtension(ref int) {

baseNode, exists := e.operation.Index.Nodes[xxhash.Sum64(e.operation.InputObjectTypeExtensionNameBytes(ref))]
if !exists {
return
}

if baseNode.Kind != ast.NodeKindInputObjectTypeDefinition {
return
}

e.operation.ExtendInputObjectTypeDefinitionByInputObjectTypeExtension(baseNode.Ref, ref)
}
33 changes: 33 additions & 0 deletions pkg/astnormalization/input_object_type_extending_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package astnormalization

import "testing"

func TestExtendInputObjectType(t *testing.T) {
t.Run("extend input object type by directive", func(t *testing.T) {
run(extendInputObjectTypeDefinition, testDefinition, `
input DogSize {width: Float height: Float}
extend input DogSize @deprecated(reason: "some reason")
`, `
input DogSize @deprecated(reason: "some reason") {width: Float height: Float}
extend input DogSize @deprecated(reason: "some reason")
`)
})
t.Run("extend input object type by input fields definition", func(t *testing.T) {
run(extendInputObjectTypeDefinition, testDefinition, `
input DogSize {width: Float height: Float}
extend input DogSize {breadth: Float}
`, `
input DogSize {width: Float height: Float, breadth: Float}
extend input DogSize {breadth: Float}
`)
})
t.Run("extend input object type by multiple input fields definition and directives", func(t *testing.T) {
run(extendInputObjectTypeDefinition, testDefinition, `
input DogSize {width: Float height: Float}
extend input DogSize @deprecated(reason: "some reason") @skip(if: false) {breadth: Float weight: Float}
`, `
input DogSize @deprecated(reason: "some reason") @skip(if: false) {width: Float height: Float breadth: Float weight: Float}
extend input DogSize @deprecated(reason: "some reason") @skip(if: false) {breadth: Float weight: Float}
`)
})
}
38 changes: 38 additions & 0 deletions pkg/astnormalization/interface_type_extending.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package astnormalization

import (
"github.com/cespare/xxhash"
"github.com/jensneuse/graphql-go-tools/pkg/ast"
"github.com/jensneuse/graphql-go-tools/pkg/astvisitor"
)

func extendInterfaceTypeDefinition(walker *astvisitor.Walker) {
visitor := extendInterfaceTypeDefinitionVisitor{
Walker: walker,
}
walker.RegisterEnterDocumentVisitor(&visitor)
walker.RegisterEnterInterfaceTypeExtensionVisitor(&visitor)
}

type extendInterfaceTypeDefinitionVisitor struct {
*astvisitor.Walker
operation *ast.Document
}

func (e *extendInterfaceTypeDefinitionVisitor) EnterDocument(operation, definition *ast.Document) {
e.operation = operation
}

func (e *extendInterfaceTypeDefinitionVisitor) EnterInterfaceTypeExtension(ref int) {

59AD baseNode, exists := e.operation.Index.Nodes[xxhash.Sum64(e.operation.InterfaceTypeExtensionNameBytes(ref))]
if !exists {
return
}

if baseNode.Kind != ast.NodeKindInterfaceTypeDefinition {
return
}

e.operation.ExtendInterfaceTypeDefinitionByInterfaceTypeExtension(baseNode.Ref, ref)
}
Loading
0