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

[Codegen] Add CompiledArgumentDefinition #5797

Merged
merged 18 commits into from
Apr 15, 2024
Merged

Conversation

BoD
Copy link
Contributor

@BoD BoD commented Apr 10, 2024

  • Introduce CompiledArgumentDefinition instead of storing schema argument details (isKey, isPagination) in CompiledArgument

  • They are added as fields inside the Type class, with the form __fieldName__argumentName

  • To limit the size of the generated code, track arguments that are used by operations and output only the definition for those

    • To do that, a wrapper class UsedCoordinates is introduced, to avoid manipulating maps directly.
    • The used coordinated are now tracked by the CodegenTest in used-coordinates.json files
  • Behavior change: only the specified arguments values are set to the CompiledArgument, and not the default value from the schema. This makes the note saying The argument defaultValues are not added to the name in the Kdoc of nameWithArguments() true.

Resolves #5781

@BoD BoD requested a review from martinbonnin as a code owner April 10, 2024 16:40
Copy link

netlify bot commented Apr 10, 2024

Deploy Preview for apollo-android-docs canceled.

Name Link
🔨 Latest commit b0d2dae
🔍 Latest deploy log https://app.netlify.com/sites/apollo-android-docs/deploys/6619307566413b0008609f17

.idea/codeStyles/Project.xml Show resolved Hide resolved
libraries/apollo-api/api/apollo-api.api Show resolved Hide resolved
Comment on lines 98 to 99
val parentType: String,
val parentField: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you merge parentType and parentField (and name) in an id field like in IrModel.id that you can later use to resolve the argument definition classname for that id?

I'm trying to avoid GraphQL things in the IR. It's OK to have opaque ids but IR doesn't need to know about GraphQL names.

Comment on lines 773 to 777
private fun UsedCoordinates.putAllArguments(
parentType: String,
selections: List<GQLSelection>,
allFragmentDefinitions: Map<String, GQLFragmentDefinition>,
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you end up keeping this, allFragmentDefinitions is in the context already, I think you can skip it here.

Also side note: yet another thing that would be easier to do with a proper traversal API.

Comment on lines 613 to 615
// When a field with arguments is selected, its parent type is referenced in the compiled selections
if (first.definitionHasArguments) {
usedCoordinates.putType(first.parentType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add all the arguments here instead of calling UsedCoordinates.putAllArguments at the end of the process? You'll probably have to add arguments to the CollectedField but it's colocating everything.

@@ -62,6 +66,10 @@ internal data class IrObject(
val deprecationReason: String?,
val embeddedFields: List<String>,
val mapProperties: List<IrMapProperty>,
/**
* Only contains fields that have arguments used in operations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's OK to skip that comment since it's the whole premise of the IR that it matches the target and not the GraphQL schema.

We could add a more general comment how these things are decided in IrOperationBuilder and link from here though.

/**
* The compile-time value of that argument.
*
* Can be the defaultValue if no argument is defined in the operation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we go for "no need for the schema defaultValue"?

Copy link
Contributor

@martinbonnin martinbonnin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -33,6 +33,7 @@ enum class ResolverKeyKind {
Schema,
CustomScalarAdapters,
Pagination,
ArgumentDefinition,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For later: we can use the coordinate to lookup the matching kotlin instead of adding a new kind each time.

Comment on lines +139 to +140
fun id(type: String, field: String, argument: String) = "$type.$field.$argument"
fun propertyName(fieldName: String, argumentName: String) = "__${fieldName}_${argumentName}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For later: we should come up with some rules about symbols. Are __ to escape nameclashes or a signal that it is not meant to be called directly. It's not 100% clear at the moment

@BoD BoD merged commit fa85469 into main Apr 15, 2024
9 checks passed
@BoD BoD deleted the compiled-argument-definition branch April 15, 2024 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Codegen: rework how compiled field arguments are generated
2 participants