|
10 | 10 | import graphql.schema.diffing.Vertex; |
11 | 11 | import graphql.schema.idl.ScalarInfo; |
12 | 12 |
|
| 13 | +import java.util.ArrayList; |
| 14 | +import java.util.Comparator; |
13 | 15 | import java.util.LinkedHashMap; |
14 | 16 | import java.util.List; |
15 | 17 | import java.util.Map; |
@@ -132,6 +134,8 @@ public EditOperationAnalyzer(GraphQLSchema oldSchema, |
132 | 134 | } |
133 | 135 |
|
134 | 136 | public EditOperationAnalysisResult analyzeEdits(List<EditOperation> editOperations, Mapping mapping) { |
| 137 | + editOperations = getTraversalOrder(editOperations); |
| 138 | + |
135 | 139 | handleTypeVertexChanges(editOperations); |
136 | 140 |
|
137 | 141 | for (EditOperation editOperation : editOperations) { |
@@ -164,6 +168,7 @@ public EditOperationAnalysisResult analyzeEdits(List<EditOperation> editOperatio |
164 | 168 | } |
165 | 169 | } |
166 | 170 | } |
| 171 | + |
167 | 172 | handleTypeChanges(editOperations, mapping); |
168 | 173 | handleImplementsChanges(editOperations, mapping); |
169 | 174 | handleUnionMemberChanges(editOperations, mapping); |
@@ -1976,4 +1981,69 @@ private void changedUnion(EditOperation editOperation) { |
1976 | 1981 | unionDifferences.put(oldName, objectModification); |
1977 | 1982 | unionDifferences.put(newName, objectModification); |
1978 | 1983 | } |
| 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 | + } |
1979 | 2049 | } |
0 commit comments