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
13 changes: 6 additions & 7 deletions src/main/java/graphql/analysis/values/ValueTraverser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.collect.ImmutableList;
import graphql.PublicApi;
import graphql.collect.ImmutableKit;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.DataFetchingEnvironmentImpl;
import graphql.schema.GraphQLAppliedDirective;
Expand All @@ -22,7 +23,6 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static graphql.Assert.assertShouldNeverHappen;
import static graphql.Assert.assertTrue;
Expand Down Expand Up @@ -62,13 +62,12 @@ private InputElements(GraphQLInputSchemaElement startElement) {

private InputElements(ImmutableList<GraphQLInputSchemaElement> inputElements) {
this.inputElements = inputElements;
this.unwrappedInputElements = inputElements.stream()
.filter(it -> !(it instanceof GraphQLNonNull || it instanceof GraphQLList))
.collect(ImmutableList.toImmutableList());
this.unwrappedInputElements = ImmutableKit.filter(inputElements,
it -> !(it instanceof GraphQLNonNull || it instanceof GraphQLList));

List<GraphQLInputValueDefinition> inputValDefs = unwrappedInputElements.stream()
.filter(it -> it instanceof GraphQLInputValueDefinition)
.map(GraphQLInputValueDefinition.class::cast).collect(Collectors.toList());
List<GraphQLInputValueDefinition> inputValDefs = ImmutableKit.filterAndMap(unwrappedInputElements,
it -> it instanceof GraphQLInputValueDefinition,
GraphQLInputValueDefinition.class::cast);
this.lastElement = inputValDefs.isEmpty() ? null : inputValDefs.get(inputValDefs.size() - 1);
}

Expand Down
70 changes: 62 additions & 8 deletions src/main/java/graphql/collect/ImmutableKit.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import graphql.Internal;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

import static graphql.Assert.assertNotNull;

@Internal
@SuppressWarnings({"UnstableApiUsage"})
@NullMarked
public final class ImmutableKit {

public static <T> ImmutableList<T> emptyList() {
return ImmutableList.of();
}

public static <T> ImmutableList<T> nonNullCopyOf(Collection<T> collection) {
public static <T> ImmutableList<T> nonNullCopyOf(@Nullable Collection<T> collection) {
return collection == null ? emptyList() : ImmutableList.copyOf(collection);
}

Expand All @@ -41,9 +44,9 @@ public static <T> ImmutableList<T> concatLists(List<T> l1, List<T> l2) {
* for the flexible style. Benchmarking has shown this to outperform `stream()`.
*
* @param collection the collection to map
* @param mapper the mapper function
* @param <T> for two
* @param <R> for result
* @param mapper the mapper function
* @param <T> for two
* @param <R> for result
*
* @return a map immutable list of results
*/
Expand All @@ -58,15 +61,66 @@ public static <T, R> ImmutableList<R> map(Collection<? extends T> collection, Fu
return builder.build();
}

/**
* This is more efficient than `c.stream().filter().collect()` because it does not create the intermediate objects needed
* for the flexible style. Benchmarking has shown this to outperform `stream()`.
*
* @param collection the collection to map
* @param filter the filter predicate
* @param <T> for two
*
* @return a map immutable list of results
*/
public static <T> ImmutableList<T> filter(Collection<? extends T> collection, Predicate<? super T> filter) {
assertNotNull(collection);
assertNotNull(filter);
return filterAndMap(collection, filter, Function.identity());
}

/**
* This is more efficient than `c.stream().filter().map().collect()` because it does not create the intermediate objects needed
* for the flexible style. Benchmarking has shown this to outperform `stream()`.
*
* @param collection the collection to map
* @param filter the filter predicate
* @param mapper the mapper function
* @param <T> for two
* @param <R> for result
*
* @return a map immutable list of results
*/
public static <T, R> ImmutableList<R> filterAndMap(Collection<? extends T> collection, Predicate<? super T> filter, Function<? super T, ? extends R> mapper) {
assertNotNull(collection);
assertNotNull(mapper);
assertNotNull(filter);
ImmutableList.Builder<R> builder = ImmutableList.builderWithExpectedSize(collection.size());
for (T t : collection) {
if (filter.test(t)) {
R r = mapper.apply(t);
builder.add(r);
}
}
return builder.build();
}

public static <T> ImmutableList<T> flatMapList(Collection<List<T>> listLists) {
ImmutableList.Builder<T> builder = ImmutableList.builder();
for (List<T> t : listLists) {
builder.addAll(t);
}
return builder.build();
}


/**
* This will map a collection of items but drop any that are null from the input.
* This is more efficient than `c.stream().map().collect()` because it does not create the intermediate objects needed
* for the flexible style. Benchmarking has shown this to outperform `stream()`.
*
* @param collection the collection to map
* @param mapper the mapper function
* @param <T> for two
* @param <R> for result
* @param mapper the mapper function
* @param <T> for two
* @param <R> for result
*
* @return a map immutable list of results
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import graphql.analysis.QueryTraverser;
import graphql.analysis.QueryVisitorFieldEnvironment;
import graphql.analysis.QueryVisitorStub;
import graphql.collect.ImmutableKit;
import graphql.execution.ExecutionContext;
import graphql.execution.ResultPath;
import graphql.language.Field;
Expand Down Expand Up @@ -140,7 +141,7 @@ private static class FieldValidationEnvironmentImpl implements FieldValidationEn
FieldValidationEnvironmentImpl(ExecutionContext executionContext, Map<ResultPath, List<FieldAndArguments>> fieldArgumentsMap) {
this.executionContext = executionContext;
this.fieldArgumentsMap = fieldArgumentsMap;
this.fieldArguments = fieldArgumentsMap.values().stream().flatMap(List::stream).collect(ImmutableList.toImmutableList());
this.fieldArguments = ImmutableKit.flatMapList(fieldArgumentsMap.values());
}


Expand Down
8 changes: 3 additions & 5 deletions src/main/java/graphql/language/AstSignature.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package graphql.language;

import com.google.common.collect.ImmutableList;
import graphql.PublicApi;
import graphql.collect.ImmutableKit;
import graphql.util.TraversalControl;
Expand Down Expand Up @@ -149,16 +148,15 @@ private Document dropUnusedQueryDefinitions(Document document, final String oper
NodeVisitorStub visitor = new NodeVisitorStub() {
@Override
public TraversalControl visitDocument(Document node, TraverserContext<Node> context) {
List<Definition> wantedDefinitions = node.getDefinitions().stream()
.filter(d -> {
List<Definition> wantedDefinitions = ImmutableKit.filter(node.getDefinitions(),
d -> {
if (d instanceof OperationDefinition) {
OperationDefinition operationDefinition = (OperationDefinition) d;
return isThisOperation(operationDefinition, operationName);
}
return d instanceof FragmentDefinition;
// SDL in a query makes no sense - its gone should it be present
})
.collect(ImmutableList.toImmutableList());
});

Document changedNode = node.transform(builder -> {
builder.definitions(wantedDefinitions);
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/graphql/language/Document.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ public List<Definition> getDefinitions() {
* @return a list of definitions of that class or empty list
*/
public <T extends Definition> List<T> getDefinitionsOfType(Class<T> definitionClass) {
return definitions.stream()
.filter(d -> definitionClass.isAssignableFrom(d.getClass()))
.map(definitionClass::cast)
.collect(ImmutableList.toImmutableList());
return ImmutableKit.filterAndMap(definitions,
d -> definitionClass.isAssignableFrom(d.getClass()),
definitionClass::cast);
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/graphql/language/NodeParentTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.ImmutableList;
import graphql.Internal;
import graphql.PublicApi;
import graphql.collect.ImmutableKit;

import java.util.ArrayDeque;
import java.util.ArrayList;
Expand Down Expand Up @@ -42,10 +43,9 @@ public NodeParentTree(Deque<T> nodeStack) {
}

private ImmutableList<String> mkPath(Deque<T> copy) {
return copy.stream()
.filter(node1 -> node1 instanceof NamedNode)
.map(node1 -> ((NamedNode) node1).getName())
.collect(ImmutableList.toImmutableList());
return ImmutableKit.filterAndMap(copy,
node1 -> node1 instanceof NamedNode,
node1 -> ((NamedNode) node1).getName());
}


Expand Down
7 changes: 3 additions & 4 deletions src/main/java/graphql/language/SelectionSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ public List<Selection> getSelections() {
* @return a list of selections of that class or empty list
*/
public <T extends Selection> List<T> getSelectionsOfType(Class<T> selectionClass) {
return selections.stream()
.filter(d -> selectionClass.isAssignableFrom(d.getClass()))
.map(selectionClass::cast)
.collect(ImmutableList.toImmutableList());
return ImmutableKit.filterAndMap(selections,
d -> selectionClass.isAssignableFrom(d.getClass()),
selectionClass::cast);
}

@Override
Expand Down
12 changes: 5 additions & 7 deletions src/main/java/graphql/schema/visibility/BlockedFields.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package graphql.schema.visibility;

import com.google.common.collect.ImmutableList;
import graphql.Internal;
import graphql.PublicApi;
import graphql.collect.ImmutableKit;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLFieldsContainer;
import graphql.schema.GraphQLInputFieldsContainer;
Expand Down Expand Up @@ -35,9 +35,8 @@ private BlockedFields(List<Pattern> patterns) {

@Override
public List<GraphQLFieldDefinition> getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) {
return fieldsContainer.getFieldDefinitions().stream()
.filter(fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName())))
.collect(ImmutableList.toImmutableList());
return ImmutableKit.filter(fieldsContainer.getFieldDefinitions(),
fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName())));
}

@Override
Expand All @@ -53,9 +52,8 @@ public GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsCo

@Override
public List<GraphQLInputObjectField> getFieldDefinitions(GraphQLInputFieldsContainer fieldsContainer) {
return fieldsContainer.getFieldDefinitions().stream()
.filter(fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName())))
.collect(ImmutableList.toImmutableList());
return ImmutableKit.filter(fieldsContainer.getFieldDefinitions(),
fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName())));
}

