Closed jenschude closed 1 year ago
Checkout v5.0.0-preview.1 Now it will add a suffix to the class name in this case.
Thanks for the fast reply. It's not working completely. Generated code with the above schema produces this snippet:
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class Limit_ZeroQL
{
[ZeroQL.GraphQLFieldSelector("limit")]
[JsonPropertyName("limit")]
public long? Limit { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class Query : global::ZeroQL.Internal.IQuery
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("perVariant")]
public Limit __PerVariant { get; set; }
[ZeroQL.GraphQLFieldSelector("perVariant")]
public T PerVariant<T>(Func<Limit, T> selector = default !)
{
return __PerVariant is null ? throw new NullReferenceException("PerVariant is null but it should not be null. Schema can be outdated.") : selector(__PerVariant);
}
}
The __PerVariant
property references the wrong type. Maybe it makes sense to just suffix every generated type with something like Model
or Type
so you can easily generate the type name without looking it up or evaluating first.
My bad. The v5.0.0-preview.2 should definitely work.
Found a new edge case when referencing the type multiple times. The above schema was trying to reproduce it with minimum nesting. Rerun with our schema and still not all occurences have been replaced. An updated reproducer schema:
schema {
query: Query
}
type Query {
limits: ProjectCustomLimitsProjection!
}
type CategoryLimitsProjection {
maxCategories: Limit!
}
type ProjectCustomLimitsProjection {
products: ProductLimitsProjection!
category: CategoryLimitsProjection!
}
type ProductLimitsProjection {
pricesPerVariant: Limit!
variants: Limit!
}
type Limit {
limit: Long
}
The generated source:
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class CategoryLimitsProjection
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("maxCategories")]
public Limit __MaxCategories { get; set; }
[ZeroQL.GraphQLFieldSelector("maxCategories")]
public T MaxCategories<T>(Func<Limit, T> selector = default !)
{
return __MaxCategories is null ? throw new NullReferenceException("MaxCategories is null but it should not be null. Schema can be outdated.") : selector(__MaxCategories);
}
}
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class Limit_ReplacementType
{
[ZeroQL.GraphQLFieldSelector("limit")]
[JsonPropertyName("limit")]
public long? Limit { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class ProductLimitsProjection
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("pricesPerVariant")]
public Limit_ReplacementType __PricesPerVariant { get; set; }
[ZeroQL.GraphQLFieldSelector("pricesPerVariant")]
public T PricesPerVariant<T>(Func<Limit_ReplacementType, T> selector = default !)
{
return __PricesPerVariant is null ? throw new NullReferenceException("PricesPerVariant is null but it should not be null. Schema can be outdated.") : selector(__PricesPerVariant);
}
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("variants")]
public Limit_ReplacementType __Variants { get; set; }
[ZeroQL.GraphQLFieldSelector("variants")]
public T Variants<T>(Func<Limit_ReplacementType, T> selector = default !)
{
return __Variants is null ? throw new NullReferenceException("Variants is null but it should not be null. Schema can be outdated.") : selector(__Variants);
}
}
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class ProjectCustomLimitsProjection
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("products")]
public ProductLimitsProjection __Products { get; set; }
[ZeroQL.GraphQLFieldSelector("products")]
public T Products<T>(Func<ProductLimitsProjection, T> selector = default !)
{
return __Products is null ? throw new NullReferenceException("Products is null but it should not be null. Schema can be outdated.") : selector(__Products);
}
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("category")]
public CategoryLimitsProjection __Category { get; set; }
[ZeroQL.GraphQLFieldSelector("category")]
public T Category<T>(Func<CategoryLimitsProjection, T> selector = default !)
{
return __Category is null ? throw new NullReferenceException("Category is null but it should not be null. Schema can be outdated.") : selector(__Category);
}
}
[System.CodeDom.Compiler.GeneratedCode ( "ZeroQL" , "5.0.0.0" )]
public class Query : global::ZeroQL.Internal.IQuery
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("limits")]
public ProjectCustomLimitsProjection __Limits { get; set; }
[ZeroQL.GraphQLFieldSelector("limits")]
public T Limits<T>(Func<ProjectCustomLimitsProjection, T> selector = default !)
{
return __Limits is null ? throw new NullReferenceException("Limits is null but it should not be null. Schema can be outdated.") : selector(__Limits);
}
}
Just saw that you released a new preview. Really appreciate it. Directly ran it against our schema again and found the next issue with the suffixes when such a clashing type is used in a List.
schema {
query: Query
}
type Query {
limits: ProjectCustomLimitsProjection!
searchKeywords: [SearchKeywords!]!
}
type SearchKeywords {
locale: Locale!
searchKeywords: [SearchKeyword!]!
}
type SearchKeyword {
text: String!
}
type CategoryLimitsProjection {
maxCategories: Limit!
}
type ProjectCustomLimitsProjection {
products: ProductLimitsProjection!
category: CategoryLimitsProjection!
}
type ProductLimitsProjection {
pricesPerVariant: Limit!
variants: Limit!
}
type Limit {
limit: Long
}
The relevant part here in the generated client code:
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never), JsonPropertyName("searchKeywords")]
public SearchKeywords[] __SearchKeywords { get; set; }
[ZeroQL.GraphQLFieldSelector("searchKeywords")]
public T[] SearchKeywords<T>(Func<SearchKeywordsZeroQL, T> selector = default !)
{
return __SearchKeywords is null ? throw new NullReferenceException("SearchKeywords is null but it should not be null. Schema can be outdated.") : __SearchKeywords.Select(o => o is null ? throw new NullReferenceException("SearchKeywords is null but it should not be null. Schema can be outdated.") : selector(o)).ToArray();
}
Checkout v5.0.0-preview.4
🥳
It works now! Appreciating the effort.
Now I have to figure out what kind of interface incompatibility is in our schema.
Describe the bug
The generated schema stumbles across properties which have the same name as the type itself
How to Reproduce
As it's not allowed to have Members with the same name as the class in CSharp:
[CS0542] 'Limit': member names cannot be the same as their enclosing type
Expected behavior
The class or member may be pre-/suffixed to avoid these name clashes and be able to generate a compiling client