diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/parser/GraphQLDocumentParser.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/parser/GraphQLDocumentParser.kt index df532bf9868..847bead54b3 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/parser/GraphQLDocumentParser.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/parser/GraphQLDocumentParser.kt @@ -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 { + 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