Skip to content
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
13 changes: 13 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Refitter

Refitter generates C# REST API clients — Refit interfaces and their contracts —
from OpenAPI specifications. It ships as a CLI tool, an MSBuild task, and a C#
source generator, all driven by the same `.refitter` settings.

## Language

**Parameter list**:
The ordered set of a generated Refit method's parameters, derived from an OpenAPI
operation's path, query, header, body, and form inputs, plus any trailing
request-options or cancellation-token argument.
_Avoid_: arguments, args
5 changes: 2 additions & 3 deletions src/Refitter.Core/Generation/InterfaceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ internal InterfaceGenerator(
RefitGeneratorSettings settings,
OpenApiDocument document,
CustomCSharpClientGenerator generator,
XmlDocumentationGenerator docGenerator,
IParameterExtractor? parameterExtractor = null)
XmlDocumentationGenerator docGenerator)
: this(
settings,
document,
generator,
docGenerator,
new ReturnTypeGenerator(settings, generator),
new MethodAttributeGenerator(settings, document),
new MethodSignatureGenerator(settings, parameterExtractor ?? new ParameterAggregator()))
new MethodSignatureGenerator(settings))
{
}

Expand Down
21 changes: 8 additions & 13 deletions src/Refitter.Core/Generation/MethodSignatureGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,22 @@

namespace Refitter.Core;

internal class MethodSignatureGenerator(
RefitGeneratorSettings settings,
IParameterExtractor? parameterExtractor = null)
internal class MethodSignatureGenerator(RefitGeneratorSettings settings)
: IMethodSignatureGenerator
{
private readonly IParameterExtractor parameterExtractor = parameterExtractor ?? new ParameterAggregator();
private readonly ParameterListBuilder parameterListBuilder = new(settings);

public (string ParametersString, IReadOnlyList<string> Parameters, string? DynamicQuerystringParameters) Generate(
CSharpOperationModel operationModel,
OpenApiOperation operation,
string dynamicQuerystringParameterType)
{
var parameters = parameterExtractor.ExtractParameters(
operationModel,
operation,
settings,
dynamicQuerystringParameterType,
out var operationDynamicQuerystringParameters)
.ToList();
var parameterList = parameterListBuilder.Build(
operationModel,
operation,
dynamicQuerystringParameterType);

var parametersString = string.Join(", ", parameters);
return (parametersString, parameters, operationDynamicQuerystringParameters);
var parametersString = string.Join(", ", parameterList.Parameters);
return (parametersString, parameterList.Parameters, parameterList.DynamicQuerystringCode);
}
}
10 changes: 5 additions & 5 deletions src/Refitter.Core/ParameterExtraction/BodyParameterExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Refitter.Core;

