Skip to content

Commit b715ed9

Browse files
smyrickgscheibel
authored andcommitted
feat: add superclass hooks (#139)
* feat: add superclass hooks * test: superclassFilters unit tests
1 parent 0beeb78 commit b715ed9

File tree

14 files changed

+260
-109
lines changed

14 files changed

+260
-109
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.expedia.graphql.generator.extensions
2+
3+
import kotlin.reflect.KCallable
4+
import kotlin.reflect.KVisibility
5+
6+
internal fun KCallable<*>.isPublic(): Boolean = this.visibility == KVisibility.PUBLIC

src/main/kotlin/com/expedia/graphql/generator/extensions/kClassExtensions.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.expedia.graphql.generator.extensions
22

33
import com.expedia.graphql.exceptions.CouldNotGetNameOfKClassException
4-
import com.expedia.graphql.generator.functionFilters
5-
import com.expedia.graphql.generator.propertyFilters
4+
import com.expedia.graphql.generator.filters.functionFilters
5+
import com.expedia.graphql.generator.filters.propertyFilters
6+
import com.expedia.graphql.generator.filters.superclassFilters
67
import com.expedia.graphql.hooks.SchemaGeneratorHooks
78
import kotlin.reflect.KClass
89
import kotlin.reflect.KFunction
@@ -14,6 +15,7 @@ import kotlin.reflect.full.declaredMemberProperties
1415
import kotlin.reflect.full.findParameterByName
1516
import kotlin.reflect.full.isSubclassOf
1617
import kotlin.reflect.full.primaryConstructor
18+
import kotlin.reflect.full.superclasses
1719

1820
internal fun KClass<*>.getValidProperties(hooks: SchemaGeneratorHooks): List<KProperty<*>> =
1921
this.declaredMemberProperties
@@ -25,6 +27,11 @@ internal fun KClass<*>.getValidFunctions(hooks: SchemaGeneratorHooks): List<KFun
2527
.filter { hooks.isValidFunction(it) }
2628
.filter { func -> functionFilters.all { it.invoke(func) } }
2729

30+
internal fun KClass<*>.getValidSuperclasses(hooks: SchemaGeneratorHooks): List<KClass<*>> =
31+
this.superclasses
32+
.filter { hooks.isValidSuperclass(it) }
33+
.filter { kClass -> superclassFilters.all { it.invoke(kClass) } }
34+
2835
internal fun KClass<*>.findConstructorParamter(name: String): KParameter? =
2936
this.primaryConstructor?.findParameterByName(name)
3037

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.expedia.graphql.generator.filters
2+
3+
import com.expedia.graphql.generator.extensions.isGraphQLIgnored
4+
import com.expedia.graphql.generator.extensions.isPublic
5+
import kotlin.reflect.KCallable
6+
7+
private typealias CallableFilter = (KCallable<*>) -> Boolean
8+
9+
private val blacklistFunctions: List<String> = listOf("annotationType", "toString", "copy", "equals", "hashCode")
10+
private val componentFunctionRegex = Regex("component([0-9]+)")
11+
12+
private val isPublic: CallableFilter = { it.isPublic() }
13+
private val isNotGraphQLIgnored: CallableFilter = { it.isGraphQLIgnored().not() }
14+
private val isBlacklistedFunction: CallableFilter = { blacklistFunctions.contains(it.name) }
15+
private val isComponentFunction: CallableFilter = { it.name.matches(componentFunctionRegex) }
16+
private val isNotBlacklistedFunction: CallableFilter = { isBlacklistedFunction(it).not() && isComponentFunction(it).not() }
17+
18+
internal val functionFilters: List<CallableFilter> = listOf(isPublic, isNotGraphQLIgnored, isNotBlacklistedFunction)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.expedia.graphql.generator.filters
2+
3+
import com.expedia.graphql.generator.extensions.isPropertyGraphQLIgnored
4+
import com.expedia.graphql.generator.extensions.isPublic
5+
import com.expedia.graphql.generator.extensions.qualifiedName
6+
import kotlin.reflect.KClass
7+
import kotlin.reflect.KProperty
8+
9+
private typealias PropertyFilter = (KProperty<*>, KClass<*>) -> Boolean
10+
11+
private val blacklistTypes: List<String> = listOf("kotlin.reflect.KClass")
12+
13+
private val isPropertyPublic: PropertyFilter = { prop, _ -> prop.isPublic() }
14+
private val isPropertyNotGraphQLIgnored: PropertyFilter = { prop, parentClass -> prop.isPropertyGraphQLIgnored(parentClass).not() }
15+
private val isNotBlacklistedType: PropertyFilter = { prop, _ -> blacklistTypes.contains(prop.returnType.qualifiedName).not() }
16+
17+
internal val propertyFilters: List<PropertyFilter> = listOf(isPropertyPublic, isNotBlacklistedType, isPropertyNotGraphQLIgnored)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.expedia.graphql.generator.filters
2+
3+
import com.expedia.graphql.generator.extensions.isInterface
4+
import com.expedia.graphql.generator.extensions.isPublic
5+
import com.expedia.graphql.generator.extensions.isUnion
6+
import kotlin.reflect.KClass
7+
8+
private typealias SuperclassFilter = (KClass<*>) -> Boolean
9+
10+
private val isPublic: SuperclassFilter = { it.isPublic() }
11+
private val isInterface: SuperclassFilter = { it.isInterface() }
12+
private val isNotUnion: SuperclassFilter = { it.isUnion().not() }
13+
14+
internal val superclassFilters: List<SuperclassFilter> = listOf(isPublic, isInterface, isNotUnion)

src/main/kotlin/com/expedia/graphql/generator/schemaFilters.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/main/kotlin/com/expedia/graphql/generator/types/ObjectTypeBuilder.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@ import com.expedia.graphql.generator.extensions.getGraphQLDescription
66
import com.expedia.graphql.generator.extensions.getSimpleName
77
import com.expedia.graphql.generator.extensions.getValidFunctions
88
import com.expedia.graphql.generator.extensions.getValidProperties
9-
import com.expedia.graphql.generator.extensions.isInterface
10-
import com.expedia.graphql.generator.extensions.isPublic
11-
import com.expedia.graphql.generator.extensions.isUnion
9+
import com.expedia.graphql.generator.extensions.getValidSuperclasses
1210
import graphql.schema.GraphQLInterfaceType
1311
import graphql.schema.GraphQLObjectType
1412
import graphql.schema.GraphQLType
1513
import kotlin.reflect.KClass
1614
import kotlin.reflect.full.createType
17-
import kotlin.reflect.full.superclasses
1815

1916
internal class ObjectTypeBuilder(generator: SchemaGenerator) : TypeBuilder(generator) {
2017

@@ -32,9 +29,7 @@ internal class ObjectTypeBuilder(generator: SchemaGenerator) : TypeBuilder(gener
3229
if (interfaceType != null) {
3330
builder.withInterface(interfaceType)
3431
} else {
35-
kClass.superclasses
36-
.asSequence()
37-
.filter { it.isPublic() && it.isInterface() && !it.isUnion() }
32+
kClass.getValidSuperclasses(config.hooks)
3833
.map { objectFromReflection(it.createType(), false) as? GraphQLInterfaceType }
3934
.forEach { builder.withInterface(it) }
4035
}

src/main/kotlin/com/expedia/graphql/hooks/SchemaGeneratorHooks.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import graphql.schema.GraphQLFieldDefinition
55
import graphql.schema.GraphQLSchema
66
import graphql.schema.GraphQLType
77
import java.util.concurrent.CompletableFuture
8+
import kotlin.reflect.KClass
89
import kotlin.reflect.KFunction
910
import kotlin.reflect.KProperty
1011
import kotlin.reflect.KType
@@ -39,6 +40,13 @@ interface SchemaGeneratorHooks {
3940
type
4041
}
4142

43+
/**
44+
* Called when looking at the KClass superclasses to determine if it valid for adding to the generated schema.
45+
* If any filter returns false, it is rejected.
46+
*/
47+
@Suppress("Detekt.FunctionOnlyReturningConstant")
48+
fun isValidSuperclass(kClass: KClass<*>): Boolean = true
49+
4250
/**
4351
* Called when looking at the KClass properties to determine if it valid for adding to the generated schema.
4452
* If any filter returns false, it is rejected.

src/test/kotlin/com/expedia/graphql/generator/SchemaFiltersTest.kt

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.expedia.graphql.generator.extensions
2+
3+
import org.junit.jupiter.api.Test
4+
import kotlin.reflect.full.functions
5+
import kotlin.test.assertFalse
6+
import kotlin.test.assertTrue
7+
8+
internal class KCallableExtensionsKtTest {
9+
10+
@Suppress("Detekt.FunctionOnlyReturningConstant", "Detekt.UnusedPrivateMember")
11+
internal open class MyTestClass {
12+
fun public() = 1
13+
14+
protected fun protected() = 2
15+
16+
internal fun internal() = 3
17+
18+
private fun private() = 4
19+
}
20+
21+
@Test
22+
fun isPublic() {
23+
assertTrue(MyTestClass::public.isPublic())
24+
assertFalse(MyTestClass::internal.isPublic())
25+
assertFalse(MyTestClass::class.functions.find { it.name == "protected" }?.isPublic().isTrue())
26+
assertFalse(MyTestClass::class.functions.find { it.name == "private" }?.isPublic().isTrue())
27+
}
28+
}

0 commit comments

Comments
 (0)