Skip to content
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

[⚒️compiler] Track schemanticNonNull spec #5577

Merged
merged 6 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
8 changes: 7 additions & 1 deletion .idea/runConfigurations/ValidationTest.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<p>
Before being referenced, directives and types supported by Apollo Kotlin must be imported by your schema using the <code>@link</code> directive<br>.
For instance, to use the <code>@semanticNonNull</code> directive, import it from the
<a href="https://specs.apollo.dev/nullability/v0.1"><code>nullability</code></a> definitions:
<a href="https://specs.apollo.dev/nullability/v0.2"><code>nullability</code></a> definitions:
<pre>
extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@semanticNonNull"]
)
</pre>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@catch"]
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@catch", "CatchTo"]
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@catch", "CatchTo"]
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@catch", "CatchTo"]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extend schema

extend schema
@link(
url: "https://specs.apollo.dev/nullability/v0.1",
url: "https://specs.apollo.dev/nullability/v0.2",
import: ["@catch", "CatchTo"]
)

Expand Down
1 change: 1 addition & 0 deletions libraries/apollo-ast/api/apollo-ast.api
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ public final class com/apollographql/apollo3/ast/Schema {
public static final field OPTIONAL Ljava/lang/String;
public static final field REQUIRES_OPT_IN Ljava/lang/String;
public static final field SEMANTIC_NON_NULL Ljava/lang/String;
public static final field SEMANTIC_NON_NULL_FIELD Ljava/lang/String;
public static final field TYPE_POLICY Ljava/lang/String;
public final fun getDirectiveDefinitions ()Ljava/util/Map;
public final fun getErrorAware ()Z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ class Schema internal constructor(
@ApolloExperimental
const val SEMANTIC_NON_NULL = "semanticNonNull"
@ApolloExperimental
const val SEMANTIC_NON_NULL_FIELD = "semanticNonNullField"
@ApolloExperimental
const val IGNORE_ERRORS = "ignoreErrors"

const val FIELD_POLICY_FOR_FIELD = "forField"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ enum class CatchTo {
}

@ApolloInternal
data class Catch(val to: CatchTo, val level: Int?)
data class Catch(val to: CatchTo, val levels: List<Int>)

private fun GQLDirectiveDefinition.getArgumentDefaultValue(argName: String): GQLValue? {
return arguments.firstOrNull { it.name == argName }?.defaultValue
}

@ApolloInternal
fun GQLDirective.getArgument(argName: String, schema: Schema): GQLValue? {
fun GQLDirective.getArgumentValueOrDefault(argName: String, schema: Schema): GQLValue? {
val directiveDefinition: GQLDirectiveDefinition = schema.directiveDefinitions.get(name)!!
val argument = arguments.firstOrNull { it.name == argName }
if (argument == null) {
Expand All @@ -99,6 +99,18 @@ fun GQLDirective.getArgument(argName: String, schema: Schema): GQLValue? {
return argument.value
}

private fun GQLValue.toListOfInt(): List<Int> {
check(this is GQLListValue) {
error("${sourceLocation}: expected a list value")
}
return this.values.map {
check(it is GQLIntValue) {
error("${it.sourceLocation}: expected an int value")
}
it.value.toInt()
}
}

private fun GQLValue.toIntOrNull(): Int? {
return when (this) {
is GQLNullValue -> null
Expand Down Expand Up @@ -136,32 +148,39 @@ private fun GQLValue?.toCatchTo(): CatchTo {
}

@ApolloInternal
fun List<GQLDirective>.findCatches(schema: Schema): List<Catch> {
fun List<GQLDirective>.findCatch(schema: Schema): Catch? {
return filter {
schema.originalDirectiveName(it.name) == Schema.CATCH
}.map {
Catch(
to = it.getArgument("to", schema).toCatchTo(),
level = it.getArgument("level", schema)?.toIntOrNull(),
to = it.getArgumentValueOrDefault("to", schema).toCatchTo(),
levels = it.getArgumentValueOrDefault("levels", schema)!!.toListOfInt(),
)
}
}.singleOrNull()
}

@ApolloInternal
fun GQLFieldDefinition.findSemanticNonNulls(schema: Schema): List<Int?> {
return directives.filter {
fun GQLFieldDefinition.findSemanticNonNulls(schema: Schema): List<Int> {
val semanticNonNulls = directives.filter {
schema.originalDirectiveName(it.name) == Schema.SEMANTIC_NON_NULL
}.map {
it.getArgument("level", schema)?.toIntOrNull()
}

val semanticNonNull = semanticNonNulls.singleOrNull()
if (semanticNonNull == null) {
return emptyList()
}
return semanticNonNull.getArgumentValueOrDefault("levels", schema)!!.toListOfInt()
}

@ApolloInternal
fun GQLTypeDefinition.findSemanticNonNulls(fieldName: String, schema: Schema): List<Int?> {
return directives.filter {
schema.originalDirectiveName(it.name) == Schema.SEMANTIC_NON_NULL
&& it.getArgument("field", schema)?.toStringOrNull() == fieldName
}.map {
it.getArgument("level", schema)?.toIntOrNull()
fun GQLTypeDefinition.findSemanticNonNulls(fieldName: String, schema: Schema): List<Int> {
val semanticNonNulls = directives.filter {
schema.originalDirectiveName(it.name) == Schema.SEMANTIC_NON_NULL_FIELD
&& it.getArgumentValueOrDefault("name", schema)?.toStringOrNull() == fieldName
}
val semanticNonNull = semanticNonNulls.singleOrNull()
if (semanticNonNull == null) {
return emptyList()
}
return semanticNonNull.getArgumentValueOrDefault("levels", schema)!!.toListOfInt()
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fun kotlinLabsDefinitions(version: String): List<GQLDefinition> {
})
}

@ApolloInternal const val NULLABILITY_VERSION = "v0.1"
@ApolloInternal const val NULLABILITY_VERSION = "v0.2"

/**
* Extra nullability definitions from https://specs.apollo.dev/nullability/<[version]>
Expand Down
Loading
Loading