Skip to content

Commit

Permalink
Update normalization AST generation
Browse files Browse the repository at this point in the history
Reviewed By: alunyov

Differential Revision: D50455558

fbshipit-source-id: 520368e23860e5f6554919d456cd3c99bd770402
  • Loading branch information
germtb authored and facebook-github-bot committed Oct 20, 2023
1 parent 4668757 commit 0c70e54
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 15 deletions.
10 changes: 5 additions & 5 deletions compiler/crates/relay-codegen/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ pub struct JSModuleDependency {
}

#[derive(Eq, PartialEq, Hash, PartialOrd, Ord, Debug, Clone)]
pub struct JSModuleReference {
pub parent_type: StringKey,
pub import_name: ModuleImportName,
pub struct ResolverModuleReference {
pub field_type: StringKey,
pub resolver_function_name: ModuleImportName,
}

#[derive(Eq, PartialEq, Hash, Debug)]
pub enum JSModule {
Reference(JSModuleReference),
Reference(ResolverModuleReference),
Dependency(JSModuleDependency),
}

Expand All @@ -111,7 +111,7 @@ pub enum Primitive {
RawString(String),
GraphQLModuleDependency(GraphQLModuleDependency),
JSModuleDependency(JSModuleDependency),
JSModuleReference(JSModuleReference),
ResolverModuleReference(ResolverModuleReference),

// Don't include the value in the output when
// skip_printing_nulls is enabled
Expand Down
61 changes: 60 additions & 1 deletion compiler/crates/relay-codegen/src/build_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ use relay_transforms::RELAY_ACTOR_CHANGE_DIRECTIVE_FOR_CODEGEN;
use relay_transforms::TYPE_DISCRIMINATOR_DIRECTIVE_NAME;
use schema::SDLSchema;
use schema::Schema;
use schema::Type;

use crate::ast::Ast;
use crate::ast::AstBuilder;
Expand All @@ -72,6 +73,7 @@ use crate::ast::ObjectEntry;
use crate::ast::Primitive;
use crate::ast::QueryID;
use crate::ast::RequestParameters;
use crate::ast::ResolverModuleReference;
use crate::constants::CODEGEN_CONSTANTS;
use crate::object;

Expand Down Expand Up @@ -647,7 +649,9 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> {
resolver_metadata: &RelayResolverMetadata,
inline_fragment: Option<Primitive>,
) -> Primitive {
if self
if self.project_config.feature_flags.enable_schema_resolvers {
self.build_normalization_relay_resolver_execution_time_for_worker(resolver_metadata)
} else if self
.project_config
.feature_flags
.enable_resolver_normalization_ast
Expand Down Expand Up @@ -756,6 +760,61 @@ impl<'schema, 'builder, 'config> CodegenBuilder<'schema, 'builder, 'config> {
}))
}

fn build_normalization_relay_resolver_execution_time_for_worker(
&mut self,
resolver_metadata: &RelayResolverMetadata,
) -> Primitive {
let field_name = resolver_metadata.field_name(self.schema);
let field_arguments = &resolver_metadata.field_arguments;
let args = self.build_arguments(field_arguments);
let is_output_type = resolver_metadata
.output_type_info
.normalization_ast_should_have_is_output_type_true();

let field_type = match resolver_metadata.field(self.schema).parent_type.unwrap() {
Type::Interface(interface_id) => self.schema.interface(interface_id).name.item.0,
Type::Object(object_id) => self.schema.object(object_id).name.item.0,
_ => panic!("Unexpected parent type for resolver."),
};

let variable_name = resolver_metadata.generate_local_resolver_name(self.schema);
let resolver_js_module = ResolverModuleReference {
field_type,
resolver_function_name: match resolver_metadata.import_name {
Some(name) => ModuleImportName::Named {
name,
import_as: Some(variable_name),
},
None => ModuleImportName::Default(variable_name),
},
};
let kind = if resolver_metadata.live {
CODEGEN_CONSTANTS.relay_live_resolver
} else {
CODEGEN_CONSTANTS.relay_resolver
};
Primitive::Key(self.object(object! {
name: Primitive::String(field_name),
args: match args {
None => Primitive::SkippableNull,
Some(key) => Primitive::Key(key),
},
kind: Primitive::String(kind),
storage_key: match args {
None => Primitive::SkippableNull,
Some(key) => {
if is_static_storage_key_available(&resolver_metadata.field_arguments) {
Primitive::StorageKey(field_name, key)
} else {
Primitive::SkippableNull
}
}
},
is_output_type: Primitive::Bool(is_output_type),
resolver_module: Primitive::ResolverModuleReference(resolver_js_module),
}))
}

