Skip to content

Commit

Permalink
SchemaPrinter cleanup (#1423)
Browse files Browse the repository at this point in the history
  • Loading branch information
sungam3r committed Feb 21, 2021
1 parent c277b10 commit ad980bd
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 72 deletions.
2 changes: 2 additions & 0 deletions docs2/site/docs/migrations/migration4.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ lock (field)
* `ApolloTracing.ConvertTime` is now private and `ResolverTrace.Path` does not initialize an empty list when created.
* `SchemaBuilder.RegisterType` and `SchemaBuilder.RegisterTypes` methods have been removed, use `ISchema.RegisterType` on the builded schema instead.
* `SchemaBuilder.Directives` and `SchemaBuilder.RegisterDirectiveVisitor` have been removed, use `ISchema.RegisterVisitor` on the builded schema instead.
* `SchemaPrinter.IsBuiltInScalar`, `SchemaPrinter.IsSpecDirective`, `SchemaPrinter.IsIntrospectionType`, `SchemaPrinter.IsDefinedType` methods have been removed from public API
* `SchemaPrinterOptions.CustomScalars` property has been removed

### Other Breaking Changes (including but not limited to)

Expand Down
10 changes: 5 additions & 5 deletions src/GraphQL.ApiTests/GraphQL.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2586,11 +2586,9 @@ namespace GraphQL.Utilities
public string[] BreakLine(string line, int len) { }
public string FormatDefaultValue(object value, GraphQL.Types.IGraphType graphType) { }
protected string FormatDescription(string description, string indentation = "") { }
public bool IsBuiltInScalar(string typeName) { }
public virtual bool IsDefinedType(string typeName) { }
public bool IsIntrospectionType(string typeName) { }
protected virtual bool IsDefinedDirective(string directiveName) { }
protected virtual bool IsDefinedType(string typeName) { }
public bool IsSchemaOfCommonNames(GraphQL.Types.ISchema schema) { }
public bool IsSpecDirective(string directiveName) { }
public string Print() { }
public string PrintArgs(GraphQL.Types.FieldType field) { }
public string PrintDeprecation(string reason) { }
Expand All @@ -2609,12 +2607,14 @@ namespace GraphQL.Utilities
public string PrintSchemaDefinition(GraphQL.Types.ISchema schema) { }
public string PrintType(GraphQL.Types.IGraphType type) { }
public string PrintUnion(GraphQL.Types.UnionGraphType type) { }
protected static bool IsBuiltInDirective(string directiveName) { }
protected static bool IsBuiltInScalar(string typeName) { }
protected static bool IsIntrospectionType(string typeName) { }
public static string ResolveName(GraphQL.Types.IGraphType type) { }
}
public class SchemaPrinterOptions
{
public SchemaPrinterOptions() { }
public System.Collections.Generic.List<string> CustomScalars { get; set; }
public bool IncludeDeprecationReasons { get; set; }
public bool IncludeDescriptions { get; set; }
public bool OldImplementsSyntax { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL/GraphQLExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class GraphQLExtensions
/// <summary>
/// Determines if this graph type is an introspection type.
/// </summary>
internal static bool IsIntrospectionType(this IGraphType type) => type?.Name?.StartsWith("__") ?? false;
internal static bool IsIntrospectionType(this IGraphType type) => type?.Name?.StartsWith("__", StringComparison.InvariantCulture) ?? false;

/// <summary>
/// Indicates if the graph type is a union, interface or object graph type.
Expand Down
3 changes: 1 addition & 2 deletions src/GraphQL/Utilities/Federation/FederatedSchemaPrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace GraphQL.Utilities.Federation
{
public class FederatedSchemaPrinter : SchemaPrinter
{

private readonly List<string> _federatedDirectives = new List<string>
{
"external",
Expand Down Expand Up @@ -98,7 +97,7 @@ public override string PrintFields(IComplexGraphType type)
public string PrintFederatedSchema()
{
return PrintFilteredSchema(
directiveName => !IsSpecDirective(directiveName) && !IsFederatedDirective(directiveName),
directiveName => !IsBuiltInDirective(directiveName) && !IsFederatedDirective(directiveName),
typeName => !IsFederatedType(typeName) && IsDefinedType(typeName));
}

Expand Down
122 changes: 65 additions & 57 deletions src/GraphQL/Utilities/SchemaPrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,70 @@

namespace GraphQL.Utilities
{
/// <summary>
/// Enables printing schema as SDL (Schema Definition Language) document.
/// <br/>
/// See <see href="http://spec.graphql.org/June2018/#sec-Type-System"/> for more information.
/// </summary>
public class SchemaPrinter //TODO: rewrite string concatenations to use buffer ?
{
protected SchemaPrinterOptions Options { get; }

private readonly List<string> _scalars = new List<string>(
new[]
{
"String",
"Boolean",
"Int",
"Float",
"ID"
});

public SchemaPrinter(
ISchema schema,
SchemaPrinterOptions options = null)
private static readonly List<string> _builtInScalars = new List<string>
{
"String",
"Boolean",
"Int",
"Float",
"ID"
};

private static readonly List<string> _builtInDirectives = new List<string>
{
"skip",
"include",
"deprecated"
};

/// <summary>
/// Creates printer with the specified options.
/// </summary>
/// <param name="schema">Schema to print.</param>
/// <param name="options">Printer options.</param>
public SchemaPrinter(ISchema schema, SchemaPrinterOptions options = null)
{
Schema = schema;
Options = options ?? new SchemaPrinterOptions();

if (Options.CustomScalars?.Count > 0)
{
_scalars.AddRange(Options.CustomScalars);
}
}

private ISchema Schema { get; set; }
protected static bool IsIntrospectionType(string typeName) => typeName.StartsWith("__", StringComparison.InvariantCulture);

public string Print()
{
return PrintFilteredSchema(n => !IsSpecDirective(n), IsDefinedType);
}
protected static bool IsBuiltInScalar(string typeName) => _builtInScalars.Contains(typeName);

public string PrintIntrospectionSchema()
{
return PrintFilteredSchema(IsSpecDirective, IsIntrospectionType);
}
protected static bool IsBuiltInDirective(string directiveName) => _builtInDirectives.Contains(directiveName);

private ISchema Schema { get; set; }

protected SchemaPrinterOptions Options { get; }

/// <summary>
/// Prints only 'defined' types and directives.
/// <br/>
/// See <see cref="IsDefinedType(string)"/> and <see cref="IsDefinedDirective(string)"/> for more information about what 'defined' means.
/// </summary>
/// <returns>SDL document.</returns>
public string Print() => PrintFilteredSchema(IsDefinedDirective, IsDefinedType);

/// <summary>
/// Prints only introspection types.
/// </summary>
/// <returns>SDL document.</returns>
public string PrintIntrospectionSchema() => PrintFilteredSchema(IsBuiltInDirective, IsIntrospectionType);

/// <summary>
/// Prints schema according to the specified filters.
/// </summary>
/// <param name="directiveFilter">Filter for directives.</param>
/// <param name="typeFilter">Filter for types.</param>
/// <returns>SDL document.</returns>
public string PrintFilteredSchema(Func<string, bool> directiveFilter, Func<string, bool> typeFilter)
{
Schema.Initialize();
Expand All @@ -72,31 +97,17 @@ public string PrintFilteredSchema(Func<string, bool> directiveFilter, Func<strin
return string.Join(Environment.NewLine + Environment.NewLine, result) + Environment.NewLine;
}

public virtual bool IsDefinedType(string typeName)
{
return !IsIntrospectionType(typeName) && !IsBuiltInScalar(typeName);
}

public bool IsIntrospectionType(string typeName)
{
return typeName.StartsWith("__", StringComparison.InvariantCulture);
}
/// <summary>
/// Determines that the specified directive is defined in the schema and should be printed.
/// By default, all directives are defined (printed) except for built-in directives.
/// </summary>
protected virtual bool IsDefinedDirective(string directiveName) => !IsBuiltInDirective(directiveName);

public bool IsBuiltInScalar(string typeName)
{
return _scalars.Contains(typeName);
}

public bool IsSpecDirective(string directiveName)
{
var names = new[]
{
"skip",
"include",
"deprecated"
};
return names.Contains(directiveName);
}
/// <summary>
/// Determines that the specified type is defined in the schema and should be printed.
/// By default, all types are defined (printed) except for introspection types and built-in scalars.
/// </summary>
protected virtual bool IsDefinedType(string typeName) => !IsIntrospectionType(typeName) && !IsBuiltInScalar(typeName);

public string PrintSchemaDefinition(ISchema schema)
{
Expand Down Expand Up @@ -263,10 +274,7 @@ public string PrintInputValue(QueryArgument argument)
public string PrintDirective(DirectiveGraphType directive)
{
var builder = new StringBuilder();
if (Options.IncludeDescriptions)
{
builder.Append(PrintDescription(directive.Description));
}
builder.Append(FormatDescription(directive.Description));
builder.AppendLine($"directive @{directive.Name}(");
builder.AppendLine(FormatDirectiveArguments(directive.Arguments));
builder.Append($") on {FormatDirectiveLocationList(directive.Locations)}");
Expand Down
22 changes: 15 additions & 7 deletions src/GraphQL/Utilities/SchemaPrinterOptions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
using System.Collections.Generic;

namespace GraphQL.Utilities
{
/// <summary>
/// Options for schema printing when using <see cref="SchemaPrinter.Print"/>.
/// </summary>
public class SchemaPrinterOptions
{
public List<string> CustomScalars { get; set; } = new List<string>();

public bool IncludeDescriptions { get; set; } = false;
/// <summary>
/// Indicates whether to print a description for types, fields, directives, arguments and other schema elements.
/// </summary>
public bool IncludeDescriptions { get; set; }

public bool IncludeDeprecationReasons { get; set; } = false;
/// <summary>
/// Indicates whether to print a deprecation reason for fields and enum values.
/// </summary>
public bool IncludeDeprecationReasons { get; set; }

public bool OldImplementsSyntax { get; set; } = false;
/// <summary>
/// Indicates whether to use ',' instead of '&amp;' when inheriting a type from multiple interfaces.
/// </summary>
public bool OldImplementsSyntax { get; set; }
}
}

0 comments on commit ad980bd

Please sign in to comment.