Skip to content

Commit ddf21f4

Browse files
committed
Sort diff edits before analysis
1 parent 4a99b07 commit ddf21f4

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import graphql.schema.diffing.Vertex;
1111
import graphql.schema.idl.ScalarInfo;
1212

13+
import java.util.ArrayList;
14+
import java.util.Comparator;
1315
import java.util.LinkedHashMap;
1416
import java.util.List;
1517
import java.util.Map;
@@ -132,6 +134,8 @@ public EditOperationAnalyzer(GraphQLSchema oldSchema,
132134
}
133135

134136
public EditOperationAnalysisResult analyzeEdits(List<EditOperation> editOperations, Mapping mapping) {
137+
editOperations = getTraversalOrder(editOperations);
138+
135139
handleTypeVertexChanges(editOperations);
136140

137141
for (EditOperation editOperation : editOperations) {
@@ -164,6 +168,7 @@ public EditOperationAnalysisResult analyzeEdits(List<EditOperation> editOperatio
164168
}
165169
}
166170
}
171+
167172
handleTypeChanges(editOperations, mapping);
168173
handleImplementsChanges(editOperations, mapping);
169174
handleUnionMemberChanges(editOperations, mapping);
@@ -1976,4 +1981,69 @@ private void changedUnion(EditOperation editOperation) {
19761981
unionDifferences.put(oldName, objectModification);
19771982
unionDifferences.put(newName, objectModification);
19781983
}
1984+
1985+
/**
1986+
* The input list of {@link EditOperation}s does not conform to any order.
1987+
* <p>
1988+
* We need to sort it as we sometimes rely on the parents being processed first.
1989+
* <p>
1990+
* e.g. we ignore a new argument if the parent of the argument is new.
1991+
* However, if the argument addition is processed before the
1992+
*/
1993+
private List<EditOperation> getTraversalOrder(List<EditOperation> editOperations) {
1994+
List<List<String>> orderSpec = List.of(
1995+
// These are all top level declarations
1996+
List.of(
1997+
SchemaGraph.SCHEMA,
1998+
SchemaGraph.OBJECT,
1999+
SchemaGraph.INTERFACE,
2000+
SchemaGraph.UNION,
2001+
SchemaGraph.SCALAR,
2002+
SchemaGraph.ENUM,
2003+
SchemaGraph.INPUT_OBJECT,
2004+
SchemaGraph.DIRECTIVE
2005+
),
2006+
// These are all direct descendants of top level declarations
2007+
List.of(
2008+
SchemaGraph.FIELD,
2009+
SchemaGraph.INPUT_FIELD,
2010+
SchemaGraph.ENUM_VALUE
2011+
),
2012+
List.of(SchemaGraph.ARGUMENT),
2013+
List.of(SchemaGraph.APPLIED_DIRECTIVE),
2014+
List.of(SchemaGraph.APPLIED_ARGUMENT),
2015+
List.of(SchemaGraph.ISOLATED)
2016+
);
2017+
2018+
ArrayList<EditOperation> sorted = new ArrayList<>(editOperations);
2019+
2020+
sorted.sort(Comparator.comparing((editOperation) -> {
2021+
// Converts this editOperation into an index from the order
2022+
// The lower the index, the earlier it appears in the sorted list
2023+
for (int i = 0; i < orderSpec.size(); i++) {
2024+
List<String> typesForThisOrder = orderSpec.get(i);
2025+
2026+
for (String type : typesForThisOrder) {
2027+
if (isAnyVertexOfType(editOperation, type)) {
2028+
return i;
2029+
}
2030+
}
2031+
}
2032+
2033+
return Assert.assertShouldNeverHappen();
2034+
}));
2035+
2036+
return sorted;
2037+
}
2038+
2039+
private static boolean isAnyVertexOfType(EditOperation edit, String type) {
2040+
return (edit.getSourceVertex() != null && edit.getSourceVertex().isOfType(type))
2041+
|| (edit.getTargetVertex() != null && edit.getTargetVertex().isOfType(type))
2042+
|| (edit.getSourceEdge() != null && isAnyVertexOfType(edit.getSourceEdge(), type))
2043+
|| (edit.getTargetEdge() != null && isAnyVertexOfType(edit.getTargetEdge(), type));
2044+
}
2045+
2046+
private static boolean isAnyVertexOfType(Edge edge, String type) {
2047+
return edge.getFrom().isOfType(type) || edge.getTo().isOfType(type);
2048+
}
19792049
}

0 commit comments

Comments
 (0)