fn build_scalar_field_and_handles(&mut self, field: &ScalarField) -> Vec<Primitive> {
if let Some(resolver_metadata) = RelayResolverMetadata::find(&field.directives) {
return vec![self.build_scalar_backed_resolver_field(field, resolver_metadata)];
Expand Down
32 changes: 26 additions & 6 deletions compiler/crates/relay-codegen/src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ use crate::ast::AstBuilder;
use crate::ast::AstKey;
use crate::ast::GraphQLModuleDependency;
use crate::ast::JSModuleDependency;
use crate::ast::JSModuleReference;
use crate::ast::ModuleImportName;
use crate::ast::ObjectEntry;
use crate::ast::Primitive;
use crate::ast::QueryID;
use crate::ast::RequestParameters;
use crate::ast::ResolverModuleReference;
use crate::build_ast::build_fragment;
use crate::build_ast::build_operation;
use crate::build_ast::build_provided_variables;
Expand Down Expand Up @@ -508,11 +508,11 @@ impl<'b> JSONPrinter<'b> {
import_name.clone(),
get_module_path(self.js_module_format, *path),
),
Primitive::JSModuleReference(JSModuleReference {
parent_type: _,
import_name: _,
Primitive::ResolverModuleReference(ResolverModuleReference {
field_type,
resolver_function_name,
}) => {
todo!("Not implemented yet")
self.write_resolver_module_reference(f, resolver_function_name.clone(), field_type)
}
Primitive::DynamicImport { provider, module } => match provider {
DynamicModuleProvider::JSResource => {
Expand Down Expand Up @@ -562,6 +562,26 @@ impl<'b> JSONPrinter<'b> {
}
}

fn write_resolver_module_reference(
&mut self,
f: &mut String,
resolver_function_name: ModuleImportName,
field_type: &StringKey,
) -> FmtResult {
match resolver_function_name {
ModuleImportName::Default(_) => {
panic!("Expected a named import for Relay Resolvers")
}
ModuleImportName::Named { name, .. } => {
write!(
f,
"{{ resolverFunctionName: \"{}\", fieldType: \"{}\" }}",
name, field_type
)
}
}
}

fn write_js_dependency(
&mut self,
f: &mut String,
Expand Down Expand Up @@ -834,7 +854,7 @@ fn write_constant_value(f: &mut String, builder: &AstBuilder, value: &Primitive)
Primitive::RawString(_) => panic!("Unexpected RawString"),
Primitive::GraphQLModuleDependency(_) => panic!("Unexpected GraphQLModuleDependency"),
Primitive::JSModuleDependency { .. } => panic!("Unexpected JSModuleDependency"),
Primitive::JSModuleReference { .. } => panic!("Unexpected JSModuleReference"),
Primitive::ResolverModuleReference { .. } => panic!("Unexpected ResolverModuleReference"),
Primitive::DynamicImport { .. } => panic!("Unexpected DynamicImport"),
Primitive::RelayResolverModel { .. } => panic!("Unexpected RelayResolver"),
Primitive::RelayResolverWeakObjectWrapper { .. } => {
Expand Down
1 change: 1 addition & 0 deletions packages/relay-runtime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ export type {
export type {Local3DPayload} from './util/createPayloadFor3DField';
export type {Direction} from './util/getPaginationVariables';
export type {RequestIdentifier} from './util/getRequestIdentifier';
export type {ResolverFunction} from './util/ReaderNode';

// As early as possible, check for the existence of the JavaScript globals which
// Relay Runtime relies upon, and produce a clear message if they do not exist.
Expand Down
9 changes: 7 additions & 2 deletions packages/relay-runtime/util/NormalizationNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,19 @@ export type NormalizationScalarField = {
+storageKey?: ?string,
};

export type ResolverModuleReference = {
+fieldType: string,
+resolverFunctionName: string,
};

export type NormalizationResolverField = {
+kind: 'RelayResolver',
+name: string,
+args: ?$ReadOnlyArray<NormalizationArgument>,
+fragment?: ?NormalizationInlineFragment,
+storageKey: ?string,
+isOutputType: boolean,
+resolverModule?: ResolverModule,
+resolverModule?: ResolverModule | ResolverModuleReference,
};

export type NormalizationLiveResolverField = {
Expand All @@ -182,7 +187,7 @@ export type NormalizationLiveResolverField = {
+fragment?: ?NormalizationInlineFragment,
+storageKey: ?string,
+isOutputType: boolean,
+resolverModule?: ResolverModule,
+resolverModule?: ResolverModule | ResolverModuleReference,
};

export type NormalizationClientEdgeToClientObject = {
Expand Down
2 changes: 1 addition & 1 deletion packages/relay-runtime/util/ReaderNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export type ReaderRequiredField = {
+path: string,
};

type ResolverFunction = (...args: Array<any>) => mixed; // flowlint-line unclear-type:off
export type ResolverFunction = (...args: Array<any>) => mixed; // flowlint-line unclear-type:off
// With ES6 imports, a resolver function might be exported under the `default` key.
export type ResolverModule = ResolverFunction | {default: ResolverFunction};

Expand Down

0 comments on commit 0c70e54

Please sign in to comment.