Skip to content

Commit

Permalink
create intern! macro
Browse files Browse the repository at this point in the history
Reviewed By: josephsavona

Differential Revision: D29374989

fbshipit-source-id: 2f343c036098ec52c92fd3aba0228eaf1ae683b9
  • Loading branch information
kassens authored and facebook-github-bot committed Jun 25, 2021
1 parent 8d1a6da commit efab553
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 14 deletions.
1 change: 1 addition & 0 deletions compiler/crates/interner/Cargo.toml
Expand Up @@ -9,5 +9,6 @@ license = "MIT"
[dependencies]
fnv = "1.0"
lazy_static = "1.0"
once_cell = "1.4"
parking_lot = "0.10.2"
serde = { version = "1.0.126", features = ["derive", "rc"] }
5 changes: 5 additions & 0 deletions compiler/crates/interner/src/lib.rs
Expand Up @@ -19,3 +19,8 @@ mod types;
pub use bytes::{BytesKey, StringKey};
pub use generic::InternTable;
pub use types::{Intern, InternKey, RawInternKey};

/// Re-exported values to be used by the `intern!` macro.
pub mod reexport {
pub use once_cell::sync::Lazy;
}
20 changes: 19 additions & 1 deletion compiler/crates/interner/src/macros.rs
Expand Up @@ -5,6 +5,24 @@
* LICENSE file in the root directory of this source tree.
*/

/// Interns the passed string literal and memoizes the result in a static
/// variable. This can be used in performance sensitive code.
/// ```
/// use interner::intern;
/// assert_eq!(intern!("example").lookup(), "example");
/// ```
#[macro_export]
macro_rules! intern {
($value:literal) => {{
use $crate::{reexport::Lazy, Intern, StringKey};
static KEY: Lazy<StringKey> = Lazy::new(|| Intern::intern($value));
*KEY
}};
($_:expr) => {
compile_error!("intern! macro can only be used with string literals.")
};
}

/// Macro to implement an interner for an arbitrary type.
/// Given `intern!(<Foo> as <FooKey>);`, this macro will implement the
/// `Intern` trait for `<Foo>`, interning it a generated `<FooKey>` wrapper
Expand All @@ -26,7 +44,7 @@
/// ```
///
#[macro_export]
macro_rules! intern {
macro_rules! make_intern {
($name:ident as $alias:ident) => {
use crate::{Intern, InternKey, InternTable, RawInternKey};
use lazy_static::lazy_static;
Expand Down
2 changes: 1 addition & 1 deletion compiler/crates/interner/src/tests.rs
Expand Up @@ -41,7 +41,7 @@ fn test_custom_intern() {
name: String,
}

intern!(User as UserKey);
make_intern!(User as UserKey);

let key: UserKey = User {
name: "Joe".to_owned(),
Expand Down
3 changes: 2 additions & 1 deletion compiler/crates/interner/src/types.rs
Expand Up @@ -21,7 +21,8 @@ pub trait Intern: Eq + Hash + Clone {
pub struct RawInternKey(NonZeroU32);

impl RawInternKey {
pub(crate) fn new(value: NonZeroU32) -> Self {
#[inline(always)]
pub(crate) const fn new(value: NonZeroU32) -> Self {
Self(value)
}

Expand Down
1 change: 0 additions & 1 deletion compiler/crates/relay-schema/Cargo.toml
Expand Up @@ -9,5 +9,4 @@ license = "MIT"
[dependencies]
common = { path = "../common" }
interner = { path = "../interner" }
lazy_static = "1.0"
schema = { path = "../schema" }
13 changes: 3 additions & 10 deletions compiler/crates/relay-schema/src/lib.rs
Expand Up @@ -12,19 +12,12 @@
#![deny(clippy::all)]

use common::DiagnosticsResult;
use interner::{Intern, StringKey};
use lazy_static::lazy_static;
use interner::intern;
use schema::{ArgumentDefinitions, SDLSchema, TypeReference};
use std::iter::once;

const RELAY_EXTENSIONS: &str = include_str!("./relay-extensions.graphql");

lazy_static! {
static ref DEFER_DIRECTIVE: StringKey = "defer".intern();
static ref STREAM_DIRECTIVE: StringKey = "stream".intern();
static ref LABEL_ARG: StringKey = "label".intern();
}

pub fn build_schema_with_extensions<T: AsRef<str>, U: AsRef<str>>(
server_sdls: &[T],
extension_sdls: &[U],
Expand All @@ -36,11 +29,11 @@ pub fn build_schema_with_extensions<T: AsRef<str>, U: AsRef<str>>(

// Remove label arg from @defer and @stream directives since the compiler
// adds these arguments.
for directive_name in &[*DEFER_DIRECTIVE, *STREAM_DIRECTIVE] {
for directive_name in &[intern!("defer"), intern!("stream")] {
if let Some(directive) = schema.get_directive_mut(*directive_name) {
let mut next_args: Vec<_> = directive.arguments.iter().cloned().collect();
for arg in next_args.iter_mut() {
if arg.name == *LABEL_ARG {
if arg.name == intern!("label") {
if let TypeReference::NonNull(of) = &arg.type_ {
arg.type_ = *of.clone()
};
Expand Down

0 comments on commit efab553

Please sign in to comment.