Skip to content

Commit

Permalink
Use fully qualified paths in generated code
Browse files Browse the repository at this point in the history
If user code has a type alias (or custom type) called `Result` or
`Option` etc, this would be used instead of the intended standard
library types causing surprising compile errors from generated code.

Using the fully qualified path allows the generated code to be isolated
from user types.

Includes two basic regression tests covering `Result` and `Send`.

Fixes #1194
  • Loading branch information
tpoliaw committed Oct 4, 2023
1 parent 9849736 commit d3cd490
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 118 deletions.
10 changes: 5 additions & 5 deletions juniper_codegen/src/common/deprecation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ impl Directive {

impl ToTokens for Directive {
fn to_tokens(&self, into: &mut TokenStream) {
let reason = self
.reason
.as_ref()
.map_or_else(|| quote! { None }, |text| quote! { Some(#text) });
let reason = self.reason.as_ref().map_or_else(
|| quote! { ::core::option::Option::None },
|text| quote! { ::core::option::Option::Some(#text) },
);
quote! {
.deprecated(::std::option::Option::#reason)
.deprecated(#reason)
}
.to_tokens(into);
}
Expand Down
6 changes: 3 additions & 3 deletions juniper_codegen/src/common/field/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,13 @@ impl OnMethod {
::juniper::IntoFieldError::<#scalar>::into_field_error(e)
.map_message(|m| format!(#err_text, m))
})
}, Ok))
}, ::core::result::Result::Ok))
};
if for_async {
quote! {
match #arg {
Ok(v) => v,
Err(e) => return Box::pin(async { Err(e) }),
::core::result::Result::Ok(v) => v,
::core::result::Result::Err(e) => return ::std::boxed::Box::pin(async { ::core::result::Result::Err(e) }),
}
}
} else {
Expand Down
10 changes: 5 additions & 5 deletions juniper_codegen/src/common/field/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl Definition {
ty_name: &str,
) -> TokenStream {
quote! {
return Err(::juniper::FieldError::from(::std::format!(
return ::core::result::Result::Err(::juniper::FieldError::from(::std::format!(
"Field `{}` not found on type `{}`",
field,
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
Expand Down Expand Up @@ -354,18 +354,18 @@ impl Definition {
async move {
let ex = executor.as_executor();
match res2 {
Ok(Some((ctx, r))) => {
::core::result::Result::Ok(::core::option::Option::Some((ctx, r))) => {
let sub = ex.replaced_context(ctx);
sub.resolve_with_ctx_async(&(), &r)
.await
.map_err(|e| ex.new_error(e))
}
Ok(None) => Ok(::juniper::Value::null()),
Err(e) => Err(ex.new_error(e)),
::core::result::Result::Ok(::core::option::Option::None) => ::core::result::Result::Ok(::juniper::Value::null()),
::core::result::Result::Err(e) => ::core::result::Result::Err(ex.new_error(e)),
}
}
});
Ok(::juniper::Value::Scalar::<
::core::result::Result::Ok(::juniper::Value::Scalar::<
::juniper::ValuesStream::<#scalar>
>(::juniper::futures::StreamExt::boxed(stream)))
})
Expand Down
10 changes: 5 additions & 5 deletions juniper_codegen/src/common/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub(crate) fn sync_resolving_code() -> TokenStream {
quote! {
::juniper::IntoResolvable::into_resolvable(res, executor.context())
.and_then(|res| match res {
Some((ctx, r)) => executor.replaced_context(ctx).resolve_with_ctx(info, &r),
None => Ok(::juniper::Value::null()),
::core::option::Option::Some((ctx, r)) => executor.replaced_context(ctx).resolve_with_ctx(info, &r),
::core::option::Option::None => ::core::result::Result::Ok(::juniper::Value::null()),
})
}
}
Expand All @@ -34,13 +34,13 @@ pub(crate) fn async_resolving_code(ty: Option<&syn::Type>) -> TokenStream {
let ty = ty.map(|t| quote! { : #t });

quote! {
Box::pin(::juniper::futures::FutureExt::then(fut, move |res #ty| async move {
::std::boxed::Box::pin(::juniper::futures::FutureExt::then(fut, move |res #ty| async move {
match ::juniper::IntoResolvable::into_resolvable(res, executor.context())? {
Some((ctx, r)) => {
::core::option::Option::Some((ctx, r)) => {
let subexec = executor.replaced_context(ctx);
subexec.resolve_with_ctx_async(info, &r).await
},
None => Ok(::juniper::Value::null()),
::core::option::Option::None => ::core::result::Result::Ok(::juniper::Value::null()),
}
}))
}
Expand Down
30 changes: 15 additions & 15 deletions juniper_codegen/src/graphql_enum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ impl Definition {
for #ident #ty_generics
#where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}

fn meta<'r>(
Expand Down Expand Up @@ -489,13 +489,13 @@ impl Definition {
let name = &v.name;

quote! {
Self::#ident => Ok(::juniper::Value::scalar(String::from(#name))),
Self::#ident => ::core::result::Result::Ok(::juniper::Value::scalar(::std::string::String::from(#name))),
}
});

let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => Err(::juniper::FieldError::<#scalar>::from(
_ => ::core::result::Result::Err(::juniper::FieldError::<#scalar>::from(
"Cannot resolve ignored enum variant",
)),
}
Expand All @@ -509,14 +509,14 @@ impl Definition {
type Context = #context;
type TypeInfo = ();

fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}

fn resolve(
&self,
_: &(),
_: Option<&[::juniper::Selection<#scalar>]>,
_: ::core::option::Option<&[::juniper::Selection<#scalar>]>,
_: &::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
match self {
Expand Down Expand Up @@ -549,11 +549,11 @@ impl Definition {
fn resolve_async<'__a>(
&'__a self,
info: &'__a Self::TypeInfo,
selection_set: Option<&'__a [::juniper::Selection<#scalar>]>,
selection_set: ::core::option::Option<&'__a [::juniper::Selection<#scalar>]>,
executor: &'__a ::juniper::Executor<Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'__a, ::juniper::ExecutionResult<#scalar>> {
let v = ::juniper::GraphQLValue::resolve(self, info, selection_set, executor);
Box::pin(::juniper::futures::future::ready(v))
::std::boxed::Box::pin(::juniper::futures::future::ready(v))
}
}
}
Expand All @@ -577,7 +577,7 @@ impl Definition {
let name = &v.name;

quote! {
Some(#name) => Ok(Self::#ident),
::core::option::Option::Some(#name) => ::core::result::Result::Ok(Self::#ident),
}
});

Expand All @@ -588,10 +588,10 @@ impl Definition {
{
type Error = ::std::string::String;

fn from_input_value(v: &::juniper::InputValue<#scalar>) -> Result<Self, Self::Error> {
fn from_input_value(v: &::juniper::InputValue<#scalar>) -> ::core::result::Result<Self, Self::Error> {
match v.as_enum_value().or_else(|| v.as_string_value()) {
#( #variants )*
_ => Err(::std::format!("Unknown enum value: {}", v)),
_ => ::core::result::Result::Err(::std::format!("Unknown enum value: {}", v)),
}
}
}
Expand All @@ -617,14 +617,14 @@ impl Definition {

quote! {
#ident::#var_ident => ::juniper::InputValue::<#scalar>::scalar(
String::from(#name),
::std::string::String::from(#name),
),
}
});

let ignored = self.has_ignored_variants.then(|| {
quote! {
_ => panic!("Cannot resolve ignored enum variant"),
_ => ::core::panic!("Cannot resolve ignored enum variant"),
}
});

Expand Down Expand Up @@ -730,13 +730,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });

if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

Expand Down
18 changes: 9 additions & 9 deletions juniper_codegen/src/graphql_input_object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,8 @@ impl Definition {
for #ident #ty_generics
#where_clause
{
fn name(_: &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_: &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::core::option::Option::Some(#name)
}

fn meta<'r>(
Expand Down Expand Up @@ -524,7 +524,7 @@ impl Definition {
type Context = #context;
type TypeInfo = ();

fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> ::core::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}
}
Expand Down Expand Up @@ -594,11 +594,11 @@ impl Definition {

quote! {
match obj.get(#name) {
Some(v) => {
::core::option::Option::Some(v) => {
::juniper::FromInputValue::<#scalar>::from_input_value(v)
.map_err(::juniper::IntoFieldError::into_field_error)?
}
None => { #fallback }
::core::option::Option::None => { #fallback }
}
}
};
Expand All @@ -616,14 +616,14 @@ impl Definition {

fn from_input_value(
value: &::juniper::InputValue<#scalar>,
) -> Result<Self, Self::Error> {
) -> ::core::result::Result<Self, Self::Error> {
let obj = value
.to_object_value()
.ok_or_else(|| ::juniper::FieldError::<#scalar>::from(
::std::format!("Expected input object, found: {}", value))
)?;

Ok(#ident {
::core::result::Result::Ok(#ident {
#( #fields )*
})
}
Expand Down Expand Up @@ -763,13 +763,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });

if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

Expand Down
36 changes: 18 additions & 18 deletions juniper_codegen/src/graphql_interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ impl Definition {
syn::GenericParam::Const(_) => return None,
};
Some(quote! {
::std::marker::PhantomData<::std::sync::atomic::AtomicPtr<Box<#ty>>>
::core::marker::PhantomData<::std::sync::atomic::AtomicPtr<std::boxed::Box<#ty>>>
})
});
quote! { __Phantom(#(#phantom_params),*) }
Expand All @@ -487,7 +487,7 @@ impl Definition {

quote! {
#[automatically_derived]
#[derive(Clone, Copy, Debug)]
#[derive(::std::clone::Clone, ::core::marker::Copy, ::std::fmt::Debug)]
#[doc = #enum_doc]
#vis enum #enum_ident #enum_gens {
#( #[doc(hidden)] #variants_idents(#variant_gens_pars), )*
Expand Down Expand Up @@ -523,12 +523,12 @@ impl Definition {

quote! {{
const SUPPRESS_DEAD_CODE: () = {
let none = Option::<#ident #const_gens>::None;
let none = ::core::option::Option::<#ident #const_gens>::None;
match none {
Some(unreachable) => {
::core::option::Option::Some(unreachable) => {
#( let _ = unreachable.#fields; )*
}
None => {}
::core::option::Option::None => {}
}
};
let _ = SUPPRESS_DEAD_CODE;
Expand Down Expand Up @@ -715,8 +715,8 @@ impl Definition {
for #ty #ty_generics
#where_clause
{
fn name(_ : &Self::TypeInfo) -> Option<&'static str> {
Some(#name)
fn name(_ : &Self::TypeInfo) -> ::core::option::Option<&'static ::core::primitive::str> {
::std::option::Option::Some(#name)
}

fn meta<'r>(
Expand Down Expand Up @@ -784,14 +784,14 @@ impl Definition {
type Context = #context;
type TypeInfo = ();

fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> Option<&'__i str> {
fn type_name<'__i>(&self, info: &'__i Self::TypeInfo) -> std::option::Option<&'__i ::core::primitive::str> {
<Self as ::juniper::GraphQLType<#scalar>>::name(info)
}

fn resolve_field(
&self,
info: &Self::TypeInfo,
field: &str,
field: &::core::primitive::str,
args: &::juniper::Arguments<'_, #scalar>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
Expand All @@ -805,15 +805,15 @@ impl Definition {
&self,
context: &Self::Context,
info: &Self::TypeInfo,
) -> String {
) -> ::std::string::String {
#downcast_check
}

fn resolve_into_type(
&self,
info: &Self::TypeInfo,
type_name: &str,
_: Option<&[::juniper::Selection<'_, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&[::juniper::Selection<'_, #scalar>]>,
executor: &::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::ExecutionResult<#scalar> {
#downcast
Expand Down Expand Up @@ -862,21 +862,21 @@ impl Definition {
fn resolve_field_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
field: &'b str,
field: &'b ::core::primitive::str,
args: &'b ::juniper::Arguments<'_, #scalar>,
executor: &'b ::juniper::Executor<'_, '_, Self::Context, #scalar>,
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
match field {
#( #fields_resolvers )*
_ => Box::pin(async move { #no_field_err }),
_ => ::std::boxed::Box::pin(async move { #no_field_err }),
}
}

fn resolve_into_type_async<'b>(
&'b self,
info: &'b Self::TypeInfo,
type_name: &str,
_: Option<&'b [::juniper::Selection<'b, #scalar>]>,
type_name: &::core::primitive::str,
_: ::core::option::Option<&'b [::juniper::Selection<'b, #scalar>]>,
executor: &'b ::juniper::Executor<'b, 'b, Self::Context, #scalar>
) -> ::juniper::BoxFuture<'b, ::juniper::ExecutionResult<#scalar>> {
#downcast
Expand Down Expand Up @@ -1360,13 +1360,13 @@ impl Definition {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #self_ty: Sync });
.push(parse_quote! { #self_ty: ::core::marker::Sync });

if scalar.is_generic() {
generics
.make_where_clause()
.predicates
.push(parse_quote! { #scalar: Send + Sync });
.push(parse_quote! { #scalar: ::core::marker::Send + ::core::marker::Sync });
}
}

Expand Down
Loading

0 comments on commit d3cd490

Please sign in to comment.