Skip to content

Commit

Permalink
Fix issue with checking if one type is assignable from another (#1570)
Browse files Browse the repository at this point in the history
This query should not fail
```
query TestQuery {
  search(text: "test") {
    ... on Character {
...
```

where `Character` is interface with `Human, Droid` possible types and `SearchResult` is a UNION type with `Human, Droid, Starship` possible types.
  • Loading branch information
sav007 authored Sep 3, 2019
1 parent e627fc0 commit bdbc209
Showing 1 changed file with 35 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -754,14 +754,46 @@ class GraphQLDocumentParser(val schema: Schema) {
}

private fun Schema.Type.isAssignableFrom(other: Schema.Type): Boolean {
if (name == other.name) {
return true
}
return when (this) {
is Schema.Type.Union -> name == other.name || (possibleTypes ?: emptyList()).mapNotNull { it.rawType.name }.contains(other.name)
is Schema.Type.Interface -> name == other.name || (possibleTypes ?: emptyList()).mapNotNull { it.rawType.name }.contains(other.name)
is Schema.Type.Object -> name == other.name
is Schema.Type.Union -> possibleTypes().intersect(other.possibleTypes()).isNotEmpty()
is Schema.Type.Interface -> {
val possibleTypes = (possibleTypes ?: emptyList()).mapNotNull { it.rawType.name }
possibleTypes.contains(other.name) || possibleTypes.any { typeName ->
val schemaType = schema[typeName] ?: throw throw GraphQLParseException(
message = "Unknown possible type `$typeName` for INTERFACE `$name`"
)
schemaType.isAssignableFrom(other)
}
}
else -> false
}
}

private fun Schema.Type.possibleTypes(): Set<String> {
return when (this) {
is Schema.Type.Union -> (possibleTypes ?: emptyList()).flatMap { typeRef ->
val typeName = typeRef.rawType.name!!
val schemaType = schema[typeName] ?: throw throw GraphQLParseException(
message = "Unknown possible type `$typeName` for UNION `$name`"
)
schemaType.possibleTypes()
}.toSet()

is Schema.Type.Interface -> (possibleTypes ?: emptyList()).flatMap { typeRef ->
val typeName = typeRef.rawType.name!!
val schemaType = schema[typeName] ?: throw throw GraphQLParseException(
message = "Unknown possible type `$typeName` for INTERFACE `$name`"
)
schemaType.possibleTypes()
}.toSet()

else -> setOf(name)
}
}

private fun String.isGraphQLTypeAssignableFrom(otherType: String): Boolean {
var i = 0
var j = 0
Expand Down

0 comments on commit bdbc209

Please sign in to comment.