Skip to content
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
2 changes: 1 addition & 1 deletion src/main/java/graphql/analysis/QueryTraverser.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* visitField calls.
*/
@PublicApi
public class QueryTraverser {
public class QueryTraverser {

private final Collection<? extends Node> roots;
private final GraphQLSchema schema;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/graphql/language/AstPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private AstPrinter(boolean compactMode) {
printers.put(ScalarTypeDefinition.class, scalarTypeDefinition());
printers.put(ScalarTypeExtensionDefinition.class, scalarTypeExtensionDefinition());
printers.put(SchemaDefinition.class, schemaDefinition());
printers.put(SchemaExtensionDefinition.class, schemaExtensionDefinition());
printers.put(SelectionSet.class, selectionSet());
printers.put(StringValue.class, value());
printers.put(TypeName.class, type());
Expand Down Expand Up @@ -384,6 +385,10 @@ private NodePrinter<InputObjectTypeExtensionDefinition> inputObjectTypeExtension
return (out, node) -> out.printf("extend %s", node(node, InputObjectTypeDefinition.class));
}

private NodePrinter<SchemaExtensionDefinition> schemaExtensionDefinition() {
return (out, node) -> out.printf("extend %s", node(node, SchemaDefinition.class));
}

private NodePrinter<UnionTypeDefinition> unionTypeDefinition() {
String barSep = compactMode ? "|" : " | ";
String equals = compactMode ? "=" : "= ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public static Builder newEnumTypeExtensionDefinition() {
return new Builder();
}

@Override
public EnumTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder
.enumValueDefinitions(newChildren.getChildren(CHILD_ENUM_VALUE_DEFINITIONS))
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
);
}

public EnumTypeExtensionDefinition transformExtension(Consumer<Builder> builderConsumer) {
Builder builder = new Builder(this);
builderConsumer.accept(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ public static Builder newInputObjectTypeExtensionDefinition() {
return new Builder();
}

@Override
public InputObjectTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
.inputValueDefinitions(newChildren.getChildren(CHILD_INPUT_VALUES_DEFINITIONS))
);
}

public InputObjectTypeExtensionDefinition transformExtension(Consumer<Builder> builderConsumer) {
Builder builder = new Builder(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ public static Builder newInterfaceTypeExtensionDefinition() {
return new Builder();
}

@Override
public InterfaceTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder
.definitions(newChildren.getChildren(CHILD_DEFINITIONS))
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
);
}

public InterfaceTypeExtensionDefinition transformExtension(Consumer<Builder> builderConsumer) {
Builder builder = new Builder(this);
builderConsumer.accept(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public ObjectTypeExtensionDefinition deepCopy() {
getAdditionalData());
}

@Override
public ObjectTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder.implementz(newChildren.getChildren(CHILD_IMPLEMENTZ))
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
.fieldDefinitions(newChildren.getChildren(CHILD_FIELD_DEFINITIONS)));
}

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public static Builder newScalarTypeExtensionDefinition() {
return new Builder();
}

@Override
public ScalarTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
);
}