internal class BodyParameterExtractor : IParameterTypeExtractor
internal sealed class BodyParameterExtractor
{
public IEnumerable<string> Extract(

Check warning on line 8 in src/Refitter.Core/ParameterExtraction/BodyParameterExtractor.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make 'Extract' a static method.

See more on https://sonarcloud.io/project/issues?id=christianhelle_refitter&issues=AZ8aq5vdYxAFUnzwROod&open=AZ8aq5vdYxAFUnzwROod&pullRequest=1180
CSharpOperationModel operationModel,
OpenApiOperation operation,
RefitGeneratorSettings settings)
Expand All @@ -14,17 +14,17 @@
.Where(p => p.Kind == OpenApiParameterKind.Body && !p.IsBinaryBodyParameter)
.Select(p =>
{
var variableName = ParameterShared.GetVariableName(p);
return $"{ParameterShared.JoinAttributes(ParameterShared.GetBodyAttribute(p, settings), ParameterShared.GetAliasAsAttribute(p.Name, variableName))}{ParameterShared.GetParameterType(p, settings)} {variableName}";
var variableName = ParameterNaming.GetVariableName(p);
return $"{ParameterAttributeFormatter.JoinAttributes(ParameterAttributeFormatter.GetBodyAttribute(p, settings), ParameterAttributeFormatter.GetAliasAsAttribute(p.Name, variableName))}{ParameterTypeResolver.GetParameterType(p, settings)} {variableName}";
})
.ToList();

var binaryBodyParameters = operationModel.Parameters
.Where(p => p.Kind == OpenApiParameterKind.Body && p.IsBinaryBodyParameter)
.Select(p =>
{
var variableName = ParameterShared.GetVariableName(p);
var aliasAsAttribute = ParameterShared.GetAliasAsAttribute(p.Name, variableName);
var variableName = ParameterNaming.GetVariableName(p);
var aliasAsAttribute = ParameterAttributeFormatter.GetAliasAsAttribute(p.Name, variableName);
var generatedAliasAsAttribute = string.IsNullOrWhiteSpace(aliasAsAttribute)
? string.Empty
: $"[{aliasAsAttribute}]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public static string Build(

foreach (var operationParameter in queryParameters)
{
var propertyType = ParameterShared.GetQueryParameterType(operationParameter, settings);
var variableName = ParameterShared.GetVariableName(operationParameter);
var attributes = $"{ParameterShared.JoinAttributes(ParameterShared.GetQueryAttribute(operationParameter, settings), ParameterShared.GetAliasAsAttribute(operationParameter.Name, variableName))}";
var propertyType = ParameterTypeResolver.GetQueryParameterType(operationParameter, settings);
var variableName = ParameterNaming.GetVariableName(operationParameter);
var attributes = $"{ParameterAttributeFormatter.JoinAttributes(ParameterAttributeFormatter.GetQueryAttribute(operationParameter, settings), ParameterAttributeFormatter.GetAliasAsAttribute(operationParameter.Name, variableName))}";
var propertyName = variableName.CapitalizeFirstCharacter();
if (operationParameter.IsRequired)
{
Expand All @@ -48,7 +48,7 @@ public static string Build(
if (settings.GenerateXmlDocCodeComments && !string.IsNullOrWhiteSpace(operationParameter.Description))
{
var escapedDescription = XmlDocumentationGenerator.SanitizeResponseDescription(operationParameter.Description);
ParameterShared.AppendXmlDocComment(escapedDescription, propertiesCodeBuilder);
AppendXmlDocComment(escapedDescription, propertiesCodeBuilder);
}

propertiesCodeBuilder.Append(
Expand All @@ -59,7 +59,7 @@ public static string Build(
var defaultValue = operationParameter.Schema.Default;
if (defaultValue != null)
{
var formattedDefaultValue = ParameterShared.FormatDefaultValue(defaultValue, propertyType);
var formattedDefaultValue = ParameterDefaultValueFormatter.FormatDefaultValue(defaultValue, propertyType);
propertiesCodeBuilder.Append($" = {formattedDefaultValue};");
}

Expand Down Expand Up @@ -91,4 +91,32 @@ public static string Build(

return codeBuilder.ToString();
}

internal static void AppendXmlDocComment(string description, StringBuilder codeBuilder)
{
codeBuilder.Append(
"""
/// <summary>
""");

var lines = description.Split(
["\r\n", "\r", "\n"],
StringSplitOptions.None);

foreach (var line in lines)
{
codeBuilder.AppendLine();
codeBuilder.Append(
$$"""
/// {{line.Trim()}}
""");
}

codeBuilder.AppendLine();
codeBuilder.Append(
"""
/// </summary>
""");
codeBuilder.AppendLine();
}
}
14 changes: 7 additions & 7 deletions src/Refitter.Core/ParameterExtraction/FormParameterExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Refitter.Core;

internal class FormParameterExtractor : IParameterTypeExtractor
internal sealed class FormParameterExtractor
{
public IEnumerable<string> Extract(

Check warning on line 9 in src/Refitter.Core/ParameterExtraction/FormParameterExtractor.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make 'Extract' a static method.

See more on https://sonarcloud.io/project/issues?id=christianhelle_refitter&issues=AZ8aq5sEYxAFUnzwROoa&open=AZ8aq5sEYxAFUnzwROoa&pullRequest=1180
CSharpOperationModel operationModel,
OpenApiOperation operation,
RefitGeneratorSettings settings)
Expand All @@ -16,10 +16,10 @@

foreach (var p in operationModel.Parameters.Where(p => p.Kind == OpenApiParameterKind.FormData && !p.IsBinaryBodyParameter))
{
var variableName = ParameterShared.ConvertToVariableName(p.VariableName);
var variableName = ParameterNaming.ConvertToVariableName(p.VariableName);
if (seenFormParameterNames.Add(variableName))
{
formParameters.Add($"{ParameterShared.JoinAttributes(ParameterShared.GetAliasAsAttribute(p.Name, variableName))}{ParameterShared.GetParameterType(p, settings)} {variableName}");
formParameters.Add($"{ParameterAttributeFormatter.JoinAttributes(ParameterAttributeFormatter.GetAliasAsAttribute(p.Name, variableName))}{ParameterTypeResolver.GetParameterType(p, settings)} {variableName}");
}
}

Expand All @@ -40,13 +40,13 @@

if (!isBinary)
{
var propertyType = ParameterShared.GetCSharpType(propertySchema, settings);
var variableName = ParameterShared.ConvertToVariableName(property.Key);
var propertyType = ParameterTypeResolver.GetCSharpType(propertySchema, settings);
var variableName = ParameterNaming.ConvertToVariableName(property.Key);

if (seenFormParameterNames.Add(variableName))
{
var aliasAttribute = ParameterShared.GetAliasAsAttribute(property.Key, variableName);
var parameter = $"{ParameterShared.JoinAttributes(aliasAttribute)}{propertyType} {variableName}";
var aliasAttribute = ParameterAttributeFormatter.GetAliasAsAttribute(property.Key, variableName);
var parameter = $"{ParameterAttributeFormatter.JoinAttributes(aliasAttribute)}{propertyType} {variableName}";
formParameters.Add(parameter);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Refitter.Core;

internal class HeaderParameterExtractor : IParameterTypeExtractor
internal sealed class HeaderParameterExtractor
{
public IEnumerable<string> Extract(

Check warning on line 8 in src/Refitter.Core/ParameterExtraction/HeaderParameterExtractor.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make 'Extract' a static method.

See more on https://sonarcloud.io/project/issues?id=christianhelle_refitter&issues=AZ8aq5vpYxAFUnzwROoe&open=AZ8aq5vpYxAFUnzwROoe&pullRequest=1180
CSharpOperationModel operationModel,
OpenApiOperation operation,
RefitGeneratorSettings settings)
Expand All @@ -26,8 +26,8 @@
.Where(p => !anyIgnoredHeaders || !ignoredHeaders.Contains(p.Name, StringComparer.OrdinalIgnoreCase))
.Select(p =>
{
var variableName = ParameterShared.GetVariableName(p);
return $"{ParameterShared.JoinAttributes($"Header(\"{p.Name}\")")}{ParameterShared.GetParameterType(p, settings)} {variableName}";
var variableName = ParameterNaming.GetVariableName(p);
return $"{ParameterAttributeFormatter.JoinAttributes($"Header(\"{p.Name}\")")}{ParameterTypeResolver.GetParameterType(p, settings)} {variableName}";
})
.ToList();
}
Expand All @@ -47,7 +47,7 @@
&& securityScheme.In == OpenApiSecurityApiKeyLocation.Header
&& !operationModel.Parameters.Any(p => p.Kind == OpenApiParameterKind.Header && p.IsHeader && p.Name == securityScheme.Name))
{
headerParameters.Add($"[Header(\"{securityScheme.Name}\")] string {ParameterShared.ReplaceUnsafeCharacters(securityScheme.Name)}");
headerParameters.Add($"[Header(\"{securityScheme.Name}\")] string {ParameterNaming.ReplaceUnsafeCharacters(securityScheme.Name)}");
}
else if (securityScheme is { Type: OpenApiSecuritySchemeType.Http }
&& string.Equals(securityScheme.Scheme, "bearer", StringComparison.OrdinalIgnoreCase))
Expand Down
14 changes: 0 additions & 14 deletions src/Refitter.Core/ParameterExtraction/IParameterExtractor.cs

This file was deleted.

12 changes: 0 additions & 12 deletions src/Refitter.Core/ParameterExtraction/IParameterTypeExtractor.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static List<string> Reorder(
if (NullablePattern.IsMatch(parameters[index]))
{
var parameterString = parameters[index];
var defaultValue = ParameterShared.GetDefaultValueForParameter(parameterString, parameterModels);
var defaultValue = ParameterDefaultValueFormatter.GetDefaultValueForParameter(parameterString, parameterModels);
parameters[index] = parameterString + " = " + defaultValue;
}
}
Expand Down
70 changes: 0 additions & 70 deletions src/Refitter.Core/ParameterExtraction/ParameterAggregator.cs

This file was deleted.

Loading
Loading