Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added initial structure for Fusion vNext Composition #7807

Merged
merged 14 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ Rgba
Rhai
Roslynator
runbooks
Satisfiability
Senn
shoooe
Skywalker
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<PackageVersion Include="System.Reactive" Version="6.0.0" />
<PackageVersion Include="Xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="TUnit" Version="0.3.34" />
<PackageVersion Include="TUnit" Version="0.4.71" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Immutable;
using HotChocolate.Fusion.Logging.Contracts;
using HotChocolate.Skimmed;

namespace HotChocolate.Fusion;

internal sealed class CompositionContext(
ImmutableArray<SchemaDefinition> schemaDefinitions,
ICompositionLog compositionLog)
{
/// <summary>
/// Gets the schema definitions.
/// </summary>
public ImmutableArray<SchemaDefinition> SchemaDefinitions { get; } = schemaDefinitions;

/// <summary>
/// Gets the composition log.
/// </summary>
public ICompositionLog Log { get; } = compositionLog;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace HotChocolate.Fusion.Errors;

public sealed class CompositionError(string message)
{
public string Message { get; } = message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using HotChocolate.Fusion.PreMergeValidation.Contracts;
using static HotChocolate.Fusion.Properties.CompositionResources;

namespace HotChocolate.Fusion.Errors;

internal static class ErrorHelper
{
public static CompositionError PreMergeValidationRuleFailed(IPreMergeValidationRule rule)
=> new(string.Format(ErrorHelper_PreMergeValidationRuleFailed, rule.GetType().Name));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using HotChocolate.Skimmed;

namespace HotChocolate.Fusion.Extensions;

internal static class TypeDefinitionExtensions
{
public static ITypeDefinition InnerNullableType(this ITypeDefinition type)
{
return type switch
{
ListTypeDefinition listType => listType.ElementType.NullableType(),
NonNullTypeDefinition nonNullType => nonNullType.NullableType,
_ => type
};
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>HotChocolate.Fusion.Composition</AssemblyName>
<RootNamespace>HotChocolate.Fusion</RootNamespace>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="HotChocolate.Fusion.Composition.Tests" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Skimmed\src\Skimmed\Skimmed.csproj" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\CompositionResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>CompositionResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\CompositionResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>CompositionResources.resx</DependentUpon>
</Compile>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Collections;
using HotChocolate.Fusion.Logging.Contracts;

namespace HotChocolate.Fusion.Logging;

public sealed class CompositionLog : ICompositionLog, IEnumerable<LogEntry>
{
public bool IsEmpty => _entries.Count == 0;

private readonly List<LogEntry> _entries = [];

public void Write(LogEntry entry)
{
ArgumentNullException.ThrowIfNull(entry);

_entries.Add(entry);
}

public ILoggingSession CreateSession()
{
return new LoggingSession(this);
}

public IEnumerator<LogEntry> GetEnumerator() => _entries.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace HotChocolate.Fusion.Logging.Contracts;

/// <summary>
/// Defines an interface for logging composition information, warnings, and errors.
/// </summary>
public interface ICompositionLog
{
bool IsEmpty { get; }

/// <summary>
/// Writes the specified <see cref="LogEntry"/> to the log.
/// </summary>
/// <param name="entry">The <see cref="LogEntry"/> to write.</param>
void Write(LogEntry entry);

/// <summary>
/// Creates a new logging session that keeps track of the number of info, warning, and error
/// entries logged.
/// </summary>
ILoggingSession CreateSession();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace HotChocolate.Fusion.Logging.Contracts;

public interface ILoggingSession
{
int InfoCount { get; }

int WarningCount { get; }

int ErrorCount { get; }

void Write(LogEntry entry);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using HotChocolate.Skimmed;

namespace HotChocolate.Fusion.Logging;

/// <summary>
/// Represents an entry in a composition log that describes an issue encountered during the
/// composition process.
/// </summary>
public sealed record LogEntry
{
/// <summary>
/// Initializes a new instance of the <see cref="LogEntry"/> record with the specified values.
/// </summary>
public LogEntry(
string message,
string code,
LogSeverity severity = LogSeverity.Error,
SchemaCoordinate? coordinate = null,
ITypeSystemMemberDefinition? member = null,
SchemaDefinition? schema = null,
object? extension = null)
{
ArgumentNullException.ThrowIfNull(message);
ArgumentNullException.ThrowIfNull(code);

Message = message;
glen-84 marked this conversation as resolved.
Show resolved Hide resolved
Code = code;
Severity = severity;
Coordinate = coordinate;
Member = member;
Schema = schema;
Extension = extension;
}

/// <summary>
/// Gets the message associated with this log entry.
/// </summary>
public string Message { get; }

/// <summary>
/// Gets the code associated with this log entry.
/// </summary>
public string Code { get; }

/// <summary>
/// Gets the severity of this log entry.
/// </summary>
public LogSeverity Severity { get; }

/// <summary>
/// Gets the schema coordinate associated with this log entry.
/// </summary>
public SchemaCoordinate? Coordinate { get; }

/// <summary>
/// Gets the type system member associated with this log entry.
/// </summary>
public ITypeSystemMemberDefinition? Member { get; }

/// <summary>
/// Gets the schema associated with this log entry.
/// </summary>
public SchemaDefinition? Schema { get; }

/// <summary>
/// Gets the extension object associated with this log entry.
/// </summary>
public object? Extension { get; }

public override string ToString() => Message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HotChocolate.Fusion.Logging;

public static class LogEntryCodes
{
public const string DisallowedInaccessible = "DISALLOWED_INACCESSIBLE";
public const string OutputFieldTypesNotMergeable = "OUTPUT_FIELD_TYPES_NOT_MERGEABLE";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using HotChocolate.Skimmed;
using static HotChocolate.Fusion.Properties.CompositionResources;

namespace HotChocolate.Fusion.Logging;

internal static class LogEntryHelper
{
public static LogEntry DisallowedInaccessibleScalar(
ScalarTypeDefinition scalar,
SchemaDefinition schema)
=> new(
string.Format(LogEntryHelper_DisallowedInaccessibleScalar, scalar.Name),
LogEntryCodes.DisallowedInaccessible,
LogSeverity.Error,
new SchemaCoordinate(scalar.Name),
scalar,
schema);

public static LogEntry DisallowedInaccessibleIntrospectionType(
INamedTypeDefinition type,
SchemaDefinition schema)
=> new(
string.Format(LogEntryHelper_DisallowedInaccessibleIntrospectionType, type.Name),
LogEntryCodes.DisallowedInaccessible,
LogSeverity.Error,
new SchemaCoordinate(type.Name),
type,
schema);

public static LogEntry DisallowedInaccessibleIntrospectionField(
OutputFieldDefinition field,
string typeName,
SchemaDefinition schema)
=> new(
string.Format(
LogEntryHelper_DisallowedInaccessibleIntrospectionField,
field.Name,
typeName),
LogEntryCodes.DisallowedInaccessible,
LogSeverity.Error,
new SchemaCoordinate(typeName, field.Name),
field,
schema);

public static LogEntry DisallowedInaccessibleIntrospectionArgument(
InputFieldDefinition argument,
string fieldName,
string typeName,
SchemaDefinition schema)
{
var coordinate = new SchemaCoordinate(typeName, fieldName, argument.Name);

return new LogEntry(
string.Format(
LogEntryHelper_DisallowedInaccessibleIntrospectionArgument,
argument.Name,
coordinate),
LogEntryCodes.DisallowedInaccessible,
LogSeverity.Error,
coordinate,
argument,
schema);
}

public static LogEntry DisallowedInaccessibleDirectiveArgument(
InputFieldDefinition argument,
string directiveName,
SchemaDefinition schema)
=> new(
string.Format(
LogEntryHelper_DisallowedInaccessibleDirectiveArgument,
argument.Name,
directiveName),
LogEntryCodes.DisallowedInaccessible,
LogSeverity.Error,
new SchemaCoordinate(directiveName, argumentName: argument.Name, ofDirective: true),
schema: schema);

public static LogEntry OutputFieldTypesNotMergeable(string typeName, string fieldName)
=> new(
string.Format(
LogEntryHelper_OutputFieldTypesNotMergeable,
typeName,
fieldName),
LogEntryCodes.OutputFieldTypesNotMergeable,
LogSeverity.Error,
new SchemaCoordinate(typeName, fieldName));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace HotChocolate.Fusion.Logging;

/// <summary>
/// Defines the severity of the log entry.
/// </summary>
public enum LogSeverity
{
/// <summary>
/// The entry contains an informational message.
/// </summary>
Info,

/// <summary>
/// The entry contains a warning message.
/// </summary>
Warning,

/// <summary>
/// The entry contains an error message.
/// </summary>
Error
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using HotChocolate.Fusion.Logging.Contracts;

namespace HotChocolate.Fusion.Logging;

public sealed class LoggingSession(ICompositionLog compositionLog) : ILoggingSession
{
public int InfoCount { get; private set; }

public int WarningCount { get; private set; }

public int ErrorCount { get; private set; }

public void Write(LogEntry entry)
{
ArgumentNullException.ThrowIfNull(entry);

switch (entry.Severity)
{
case LogSeverity.Info:
InfoCount++;
break;

case LogSeverity.Warning:
WarningCount++;
break;

case LogSeverity.Error:
ErrorCount++;
break;

default:
throw new InvalidOperationException();
}

compositionLog.Write(entry);
}
}
Loading
Loading