Skip to content

Allow explicit CCN syntax #5148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -1529,15 +1529,17 @@ class GQLNullDesignator(override val sourceLocation: SourceLocation? = null) : G
@ApolloExperimental
class GQLListNullability(
override val sourceLocation: SourceLocation? = null,
val itemNullability: GQLNullability,
val itemNullability: GQLNullability?,
val selfNullability: GQLNullability?,
) : GQLNullability {
override val children: List<GQLNode>
get() = listOf(itemNullability)
get() = listOfNotNull(itemNullability)

override fun writeInternal(writer: SDLWriter) {
writer.write("[")
writer.write(itemNullability)
if (itemNullability != null) {
writer.write(itemNullability)
}
writer.write("]")
if (selfNullability != null) {
writer.write(selfNullability)
Expand All @@ -1552,7 +1554,7 @@ class GQLListNullability(

fun copy(
sourceLocation: SourceLocation? = this.sourceLocation,
ofNullability: GQLNullability = this.itemNullability,
ofNullability: GQLNullability? = this.itemNullability,
selfNullability: GQLNullability? = this.selfNullability,
): GQLListNullability {
return GQLListNullability(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ internal fun isVariableUsageAllowed(variableDefinition: GQLVariableDefinition, u
}

internal fun areTypesCompatible(variableType: GQLType, locationType: GQLType): Boolean {
return if(locationType is GQLNonNullType) {
return if (locationType is GQLNonNullType) {
if (variableType !is GQLNonNullType) {
false
} else {
areTypesCompatible(variableType.type, locationType.type)
}
} else if (variableType is GQLNonNullType) {
areTypesCompatible(variableType.type, locationType)
} else if (locationType is GQLListType){
} else if (locationType is GQLListType) {
if (variableType !is GQLListType) {
false
} else {
Expand Down Expand Up @@ -84,43 +84,43 @@ internal fun GQLType.isOutputType(typeDefinitions: Map<String, GQLTypeDefinition
}
}

private fun GQLNullability?.selfNullability(): GQLNullability? {
return when (this) {
is GQLListNullability -> this.selfNullability
else -> this
}
}

private fun GQLType.withListNullability(nullability: GQLNullability?): GQLType {
if (this is GQLListType && nullability is GQLListNullability) {
return copy(type = type.withNullability(nullability.itemNullability))
} else if (this is GQLListType && nullability !is GQLListNullability) {
private fun GQLType.withItemNullability(itemNullability: GQLNullability?): GQLType {
if (itemNullability == null) {
return this
} else if (this !is GQLListType && nullability is GQLListNullability) {
return this
} else if (this !is GQLListType && nullability !is GQLListNullability) {
return this
} else {
error("")
}

check(this is GQLListType)

return this.copy(type = type.withNullability(itemNullability))
}

@ApolloExperimental
fun GQLType.withNullability(nullability: GQLNullability?): GQLType {
val selfNullability = nullability.selfNullability()
val selfNullability: GQLNullability?
val itemNullability: GQLNullability?

if (this is GQLNonNullType && selfNullability == null) {
return this.copy(type = type.withListNullability(nullability))
when(nullability) {
is GQLListNullability -> {
selfNullability = nullability.selfNullability
itemNullability = nullability.itemNullability
}
else -> {
selfNullability = nullability
itemNullability = null
}
}
return if (this is GQLNonNullType && selfNullability == null) {
this.copy(type = type.withItemNullability(itemNullability))
} else if (this is GQLNonNullType && selfNullability is GQLNonNullDesignator) {
return this.copy(type = type.withListNullability(nullability))
this.copy(type = type.withItemNullability(itemNullability))
} else if (this is GQLNonNullType && selfNullability is GQLNullDesignator) {
return this.type.withListNullability(nullability)
this.type.withItemNullability(itemNullability)
} else if (this !is GQLNonNullType && selfNullability == null) {
return this.withListNullability(nullability)
this.withItemNullability(itemNullability)
} else if (this !is GQLNonNullType && selfNullability is GQLNonNullDesignator) {
return GQLNonNullType(type = this.withListNullability(nullability))
GQLNonNullType(type = this.withItemNullability(itemNullability))
} else if (this !is GQLNonNullType && selfNullability is GQLNullDesignator) {
return this.withListNullability(nullability)
this.withItemNullability(itemNullability)
} else {
error("")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import com.apollographql.apollo3.ast.GQLListType
import com.apollographql.apollo3.ast.GQLListValue
import com.apollographql.apollo3.ast.GQLNamedType
import com.apollographql.apollo3.ast.GQLNode
import com.apollographql.apollo3.ast.GQLNonNullDesignator
import com.apollographql.apollo3.ast.GQLNonNullType
import com.apollographql.apollo3.ast.GQLNullDesignator
import com.apollographql.apollo3.ast.GQLNullValue
import com.apollographql.apollo3.ast.GQLNullability
import com.apollographql.apollo3.ast.GQLObjectTypeDefinition
import com.apollographql.apollo3.ast.GQLObjectValue
import com.apollographql.apollo3.ast.GQLOperationDefinition
import com.apollographql.apollo3.ast.GQLNullDesignator
import com.apollographql.apollo3.ast.GQLNonNullDesignator
import com.apollographql.apollo3.ast.GQLScalarTypeDefinition
import com.apollographql.apollo3.ast.GQLSelection
import com.apollographql.apollo3.ast.GQLStringValue
Expand Down Expand Up @@ -246,7 +246,7 @@ internal class ExecutableValidationScope(

private fun GQLNullability.listDimension(): Int {
return when (this) {
is GQLListNullability -> 1 + this.itemNullability.listDimension()
is GQLListNullability -> 1 + (this.itemNullability?.listDimension() ?: 0)
is GQLNullDesignator -> 0
is GQLNonNullDesignator -> 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,12 @@ internal class Parser(
}

private fun parseListNullability(): GQLListNullability {
val start = token
val sourceLocation = sourceLocation()

expectToken<Token.LeftBracket>()
val ofNullability = parseNullability()
expectToken<Token.RightBracket>()

if (ofNullability == null) {
throw ParserException("List nullability must not be empty", start)
}

return GQLListNullability(
sourceLocation = sourceLocation,
itemNullability = ofNullability,
Expand Down
3 changes: 3 additions & 0 deletions tests/ccn/src/main/graphql/operation.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ query GetList {
enemies[!]! {
name
}
frenemies: enemies[]! {
name
}
}
}
4 changes: 3 additions & 1 deletion tests/ccn/src/test/kotlin/test/CcnTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class CcnTest {
{
"name": "nullability"
}
]
],
"frenemies": []
}
}
}
Expand All @@ -54,5 +55,6 @@ class CcnTest {
}
assertEquals(null, response.data!!.user!!.friends[0]?.name)
assertEquals("nullability", response.data!!.user!!.enemies[0].name)
assertEquals(0, response.data!!.user!!.frenemies.size)
}
}