@Override
Expand Down
13 changes: 12 additions & 1 deletion src/test/groovy/graphql/collect/ImmutableKitTest.groovy
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package graphql.collect

import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap
import spock.lang.Specification

class ImmutableKitTest extends Specification {
Expand Down Expand Up @@ -63,4 +62,16 @@ class ImmutableKitTest extends Specification {
then:
set == ["a", "b", "c", "d", "e", "f"] as Set
}

def "flatMapList works"() {
def listOfLists = [
["A", "B"],
["C"],
["D", "E"],
]
when:
def flatList = ImmutableKit.flatMapList(listOfLists)
then:
flatList == ["A", "B", "C", "D", "E",]
}
}
12 changes: 6 additions & 6 deletions src/test/groovy/graphql/util/FpKitTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,20 @@ class FpKitTest extends Specification {
}

def "set intersection works"() {
def set1 = ["A","B","C"] as Set
def set2 = ["A","C","D"] as Set
def set1 = ["A", "B", "C"] as Set
def set2 = ["A", "C", "D"] as Set
def singleSetA = ["A"] as Set
def disjointSet = ["X","Y"] as Set
def disjointSet = ["X", "Y"] as Set

when:
def intersection = FpKit.intersection(set1, set2)
then:
intersection == ["A","C"] as Set
intersection == ["A", "C"] as Set

when: // reversed parameters
intersection = FpKit.intersection(set2, set1)
then:
intersection == ["A","C"] as Set
intersection == ["A", "C"] as Set

when: // singles
intersection = FpKit.intersection(set1, singleSetA)
Expand All @@ -130,7 +130,7 @@ class FpKitTest extends Specification {
intersection.isEmpty()

when: // disjoint reversed
intersection = FpKit.intersection(disjointSet,set1)
intersection = FpKit.intersection(disjointSet, set1)
then:
intersection.isEmpty()
}
Expand Down
Loading