Skip to content

Commit

Permalink
Store normalization info to the Relay resolver node
Browse files Browse the repository at this point in the history
Reviewed By: captbaritone

Differential Revision: D39831310

fbshipit-source-id: dc9ae9e889afa7c3b026fbe559bc391133b97438
  • Loading branch information
alunyov authored and facebook-github-bot committed Sep 30, 2022
1 parent 62a5713 commit 55b829b
Show file tree
Hide file tree
Showing 62 changed files with 237 additions and 188 deletions.
63 changes: 34 additions & 29 deletions compiler/crates/relay-codegen/src/build_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> {
// information to _read_ the resolver. Specifically, enough data
// to construct a fragment key, and an import of the resolver
// module itself.
Primitive::Key(self.object(object! {
let mut object_props = object! {
:build_alias(field_alias, field_name),
args: match args {
None => Primitive::SkippableNull,
Expand All @@ -1017,7 +1017,36 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> {
name: Primitive::String(field_name),
resolver_module: Primitive::JSModuleDependency(import_path),
path: Primitive::String(path),
}))
};

if let Some(normalization_info) = &relay_resolver_metadata.normalization_info {
let normalization_artifact_source_location = normalization_info
.normalization_operation
.location
.source_location();

let path_for_artifact = self.project_config.create_path_for_artifact(
normalization_artifact_source_location,
normalization_info.normalization_operation.item.to_string(),
);

let normalization_import_path = self.project_config.js_module_import_path(
self.definition_source_location,
path_for_artifact.to_str().unwrap().intern(),
);
let normalization_info = object! {
concrete_type: Primitive::String(normalization_info.type_name),
plural: Primitive::Bool(normalization_info.plural),
normalization_node: Primitive::GraphQLModuleDependency(normalization_import_path),
};

object_props.push(ObjectEntry {
key: CODEGEN_CONSTANTS.relay_resolver_normalization_info,
value: Primitive::Key(self.object(normalization_info)),
})
}

Primitive::Key(self.object(object_props))
}

fn build_normalization_fragment_spread(
Expand Down Expand Up @@ -1237,37 +1266,13 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> {
client_edge_selections_key: selections_item,
}))
}
ClientEdgeMetadataDirective::ClientObject {
type_name,
normalization_operation,
..
} => {
let mut object_props = object! {
ClientEdgeMetadataDirective::ClientObject { type_name, .. } => {
Primitive::Key(self.object(object! {
kind: Primitive::String(CODEGEN_CONSTANTS.client_edge_to_client_object),
concrete_type: Primitive::String(type_name),
client_edge_backing_field_key: backing_field,
client_edge_selections_key: selections_item,
};
if let Some(normalization_operation) = normalization_operation {
let normalization_artifact_source_location =
normalization_operation.location.source_location();

let path_for_artifact = self.project_config.create_path_for_artifact(
normalization_artifact_source_location,
normalization_operation.item.to_string(),
);

let normalization_import_path = self.project_config.js_module_import_path(
self.definition_source_location,
path_for_artifact.to_str().unwrap().intern(),
);

object_props.push(ObjectEntry {
key: CODEGEN_CONSTANTS.client_edge_normalization_node_key,
value: Primitive::GraphQLModuleDependency(normalization_import_path),
})
}
Primitive::Key(self.object(object_props))
}))
}
};

