Skip to content

Commit 06675e0

Browse files
committed
SchemaMappingInspector detects Kotlin functions
Closes gh-995
1 parent 719ac8f commit 06675e0

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaMappingInspector.java

+31
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package org.springframework.graphql.execution;
1818

1919
import java.beans.PropertyDescriptor;
20+
import java.lang.reflect.Method;
21+
import java.lang.reflect.Modifier;
2022
import java.util.ArrayList;
2123
import java.util.Collections;
2224
import java.util.HashSet;
@@ -58,6 +60,7 @@
5860
import org.springframework.util.CollectionUtils;
5961
import org.springframework.util.LinkedMultiValueMap;
6062
import org.springframework.util.MultiValueMap;
63+
import org.springframework.util.StringUtils;
6164

6265
/**
6366
* Inspect schema mappings on startup to ensure the following:
@@ -81,6 +84,15 @@ public final class SchemaMappingInspector {
8184

8285
private static final Log logger = LogFactory.getLog(SchemaMappingInspector.class);
8386

87+
/**
88+
* GraphQL Java detects "record-like" methods that match field names.
89+
* This predicate aims to match the method {@code isRecordLike(Method)} in
90+
* {@link graphql.schema.fetching.LambdaFetchingSupport}.
91+
*/
92+
private static final Predicate<Method> recordLikePredicate = (method) ->
93+
(!method.getDeclaringClass().equals(Object.class) && !method.getReturnType().equals(Void.class) &&
94+
method.getParameterCount() == 0 && Modifier.isPublic(method.getModifiers()));
95+
8496

8597
private final GraphQLSchema schema;
8698

@@ -173,6 +185,12 @@ private void checkFieldsContainer(
173185
checkField(fieldContainer, field, ResolvableType.forMethodReturnType(descriptor.getReadMethod()));
174186
continue;
175187
}
188+
// Kotlin function?
189+
Method method = getRecordLikeMethod(resolvableType, fieldName);
190+
if (method != null) {
191+
checkField(fieldContainer, field, ResolvableType.forMethodReturnType(method));
192+
continue;
193+
}
176194
}
177195

178196
this.reportBuilder.unmappedField(FieldCoordinates.coordinates(typeName, fieldName));
@@ -249,6 +267,19 @@ private PropertyDescriptor getProperty(ResolvableType resolvableType, String fie
249267
}
250268
}
251269

270+
@Nullable
271+
private static Method getRecordLikeMethod(ResolvableType resolvableType, String fieldName) {
272+
Class<?> clazz = resolvableType.resolve();
273+
if (clazz != null) {
274+
for (Method method : clazz.getDeclaredMethods()) {
275+
if (recordLikePredicate.test(method) && fieldName.equals(StringUtils.uncapitalize(method.getName()))) {
276+
return method;
277+
}
278+
}
279+
}
280+
return null;
281+
}
282+
252283
private static boolean isNotScalarOrEnumType(GraphQLType type) {
253284
return !(type instanceof GraphQLScalarType || type instanceof GraphQLEnumType);
254285
}

0 commit comments

Comments
 (0)