Skip to content

Commit

Permalink
Allow removing null values from metadata
Browse files Browse the repository at this point in the history
The fragment & query metadata contains many null values. This change
adds a feature flag (`enable_reduced_metadata`) to allow the rust
compiler to avoid outputting those fields. The runtime will still
operate on them, due to it's pervasive use of loose equality for null /
undefined checks.
  • Loading branch information
tomgasson committed Feb 1, 2022
1 parent 30582a1 commit 9de3226
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 58 deletions.
3 changes: 3 additions & 0 deletions compiler/crates/common/src/feature_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub struct FeatureFlags {

#[serde(default)]
pub enable_provided_variables: FeatureFlag,

#[serde(default)]
pub enable_reduced_metadata: FeatureFlag,
}

#[derive(Debug, Deserialize, Clone, Serialize)]
Expand Down
1 change: 1 addition & 0 deletions compiler/crates/relay-codegen/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub enum Primitive {
Int(i64),
Bool(bool),
Null,
Elide,
StorageKey(StringKey, AstKey),
RawString(String),
GraphQLModuleDependency(StringKey),
Expand Down
50 changes: 25 additions & 25 deletions compiler/crates/relay-codegen/src/build_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
&fragment.used_global_variables),
kind: Primitive::String(CODEGEN_CONSTANTS.fragment_value),
metadata: if skip_metadata {
Primitive::Null
Primitive::Elide
} else {
self.build_fragment_metadata(fragment)
},
Expand All @@ -203,7 +203,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
fragment.type_condition,
))
} else {
Primitive::Null
Primitive::Elide
},
};
self.object(object)
Expand Down Expand Up @@ -270,7 +270,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
};
Primitive::Key(self.object(connection_object))
} else {
Primitive::Null
Primitive::Elide
};
let mut refetch_object = object! {
connection: refetch_connection,
Expand Down Expand Up @@ -299,7 +299,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
})
}
if metadata.is_empty() {
Primitive::Null
Primitive::Elide
} else {
Primitive::Key(self.object(metadata))
}
Expand All @@ -313,7 +313,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
.iter()
.map(|metadata| {
let path = match &metadata.path {
None => Primitive::Null,
None => Primitive::Elide,
Some(path) => Primitive::Key(
self.array(path.iter().cloned().map(Primitive::String).collect()),
),
Expand Down Expand Up @@ -473,18 +473,18 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
let primitive = Primitive::Key(self.object(object! {
:build_alias(alias, name),
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
kind: kind,
name: Primitive::String(name),
storage_key: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => {
if is_static_storage_key_available(&field.arguments) {
Primitive::StorageKey(name, key)
} else {
Primitive::Null
Primitive::Elide
}
}
},
Expand All @@ -505,13 +505,13 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
for directive in handle_field_directives {
let values = extract_values_from_handle_field_directive(directive);
let filters = match values.filters {
None => Primitive::Null,
None => Primitive::Elide,
Some(strs) => {
Primitive::Key(self.array(strs.into_iter().map(Primitive::String).collect()))
}
};
let arguments = match self.build_arguments(&field.arguments) {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
};
let mut object = object! {
Expand Down Expand Up @@ -556,11 +556,11 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
let primitive = Primitive::Key(self.object(object! {
:build_alias(alias, name),
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
concrete_type: if schema_field.type_.inner().is_abstract_type() {
Primitive::Null
Primitive::Elide
} else {
Primitive::String(self.schema.get_type_name(schema_field.type_.inner()))
},
Expand All @@ -569,12 +569,12 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
plural: Primitive::Bool(schema_field.type_.is_list()),
selections: selections,
storage_key: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => {
if is_static_storage_key_available(&field.arguments) {
Primitive::StorageKey(name, key)
} else {
Primitive::Null
Primitive::Elide
}
}
},
Expand All @@ -599,15 +599,15 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
None => None,
};
let filters = match values.filters {
None => Primitive::Null,
None => Primitive::Elide,
Some(strings) => {
Primitive::Key(self.array(strings.into_iter().map(Primitive::String).collect()))
}
};
let mut object = object! {
:build_alias(field.alias.map(|a| a.item), field_name),
args: match self.build_arguments(&field.arguments) {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
filters: filters,
Expand Down Expand Up @@ -682,7 +682,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
let args = self.build_arguments(&frag_spread.arguments);
let primitive = Primitive::Key(self.object(object! {
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
kind: Primitive::String(CODEGEN_CONSTANTS.fragment_spread),
Expand Down Expand Up @@ -737,7 +737,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {

Primitive::Key(self.object(object! {
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
fragment: Primitive::GraphQLModuleDependency(frag_spread.fragment.item),
Expand Down Expand Up @@ -973,7 +973,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
type_condition,
))
} else {
Primitive::Null
Primitive::Elide
},
}))
}
Expand Down Expand Up @@ -1215,7 +1215,7 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
};
let selection = Primitive::Key(self.object(object! {
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
document_name: Primitive::String(module_metadata.key),
Expand Down Expand Up @@ -1424,17 +1424,17 @@ impl<'schema, 'builder> CodegenBuilder<'schema, 'builder> {
:build_alias(alias, name),
name: Primitive::String(name),
storage_key: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => {
if is_static_storage_key_available(&linked_field.arguments) {
Primitive::StorageKey(name, key)
} else {
Primitive::Null
Primitive::Elide
}
}
},
args: match args {
None => Primitive::Null,
None => Primitive::Elide,
Some(key) => Primitive::Key(key),
},
fragment_spread_property: Primitive::Key(fragment_spread_key),
Expand Down Expand Up @@ -1475,10 +1475,10 @@ fn value_contains_variable(value: &Value) -> bool {

fn build_alias(alias: Option<StringKey>, name: StringKey) -> ObjectEntry {
let alias = match alias {
None => Primitive::Null,
None => Primitive::Elide,
Some(alias) => {
if alias == name {
Primitive::Null
Primitive::Elide
} else {
Primitive::String(alias)
}
Expand Down
17 changes: 15 additions & 2 deletions compiler/crates/relay-codegen/src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ pub struct JSONPrinter<'b> {
eager_es_modules: bool,
js_module_format: JsModuleFormat,
top_level_statements: &'b mut TopLevelStatements,
elide: bool,
}

impl<'b> JSONPrinter<'b> {
Expand All @@ -207,6 +208,10 @@ impl<'b> JSONPrinter<'b> {
builder,
js_module_format: project_config.js_module_format,
eager_es_modules: project_config.typegen_config.eager_es_modules,
elide: project_config
.feature_flags
.enable_reduced_metadata
.is_fully_enabled(),
}
}

Expand Down Expand Up @@ -306,6 +311,10 @@ impl<'b> JSONPrinter<'b> {
let next_indent = indent + 1;
f.push('{');
for ObjectEntry { key, value } in object {
match value {
Primitive::Elide if self.elide => continue,
_ => (),
}
f.push('\n');
print_indentation(f, next_indent);
write!(f, "\"{}\": ", key).unwrap();
Expand Down Expand Up @@ -333,6 +342,10 @@ impl<'b> JSONPrinter<'b> {
f.push('[');
let next_indent = indent + 1;
for value in array {
match value {
Primitive::Elide if self.elide => continue,
_ => (),
}
f.push('\n');
print_indentation(f, next_indent);
self.print_primitive(f, value, next_indent, is_dedupe_var)
Expand All @@ -356,7 +369,7 @@ impl<'b> JSONPrinter<'b> {
is_dedupe_var: bool,
) -> FmtResult {
match primitive {
Primitive::Null => write!(f, "null"),
Primitive::Null | Primitive::Elide => write!(f, "null"),
Primitive::Bool(b) => write!(f, "{}", if *b { "true" } else { "false" }),
Primitive::RawString(str) => {
f.push('\"');
Expand Down Expand Up @@ -545,7 +558,7 @@ fn write_constant_value(f: &mut String, builder: &AstBuilder, value: &Primitive)
}
}
}
Primitive::Null => {
Primitive::Null | Primitive::Elide => {
f.push_str("null");
Ok(())
}
Expand Down
Loading

0 comments on commit 9de3226

Please sign in to comment.