public ScalarTypeExtensionDefinition transformExtension(Consumer<Builder> builderConsumer) {
Builder builder = new Builder(this);
builderConsumer.accept(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ public static Builder newUnionTypeExtensionDefinition() {
return new Builder();
}

@Override
public UnionTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) {
return transformExtension(builder -> builder
.directives(newChildren.getChildren(CHILD_DIRECTIVES))
.memberTypes(newChildren.getChildren(CHILD_MEMBER_TYPES))
);
}

public UnionTypeExtensionDefinition transformExtension(Consumer<Builder> builderConsumer) {
Builder builder = new Builder(this);
builderConsumer.accept(builder);
Expand Down
10 changes: 9 additions & 1 deletion src/test/groovy/graphql/language/AstPrinterTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,10 @@ type Query {

def "print type extensions"() {
def query = '''
extend schema {
query: Query
}

extend type Object @directive {
objectField : String
}
Expand All @@ -479,7 +483,11 @@ type Query {
String output = printAst(document)

expect:
output == '''extend type Object @directive {
output == '''extend schema {
query: Query
}

extend type Object @directive {
objectField: String
}

Expand Down
101 changes: 101 additions & 0 deletions src/test/groovy/graphql/language/AstTransformerTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import graphql.util.TraversalControl
import graphql.util.TraverserContext
import spock.lang.Specification

import static graphql.language.AstPrinter.printAst
import static graphql.language.AstPrinter.printAstCompact
import static graphql.util.TreeTransformerUtil.changeNode
import static graphql.util.TreeTransformerUtil.deleteNode
Expand Down Expand Up @@ -795,5 +796,105 @@ class AstTransformerTest extends Specification {

}

def "regression: changing a property of an extension should not change the extension to a base definition"() {
def document = TestUtil.toDocument("""
extend schema { query: Query }
extend type MyObjectType { login: String }
extend input MyInputObjectType { login: String }
extend interface MyInterface { login: String }
extend enum MyEnum { MONDAY }
extend scalar MyScalar @myDirective
extend union MyUnion = MyObjectType
""")

AstTransformer astTransformer = new AstTransformer()

def visitor = new NodeVisitorStub() {

@Override
TraversalControl visitFieldDefinition(FieldDefinition fieldDefinition, TraverserContext<Node> context) {
if (fieldDefinition.name == "login") {
// change name
FieldDefinition signin = fieldDefinition.transform({ builder -> builder.name("signin") })
return changeNode(context, signin)
}
return super.visitFieldDefinition(fieldDefinition, context)
}

@Override
TraversalControl visitInputValueDefinition(InputValueDefinition fieldDefinition, TraverserContext<Node> context) {
if (fieldDefinition.name == "login") {
// change name
InputValueDefinition signin = fieldDefinition.transform({ builder -> builder.name("signin") })
return changeNode(context, signin)
}
return super.visitInputValueDefinition(fieldDefinition, context)
}

@Override
TraversalControl visitEnumValueDefinition(EnumValueDefinition node, TraverserContext<Node> context) {
if (node.name == "MONDAY") {
// change name
return changeNode(context, node.transform({ builder -> builder.name("TUESDAY") }))
}
return super.visitEnumValueDefinition(node, context)
}

@Override
TraversalControl visitSchemaDefinition(SchemaDefinition node, TraverserContext<Node> context) {
if (node instanceof SchemaExtensionDefinition) {
return changeNode(context, node.transformExtension({
it.operationTypeDefinitions([OperationTypeDefinition.newOperationTypeDefinition()
.name("myQuery")
.typeName(TypeName.newTypeName("MyQuery").build())
.build()])
}))
}
return super.visitSchemaDefinition(node, context)
}
}

when:
def newDocument = astTransformer.transform(document, visitor)

then:
newDocument instanceof Document

and:
def transformedDoc = newDocument as Document
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyObjectType"} instanceof ObjectTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyInputObjectType"} instanceof InputObjectTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyInterface"} instanceof InterfaceTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyEnum"} instanceof EnumTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyScalar"} instanceof ScalarTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyUnion"} instanceof UnionTypeExtensionDefinition
transformedDoc.definitions.find {it instanceof SchemaDefinition } instanceof SchemaExtensionDefinition

and:
printAst(newDocument).trim() == """
|extend schema {
| myQuery: MyQuery
|}
|
|extend type MyObjectType {
| signin: String
|}
|
|extend input MyInputObjectType {
| signin: String
|}
|
|extend interface MyInterface {
| signin: String
|}
|
|extend enum MyEnum {
| TUESDAY
|}
|
|extend scalar MyScalar @myDirective
|
|extend union MyUnion = MyObjectType
""".trim().stripMargin()
}
}