Skip to content

Commit

Permalink
Refine ClientUriBuilder (#5148)
Browse files Browse the repository at this point in the history
- Remove `BaseType` from `ClientUriBuilder`
- Add `UriBuilderType` to `HttpRequestApi`
- Make `Instance(CSharpType type, params ValueExpression[] arguments)`
equivalent to `New.Instance<T>(params ValueExpression[] arguments)`
- Apply the actual type of value during implementation of
`Declare(string name, ScopedApi value, out ScopedApi variable)`
- Replace `RequestOptions` with `IHttpRequestOptionsApi`

The corresponding changes in Azure plugin:
Azure/azure-sdk-for-net#47259
  • Loading branch information
live1206 authored Nov 22, 2024
1 parent 5eb74eb commit d8b2c45
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ protected HttpRequestApi(CSharpType type, ValueExpression original) : base(type,
{
}

public abstract Type UriBuilderType { get; }
public abstract MethodBodyStatement SetMethod(string httpMethod);

public abstract MethodBodyStatement SetUri(ValueExpression uri);

public abstract MethodBodyStatement SetHeaders(IReadOnlyList<ValueExpression> arguments);

public abstract ValueExpression Content();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,16 @@ protected override MethodProvider[] BuildMethods()
{
var methods = new List<MethodProvider>();

if (GetBaseType() is null)
{
methods.Add(BuildResetMethod());
methods.AddRange(BuildAppendPathMethods());
methods.AddRange(BuildAppendPathDelimitedMethods());
methods.AddRange(BuildAppendQueryMethods());
methods.AddRange(BuildAppendQueryDelimitedMethods());
methods.Add(BuildToUriMethod());
}
methods.Add(BuildResetMethod());
methods.AddRange(BuildAppendPathMethods());
methods.AddRange(BuildAppendPathDelimitedMethods());
methods.AddRange(BuildAppendQueryMethods());
methods.AddRange(BuildAppendQueryDelimitedMethods());
methods.Add(BuildToUriMethod());

return methods.ToArray();
}

protected override CSharpType? GetBaseType() => ClientModelPlugin.Instance.TypeFactory.ClientUriBuilderBaseType;

private MethodProvider BuildResetMethod()
{
var uriParameter = new ParameterProvider("uri", $"The uri.", typeof(Uri));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Generator.CSharp.ClientModel.Snippets;
using static Microsoft.Generator.CSharp.Snippets.Snippet;
using Microsoft.Generator.CSharp.Statements;
using System;

namespace Microsoft.Generator.CSharp.ClientModel.Providers
{
Expand All @@ -19,6 +20,8 @@ public PipelineRequestProvider(ValueExpression original) : base(typeof(PipelineR
private static HttpRequestApi? _instance;
internal static HttpRequestApi Instance => _instance ??= new PipelineRequestProvider(Empty);

public override Type UriBuilderType => typeof(ClientUriBuilderDefinition);

public override ValueExpression Content()
=> Original.Property(nameof(PipelineRequest.Content));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ private MethodProvider BuildCreateRequestMethod(InputOperation operation)
message.ApplyResponseClassifier(classifier.ToApi<StatusCodeClassifierApi>()),
Declare("request", message.Request().ToApi<HttpRequestApi>(), out HttpRequestApi request),
request.SetMethod(operation.HttpMethod),
Declare("uri", New.Instance<ClientUriBuilderDefinition>(), out ScopedApi<ClientUriBuilderDefinition> uri),
Declare("uri", New.Instance(request.UriBuilderType), out ScopedApi uri),
uri.Reset(ClientProvider.EndpointField).Terminate(),
.. AppendPathParameters(uri, operation, paramMap),
.. AppendQueryParameters(uri, operation, paramMap),
Expand Down Expand Up @@ -231,7 +231,7 @@ private IEnumerable<MethodBodyStatement> AppendHeaderParameters(HttpRequestApi r
return statements;
}

private static List<MethodBodyStatement> AppendQueryParameters(ScopedApi<ClientUriBuilderDefinition> uri, InputOperation operation, Dictionary<string, ParameterProvider> paramMap)
private static List<MethodBodyStatement> AppendQueryParameters(ScopedApi uri, InputOperation operation, Dictionary<string, ParameterProvider> paramMap)
{
List<MethodBodyStatement> statements = new(operation.Parameters.Count);

Expand Down Expand Up @@ -342,7 +342,7 @@ private static IfStatement BuildQueryParameterNullCheck(
return new IfStatement(valueExpression.NotEqual(Null)) { originalStatement };
}

private IEnumerable<MethodBodyStatement> AppendPathParameters(ScopedApi<ClientUriBuilderDefinition> uri, InputOperation operation, Dictionary<string, ParameterProvider> paramMap)
private IEnumerable<MethodBodyStatement> AppendPathParameters(ScopedApi uri, InputOperation operation, Dictionary<string, ParameterProvider> paramMap)
{
Dictionary<string, InputParameter> inputParamHash = new(operation.Parameters.ToDictionary(p => p.Name));
List<MethodBodyStatement> statements = new(operation.Parameters.Count);
Expand All @@ -356,7 +356,7 @@ private IEnumerable<MethodBodyStatement> AppendPathParameters(ScopedApi<ClientUr
private void AddUriSegments(
string segments,
int offset,
ScopedApi<ClientUriBuilderDefinition> uri,
ScopedApi uri,
List<MethodBodyStatement> statements,
Dictionary<string, InputParameter> inputParamHash,
Dictionary<string, ParameterProvider> paramMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private IReadOnlyList<ValueExpression> GetProtocolMethodArguments(

conversions.Add(
isAsync
? RequestOptionsSnippets.FromCancellationToken(ScmKnownParameters.CancellationToken)
? IHttpRequestOptionsApiSnippets.FromCancellationToken(ScmKnownParameters.CancellationToken)
: ScmKnownParameters.RequestOptions.PositionalReference(Null));
return conversions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public class ScmTypeFactory : TypeFactory

public virtual CSharpType TokenCredentialType => throw new NotImplementedException("Token credential is not supported in Scm libraries yet");

public virtual CSharpType? ClientUriBuilderBaseType => null;

public virtual IClientResponseApi ClientResponseApi => ClientResultProvider.Instance;

public virtual IHttpResponseApi HttpResponseApi => PipelineResponseProvider.Instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.

using System;
using Microsoft.Generator.CSharp.ClientModel.Providers;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Snippets;
using static Microsoft.Generator.CSharp.Snippets.Snippet;
Expand All @@ -11,25 +10,25 @@ namespace Microsoft.Generator.CSharp.ClientModel.Snippets
{
internal static class ClientUriBuilderSnippets
{
public static InvokeMethodExpression Reset(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression baseUri)
public static InvokeMethodExpression Reset(this ScopedApi uriBuilder, ValueExpression baseUri)
=> uriBuilder.Invoke("Reset", baseUri);

public static InvokeMethodExpression AppendPath(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression path, bool? shouldEscape)
public static InvokeMethodExpression AppendPath(this ScopedApi uriBuilder, ValueExpression path, bool? shouldEscape)
=> uriBuilder.Invoke("AppendPath", path, Literal(shouldEscape));

public static InvokeMethodExpression AppendPathDelimited(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression path, string? format, bool? shouldEscape, string? delimiter = ",")
=> uriBuilder.Invoke("AppendPathDelimited", [path, Literal(delimiter), Literal(format), Literal(shouldEscape)]);
public static InvokeMethodExpression AppendPathDelimited(this ScopedApi uriBuilder, ValueExpression path, string? format, bool? shouldEscape, string? delimiter = ",")
=> uriBuilder.Invoke("AppendPathDelimited", [path, Literal(delimiter), Literal(format), Literal(shouldEscape)]);

public static InvokeMethodExpression AppendQuery(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression name, ValueExpression value, bool shouldEscape)
public static InvokeMethodExpression AppendQuery(this ScopedApi uriBuilder, ValueExpression name, ValueExpression value, bool shouldEscape)
=> uriBuilder.Invoke("AppendQuery", [name, value, Literal(shouldEscape)]);

public static InvokeMethodExpression AppendQuery(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression name, ValueExpression value, string? format, bool shouldEscape)
public static InvokeMethodExpression AppendQuery(this ScopedApi uriBuilder, ValueExpression name, ValueExpression value, string? format, bool shouldEscape)
=> uriBuilder.Invoke("AppendQuery", [name, value, Literal(format), Literal(shouldEscape)]);

public static InvokeMethodExpression AppendQueryDelimited(this ScopedApi<ClientUriBuilderDefinition> uriBuilder, ValueExpression name, ValueExpression value, string? format, bool shouldEscape, string? delimiter = ",")
public static InvokeMethodExpression AppendQueryDelimited(this ScopedApi uriBuilder, ValueExpression name, ValueExpression value, string? format, bool shouldEscape, string? delimiter = ",")
=> uriBuilder.Invoke("AppendQueryDelimited", [name, value, Literal(delimiter), Literal(format), Literal(shouldEscape)]);

public static ScopedApi<Uri> ToUri(this ScopedApi<ClientUriBuilderDefinition> uriBuilder)
public static ScopedApi<Uri> ToUri(this ScopedApi uriBuilder)
=> uriBuilder.Invoke("ToUri").As<Uri>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@
using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Generator.CSharp.ClientModel.Providers;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Snippets;
using static Microsoft.Generator.CSharp.Snippets.Snippet;

namespace Microsoft.Generator.CSharp.ClientModel.Snippets
{
internal static class RequestOptionsSnippets
internal static class IHttpRequestOptionsApiSnippets
{
public static ScopedApi<RequestOptions> FromCancellationToken(ValueExpression cancellationToken)
public static ScopedApi<IHttpRequestOptionsApi> FromCancellationToken(ValueExpression cancellationToken)
=> new TernaryConditionalExpression(
cancellationToken.Property(nameof(CancellationToken.CanBeCanceled)),
New.Instance<RequestOptions>(
New.Instance(
ClientModelPlugin.Instance.TypeFactory.HttpRequestOptionsApi.HttpRequestOptionsType,
arguments: [],
properties: new Dictionary<ValueExpression, ValueExpression>
{ { new MemberExpression(null, nameof(RequestOptions.CancellationToken)), cancellationToken } },
useSingleLineForPropertyInitialization: true),
Null).As<RequestOptions>();
Null).As<IHttpRequestOptionsApi>();

public static ValueExpression ErrorOptions(this ScopedApi<RequestOptions> requestOptions) => requestOptions.Property(nameof(RequestOptions.ErrorOptions));
public static ValueExpression ErrorOptions(this ScopedApi<IHttpRequestOptionsApi> requestOptions) => requestOptions.Property(nameof(RequestOptions.ErrorOptions));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ public static MethodBodyStatement Declare(string name, DictionaryExpression valu

public static MethodBodyStatement Declare(string name, ScopedApi value, out ScopedApi variable)
{
var declaration = new VariableExpression(value.Type, name);
variable = declaration.As(value.Type);
return Declare(declaration, value);
var declaration = new CodeWriterDeclaration(name);
var variableExpression = new VariableExpression(TypeReferenceExpression.GetTypeFromDefinition(value.Type)!, declaration);
variable = variableExpression.As(value.Type);
return Declare(variableExpression, value);
}

public static MethodBodyStatement Declare(VariableExpression variable, ValueExpression value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ public static DictionaryExpression Dictionary(CSharpType keyType, CSharpType val
public static ValueExpression Instance(CSharpType type, IReadOnlyList<ValueExpression> arguments) => new NewInstanceExpression(type, arguments);
public static ValueExpression Instance(CSharpType type, params ValueExpression[] arguments) => new NewInstanceExpression(type, arguments);
public static ValueExpression Instance(CSharpType type, IReadOnlyDictionary<ValueExpression, ValueExpression> properties) => new NewInstanceExpression(type, [], new ObjectInitializerExpression(properties));
public static ScopedApi Instance(Type type, params ValueExpression[] arguments) => new NewInstanceExpression(type, arguments).As(type);
public static ScopedApi Instance(Type type, params ValueExpression[] arguments) => new NewInstanceExpression(TypeReferenceExpression.GetTypeFromDefinition(type), arguments).As(type);
public static ScopedApi Instance(Type type, IReadOnlyDictionary<ValueExpression, ValueExpression> properties) => new NewInstanceExpression(type, [], new ObjectInitializerExpression(properties)).As(type);
public static ScopedApi Instance(CSharpType type, IEnumerable<ValueExpression> arguments, IReadOnlyDictionary<ValueExpression, ValueExpression> properties, bool useSingleLineForPropertyInitialization = false)
=> new NewInstanceExpression(TypeReferenceExpression.GetTypeFromDefinition(type), [.. arguments], new ObjectInitializerExpression(properties, useSingleLineForPropertyInitialization)).As(type);
public static ScopedApi<T> Instance<T>(IEnumerable<ValueExpression> arguments, IReadOnlyDictionary<ValueExpression, ValueExpression> properties, bool useSingleLineForPropertyInitialization = false)
=> new NewInstanceExpression(TypeReferenceExpression.GetTypeFromDefinition(typeof(T)), [.. arguments], new ObjectInitializerExpression(properties, useSingleLineForPropertyInitialization)).As<T>();
public static ScopedApi<T> Instance<T>(params ValueExpression[] arguments)
Expand Down

0 comments on commit d8b2c45

Please sign in to comment.