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

Housekeeping Update tests to remove need for comments #1697

Merged
merged 5 commits into from
May 24, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
with:
configuration: Release
productNamespacePrefix: "Refit"
dotNetBuild: true
useVisualStudioPreview: false
useMauiCheckDotNetTool: false
srcFolder: "./"
Expand Down
53 changes: 41 additions & 12 deletions InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ namespace Refit.Generator
// * Generate the data we need for the template based on interface method
// defn's

/// <summary>
/// InterfaceStubGeneratorV2.
/// </summary>
[Generator]
#if ROSLYN_4
public class InterfaceStubGeneratorV2 : IIncrementalGenerator
Expand Down Expand Up @@ -49,6 +52,10 @@ public class InterfaceStubGenerator : ISourceGenerator

#if !ROSLYN_4

/// <summary>
/// Executes the specified context.
/// </summary>
/// <param name="context">The context.</param>
public void Execute(GeneratorExecutionContext context)
{
if (context.SyntaxReceiver is not SyntaxReceiver receiver)
Expand All @@ -71,6 +78,18 @@ public void Execute(GeneratorExecutionContext context)
}
#endif

/// <summary>
/// Generates the interface stubs.
/// </summary>
/// <typeparam name="TContext">The type of the context.</typeparam>
/// <param name="context">The context.</param>
/// <param name="reportDiagnostic">The report diagnostic.</param>
/// <param name="addSource">The add source.</param>
/// <param name="compilation">The compilation.</param>
/// <param name="refitInternalNamespace">The refit internal namespace.</param>
/// <param name="candidateMethods">The candidate methods.</param>
/// <param name="candidateInterfaces">The candidate interfaces.</param>
/// <returns></returns>
public void GenerateInterfaceStubs<TContext>(
TContext context,
Action<TContext, Diagnostic> reportDiagnostic,
Expand Down Expand Up @@ -160,7 +179,7 @@ ImmutableArray<InterfaceDeclarationSyntax> candidateInterfaces
{
// Add the interface to the generation list with an empty set of methods
// The logic already looks for base refit methods
interfaces.Add(ifaceSymbol, new List<IMethodSymbol>());
interfaces.Add(ifaceSymbol, []);
var isAnnotated =
model.GetNullableContext(iface.SpanStart) == NullableContext.Enabled;

Expand All @@ -170,7 +189,7 @@ ImmutableArray<InterfaceDeclarationSyntax> candidateInterfaces
}

// Bail out if there aren't any interfaces to generate code for. This may be the case with transitives
if (!interfaces.Any())
if (interfaces.Count == 0)
return;

var supportsNullable = options.LanguageVersion >= LanguageVersion.CSharp8;
Expand Down Expand Up @@ -275,7 +294,7 @@ internal static partial class Generated
}
}

