diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmKnownParameters.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmKnownParameters.cs
index fd69bab995..989cac3dae 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmKnownParameters.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmKnownParameters.cs
@@ -2,12 +2,12 @@
// Licensed under the MIT License.
using System;
+using System.ClientModel;
using System.ClientModel.Primitives;
using System.Text.Json;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Generator.CSharp.Providers;
-using Microsoft.Generator.CSharp.Snippets;
using static Microsoft.Generator.CSharp.Snippets.Snippet;
namespace Microsoft.Generator.CSharp.ClientModel
@@ -17,25 +17,19 @@ internal static class ScmKnownParameters
private static readonly CSharpType modelReaderWriterOptionsType = typeof(ModelReaderWriterOptions);
private static readonly CSharpType nullableModelReaderWriterOptionsType = new CSharpType(typeof(ModelReaderWriterOptions), isNullable: true);
- public static readonly ParameterProvider XmlWriter = new ParameterProvider("writer", FormattableStringHelpers.Empty, typeof(XmlWriter));
- public static readonly ParameterProvider NameHint = new ParameterProvider("nameHint", FormattableStringHelpers.Empty, typeof(string));
- public static readonly ParameterProvider XElement = new ParameterProvider("element", FormattableStringHelpers.Empty, typeof(XElement));
-
- public static readonly ParameterProvider Utf8JsonWriter = new ParameterProvider("writer", FormattableStringHelpers.Empty, typeof(Utf8JsonWriter));
- public static readonly ParameterProvider Utf8JsonReader = new ParameterProvider("reader", FormattableStringHelpers.Empty, typeof(Utf8JsonReader), isRef: true);
- public static readonly ParameterProvider JsonOptions = new ParameterProvider("options", FormattableStringHelpers.Empty, typeof(JsonSerializerOptions));
- public static readonly ParameterProvider Options = new ParameterProvider("options", FormattableStringHelpers.Empty, modelReaderWriterOptionsType);
- public static readonly ParameterProvider OptionalOptions = new ParameterProvider("options", FormattableStringHelpers.Empty, nullableModelReaderWriterOptionsType, DefaultOf(nullableModelReaderWriterOptionsType));
- public static readonly ParameterProvider JsonElement = new ParameterProvider("element", FormattableStringHelpers.Empty, typeof(JsonElement));
- public static readonly ParameterProvider Data = new ParameterProvider("data", FormattableStringHelpers.Empty, typeof(BinaryData));
-
- private static ParameterProvider? _tokenAuth;
- public static ParameterProvider TokenAuth => _tokenAuth ??= new("tokenCredential", $"The token credential to copy", ClientModelPlugin.Instance.TypeFactory.TokenCredentialType());
-
- private static ParameterProvider? _matchConditionsParameter;
- public static ParameterProvider MatchConditionsParameter => _matchConditionsParameter ??= new("matchConditions", $"The content to send as the request conditions of the request.", ClientModelPlugin.Instance.TypeFactory.MatchConditionsType(), Snippet.DefaultOf(ClientModelPlugin.Instance.TypeFactory.RequestConditionsType()));
-
- private static ParameterProvider? _requestConditionsParameter;
- public static ParameterProvider RequestConditionsParameter => _requestConditionsParameter ??= new("requestConditions", $"The content to send as the request conditions of the request.", ClientModelPlugin.Instance.TypeFactory.RequestConditionsType(), Snippet.DefaultOf(ClientModelPlugin.Instance.TypeFactory.RequestConditionsType()));
+ public static readonly ParameterProvider XmlWriter = new("writer", FormattableStringHelpers.Empty, typeof(XmlWriter));
+ public static readonly ParameterProvider NameHint = new("nameHint", FormattableStringHelpers.Empty, typeof(string));
+ public static readonly ParameterProvider XElement = new("element", FormattableStringHelpers.Empty, typeof(XElement));
+ public static readonly ParameterProvider Utf8JsonWriter = new("writer", FormattableStringHelpers.Empty, typeof(Utf8JsonWriter));
+ public static readonly ParameterProvider Utf8JsonReader = new("reader", FormattableStringHelpers.Empty, typeof(Utf8JsonReader), isRef: true);
+ public static readonly ParameterProvider JsonOptions = new("options", FormattableStringHelpers.Empty, typeof(JsonSerializerOptions));
+ public static readonly ParameterProvider Options = new("options", FormattableStringHelpers.Empty, modelReaderWriterOptionsType);
+ public static readonly ParameterProvider OptionalOptions = new("options", FormattableStringHelpers.Empty, nullableModelReaderWriterOptionsType, DefaultOf(nullableModelReaderWriterOptionsType));
+ public static readonly ParameterProvider JsonElement = new("element", FormattableStringHelpers.Empty, typeof(JsonElement));
+ public static readonly ParameterProvider Data = new("data", FormattableStringHelpers.Empty, typeof(BinaryData));
+ public static readonly ParameterProvider TokenAuth = new("tokenCredential", $"The token credential to copy", ClientModelPlugin.Instance.TypeFactory.TokenCredentialType());
+ public static readonly ParameterProvider MatchConditionsParameter = new("matchConditions", $"The content to send as the request conditions of the request.", ClientModelPlugin.Instance.TypeFactory.MatchConditionsType(), DefaultOf(ClientModelPlugin.Instance.TypeFactory.MatchConditionsType()));
+ public static readonly ParameterProvider RequestOptions = new("options", $"The request options, which can override default behaviors of the client pipeline on a per-call basis.", typeof(RequestOptions));
+ public static readonly ParameterProvider BinaryContent = new("content", $"The content to send as the body of the request.", typeof(BinaryContent));
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmOutputLibrary.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmOutputLibrary.cs
index dfa7ec4af5..70bb87afa5 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmOutputLibrary.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmOutputLibrary.cs
@@ -37,7 +37,9 @@ protected override TypeProvider[] BuildTypeProviders()
..baseTypes,
..BuildClients(),
new ModelSerializationExtensionsProvider(),
- new TypeFormattersProvider()
+ new TypeFormattersProvider(),
+ new ClientPipelineExtensionsProvider(),
+ new ErrorResultProvider()
];
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmTypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmTypeFactory.cs
index 65a0de09ec..f6aa05c1fd 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmTypeFactory.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/OutputTypes/ScmTypeFactory.cs
@@ -1,7 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-using System;
+using System.ClientModel;
+using System.ClientModel.Primitives;
using System.Collections.Generic;
using Microsoft.Generator.CSharp.ClientModel.Providers;
using Microsoft.Generator.CSharp.Input;
@@ -21,28 +22,8 @@ public class ScmTypeFactory : TypeFactory
/// The enclosing type of the operation.
public override MethodProviderCollection CreateMethodProviders(InputOperation operation, TypeProvider enclosingType) => new ScmMethodProviderCollection(operation, enclosingType);
- public virtual CSharpType MatchConditionsType()
- {
- // TO-DO: Determine what the correct type is for MatchConditions: https://github.com/Azure/autorest.csharp/issues/4166
- throw new NotImplementedException();
- }
+ public virtual CSharpType MatchConditionsType() => typeof(PipelineMessageClassifier);
- public virtual CSharpType RequestConditionsType()
- {
- // TO-DO: Determine what the correct type is for RequestConditions: https://github.com/Azure/autorest.csharp/issues/4166
- throw new NotImplementedException();
- }
-
- public virtual CSharpType TokenCredentialType()
- {
- // TO-DO: Determine what the correct type is for TokenCredential: https://github.com/Azure/autorest.csharp/issues/4166
- throw new NotImplementedException();
- }
-
- public virtual CSharpType PageResponseType()
- {
- // TO-DO: Determine what the correct type is for Page: https://github.com/Azure/autorest.csharp/issues/4166
- throw new NotImplementedException();
- }
+ public virtual CSharpType TokenCredentialType() => typeof(ApiKeyCredential);
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientPipelineExtensionsProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientPipelineExtensionsProvider.cs
index 04f3a5448e..8d3f9a2f19 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientPipelineExtensionsProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientPipelineExtensionsProvider.cs
@@ -1,19 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+using System;
+using System.ClientModel;
using System.ClientModel.Primitives;
-using System.Collections.Generic;
using System.IO;
+using System.Threading.Tasks;
using Microsoft.Generator.CSharp.ClientModel.Snippets;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Providers;
+using Microsoft.Generator.CSharp.Statements;
+using static Microsoft.Generator.CSharp.Snippets.Snippet;
namespace Microsoft.Generator.CSharp.ClientModel.Providers
{
internal class ClientPipelineExtensionsProvider : TypeProvider
{
- public override string RelativeFilePath => Path.Combine("src", "Generated", "Internal", $"{Name}.cs");
- public override string Name { get; }
+ private static readonly Lazy _instance = new(() => new ClientPipelineExtensionsProvider());
+
+ public static ClientPipelineExtensionsProvider Instance => _instance.Value;
private const string _processMessageAsync = "ProcessMessageAsync";
private const string _processMessage = "ProcessMessage";
@@ -22,16 +27,19 @@ internal class ClientPipelineExtensionsProvider : TypeProvider
private ParameterProvider _pipelineParam;
private ParameterProvider _messageParam;
- private ParameterProvider _requestContextParam;
- private MemberExpression _messageResponse;
+ private ParameterProvider _requestOptionsParam;
+ private ClientPipelineSnippet _pipeline;
+ private PipelineMessageSnippet _message;
+ private RequestOptionsSnippet _options;
- internal ClientPipelineExtensionsProvider()
+ public ClientPipelineExtensionsProvider()
{
- Name = "ClientPipelineExtensions";
- _pipelineParam = new ParameterProvider("pipeline", $"The pipeline.", typeof(ClientPipeline));
- _messageParam = new ParameterProvider("message", $"The message.", typeof(PipelineMessage));
- _requestContextParam = new ParameterProvider("requestContext", $"The request context.", typeof(RequestOptions));
- _messageResponse = new MemberExpression(_messageParam, "Response");
+ _pipelineParam = new ParameterProvider("pipeline", FormattableStringHelpers.Empty, typeof(ClientPipeline));
+ _messageParam = new ParameterProvider("message", FormattableStringHelpers.Empty, typeof(PipelineMessage));
+ _requestOptionsParam = new ParameterProvider("options", FormattableStringHelpers.Empty, typeof(RequestOptions));
+ _pipeline = new ClientPipelineSnippet(_pipelineParam);
+ _message = new PipelineMessageSnippet(_messageParam);
+ _options = new RequestOptionsSnippet(_requestOptionsParam);
}
protected override TypeSignatureModifiers GetDeclarationModifiers()
@@ -39,14 +47,135 @@ protected override TypeSignatureModifiers GetDeclarationModifiers()
return TypeSignatureModifiers.Internal | TypeSignatureModifiers.Static;
}
- internal PipelineResponseSnippet ProcessMessage(IReadOnlyList arguments, bool isAsync)
+ public override string Name => "ClientPipelineExtensions";
+
+ public override string RelativeFilePath => Path.Combine("src", "Generated", "Internal", $"{Name}.cs");
+
+ protected override MethodProvider[] BuildMethods()
{
- return new(new InvokeStaticMethodExpression(Type, isAsync ? _processMessageAsync : _processMessage, arguments, CallAsExtension: true, CallAsAsync: isAsync));
+ return
+ [
+ BuildProcessMessageAsync(),
+ BuildProcessMessage(),
+ ProcessHeadAsBoolMessageAsync(),
+ ProcessHeadAsBoolMessage()
+ ];
}
- internal ClientResultSnippet ProcessHeadAsBoolMessage(IReadOnlyList arguments, bool isAsync)
+ private MethodProvider ProcessHeadAsBoolMessage()
{
- return new(new InvokeStaticMethodExpression(Type, isAsync ? _processHeadAsBoolMessageAsync : _processHeadAsBoolMessage, arguments, CallAsExtension: true, CallAsAsync: isAsync));
+ MethodSignature signature = GetProcessHeadAsBoolMessageSignature(false);
+ var responseVariable = new VariableExpression(typeof(PipelineResponse), "response");
+ var response = new PipelineResponseSnippet(responseVariable);
+ return new MethodProvider(signature, new MethodBodyStatement[]
+ {
+ new DeclarationExpression(responseVariable, false).Assign(_pipeline.ProcessMessage(_message, _options, false)).Terminate(),
+ GetProcessHeadAsBoolMessageBody(response)
+ }, this);
+ }
+
+ private MethodProvider ProcessHeadAsBoolMessageAsync()
+ {
+ MethodSignature signature = GetProcessHeadAsBoolMessageSignature(true);
+ var responseVariable = new VariableExpression(typeof(PipelineResponse), "response");
+ var response = new PipelineResponseSnippet(responseVariable);
+ return new MethodProvider(signature, new MethodBodyStatement[]
+ {
+ new DeclarationExpression(responseVariable, false).Assign(_pipeline.ProcessMessage(_message, _options, true)).Terminate(),
+ GetProcessHeadAsBoolMessageBody(response)
+ }, this);
+ }
+
+ private MethodBodyStatement GetProcessHeadAsBoolMessageBody(PipelineResponseSnippet response)
+ {
+ return new MethodBodyStatement[]
+ {
+ new SwitchStatement(new MemberExpression(response, "Status"), new SwitchCaseStatement[]
+ {
+ new SwitchCaseStatement(ValueExpression.Empty.GreaterThanOrEqual(Literal(200)).AndExpr(ValueExpression.Empty.LessThan(Literal(300))), new MethodBodyStatement[]
+ {
+ Return(ClientResultSnippet.FromValue(typeof(bool), True, response))
+ }),
+ new SwitchCaseStatement(ValueExpression.Empty.GreaterThanOrEqual(Literal(400)).AndExpr(ValueExpression.Empty.LessThan(Literal(500))), new MethodBodyStatement[]
+ {
+ Return(ClientResultSnippet.FromValue(typeof(bool), False, response))
+ }),
+ new SwitchCaseStatement(Array.Empty(), new MethodBodyStatement[]
+ {
+ Return(new NewInstanceExpression(ErrorResultSnippet.ErrorResultType.MakeGenericType([typeof(bool)]), [response, new NewInstanceExpression(typeof(ClientResultException), [response])]))
+ })
+ }),
+ };
+ }
+
+ private MethodSignature GetProcessHeadAsBoolMessageSignature(bool isAsync)
+ {
+ var modifiers = MethodSignatureModifiers.Public | MethodSignatureModifiers.Static | MethodSignatureModifiers.Extension;
+ if (isAsync)
+ {
+ modifiers |= MethodSignatureModifiers.Async;
+ }
+ return new MethodSignature(
+ isAsync ? "ProcessHeadAsBoolMessageAsync" : "ProcessHeadAsBoolMessage",
+ null,
+ modifiers,
+ isAsync ? typeof(ValueTask>) : typeof(ClientResult),
+ null,
+ [_pipelineParam, _messageParam, _requestOptionsParam]);
+ }
+
+ private MethodProvider BuildProcessMessage()
+ {
+ MethodSignature signature = GetProcessMessageSignature(false);
+
+ var clientErrorNoThrow = FrameworkEnumValue(ClientErrorBehaviors.NoThrow);
+ return new MethodProvider(signature, new MethodBodyStatement[]
+ {
+ _pipeline.Invoke(nameof(ClientPipeline.Send), [_message]).Terminate(),
+ MethodBodyStatement.EmptyLine,
+ new IfStatement(_message.Response.IsError.And(new BinaryOperatorExpression("&", _options.Property("ErrorOptions", true), clientErrorNoThrow).NotEqual(clientErrorNoThrow)))
+ {
+ Throw(New.Instance(typeof(ClientResultException), _message.Response))
+ },
+ MethodBodyStatement.EmptyLine,
+ Declare(typeof(PipelineResponse), "response", new TernaryConditionalExpression(_message.BufferResponse, _message.Response, _message.ExtractResponse()), out var response),
+ Return(response)
+ }, this);
+ }
+
+ private MethodSignature GetProcessMessageSignature(bool isAsync)
+ {
+ var modifiers = MethodSignatureModifiers.Public | MethodSignatureModifiers.Static | MethodSignatureModifiers.Extension;
+ if (isAsync)
+ {
+ modifiers |= MethodSignatureModifiers.Async;
+ }
+ return new MethodSignature(
+ isAsync ? "ProcessMessageAsync" : "ProcessMessage",
+ null,
+ modifiers,
+ isAsync ? typeof(ValueTask) : typeof(PipelineResponse),
+ null,
+ [_pipelineParam, _messageParam, _requestOptionsParam]);
+ }
+
+ private MethodProvider BuildProcessMessageAsync()
+ {
+ MethodSignature signature = GetProcessMessageSignature(true);
+
+ var clientErrorNoThrow = FrameworkEnumValue(ClientErrorBehaviors.NoThrow);
+ return new MethodProvider(signature, new MethodBodyStatement[]
+ {
+ _pipeline.Expression.Invoke(nameof(ClientPipeline.SendAsync), [_message], true).Terminate(),
+ MethodBodyStatement.EmptyLine,
+ new IfStatement(_message.Response.IsError.And(new BinaryOperatorExpression("&", _options.Property("ErrorOptions", true), clientErrorNoThrow).NotEqual(clientErrorNoThrow)))
+ {
+ Throw(new InvokeStaticMethodExpression(typeof(ClientResultException), nameof(ClientResultException.CreateAsync), [_message.Response], CallAsAsync: true))
+ },
+ MethodBodyStatement.EmptyLine,
+ Declare(typeof(PipelineResponse), "response", new TernaryConditionalExpression(_message.BufferResponse, _message.Response, _message.ExtractResponse()), out var response),
+ Return(response)
+ }, this);
}
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientProvider.cs
index e742878f13..8e1ec50686 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientProvider.cs
@@ -1,14 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.IO;
+using Microsoft.Generator.CSharp.ClientModel.Snippets;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Providers;
+using Microsoft.Generator.CSharp.Snippets;
+using Microsoft.Generator.CSharp.Statements;
namespace Microsoft.Generator.CSharp.ClientModel.Providers
{
- public sealed class ClientProvider : TypeProvider
+ public class ClientProvider : TypeProvider
{
private readonly InputClient _inputClient;
@@ -20,6 +24,25 @@ public ClientProvider(InputClient inputClient)
{
_inputClient = inputClient;
Name = inputClient.Name.ToCleanName();
+ PipelineField = new FieldProvider(FieldModifiers.Private, typeof(ClientPipeline), "_pipeline");
+ }
+
+ public FieldProvider PipelineField { get; }
+
+ protected override FieldProvider[] BuildFields()
+ {
+ return [PipelineField];
+ }
+
+ protected override MethodProvider[] BuildConstructors()
+ {
+ return
+ [
+ new MethodProvider(
+ new ConstructorSignature(Type, $"{_inputClient.Description}", MethodSignatureModifiers.Public, []),
+ new MethodBodyStatement[] { PipelineField.Assign(ClientPipelineSnippet.Create()).Terminate() },
+ this)
+ ];
}
protected override MethodProvider[] BuildMethods()
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ErrorResultProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ErrorResultProvider.cs
new file mode 100644
index 0000000000..cefb16755d
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ErrorResultProvider.cs
@@ -0,0 +1,87 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.ClientModel;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Generator.CSharp.Expressions;
+using Microsoft.Generator.CSharp.Providers;
+using Microsoft.Generator.CSharp.Statements;
+using static Microsoft.Generator.CSharp.Snippets.Snippet;
+
+namespace Microsoft.Generator.CSharp.ClientModel.Providers
+{
+ internal class ErrorResultProvider : TypeProvider
+ {
+ private class ErrorResultTemplate { }
+
+ private CSharpType _t = typeof(ErrorResultTemplate<>).GetGenericArguments()[0];
+ private FieldProvider _responseField;
+ private FieldProvider _exceptionField;
+ private VariableExpression _response;
+ private VariableExpression _exception;
+
+ public ErrorResultProvider()
+ {
+ _responseField = new FieldProvider(FieldModifiers.Private | FieldModifiers.ReadOnly, typeof(PipelineResponse), "_response");
+ _exceptionField = new FieldProvider(FieldModifiers.Private | FieldModifiers.ReadOnly, typeof(ClientResultException), "_exception");
+ _response = new VariableExpression(_responseField.Type, _responseField.Declaration);
+ _exception = new VariableExpression(_exceptionField.Type, _exceptionField.Declaration);
+ }
+
+ protected override TypeSignatureModifiers GetDeclarationModifiers()
+ {
+ return TypeSignatureModifiers.Internal;
+ }
+
+ public override string Name => "ErrorResult";
+
+ public override string RelativeFilePath => Path.Combine("src", "Generated", "Internal", $"{Name}.cs");
+
+ protected override CSharpType[] BuildTypeArguments()
+ {
+ return [_t];
+ }
+
+ protected override CSharpType[] BuildImplements()
+ {
+ return [new CSharpType(typeof(ClientResult<>), _t)];
+ }
+
+ protected override FieldProvider[] BuildFields()
+ {
+ return [_responseField, _exceptionField];
+ }
+
+ protected override MethodProvider[] BuildConstructors()
+ {
+ return [BuildCtor()];
+ }
+
+ private MethodProvider BuildCtor()
+ {
+ var response = new ParameterProvider("response", FormattableStringHelpers.Empty, typeof(PipelineResponse));
+ var exception = new ParameterProvider("exception", FormattableStringHelpers.Empty, typeof(ClientResultException));
+ var baseInitializer = new ConstructorInitializer(true, new List { Default, response });
+ var signature = new ConstructorSignature(Type, null, MethodSignatureModifiers.Public, [response, exception], Initializer: baseInitializer);
+ return new MethodProvider(signature, new MethodBodyStatement[]
+ {
+ _response.Assign(response).Terminate(),
+ _exception.Assign(exception).Terminate(),
+ }, this);
+ }
+
+ protected override PropertyProvider[] BuildProperties()
+ {
+ return [BuildValue()];
+ }
+
+ private PropertyProvider BuildValue()
+ {
+ return new PropertyProvider(null, MethodSignatureModifiers.Public | MethodSignatureModifiers.Override, _t, "Value", new ExpressionPropertyBody(
+ ThrowExpression(_exception)
+ ));
+ }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ModelSerializationExtensionsProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ModelSerializationExtensionsProvider.cs
index 63cb122f6d..d2b94bcb8a 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ModelSerializationExtensionsProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ModelSerializationExtensionsProvider.cs
@@ -206,7 +206,7 @@ private MethodProvider BuildGetBytesFromBase64()
{
Return(Null)
},
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
Return(new SwitchExpression(format,
new SwitchCaseExpression(Literal("U"), FromBase64UrlString(GetRequiredString(element))),
new SwitchCaseExpression(Literal("D"), element.GetBytesFromBase64()),
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/MrwSerializationTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/MrwSerializationTypeProvider.cs
index 770b371ccf..f141116349 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/MrwSerializationTypeProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/MrwSerializationTypeProvider.cs
@@ -350,7 +350,7 @@ private MethodBodyStatement CallBaseJsonModelWriteCore()
// base.()
return _shouldOverrideMethods ?
Base.Invoke(JsonModelWriteCoreMethodName, [_utf8JsonWriterParameter, _serializationOptionsParameter]).Terminate()
- : EmptyStatement;
+ : MethodBodyStatement.Empty;
}
private MethodBodyStatement GetPropertyInitializers(IReadOnlyList parameters)
@@ -601,7 +601,7 @@ private MethodBodyStatement CreateDictionarySerializationStatement(
{
_utf8JsonWriterSnippet.WritePropertyName(keyValuePair.Key),
TypeRequiresNullCheckInSerialization(keyValuePair.ValueType) ?
- new IfStatement(keyValuePair.Value.Equal(Null)) { _utf8JsonWriterSnippet.WriteNullValue(), Continue }: EmptyStatement,
+ new IfStatement(keyValuePair.Value.Equal(Null)) { _utf8JsonWriterSnippet.WriteNullValue(), Continue }: MethodBodyStatement.Empty,
CreateSerializationStatement(keyValuePair.ValueType, keyValuePair.Value, serializationFormat)
},
_utf8JsonWriterSnippet.WriteEndObject()
@@ -618,7 +618,7 @@ private MethodBodyStatement CreateListSerializationStatement(
new ForeachStatement("item", array, out VariableExpression item)
{
TypeRequiresNullCheckInSerialization(item.Type) ?
- new IfStatement(item.Equal(Null)) { _utf8JsonWriterSnippet.WriteNullValue(), Continue } : EmptyStatement,
+ new IfStatement(item.Equal(Null)) { _utf8JsonWriterSnippet.WriteNullValue(), Continue } : MethodBodyStatement.Empty,
CreateSerializationStatement(item.Type, item, serializationFormat)
},
_utf8JsonWriterSnippet.WriteEndArray()
@@ -763,7 +763,7 @@ private MethodBodyStatement CreateWriteAdditionalRawDataStatement()
{
if (_rawDataField == null)
{
- return EmptyStatement;
+ return MethodBodyStatement.Empty;
}
var rawDataMemberExp = new MemberExpression(null, _rawDataField.Name);
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ScmMethodProviderCollection.cs
index 059fd29fcc..6bd4310559 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ScmMethodProviderCollection.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ScmMethodProviderCollection.cs
@@ -1,23 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+using System;
+using System.ClientModel;
+using System.ClientModel.Primitives;
using System.Collections.Generic;
-using Microsoft.Generator.CSharp.Expressions;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Providers;
using Microsoft.Generator.CSharp.Statements;
using static Microsoft.Generator.CSharp.Snippets.Snippet;
-using Microsoft.Generator.CSharp.Snippets;
namespace Microsoft.Generator.CSharp.ClientModel.Providers
{
internal class ScmMethodProviderCollection : MethodProviderCollection
{
+ private string _cleanOperationName;
+ private string _createRequestMethodName;
+
public ScmMethodProviderCollection(InputOperation operation, TypeProvider enclosingType)
: base(operation, enclosingType)
{
+ _cleanOperationName = operation.Name.ToCleanName();
+ _createRequestMethodName = "Create" + _cleanOperationName + "Request";
}
protected override IReadOnlyList BuildMethods()
@@ -25,19 +32,41 @@ protected override IReadOnlyList BuildMethods()
return
[
// TO-DO: Add Protocol and Convenience methods https://github.com/Azure/autorest.csharp/issues/4585, https://github.com/Azure/autorest.csharp/issues/4586
- BuildCreateMessageMethod(_operation, _enclosingType),
- BuildProtocolMethod(_operation, _enclosingType, false),
- BuildProtocolMethod(_operation, _enclosingType, true)
+ BuildCreateMessageMethod(),
+ BuildProtocolMethod(false),
+ BuildProtocolMethod(true)
];
}
- private static MethodProvider BuildProtocolMethod(InputOperation operation, TypeProvider enclosingType, bool isAsync)
+
+ private List? _methodParameters;
+ private List MethodParameters => _methodParameters ??= GetMethodParameters(_operation);
+
+ private static List GetMethodParameters(InputOperation operation)
{
List methodParameters = new();
foreach (InputParameter inputParam in operation.Parameters)
{
if (inputParam.Kind != InputOperationParameterKind.Method)
continue;
- methodParameters.Add(ClientModelPlugin.Instance.TypeFactory.CreateCSharpParam(inputParam));
+ if (inputParam.Location == RequestLocation.Body)
+ {
+ // TODO: add concrete body with https://github.com/Azure/autorest.csharp/issues/4586
+ methodParameters.Add(ScmKnownParameters.BinaryContent);
+ }
+ else
+ {
+ methodParameters.Add(ClientModelPlugin.Instance.TypeFactory.CreateCSharpParam(inputParam));
+ }
+ }
+ return methodParameters;
+ }
+
+ private MethodProvider BuildProtocolMethod(bool isAsync)
+ {
+ ClientProvider? client = _enclosingType as ClientProvider;
+ if (client is null)
+ {
+ throw new InvalidOperationException("Protocol methods can only be built for client types.");
}
var methodModifier = MethodSignatureModifiers.Public | MethodSignatureModifiers.Virtual;
@@ -45,52 +74,61 @@ private static MethodProvider BuildProtocolMethod(InputOperation operation, Type
{
methodModifier |= MethodSignatureModifiers.Async;
}
- var opName = operation.Name.ToCleanName();
var methodSignature = new MethodSignature(
- isAsync ? opName + "Async" : opName,
- FormattableStringHelpers.FromString(operation.Description),
+ isAsync ? _cleanOperationName + "Async" : _cleanOperationName,
+ FormattableStringHelpers.FromString(_operation.Description),
methodModifier,
- GetResponseType(operation.Responses, isAsync),
- null,
- Parameters: [.. methodParameters, KnownParameters.CancellationTokenParameter]);
+ GetResponseType(_operation.Responses, false, isAsync),
+ $"The response returned from the service.",
+ Parameters: [.. MethodParameters, ScmKnownParameters.RequestOptions]);
+ var processMessageName = isAsync ? "ProcessMessageAsync" : "ProcessMessage";
MethodBodyStatement[] methodBody =
[
- //UsingDeclare("message", typeof(RequestMess)
- //using PipelineMessage message = CreateSayHiRequest(headParameter, queryParameter, optionalQuery, options);
- isAsync ? new InvokeStaticPropertyExpression(typeof(Task), nameof(Task.CompletedTask), true).Terminate() : EmptyStatement
+ UsingDeclare("message", typeof(PipelineMessage), This.Invoke(_createRequestMethodName, [.. MethodParameters, ScmKnownParameters.RequestOptions]), out var message),
+ Return(new InvokeStaticMethodExpression(
+ typeof(ClientResult),
+ nameof(ClientResult.FromResponse),
+ client.PipelineField.Invoke(processMessageName, [message, ScmKnownParameters.RequestOptions], isAsync, true))),
];
- return new MethodProvider(methodSignature, methodBody, enclosingType);
+ var protocolMethod = new MethodProvider(methodSignature, methodBody, _enclosingType);
+ protocolMethod.XmlDocs!.Exceptions.Add(new(typeof(ClientResultException), "Service returned a non-success status code.", []));
+ List listItems = new List();
+ listItems.Add(new XmlDocStatement("item", [], new XmlDocStatement("description", [$"This protocol method allows explicit creation of the request and processing of the response for advanced scenarios."])));
+ XmlDocStatement listXmlDoc = new XmlDocStatement("", "
", [], innerStatements: [.. listItems]);
+ protocolMethod.XmlDocs.Summary = new XmlDocSummaryStatement([$"[Protocol Method] {_operation.Description}"], listXmlDoc);
+ return protocolMethod;
}
- private static CSharpType? GetResponseType(IReadOnlyList responses, bool isAsync)
+ private static CSharpType? GetResponseType(IReadOnlyList responses, bool isConvenience, bool isAsync)
+ {
+ var returnType = isConvenience ? GetConvenienceReturnType(responses) : typeof(ClientResult);
+ return isAsync ? new CSharpType(typeof(Task<>), returnType) : returnType;
+ }
+
+ private static CSharpType GetConvenienceReturnType(IReadOnlyList responses)
{
var response = responses.FirstOrDefault(r => !r.IsErrorResponse);
- if (response is null || response.BodyType is null)
- return null;
- var returnType = ClientModelPlugin.Instance.TypeFactory.CreateCSharpType(response.BodyType);
- if (isAsync)
- {
- returnType = returnType.WrapInTask();
- }
- return returnType;
+ return response is null || response.BodyType is null
+ ? typeof(ClientResult)
+ : new CSharpType(typeof(ClientResult<>), ClientModelPlugin.Instance.TypeFactory.CreateCSharpType(response.BodyType));
}
- private static MethodProvider BuildCreateMessageMethod(InputOperation operation, TypeProvider enclosingType)
+ private MethodProvider BuildCreateMessageMethod()
{
// TO-DO: properly build method https://github.com/Azure/autorest.csharp/issues/4583
- List methodParameters = new();
- foreach (var inputParam in operation.Parameters)
- {
- methodParameters.Add(ClientModelPlugin.Instance.TypeFactory.CreateCSharpParam(inputParam));
- }
var methodModifier = MethodSignatureModifiers.Internal;
- var methodSignatureName = $"Create{operation.Name.ToCleanName()}Request";
- var methodSignature = new MethodSignature(methodSignatureName, FormattableStringHelpers.FromString(operation.Description), methodModifier, null, null, Parameters: methodParameters);
+ var methodSignature = new MethodSignature(
+ _createRequestMethodName,
+ FormattableStringHelpers.FromString(_operation.Description),
+ methodModifier,
+ typeof(PipelineMessage),
+ null,
+ Parameters: [.. MethodParameters, ScmKnownParameters.RequestOptions]);
var methodBody = Throw(New.NotImplementedException(Literal("Method not implemented.")));
- return new MethodProvider(methodSignature, methodBody, enclosingType);
+ return new MethodProvider(methodSignature, methodBody, _enclosingType);
}
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/TypeFormattersProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/TypeFormattersProvider.cs
index 1757392197..2ca0acdd82 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/TypeFormattersProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/TypeFormattersProvider.cs
@@ -170,9 +170,9 @@ private MethodProvider BuildToBase64UrlStringMethodProvider()
body.Add(new MethodBodyStatement[]
{
Declare(outputVar, New.Array(typeof(char), size)),
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
Declare("numBase64Chars", new IntSnippet(new InvokeStaticMethodExpression(typeof(Convert), nameof(Convert.ToBase64CharArray), [value, Int(0), valueLength, output, Int(0)])), out var numBase64Chars),
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
Declare("i", Int(0), out var i),
new ForStatement(null, i.LessThan(numBase64Chars), new UnaryOperatorExpression("++", i, true))
{
@@ -188,7 +188,7 @@ private MethodProvider BuildToBase64UrlStringMethodProvider()
Break
}))
},
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
Return(New.Instance(typeof(string), output, Int(0), i))
});
@@ -234,12 +234,12 @@ private MethodProvider BuildFromBase64UrlString()
output[i].Assign(Literal('/')).Terminate()
}, output[i].Assign(ch).Terminate()))
},
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
new ForStatement(null, i.LessThan(outputLength), new UnaryOperatorExpression("++", i, true))
{
output[i].Assign(Literal('=')).Terminate()
},
- EmptyLineStatement,
+ MethodBodyStatement.EmptyLine,
Return(new InvokeStaticMethodExpression(typeof(Convert), nameof(Convert.FromBase64CharArray), new[] { output, Int(0), outputLength }))
});
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ClientPipelineSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ClientPipelineSnippet.cs
new file mode 100644
index 0000000000..8a732c062c
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ClientPipelineSnippet.cs
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using Microsoft.Generator.CSharp.Expressions;
+using Microsoft.Generator.CSharp.Snippets;
+using static Microsoft.Generator.CSharp.Snippets.Snippet;
+
+namespace Microsoft.Generator.CSharp.ClientModel.Snippets
+{
+ internal sealed record ClientPipelineSnippet(ValueExpression Expression) : TypedSnippet(Expression)
+ {
+ private const string _processMessageAsync = "ProcessMessageAsync";
+ private const string _processMessage = "ProcessMessage";
+ private const string _processHeadAsBoolMessageAsync = "ProcessHeadAsBoolMessageAsync";
+ private const string _processHeadAsBoolMessage = "ProcessHeadAsBoolMessage";
+
+ public PipelineMessageSnippet CreateMessage(RequestOptionsSnippet requestOptions, ValueExpression responseClassifier)
+ => new(Expression.Invoke(nameof(ClientPipeline.CreateMessage), requestOptions, responseClassifier));
+
+ public PipelineResponseSnippet ProcessMessage(ValueExpression message, RequestOptionsSnippet? requestOptions, bool isAsync)
+ {
+ var arguments = new List
+ {
+ Expression,
+ message,
+ requestOptions ?? Null
+ };
+
+ return new(new InvokeStaticMethodExpression(Type, isAsync ? _processMessageAsync : _processMessage, arguments, CallAsExtension: true, CallAsAsync: isAsync));
+ }
+
+ public ClientResultSnippet ProcessHeadAsBoolMessage(ValueExpression message, RequestOptionsSnippet? requestContext, bool isAsync)
+ {
+ var arguments = new List
+ {
+ Expression,
+ message,
+ requestContext ?? Null
+ };
+
+ return new(new InvokeStaticMethodExpression(Type, isAsync ? _processHeadAsBoolMessageAsync : _processHeadAsBoolMessage, arguments, CallAsExtension: true, CallAsAsync: isAsync));
+ }
+
+ public static ClientPipelineSnippet Create() => new(InvokeStatic(nameof(ClientPipeline.Create)));
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ErrorResultSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ErrorResultSnippet.cs
new file mode 100644
index 0000000000..8762b8e547
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/ErrorResultSnippet.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.Generator.CSharp.ClientModel.Providers;
+using Microsoft.Generator.CSharp.Expressions;
+using Microsoft.Generator.CSharp.Snippets;
+
+namespace Microsoft.Generator.CSharp.ClientModel.Snippets
+{
+ internal sealed record ErrorResultSnippet(ValueExpression Expression) : TypedSnippet(Expression)
+ {
+ private static readonly ErrorResultProvider _errorResultProvider = new();
+
+ public static CSharpType ErrorResultType => _errorResultProvider.Type;
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineMessageSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineMessageSnippet.cs
index 1248767257..48b02bdc7c 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineMessageSnippet.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineMessageSnippet.cs
@@ -14,5 +14,7 @@ internal sealed record PipelineMessageSnippet(ValueExpression Expression) : Type
public PipelineResponseSnippet Response => new(Property(nameof(PipelineMessage.Response)));
public BoolSnippet BufferResponse => new(Property(nameof(PipelineMessage.BufferResponse)));
+
+ public PipelineResponseSnippet ExtractResponse() => new(Invoke(nameof(PipelineMessage.ExtractResponse), []));
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineResponseSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineResponseSnippet.cs
index 5639f15953..9710a1520e 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineResponseSnippet.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/TypedSnippets/PipelineResponseSnippet.cs
@@ -12,5 +12,7 @@ internal sealed record PipelineResponseSnippet(ValueExpression Expression) : Typ
public BinaryDataSnippet Content => new(Property(nameof(PipelineResponse.Content)));
public StreamSnippet ContentStream => new(Property(nameof(PipelineResponse.ContentStream)));
+
+ public BoolSnippet IsError => new(Property(nameof(PipelineResponse.IsError)));
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockClientTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockClientTypeProvider.cs
new file mode 100644
index 0000000000..908a644a22
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockClientTypeProvider.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.Generator.CSharp.ClientModel.Providers;
+using Microsoft.Generator.CSharp.Input;
+
+namespace Microsoft.Generator.CSharp.ClientModel.Tests
+{
+ internal class MockClientTypeProvider : ClientProvider
+ {
+ public MockClientTypeProvider() : base(new InputClient("TestClient", "TestClient description", [], true, [], null))
+ {
+ }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockTypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockTypeFactory.cs
index 84a6e9374b..ae440182b3 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockTypeFactory.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Mocks/MockTypeFactory.cs
@@ -27,10 +27,6 @@ protected override CSharpType CreateCSharpTypeCore(InputType input)
public override CSharpType MatchConditionsType() => typeof(int);
- public override CSharpType PageResponseType() => typeof(int);
-
- public override CSharpType RequestConditionsType() => typeof(int);
-
public override CSharpType TokenCredentialType() => typeof(int);
public override CSharpType ListInitializationType => new CSharpType(typeof(List<>), arguments: typeof(int));
public override CSharpType DictionaryInitializationType => new CSharpType(typeof(Dictionary<,>), arguments: [typeof(string), typeof(int)]);
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/OutputTypes/ScmKnownParametersTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/OutputTypes/ScmKnownParametersTests.cs
index 584d64e737..22347da2da 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/OutputTypes/ScmKnownParametersTests.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/OutputTypes/ScmKnownParametersTests.cs
@@ -34,14 +34,5 @@ public void TestMatchConditionsParameter()
Assert.IsNotNull(result.Type);
Assert.IsTrue(result.Type.Equals(new CSharpType(typeof(int))));
}
-
- [TestCase]
- public void TestRequestConditionsParameter()
- {
- var result = ScmKnownParameters.RequestConditionsParameter;
- Assert.IsNotNull(result);
- Assert.IsNotNull(result.Type);
- Assert.IsTrue(result.Type.Equals(new CSharpType(typeof(int))));
- }
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs
index d535ec641d..9cc1fbfa46 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs
@@ -52,7 +52,7 @@ public void Teardown()
[TestCaseSource(nameof(DefaultCSharpMethodCollectionTestCases))]
public void TestDefaultCSharpMethodCollection(InputOperation inputOperation)
{
- var methodCollection = new ScmMethodProviderCollection(inputOperation, new MockTypeProvider());
+ var methodCollection = new ScmMethodProviderCollection(inputOperation, new MockClientTypeProvider());
Assert.IsNotNull(methodCollection);
Assert.AreEqual(3, methodCollection.Count);
@@ -63,7 +63,7 @@ public void TestDefaultCSharpMethodCollection(InputOperation inputOperation)
var parameters = signature.Parameters;
Assert.IsNotNull(parameters);
- Assert.AreEqual(inputOperation.Parameters.Count, parameters.Count);
+ Assert.AreEqual(inputOperation.Parameters.Count + 1, parameters.Count);
}
public static IEnumerable DefaultCSharpMethodCollectionTestCases
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/MethodProviderBenchmark.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/MethodProviderBenchmark.cs
index a5cc25b37e..5a9bec0e1d 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/MethodProviderBenchmark.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/MethodProviderBenchmark.cs
@@ -111,7 +111,7 @@ private MethodBodyStatement GetStatementsWithHash(MethodBodyStatement bodyStatem
index++;
}
}
- statements[index] = EmptyLineStatement;
+ statements[index] = MethodBodyStatement.EmptyLine;
index++;
statements[index] = bodyStatements;
@@ -132,7 +132,7 @@ private MethodBodyStatement GetStatementsAsSingleList(MethodBodyStatement origin
}
}
if (wroteValidation)
- statements.Add(EmptyLineStatement);
+ statements.Add(MethodBodyStatement.EmptyLine);
statements.Add(original);
return statements;
@@ -150,7 +150,7 @@ private IEnumerable GetValidationStatementsWithYield()
}
}
if (wroteValidation)
- yield return EmptyLineStatement;
+ yield return MethodBodyStatement.EmptyLine;
}
private IReadOnlyList GetValidationStatements()
@@ -166,7 +166,7 @@ private IReadOnlyList GetValidationStatements()
}
}
if (wroteValidation)
- statements.Add(EmptyLineStatement);
+ statements.Add(MethodBodyStatement.EmptyLine);
return statements;
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/BinaryOperatorExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/BinaryOperatorExpression.cs
index 4fa063d56f..25f9794cd1 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/BinaryOperatorExpression.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/BinaryOperatorExpression.cs
@@ -9,7 +9,9 @@ internal override void Write(CodeWriter writer)
{
writer.AppendRaw("(");
Left.Write(writer);
- writer.AppendRaw(" ").AppendRaw(Operator).AppendRaw(" ");
+ writer.AppendRawIf(" ", !ReferenceEquals(Left, Empty));
+ writer.AppendRaw(Operator);
+ writer.AppendRawIf(" ", !ReferenceEquals(Right, Empty));
Right.Write(writer);
writer.AppendRaw(")");
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/ValueExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/ValueExpression.cs
index ee6888a477..623ae7c8d3 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/ValueExpression.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/ValueExpression.cs
@@ -6,7 +6,6 @@
using System.Diagnostics;
using System.Linq;
using Microsoft.Generator.CSharp.Snippets;
-using Microsoft.Generator.CSharp.Statements;
namespace Microsoft.Generator.CSharp.Expressions
{
@@ -16,6 +15,10 @@ namespace Microsoft.Generator.CSharp.Expressions
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
public record ValueExpression
{
+ public static readonly ValueExpression Empty = new();
+
+ protected ValueExpression() { }
+
internal virtual void Write(CodeWriter writer) { }
public static implicit operator ValueExpression(Type type) => new TypeReferenceExpression(type);
@@ -61,6 +64,7 @@ public InvokeInstanceMethodExpression Invoke(string methodName, IReadOnlyList new CastExpression(this, to);
public BoolSnippet GreaterThan(ValueExpression other) => new(new BinaryOperatorExpression(">", this, other));
+ public BoolSnippet GreaterThanOrEqual(ValueExpression other) => new(new BinaryOperatorExpression(">=", this, other));
public BoolSnippet LessThan(ValueExpression other) => new(new BinaryOperatorExpression("<", this, other));
@@ -70,7 +74,9 @@ public InvokeInstanceMethodExpression Invoke(string methodName, IReadOnlyList new(new BinaryOperatorExpression("is", this, other));
- public ValueExpression Increment() => new UnaryOperatorExpression("++", this, true);
+ public ValueExpression Increment() => new UnaryOperatorExpression("++", this, true);
+
+ public ValueExpression AndExpr(ValueExpression other) => new BinaryOperatorExpression("and", this, other);
private string GetDebuggerDisplay()
{
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpType.cs
index d61a0e3cd2..dc26cf1fab 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpType.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpType.cs
@@ -609,15 +609,5 @@ public CSharpType MakeGenericType(IReadOnlyList arguments)
return new CSharpType(Implementation, arguments, IsNullable);
}
}
-
- public CSharpType WrapInTask()
- {
- if (IsFrameworkType && FrameworkType == typeof(Task<>))
- {
- return this;
- }
-
- return new CSharpType(typeof(Task<>), this);
- }
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs
index d39d03778c..4800bb71bb 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs
@@ -5,5 +5,5 @@
namespace Microsoft.Generator.CSharp
{
- internal record ExpressionPropertyBody(ValueExpression Getter) : PropertyBody(false);
+ public record ExpressionPropertyBody(ValueExpression Getter) : PropertyBody(false);
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ChangeTrackingListProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ChangeTrackingListProvider.cs
index 365af0ae1c..334e969782 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ChangeTrackingListProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ChangeTrackingListProvider.cs
@@ -78,7 +78,7 @@ protected override MethodProvider[] BuildConstructors()
return
[
- new MethodProvider(new ConstructorSignature(Type, null, MethodSignatureModifiers.Public, Array.Empty()), EmptyStatement, this),
+ new MethodProvider(new ConstructorSignature(Type, null, MethodSignatureModifiers.Public, Array.Empty()), MethodBodyStatement.Empty, this),
new MethodProvider(iListSignature, iListBody, this),
new MethodProvider(iReadOnlyListSignature, iReadOnlyListBody, this)
];
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/MethodProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/MethodProvider.cs
index b53284c650..ea071eeca7 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/MethodProvider.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/MethodProvider.cs
@@ -106,7 +106,7 @@ private MethodBodyStatement GetBodyStatementWithValidation(MethodBodyStatement b
index++;
}
}
- statements[index] = EmptyLineStatement;
+ statements[index] = MethodBodyStatement.EmptyLine;
index++;
statements[index] = bodyStatements;
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/Snippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/Snippet.cs
index c9a8c7daa2..bcfb4b56a1 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/Snippet.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/Snippet.cs
@@ -12,17 +12,6 @@ namespace Microsoft.Generator.CSharp.Snippets
{
public static partial class Snippet
{
- private class PrivateEmptyLineStatement : MethodBodyStatement
- {
- internal override void Write(CodeWriter writer)
- {
- writer.WriteLine();
- }
- }
-
- public static readonly MethodBodyStatement EmptyStatement = new();
- public static readonly MethodBodyStatement EmptyLineStatement = new PrivateEmptyLineStatement();
-
public static ValueExpression Identifier(string name) => new MemberExpression(null, name);
public static MethodBodyStatement AsStatement(this IEnumerable statements) => statements.ToArray();
@@ -97,5 +86,8 @@ public static InvokeInstanceMethodExpression Invoke(this ParameterProvider param
public static ValueExpression Property(this ParameterProvider parameter, string propertyName, bool nullConditional = false)
=> new MemberExpression(nullConditional ? new NullConditionalExpression(parameter) : parameter, propertyName);
+
+ public static ValueExpression Invoke(this FieldProvider field, string methodName, IEnumerable parameters, bool isAsync, bool configureAwait)
+ => new InvokeInstanceMethodExpression(field, methodName, [.. parameters], null, isAsync, configureAwait);
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/MethodBodyStatement.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/MethodBodyStatement.cs
index 40e4ea4af1..341d50aab3 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/MethodBodyStatement.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/MethodBodyStatement.cs
@@ -13,6 +13,17 @@ internal virtual void Write(CodeWriter writer) { }
public static implicit operator MethodBodyStatement(MethodBodyStatement[] statements) => new MethodBodyStatements(statements);
public static implicit operator MethodBodyStatement(List statements) => new MethodBodyStatements(statements);
+ private class PrivateEmptyLineStatement : MethodBodyStatement
+ {
+ internal override void Write(CodeWriter writer)
+ {
+ writer.WriteLine();
+ }
+ }
+
+ public static readonly MethodBodyStatement Empty = new();
+ public static readonly MethodBodyStatement EmptyLine = new PrivateEmptyLineStatement();
+
private string GetDebuggerDisplay()
{
using CodeWriter writer = new CodeWriter();
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/XmlDocExceptionStatement.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/XmlDocExceptionStatement.cs
index 5131babee0..3de7f9e457 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/XmlDocExceptionStatement.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Statements/XmlDocExceptionStatement.cs
@@ -22,6 +22,13 @@ public XmlDocExceptionStatement(ParameterValidationType validationType, IReadOnl
_reason = GetText(validationType);
}
+ public XmlDocExceptionStatement(Type exceptionType, string reason, IReadOnlyList parameters)
+ {
+ ExceptionType = exceptionType;
+ Parameters = parameters;
+ _reason = reason;
+ }
+
private static Type GetExceptionType(ParameterValidationType validationType) => validationType switch
{
ParameterValidationType.AssertNotNull => typeof(ArgumentNullException),
@@ -42,13 +49,16 @@ internal override void Write(CodeWriter writer)
writer.Append($"/// ");
- writer.Append($" ");
- for (int i = 1; i < Parameters.Count - 1; i++)
+ if (Parameters.Count > 0)
{
- writer.Append($", ");
+ writer.Append($" ");
+ for (int i = 1; i < Parameters.Count - 1; i++)
+ {
+ writer.Append($", ");
+ }
+ if (Parameters.Count > 1)
+ writer.Append($" or ");
}
- if (Parameters.Count > 1)
- writer.Append($" or ");
writer.WriteLine($" {_reason} ");
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/ArgumentSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/ArgumentSnippet.cs
index b0f99274d0..5e60410983 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/ArgumentSnippet.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/ArgumentSnippet.cs
@@ -35,7 +35,7 @@ public static MethodBodyStatement AssertNotNullOrWhiteSpace(ValueExpression vari
{
ParameterValidationType.AssertNotNullOrEmpty => AssertNotNullOrEmpty(parameter),
ParameterValidationType.AssertNotNull => AssertNotNull(parameter),
- _ => Snippet.EmptyStatement
+ _ => MethodBodyStatement.Empty
};
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/TypedSnippet.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/TypedSnippet.cs
index 41e8509925..4bdc85833b 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/TypedSnippet.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/TypedSnippets/TypedSnippet.cs
@@ -46,6 +46,8 @@ protected static ValueExpression ValidateType(TypedSnippet typed, CSharpType typ
public InvokeInstanceMethodExpression Invoke(string methodName, params ValueExpression[] args)
=> new InvokeInstanceMethodExpression(this, methodName, [..args], null, false);
+ public ValueExpression AndExpr(ValueExpression other) => new BinaryOperatorExpression("and", this, other);
+
private string GetDebuggerDisplay()
{
using CodeWriter writer = new CodeWriter();
diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Expressions/KnownValueExpressionsTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Expressions/KnownValueExpressionsTests.cs
index ce3a596b04..42af7ae3d4 100644
--- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Expressions/KnownValueExpressionsTests.cs
+++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Expressions/KnownValueExpressionsTests.cs
@@ -3,10 +3,8 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Snippets;
-using Microsoft.Generator.CSharp.Statements;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests.Expressions
@@ -16,29 +14,29 @@ public class KnownValueExpressionsTests
[Test]
public void BinaryOperatorExpressionWithOrOperator()
{
- var left = new ValueExpression();
- var right = new ValueExpression();
+ var left = ValueExpression.Empty;
+ var right = ValueExpression.Empty;
var boolExpression = new BoolSnippet(left);
var result = boolExpression.Or(right);
using var writer = new CodeWriter();
result.Expression.Write(writer);
- Assert.AreEqual("( || )", writer.ToString(false));
+ Assert.AreEqual("(||)", writer.ToString(false));
}
[Test]
public void BinaryOperatorExpressionWithAndOperator()
{
- var left = new ValueExpression();
- var right = new ValueExpression();
+ var left = ValueExpression.Empty;
+ var right = ValueExpression.Empty;
var boolExpression = new BoolSnippet(left);
var result = boolExpression.And(right);
using var writer = new CodeWriter();
result.Expression.Write(writer);
- Assert.AreEqual("( && )", writer.ToString(false));
+ Assert.AreEqual("(&&)", writer.ToString(false));
}
[TestCase(typeof(int))]
@@ -57,7 +55,7 @@ public void BinaryOperatorExpressionWithAndOperator()
public void ListExpression(Type T)
{
var itemType = new CSharpType(T);
- var untypedValue = new ValueExpression();
+ var untypedValue = ValueExpression.Empty;
var listExpression = new ListSnippet(itemType, untypedValue);
@@ -71,8 +69,8 @@ public void ListExpression(Type T)
[Test]
public void ListExpressionAddItem()
{
- var item = new ValueExpression();
- var listExpression = new ListSnippet(new CSharpType(typeof(int)), new ValueExpression());
+ var item = ValueExpression.Empty;
+ var listExpression = new ListSnippet(new CSharpType(typeof(int)), ValueExpression.Empty);
var result = listExpression.Add(item);
@@ -100,7 +98,7 @@ public void DictionaryExpression(Type t1, Type t2)
{
var keyType = new CSharpType(t1);
var valueType = new CSharpType(t2);
- var untypedValue = new ValueExpression();
+ var untypedValue = ValueExpression.Empty;
var dictionaryExpression = new DictionarySnippet(t1, t2, untypedValue);
@@ -114,10 +112,10 @@ public void DictionaryExpressionAddItems()
{
var keyType = new CSharpType(typeof(int));
var valueType = new CSharpType(typeof(string));
- var dictionaryExpression = new DictionarySnippet(keyType, valueType, new ValueExpression());
+ var dictionaryExpression = new DictionarySnippet(keyType, valueType, ValueExpression.Empty);
- var key = new ValueExpression();
- var value = new ValueExpression();
+ var key = ValueExpression.Empty;
+ var value = ValueExpression.Empty;
var result = dictionaryExpression.Add(key, value);
var expectedStatement = dictionaryExpression.Invoke(nameof(Dictionary