Expand Down
6 changes: 4 additions & 2 deletions compiler/crates/relay-codegen/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub struct CodegenConstants {
pub client_component: StringKey,
pub client_edge_backing_field_key: StringKey,
pub client_edge_selections_key: StringKey,
pub client_edge_normalization_node_key: StringKey,
pub client_edge_to_client_object: StringKey,
pub client_edge_to_server_object: StringKey,
pub client_extension: StringKey,
Expand Down Expand Up @@ -80,6 +79,7 @@ pub struct CodegenConstants {
pub module_import: StringKey,
pub mutation: StringKey,
pub name: StringKey,
pub normalization_node: StringKey,
pub object_value: StringKey,
pub operation_kind: StringKey,
pub operation_module_provider: StringKey,
Expand All @@ -95,6 +95,7 @@ pub struct CodegenConstants {
pub query: StringKey,
pub refetch: StringKey,
pub relay_live_resolver: StringKey,
pub relay_resolver_normalization_info: StringKey,
pub relay_resolver: StringKey,
pub request: StringKey,
pub required_field: StringKey,
Expand Down Expand Up @@ -132,7 +133,6 @@ lazy_static! {
client_component: "ClientComponent".intern(),
client_edge_backing_field_key: "backingField".intern(),
client_edge_selections_key: "linkedField".intern(),
client_edge_normalization_node_key: "normalizationNode".intern(),
client_edge_to_client_object: "ClientEdgeToClientObject".intern(),
client_edge_to_server_object: "ClientEdgeToServerObject".intern(),
client_extension: "ClientExtension".intern(),
Expand Down Expand Up @@ -188,6 +188,7 @@ lazy_static! {
module_import: "ModuleImport".intern(),
mutation: "mutation".intern(),
name: "name".intern(),
normalization_node: "normalizationNode".intern(),
object_value: "ObjectValue".intern(),
operation_kind: "operationKind".intern(),
operation_module_provider: "operationModuleProvider".intern(),
Expand All @@ -203,6 +204,7 @@ lazy_static! {
query: "query".intern(),
refetch: "refetch".intern(),
relay_live_resolver: "RelayLiveResolver".intern(),
relay_resolver_normalization_info: "normalizationInfo".intern(),
relay_resolver: "RelayResolver".intern(),
request: "Request".intern(),
required_field: "RequiredField".intern(),
Expand Down
5 changes: 3 additions & 2 deletions compiler/crates/relay-docblock/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ lazy_static! {
static ref IMPORT_PATH_ARGUMENT_NAME: ArgumentName = ArgumentName("import_path".intern());
static ref LIVE_ARGUMENT_NAME: ArgumentName = ArgumentName("live".intern());
static ref DEPRECATED_REASON_ARGUMENT_NAME: ArgumentName = ArgumentName("reason".intern());
static ref IS_OUTPUT_TYPE_ARGUMENT_NAME: ArgumentName = ArgumentName("is_output_type".intern());
static ref HAS_OUTPUT_TYPE_ARGUMENT_NAME: ArgumentName =
ArgumentName("has_output_type".intern());
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -447,7 +448,7 @@ impl RelayResolverIr {

if let Some(OutputType::Output(type_)) = &self.output_type {
arguments.push(true_argument(
IS_OUTPUT_TYPE_ARGUMENT_NAME.0,
HAS_OUTPUT_TYPE_ARGUMENT_NAME.0,
type_.location,
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ graphql`
`
==================================== OUTPUT ===================================
extend type User {
favorite_page: ClientPage @relay_resolver(import_path: "/path/to/test/fixture/relay-resolver-with-output-type.js", fragment_name: "myRootFragment", is_output_type: true)
favorite_page: ClientPage @relay_resolver(import_path: "/path/to/test/fixture/relay-resolver-with-output-type.js", fragment_name: "myRootFragment", has_output_type: true)
}
17 changes: 0 additions & 17 deletions compiler/crates/relay-transforms/src/client_edges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ use schema::Schema;
use schema::Type;

use super::ValidationMessageWithData;
use crate::generate_relay_resolvers_operations_for_nested_objects::generate_name_for_nested_object_operation;
use crate::refetchable_fragment::RefetchableFragment;
use crate::refetchable_fragment::REFETCHABLE_NAME;
use crate::relay_resolvers::RELAY_RESOLVER_DIRECTIVE_NAME;
Expand All @@ -56,7 +55,6 @@ lazy_static! {
// This gets attached to fragment which defines the selection in the generated query
pub static ref CLIENT_EDGE_GENERATED_FRAGMENT_KEY: DirectiveName = DirectiveName("__clientEdgeGeneratedFragment".intern());
pub static ref CLIENT_EDGE_WATERFALL_DIRECTIVE_NAME: DirectiveName = DirectiveName("waterfall".intern());
pub static ref RELAY_RESOLVER_IS_OUTPUT_TYPE: ArgumentName = ArgumentName("is_output_type".intern());
}

/// Directive added to inline fragments created by the transform. The inline
Expand All @@ -75,7 +73,6 @@ pub enum ClientEdgeMetadataDirective {
ClientObject {
type_name: StringKey,
unique_id: u32,
normalization_operation: Option<WithLocation<OperationDefinitionName>>,
},
}
associated_data_impl!(ClientEdgeMetadataDirective);
Expand Down Expand Up @@ -355,19 +352,6 @@ impl<'program, 'sc> ClientEdgesTransform<'program, 'sc> {
));
}

let is_resolver_with_output_type = resolver_directive
.and_then(|directive| directive.arguments.named(*RELAY_RESOLVER_IS_OUTPUT_TYPE))
.is_some();

let normalization_operation_name = if is_resolver_with_output_type {
Some(generate_name_for_nested_object_operation(
&self.program.schema,
self.program.schema.field(field.definition().item),
))
} else {
None
};

match edge_to_type {
Type::Interface(_) => {
self.errors.push(Diagnostic::error(
Expand All @@ -386,7 +370,6 @@ impl<'program, 'sc> ClientEdgesTransform<'program, 'sc> {
Type::Object(object_id) => ClientEdgeMetadataDirective::ClientObject {
type_name: schema.object(object_id).name.item,
unique_id: self.get_key(),
normalization_operation: normalization_operation_name,
},
_ => {
panic!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use crate::SplitOperationMetadata;
use crate::ValidationMessage;

lazy_static! {
pub static ref IS_OUTPUT_TYPE_ARGUMENT_NAME: ArgumentName =
ArgumentName("is_output_type".intern());
pub static ref HAS_OUTPUT_TYPE_ARGUMENT_NAME: ArgumentName =
ArgumentName("has_output_type".intern());
}

fn generate_fat_selections_from_type(
Expand Down Expand Up @@ -272,9 +272,9 @@ pub fn generate_relay_resolvers_operations_for_nested_objects(
}

if let Some(directive) = field.directives.named(*RELAY_RESOLVER_DIRECTIVE_NAME) {
let is_output_type =
get_bool_argument_is_true(&directive.arguments, *IS_OUTPUT_TYPE_ARGUMENT_NAME);
if !is_output_type {
let has_output_type =
get_bool_argument_is_true(&directive.arguments, *HAS_OUTPUT_TYPE_ARGUMENT_NAME);
if !has_output_type {
continue;
}

Expand Down
36 changes: 35 additions & 1 deletion compiler/crates/relay-transforms/src/relay_resolvers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use graphql_ir::FragmentDefinitionName;
use graphql_ir::FragmentSpread;
use graphql_ir::InlineFragment;
use graphql_ir::LinkedField;
use graphql_ir::OperationDefinitionName;
use graphql_ir::Program;
use graphql_ir::ScalarField;
use graphql_ir::Selection;
Expand All @@ -38,6 +39,7 @@ use schema::Field;
use schema::Schema;

use super::ValidationMessage;
use crate::generate_relay_resolvers_operations_for_nested_objects::generate_name_for_nested_object_operation;
use crate::ClientEdgeMetadata;
use crate::FragmentAliasMetadata;
use crate::RequiredMetadataDirective;
Expand Down Expand Up @@ -66,6 +68,15 @@ lazy_static! {
pub static ref RELAY_RESOLVER_IMPORT_PATH_ARGUMENT_NAME: ArgumentName =
ArgumentName("import_path".intern());
pub static ref RELAY_RESOLVER_LIVE_ARGUMENT_NAME: ArgumentName = ArgumentName("live".intern());
pub static ref RELAY_RESOLVER_IS_OUTPUT_TYPE: ArgumentName =
ArgumentName("has_output_type".intern());
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ResolverNormalizationInfo {
pub type_name: StringKey,
pub plural: bool,
pub normalization_operation: WithLocation<OperationDefinitionName>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
Expand All @@ -75,6 +86,7 @@ struct RelayResolverFieldMetadata {
fragment_name: Option<FragmentDefinitionName>,
field_path: StringKey,
live: bool,
normalization_info: Option<ResolverNormalizationInfo>,
}
associated_data_impl!(RelayResolverFieldMetadata);

Expand All @@ -87,6 +99,7 @@ pub struct RelayResolverMetadata {
pub field_path: StringKey,
pub field_arguments: Vec<Argument>,
pub live: bool,
pub normalization_info: Option<ResolverNormalizationInfo>,
}
associated_data_impl!(RelayResolverMetadata);

Expand Down Expand Up @@ -156,6 +169,7 @@ impl<'program> RelayResolverSpreadTransform<'program> {
field_path: field_metadata.field_path,
field_arguments,
live: field_metadata.live,
normalization_info: field_metadata.normalization_info.clone(),
};

let mut new_directives: Vec<Directive> = vec![resolver_metadata.into()];
Expand Down Expand Up @@ -299,6 +313,7 @@ impl<'program> RelayResolverFieldTransform<'program> {
fragment_name,
import_path,
live,
has_output_type,
}) => {
let mut non_required_directives =
field.directives().iter().filter(|directive| {
Expand Down Expand Up @@ -328,12 +343,28 @@ impl<'program> RelayResolverFieldTransform<'program> {
}
let parent_type = field_type.parent_type.unwrap();

let normalization_info = if has_output_type {
let normalization_operation = generate_name_for_nested_object_operation(
&self.program.schema,
self.program.schema.field(field.definition().item),
);

Some(ResolverNormalizationInfo {
type_name: self.program.schema.get_type_name(field_type.type_.inner()),
plural: field_type.type_.is_list(),
normalization_operation,
})
} else {
None
};

let resolver_field_metadata = RelayResolverFieldMetadata {
import_path,
field_parent_type: self.program.schema.get_type_name(parent_type),
fragment_name,
field_path: self.path.join(".").intern(),
live,
normalization_info,
};

let mut directives: Vec<Directive> = field.directives().to_vec();
Expand Down Expand Up @@ -448,6 +479,7 @@ struct ResolverInfo {
fragment_name: Option<FragmentDefinitionName>,
import_path: StringKey,
live: bool,
has_output_type: bool,
}

fn get_resolver_info(
Expand Down Expand Up @@ -475,11 +507,13 @@ fn get_resolver_info(
error_location,
)?;
let live = get_bool_argument_is_true(arguments, *RELAY_RESOLVER_LIVE_ARGUMENT_NAME);

let has_output_type =
get_bool_argument_is_true(arguments, *RELAY_RESOLVER_IS_OUTPUT_TYPE);
Ok(ResolverInfo {
fragment_name,
import_path,
live,
has_output_type,
})
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fragment Foo_user on User {
# field_path: "best_friend",
# field_arguments: [],
# live: false,
# normalization_info: None,
# }
@waterfall
best_friend @waterfall {
Expand All @@ -66,6 +67,7 @@ fragment Foo_user on User {
# field_path: "best_friend",
# field_arguments: [],
# live: false,
# normalization_info: None,
# }
@waterfall
best_friend @waterfall {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ fragment Foo_node on Node {
# field_path: "author.best_friend",
# field_arguments: [],
# live: false,
# normalization_info: None,
# }
@waterfall
best_friend @waterfall {
Expand All @@ -73,6 +74,7 @@ fragment Foo_node on Node {
# field_path: "author.best_friend",
# field_arguments: [],
# live: false,
# normalization_info: None,
# }
@waterfall
best_friend @waterfall {
Expand Down
Loading

0 comments on commit 55b829b

Please sign in to comment.