string ProcessInterface<TContext>(
static string ProcessInterface<TContext>(
TContext context,
Action<TContext, Diagnostic> reportDiagnostic,
INamedTypeSymbol interfaceSymbol,
Expand Down Expand Up @@ -450,7 +469,7 @@ partial class {ns}{classDeclaration}
/// <param name="methodSymbol"></param>
/// <param name="isTopLevel">True if directly from the type we're generating for, false for methods found on base interfaces</param>
/// <param name="memberNames">Contains the unique member names in the interface scope.</param>
void ProcessRefitMethod(
static void ProcessRefitMethod(
StringBuilder source,
IMethodSymbol methodSymbol,
bool isTopLevel,
Expand Down Expand Up @@ -519,7 +538,7 @@ HashSet<string> memberNames
WriteMethodClosing(source);
}

void ProcessDisposableMethod(StringBuilder source, IMethodSymbol methodSymbol)
static void ProcessDisposableMethod(StringBuilder source, IMethodSymbol methodSymbol)
{
WriteMethodOpening(source, methodSymbol, true);

Expand All @@ -532,7 +551,7 @@ void ProcessDisposableMethod(StringBuilder source, IMethodSymbol methodSymbol)
WriteMethodClosing(source);
}

string GenerateConstraints(
static string GenerateConstraints(
ImmutableArray<ITypeParameterSymbol> typeParameters,
bool isOverrideOrExplicitImplementation
)
Expand All @@ -551,7 +570,7 @@ bool isOverrideOrExplicitImplementation
return source.ToString();
}

void WriteConstraitsForTypeParameter(
static void WriteConstraitsForTypeParameter(
StringBuilder source,
ITypeParameterSymbol typeParameter,
bool isOverrideOrExplicitImplementation
Expand Down Expand Up @@ -601,7 +620,7 @@ bool isOverrideOrExplicitImplementation
}
}

void ProcessNonRefitMethod<TContext>(
static void ProcessNonRefitMethod<TContext>(
TContext context,
Action<TContext, Diagnostic> reportDiagnostic,
StringBuilder source,
Expand Down Expand Up @@ -687,7 +706,7 @@ static bool ContainsTypeParameter(ITypeSymbol symbol)
}
}

void WriteMethodOpening(
static void WriteMethodOpening(
StringBuilder source,
IMethodSymbol methodSymbol,
bool isExplicitInterface,
Expand Down Expand Up @@ -737,7 +756,7 @@ static bool ContainsTypeParameter(ITypeSymbol symbol)
);
}

void WriteMethodClosing(StringBuilder source) => source.Append(@" }");
static void WriteMethodClosing(StringBuilder source) => source.Append(@" }");

static string UniqueName(string name, HashSet<string> methodNames)
{
Expand All @@ -753,7 +772,7 @@ static string UniqueName(string name, HashSet<string> methodNames)
return candidateName;
}

bool IsRefitMethod(IMethodSymbol? methodSymbol, INamedTypeSymbol httpMethodAttibute)
static bool IsRefitMethod(IMethodSymbol? methodSymbol, INamedTypeSymbol httpMethodAttibute)
{
return methodSymbol
?.GetAttributes()
Expand All @@ -763,6 +782,11 @@ bool IsRefitMethod(IMethodSymbol? methodSymbol, INamedTypeSymbol httpMethodAttib

#if ROSLYN_4

/// <summary>
/// Initializes the specified context.
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// We're looking for methods with an attribute that are in an interface
Expand All @@ -772,7 +796,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
is MethodDeclarationSyntax
{
Parent: InterfaceDeclarationSyntax,
AttributeLists: { Count: > 0 }
AttributeLists.Count: > 0
},
(context, cancellationToken) => (MethodDeclarationSyntax)context.Node
);
Expand Down Expand Up @@ -834,6 +858,11 @@ is MethodDeclarationSyntax

#else

/// <summary>
/// Initializes the specified context.
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
Expand Down
1 change: 1 addition & 0 deletions Refit.Benchmarks/Refit.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions Refit.HttpClientFactory/HttpClientFactoryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace Refit
{
/// <summary>
/// HttpClientFactoryExtensions.
/// </summary>
public static class HttpClientFactoryExtensions
{
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Refit.HttpClientFactory/Refit.HttpClientFactory.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Product>Refit HTTP Client Factory Extensions</Product>
Expand Down
30 changes: 26 additions & 4 deletions Refit.HttpClientFactory/SettingsFor.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
namespace Refit
{
/// <summary>
/// ISettingsFor
/// </summary>
public interface ISettingsFor
{
/// <summary>
/// Gets the settings.
/// </summary>
/// <value>
/// The settings.
/// </value>
RefitSettings? Settings { get; }
}

public class SettingsFor<T> : ISettingsFor
/// <summary>
/// SettingsFor.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <seealso cref="Refit.ISettingsFor" />
/// <remarks>
/// Initializes a new instance of the <see cref="SettingsFor{T}"/> class.
/// </remarks>
/// <param name="settings">The settings.</param>
public class SettingsFor<T>(RefitSettings? settings) : ISettingsFor
{
public SettingsFor(RefitSettings? settings) => Settings = settings;

public RefitSettings? Settings { get; }
/// <summary>
/// Gets the settings.
/// </summary>
/// <value>
/// The settings.
/// </value>
public RefitSettings? Settings { get; } = settings;
}
}
59 changes: 32 additions & 27 deletions Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,45 +1,36 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Newtonsoft.Json;

namespace Refit
{
/// <summary>
/// A <see langword="class"/> implementing <see cref="IHttpContentSerializer"/> using the Newtonsoft.Json APIs
/// </summary>
public sealed class NewtonsoftJsonContentSerializer : IHttpContentSerializer
/// <remarks>
/// Creates a new <see cref="NewtonsoftJsonContentSerializer"/> instance with the specified parameters
/// </remarks>
/// <param name="jsonSerializerSettings">The serialization settings to use for the current instance</param>
public sealed class NewtonsoftJsonContentSerializer(JsonSerializerSettings? jsonSerializerSettings) : IHttpContentSerializer
{
/// <summary>
/// The <see cref="Lazy{T}"/> instance providing the JSON serialization settings to use
/// </summary>
readonly Lazy<JsonSerializerSettings> jsonSerializerSettings;
readonly Lazy<JsonSerializerSettings> jsonSerializerSettings = new(
() =>
jsonSerializerSettings
?? JsonConvert.DefaultSettings?.Invoke()
?? new JsonSerializerSettings()
);

/// <summary>
/// Creates a new <see cref="NewtonsoftJsonContentSerializer"/> instance
/// </summary>
public NewtonsoftJsonContentSerializer()
: this(null) { }

/// <summary>
/// Creates a new <see cref="NewtonsoftJsonContentSerializer"/> instance with the specified parameters
/// </summary>
/// <param name="jsonSerializerSettings">The serialization settings to use for the current instance</param>
public NewtonsoftJsonContentSerializer(JsonSerializerSettings? jsonSerializerSettings)
{
this.jsonSerializerSettings = new Lazy<JsonSerializerSettings>(
() =>
jsonSerializerSettings
?? JsonConvert.DefaultSettings?.Invoke()
?? new JsonSerializerSettings()
);
}

/// <inheritdoc/>
public HttpContent ToHttpContent<T>(T item)
{
Expand All @@ -58,6 +49,11 @@ public HttpContent ToHttpContent<T>(T item)
CancellationToken cancellationToken = default
)
{
if (content == null)
{
return default;
}

var serializer = JsonSerializer.Create(jsonSerializerSettings.Value);

using var stream = await content
Expand All @@ -69,15 +65,24 @@ public HttpContent ToHttpContent<T>(T item)
return serializer.Deserialize<T>(jsonTextReader);
}

/// <summary>
/// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands
/// </summary>
/// <param name="propertyInfo">A PropertyInfo object.</param>
/// <returns>
/// The calculated field name.
/// </returns>
/// <exception cref="System.ArgumentNullException">propertyInfo</exception>
public string? GetFieldNameForProperty(PropertyInfo propertyInfo)
{
if (propertyInfo is null)
throw new ArgumentNullException(nameof(propertyInfo));

return propertyInfo
return propertyInfo switch
{
null => throw new ArgumentNullException(nameof(propertyInfo)),
_ => propertyInfo
.GetCustomAttributes<JsonPropertyAttribute>(true)
.Select(a => a.PropertyName)
.FirstOrDefault();
.FirstOrDefault()
};
}
}
}
2 changes: 1 addition & 1 deletion Refit.Tests/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,5 +1292,5 @@ Task PostMessage<T>([Body] T message)
where U : T;
}

public interface IMessage { }
public interface IMessage;
}
3 changes: 2 additions & 1 deletion Refit.Tests/Refit.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\Refit\targets\refit.props" />

<PropertyGroup>
<TargetFrameworks>net462;net6.0;net7.0</TargetFrameworks>
<Deterministic>false</Deterministic> <!-- Some tests rely on CallerFilePath -->
<RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json</RestoreAdditionalProjectSources>
<NoWarn>$(NoWarn);CS1591;CA1819;CA2000;CA2007;CA1056;CA1707;CA1861;xUnit1031</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down