Skip to content

Commit 3dfeae3

Browse files
authored
This moves the AST element builder to use immutable lists (#2101)
* This moves the AST element builder to use immutable lists with the ability to add items to individually * Missing `directive` method
1 parent ff3f691 commit 3dfeae3

48 files changed

Lines changed: 524 additions & 367 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/graphql/collect/ImmutableKit.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import com.google.common.collect.ImmutableList;
44
import com.google.common.collect.ImmutableMap;
5-
import graphql.Assert;
65
import graphql.Internal;
76

87
import java.util.Collection;
98
import java.util.List;
109
import java.util.Map;
1110
import java.util.function.Function;
1211

12+
import static graphql.Assert.assertNotNull;
13+
1314
@Internal
1415
public final class ImmutableKit {
1516

@@ -40,7 +41,7 @@ public static <K, V> ImmutableMap<K, V> emptyMap() {
4041
*/
4142

4243
public static <K, V> ImmutableMap<K, ImmutableList<V>> toImmutableMapOfLists(Map<K, List<V>> startingMap) {
43-
Assert.assertNotNull(startingMap);
44+
assertNotNull(startingMap);
4445
ImmutableMap.Builder<K, ImmutableList<V>> map = ImmutableMap.builder();
4546
for (Map.Entry<K, List<V>> e : startingMap.entrySet()) {
4647
ImmutableList<V> value = ImmutableList.copyOf(startingMap.getOrDefault(e.getKey(), emptyList()));
@@ -66,22 +67,46 @@ public static <T> ImmutableList<T> concatLists(List<T> l1, List<T> l2) {
6667
* This is more efficient than `c.stream().map().collect()` because it does not create the intermediate objects needed
6768
* for the flexible style. Benchmarking has shown this to outperform `stream()`.
6869
*
69-
* @param collection the collection to map
70-
* @param mapper the mapper function
71-
* @param <T> for two
72-
* @param <R> for result
70+
* @param iterable the iterable to map
71+
* @param mapper the mapper function
72+
* @param <T> for two
73+
* @param <R> for result
7374
*
7475
* @return a map immutable list of results
7576
*/
76-
public static <T, R> ImmutableList<R> map(Collection<T> collection, Function<? super T, ? extends R> mapper) {
77-
Assert.assertNotNull(collection);
78-
Assert.assertNotNull(mapper);
77+
public static <T, R> ImmutableList<R> map(Iterable<? extends T> iterable, Function<? super T, ? extends R> mapper) {
78+
assertNotNull(iterable);
79+
assertNotNull(mapper);
7980
@SuppressWarnings("RedundantTypeArguments")
8081
ImmutableList.Builder<R> builder = ImmutableList.<R>builder();
81-
for (T t : collection) {
82+
for (T t : iterable) {
8283
R r = mapper.apply(t);
8384
builder.add(r);
8485
}
8586
return builder.build();
8687
}
88+
89+
/**
90+
* This constructs a new Immutable list from an existing collection and adds a new element to it.
91+
*
92+
* @param existing the existing collection
93+
* @param newValue the new value to add
94+
* @param extraValues more values to add
95+
* @param <T> for two
96+
*
97+
* @return an Immutable list with the extra effort.
98+
*/
99+
public static <T> ImmutableList<T> addToList(Collection<? extends T> existing, T newValue, T... extraValues) {
100+
assertNotNull(existing);
101+
assertNotNull(newValue);
102+
int expectedSize = existing.size() + 1 + extraValues.length;
103+
ImmutableList.Builder<T> newList = ImmutableList.builderWithExpectedSize(expectedSize);
104+
newList.addAll(existing);
105+
newList.add(newValue);
106+
for (T extraValue : extraValues) {
107+
newList.add(extraValue);
108+
}
109+
return newList.build();
110+
}
111+
87112
}

src/main/java/graphql/language/Argument.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import graphql.util.TraversalControl;
88
import graphql.util.TraverserContext;
99

10-
import java.util.ArrayList;
1110
import java.util.LinkedHashMap;
1211
import java.util.List;
1312
import java.util.Map;
@@ -22,11 +21,10 @@
2221
@PublicApi
2322
public class Argument extends AbstractNode<Argument> implements NamedNode<Argument> {
2423

24+
public static final String CHILD_VALUE = "value";
2525
private final String name;
2626
private final Value value;
2727

28-
public static final String CHILD_VALUE = "value";
29-
3028
@Internal
3129
protected Argument(String name, Value value, SourceLocation sourceLocation, List<Comment> comments, IgnoredChars ignoredChars, Map<String, String> additionalData) {
3230
super(sourceLocation, comments, ignoredChars, additionalData);
@@ -44,6 +42,14 @@ public Argument(String name, Value value) {
4442
this(name, value, null, emptyList(), IgnoredChars.EMPTY, emptyMap());
4543
}
4644

45+
public static Builder newArgument() {
46+
return new Builder();
47+
}
48+
49+
public static Builder newArgument(String name, Value value) {
50+
return new Builder().name(name).value(value);
51+
}
52+
4753
@Override
4854
public String getName() {
4955
return name;
@@ -105,14 +111,6 @@ public TraversalControl accept(TraverserContext<Node> context, NodeVisitor visit
105111
return visitor.visitArgument(this, context);
106112
}
107113

108-
public static Builder newArgument() {
109-
return new Builder();
110-
}
111-
112-
public static Builder newArgument(String name, Value value) {
113-
return new Builder().name(name).value(value);
114-
}
115-
116114
public Argument transform(Consumer<Builder> builderConsumer) {
117115
Builder builder = new Builder(this);
118116
builderConsumer.accept(builder);
@@ -121,7 +119,7 @@ public Argument transform(Consumer<Builder> builderConsumer) {
121119

122120
public static final class Builder implements NodeBuilder {
123121
private SourceLocation sourceLocation;
124-
private List<Comment> comments = new ArrayList<>();
122+
private ImmutableList<Comment> comments = emptyList();
125123
private String name;
126124
private Value value;
127125
private IgnoredChars ignoredChars = IgnoredChars.EMPTY;
@@ -132,7 +130,7 @@ private Builder() {
132130

133131
private Builder(Argument existing) {
134132
this.sourceLocation = existing.getSourceLocation();
135-
this.comments = existing.getComments();
133+
this.comments = ImmutableList.copyOf(existing.getComments());
136134
this.name = existing.getName();
137135
this.value = existing.getValue();
138136
this.ignoredChars = existing.getIgnoredChars();
@@ -155,7 +153,7 @@ public Builder value(Value value) {
155153
}
156154

157155
public Builder comments(List<Comment> comments) {
158-
this.comments = comments;
156+
this.comments = ImmutableList.copyOf(comments);
159157
return this;
160158
}
161159

src/main/java/graphql/language/ArrayValue.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import com.google.common.collect.ImmutableList;
55
import graphql.Internal;
66
import graphql.PublicApi;
7+
import graphql.collect.ImmutableKit;
78
import graphql.util.TraversalControl;
89
import graphql.util.TraverserContext;
910

10-
import java.util.ArrayList;
1111
import java.util.LinkedHashMap;
1212
import java.util.List;
1313
import java.util.Map;
@@ -21,9 +21,8 @@
2121
@PublicApi
2222
public class ArrayValue extends AbstractNode<ArrayValue> implements Value<ArrayValue> {
2323

24-
private final ImmutableList<Value> values;
25-
2624
public static final String CHILD_VALUES = "values";
25+
private final ImmutableList<Value> values;
2726

2827
@Internal
2928
protected ArrayValue(List<Value> values, SourceLocation sourceLocation, List<Comment> comments, IgnoredChars ignoredChars, Map<String, String> additionalData) {
@@ -40,6 +39,10 @@ public ArrayValue(List<Value> values) {
4039
this(values, null, emptyList(), IgnoredChars.EMPTY, emptyMap());
4140
}
4241

42+
public static Builder newArrayValue() {
43+
return new Builder();
44+
}
45+
4346
public List<Value> getValues() {
4447
return values;
4548
}
@@ -92,10 +95,6 @@ public TraversalControl accept(TraverserContext<Node> context, NodeVisitor visit
9295
return visitor.visitArrayValue(this, context);
9396
}
9497

95-
public static Builder newArrayValue() {
96-
return new Builder();
97-
}
98-
9998
public ArrayValue transform(Consumer<Builder> builderConsumer) {
10099
Builder builder = new Builder(this);
101100
builderConsumer.accept(builder);
@@ -104,8 +103,8 @@ public ArrayValue transform(Consumer<Builder> builderConsumer) {
104103

105104
public static final class Builder implements NodeBuilder {
106105
private SourceLocation sourceLocation;
107-
private List<Value> values = new ArrayList<>();
108-
private List<Comment> comments = new ArrayList<>();
106+
private ImmutableList<Value> values = emptyList();
107+
private ImmutableList<Comment> comments = emptyList();
109108
private IgnoredChars ignoredChars = IgnoredChars.EMPTY;
110109
private Map<String, String> additionalData = new LinkedHashMap<>();
111110

@@ -114,8 +113,8 @@ private Builder() {
114113

115114
private Builder(ArrayValue existing) {
116115
this.sourceLocation = existing.getSourceLocation();
117-
this.comments = existing.getComments();
118-
this.values = existing.getValues();
116+
this.comments = ImmutableList.copyOf(existing.getComments());
117+
this.values = ImmutableList.copyOf(existing.getValues());
119118
this.ignoredChars = existing.getIgnoredChars();
120119
this.additionalData = new LinkedHashMap<>(existing.getAdditionalData());
121120
}
@@ -126,17 +125,17 @@ public Builder sourceLocation(SourceLocation sourceLocation) {
126125
}
127126

128127
public Builder values(List<Value> values) {
129-
this.values = values;
128+
this.values = ImmutableList.copyOf(values);
130129
return this;
131130
}
132131

133132
public Builder value(Value value) {
134-
this.values.add(value);
133+
this.values = ImmutableKit.addToList(this.values, value);
135134
return this;
136135
}
137136

138137
public Builder comments(List<Comment> comments) {
139-
this.comments = comments;
138+
this.comments = ImmutableList.copyOf(comments);
140139
return this;
141140
}
142141

src/main/java/graphql/language/BooleanValue.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package graphql.language;
22

33

4+
import com.google.common.collect.ImmutableList;
45
import graphql.Internal;
56
import graphql.PublicApi;
67
import graphql.util.TraversalControl;
78
import graphql.util.TraverserContext;
89

9-
import java.util.ArrayList;
1010
import java.util.LinkedHashMap;
1111
import java.util.List;
1212
import java.util.Map;
@@ -108,7 +108,7 @@ public BooleanValue transform(Consumer<Builder> builderConsumer) {
108108
public static final class Builder implements NodeBuilder {
109109
private SourceLocation sourceLocation;
110110
private boolean value;
111-
private List<Comment> comments = new ArrayList<>();
111+
private ImmutableList<Comment> comments = emptyList();
112112
private IgnoredChars ignoredChars = IgnoredChars.EMPTY;
113113
private Map<String, String> additionalData = new LinkedHashMap<>();
114114

@@ -117,7 +117,7 @@ private Builder() {
117117

118118
private Builder(BooleanValue existing) {
119119
this.sourceLocation = existing.getSourceLocation();
120-
this.comments = existing.getComments();
120+
this.comments = ImmutableList.copyOf(existing.getComments());
121121
this.value = existing.isValue();
122122
this.ignoredChars = existing.getIgnoredChars();
123123
this.additionalData = new LinkedHashMap<>(existing.getAdditionalData());
@@ -135,7 +135,7 @@ public Builder value(boolean value) {
135135
}
136136

137137
public Builder comments(List<Comment> comments) {
138-
this.comments = comments;
138+
this.comments = ImmutableList.copyOf(comments);
139139
return this;
140140
}
141141

src/main/java/graphql/language/Directive.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
import com.google.common.collect.ImmutableList;
55
import graphql.Internal;
66
import graphql.PublicApi;
7+
import graphql.collect.ImmutableKit;
78
import graphql.util.TraversalControl;
89
import graphql.util.TraverserContext;
910

10-
import java.util.ArrayList;
1111
import java.util.LinkedHashMap;
1212
import java.util.List;
1313
import java.util.Map;
1414
import java.util.Objects;
1515
import java.util.function.Consumer;
1616

1717
import static graphql.Assert.assertNotNull;
18+
import static graphql.collect.ImmutableKit.emptyList;
19+
import static graphql.collect.ImmutableKit.emptyMap;
1820
import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer;
1921
import static graphql.language.NodeUtil.argumentsByName;
2022
import static graphql.language.NodeUtil.getArgumentByName;
21-
import static java.util.Collections.emptyList;
22-
import static java.util.Collections.emptyMap;
2323

2424
@PublicApi
2525
public class Directive extends AbstractNode<Directive> implements NamedNode<Directive> {
@@ -138,9 +138,9 @@ public Directive transform(Consumer<Builder> builderConsumer) {
138138

139139
public static final class Builder implements NodeBuilder {
140140
private SourceLocation sourceLocation;
141-
private List<Comment> comments = new ArrayList<>();
141+
private ImmutableList<Comment> comments = emptyList();
142142
private String name;
143-
private List<Argument> arguments = new ArrayList<>();
143+
private ImmutableList<Argument> arguments = emptyList();
144144
private IgnoredChars ignoredChars = IgnoredChars.EMPTY;
145145
private Map<String, String> additionalData = new LinkedHashMap<>();
146146

@@ -149,9 +149,9 @@ private Builder() {
149149

150150
private Builder(Directive existing) {
151151
this.sourceLocation = existing.getSourceLocation();
152-
this.comments = existing.getComments();
152+
this.comments = ImmutableList.copyOf(existing.getComments());
153153
this.name = existing.getName();
154-
this.arguments = existing.getArguments();
154+
this.arguments = ImmutableList.copyOf(existing.getArguments());
155155
this.ignoredChars = existing.getIgnoredChars();
156156
this.additionalData = new LinkedHashMap<>(existing.getAdditionalData());
157157
}
@@ -163,7 +163,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) {
163163
}
164164

165165
public Builder comments(List<Comment> comments) {
166-
this.comments = comments;
166+
this.comments = ImmutableList.copyOf(comments);
167167
return this;
168168
}
169169

@@ -173,7 +173,12 @@ public Builder name(String name) {
173173
}
174174

175175
public Builder arguments(List<Argument> arguments) {
176-
this.arguments = arguments;
176+
this.arguments = ImmutableList.copyOf(arguments);
177+
return this;
178+
}
179+
180+
public Builder argument(Argument argument) {
181+
this.arguments = ImmutableKit.addToList(arguments,argument);
177182
return this;
178183
}
179184

0 commit comments

Comments
 (0)