Add support for spread of aliases & models (#4199)
This PR adds support for spread of aliases & models within a client operation's parameters. fixes: https://github.com/microsoft/typespec/issues/3831 --------- Co-authored-by: m-nash <64171366+m-nash@users.noreply.github.com>
This commit is contained in:
Родитель
e8c493e015
Коммит
371d5c1adb
|
@ -33,7 +33,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Primitives
|
|||
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)) { Validation = ParameterValidationType.AssertNotNull };
|
||||
public static readonly ParameterProvider BinaryContent = new("content", $"The content to send as the body of the request.", typeof(BinaryContent), location: ParameterLocation.Body) { Validation = ParameterValidationType.AssertNotNull };
|
||||
|
||||
// Known header parameters
|
||||
public static readonly ParameterProvider RepeatabilityRequestId = new("repeatabilityRequestId", FormattableStringHelpers.Empty, typeof(Guid))
|
||||
|
|
|
@ -356,6 +356,43 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<ParameterProvider> BuildSpreadParametersForModel(InputModelType inputModel)
|
||||
{
|
||||
var builtParameters = new ParameterProvider[inputModel.Properties.Count];
|
||||
|
||||
int index = 0;
|
||||
foreach (var property in inputModel.Properties)
|
||||
{
|
||||
// convert the property to a parameter
|
||||
var inputParameter = new InputParameter(
|
||||
property.Name,
|
||||
property.SerializedName,
|
||||
property.Description,
|
||||
property.Type,
|
||||
RequestLocation.Body,
|
||||
null,
|
||||
InputOperationParameterKind.Method,
|
||||
property.IsRequired,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null);
|
||||
|
||||
var paramProvider = ClientModelPlugin.Instance.TypeFactory.CreateParameter(inputParameter);
|
||||
paramProvider.DefaultValue = !inputParameter.IsRequired ? Default : null;
|
||||
paramProvider.SpreadSource = ClientModelPlugin.Instance.TypeFactory.CreateModel(inputModel);
|
||||
paramProvider.Type = paramProvider.Type.InputType;
|
||||
|
||||
builtParameters[index++] = paramProvider;
|
||||
}
|
||||
|
||||
return builtParameters;
|
||||
}
|
||||
|
||||
private static bool TryGetSpecialHeaderParam(InputParameter inputParameter, [NotNullWhen(true)] out ParameterProvider? parameterProvider)
|
||||
{
|
||||
if (inputParameter.Location == RequestLocation.Header)
|
||||
|
@ -375,12 +412,22 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
|
||||
internal static List<ParameterProvider> GetMethodParameters(InputOperation operation, bool isProtocol = false)
|
||||
{
|
||||
List<ParameterProvider> methodParameters = new();
|
||||
SortedList<int, ParameterProvider> sortedParams = [];
|
||||
int path = 0;
|
||||
int required = 100;
|
||||
int bodyRequired = 200;
|
||||
int bodyOptional = 300;
|
||||
int contentType = 400;
|
||||
int optional = 500;
|
||||
|
||||
foreach (InputParameter inputParam in operation.Parameters)
|
||||
{
|
||||
if (inputParam.Kind != InputOperationParameterKind.Method || TryGetSpecialHeaderParam(inputParam, out var _))
|
||||
if ((inputParam.Kind != InputOperationParameterKind.Method && inputParam.Kind != InputOperationParameterKind.Spread)
|
||||
|| TryGetSpecialHeaderParam(inputParam, out var _))
|
||||
continue;
|
||||
|
||||
var spreadInputModel = inputParam.Kind == InputOperationParameterKind.Spread ? GetSpreadParameterModel(inputParam) : null;
|
||||
|
||||
ParameterProvider? parameter = ClientModelPlugin.Instance.TypeFactory.CreateParameter(inputParam);
|
||||
|
||||
if (isProtocol)
|
||||
|
@ -394,11 +441,66 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
parameter.Type = parameter.Type.IsEnum ? parameter.Type.UnderlyingEnumType : parameter.Type;
|
||||
}
|
||||
}
|
||||
else if (spreadInputModel != null)
|
||||
{
|
||||
foreach (var bodyParam in BuildSpreadParametersForModel(spreadInputModel))
|
||||
{
|
||||
if (bodyParam.DefaultValue is null)
|
||||
{
|
||||
sortedParams.Add(bodyRequired++, bodyParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortedParams.Add(bodyOptional++, bodyParam);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parameter is not null)
|
||||
methodParameters.Add(parameter);
|
||||
if (parameter is null)
|
||||
continue;
|
||||
|
||||
switch (parameter.Location)
|
||||
{
|
||||
case ParameterLocation.Path:
|
||||
case ParameterLocation.Uri:
|
||||
sortedParams.Add(path++, parameter);
|
||||
break;
|
||||
case ParameterLocation.Query:
|
||||
case ParameterLocation.Header:
|
||||
if (inputParam.IsContentType)
|
||||
{
|
||||
sortedParams.Add(contentType++, parameter);
|
||||
}
|
||||
else if (parameter.Validation != ParameterValidationType.None)
|
||||
{
|
||||
sortedParams.Add(required++, parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortedParams.Add(optional++, parameter);
|
||||
}
|
||||
break;
|
||||
case ParameterLocation.Body:
|
||||
sortedParams.Add(bodyRequired++, parameter);
|
||||
break;
|
||||
default:
|
||||
sortedParams.Add(optional++, parameter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return methodParameters;
|
||||
|
||||
return [.. sortedParams.Values];
|
||||
}
|
||||
|
||||
internal static InputModelType GetSpreadParameterModel(InputParameter inputParam)
|
||||
{
|
||||
if (inputParam.Kind.HasFlag(InputOperationParameterKind.Spread) && inputParam.Type is InputModelType model)
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"inputParam `{inputParam.Name}` is `Spread` but not a model type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
{
|
||||
methodModifier |= MethodSignatureModifiers.Async;
|
||||
}
|
||||
|
||||
var methodSignature = new MethodSignature(
|
||||
isAsync ? _cleanOperationName + "Async" : _cleanOperationName,
|
||||
FormattableStringHelpers.FromString(Operation.Description),
|
||||
|
@ -74,12 +75,13 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
var processMessageName = isAsync ? "ProcessMessageAsync" : "ProcessMessage";
|
||||
|
||||
MethodBodyStatement[] methodBody;
|
||||
|
||||
if (responseBodyType is null)
|
||||
{
|
||||
methodBody =
|
||||
[
|
||||
.. GetStackVariablesForProtocolParamConversion(ConvenienceMethodParameters, out var paramDeclarations),
|
||||
Return(This.Invoke(protocolMethod.Signature, [.. GetParamConversions(ConvenienceMethodParameters, paramDeclarations), Null], isAsync))
|
||||
.. GetStackVariablesForProtocolParamConversion(ConvenienceMethodParameters, out var declarations),
|
||||
Return(This.Invoke(protocolMethod.Signature, [.. GetParamConversions(ConvenienceMethodParameters, declarations), Null], isAsync))
|
||||
];
|
||||
}
|
||||
else
|
||||
|
@ -88,11 +90,11 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
[
|
||||
.. GetStackVariablesForProtocolParamConversion(ConvenienceMethodParameters, out var paramDeclarations),
|
||||
Declare("result", This.Invoke(protocolMethod.Signature, [.. GetParamConversions(ConvenienceMethodParameters, paramDeclarations), Null], isAsync).As<ClientResult>(), out ScopedApi<ClientResult> result),
|
||||
.. GetStackVariablesForReturnValueConversion(result, responseBodyType, isAsync, out var declarations),
|
||||
.. GetStackVariablesForReturnValueConversion(result, responseBodyType, isAsync, out var resultDeclarations),
|
||||
Return(Static<ClientResult>().Invoke(
|
||||
nameof(ClientResult.FromValue),
|
||||
[
|
||||
GetResultConversion(result, responseBodyType, declarations),
|
||||
GetResultConversion(result, responseBodyType, resultDeclarations),
|
||||
result.Invoke("GetRawResponse")
|
||||
])),
|
||||
];
|
||||
|
@ -109,6 +111,9 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
declarations = new Dictionary<string, ValueExpression>();
|
||||
foreach (var parameter in convenienceMethodParameters)
|
||||
{
|
||||
if (parameter.SpreadSource is not null)
|
||||
continue;
|
||||
|
||||
if (parameter.Location == ParameterLocation.Body)
|
||||
{
|
||||
if (parameter.Type.IsReadOnlyMemory)
|
||||
|
@ -136,9 +141,53 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add spread parameter model variable declaration
|
||||
var spreadSource = convenienceMethodParameters.FirstOrDefault(p => p.SpreadSource is not null)?.SpreadSource;
|
||||
if (spreadSource is not null)
|
||||
{
|
||||
statements.Add(Declare("spreadModel", New.Instance(spreadSource.Type, [.. GetSpreadConversion(spreadSource)]).As(spreadSource.Type), out var spread));
|
||||
declarations["spread"] = spread;
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
private List<ValueExpression> GetSpreadConversion(TypeProvider spreadSource)
|
||||
{
|
||||
var convenienceMethodParams = ConvenienceMethodParameters.ToDictionary(p => p.Name);
|
||||
List<ValueExpression> expressions = new(spreadSource.Properties.Count);
|
||||
// we should make this find more deterministic
|
||||
var ctor = spreadSource.Constructors.First(c => c.Signature.Parameters.Count == spreadSource.Properties.Count + 1 &&
|
||||
c.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Internal));
|
||||
|
||||
foreach (var param in ctor.Signature.Parameters)
|
||||
{
|
||||
if (convenienceMethodParams.TryGetValue(param.Name, out var convenienceParam))
|
||||
{
|
||||
if (convenienceParam.Type.IsList)
|
||||
{
|
||||
var interfaceType = param.Property!.WireInfo?.IsReadOnly == true
|
||||
? new CSharpType(typeof(IReadOnlyList<>), convenienceParam.Type.Arguments)
|
||||
: new CSharpType(typeof(IList<>), convenienceParam.Type.Arguments);
|
||||
expressions.Add(NullCoalescing(
|
||||
new AsExpression(convenienceParam.NullConditional().ToList(), interfaceType),
|
||||
New.Instance(convenienceParam.Type.PropertyInitializationType, [])));
|
||||
}
|
||||
else
|
||||
{
|
||||
expressions.Add(convenienceParam);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
expressions.Add(Null);
|
||||
}
|
||||
}
|
||||
|
||||
return expressions;
|
||||
}
|
||||
|
||||
private IEnumerable<MethodBodyStatement> GetStackVariablesForReturnValueConversion(ScopedApi<ClientResult> result, CSharpType responseBodyType, bool isAsync, out Dictionary<string, ValueExpression> declarations)
|
||||
{
|
||||
if (responseBodyType.IsList)
|
||||
|
@ -216,9 +265,18 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
|
|||
private IReadOnlyList<ValueExpression> GetParamConversions(IReadOnlyList<ParameterProvider> convenienceMethodParameters, Dictionary<string, ValueExpression> declarations)
|
||||
{
|
||||
List<ValueExpression> conversions = new List<ValueExpression>();
|
||||
bool addedSpreadSource = false;
|
||||
foreach (var param in convenienceMethodParameters)
|
||||
{
|
||||
if (param.Location == ParameterLocation.Body)
|
||||
if (param.SpreadSource is not null)
|
||||
{
|
||||
if (!addedSpreadSource)
|
||||
{
|
||||
conversions.Add(declarations["spread"]);
|
||||
addedSpreadSource = true;
|
||||
}
|
||||
}
|
||||
else if (param.Location == ParameterLocation.Body)
|
||||
{
|
||||
if (param.Type.IsReadOnlyMemory || param.Type.IsList)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.ClientModel;
|
||||
using System.ClientModel.Primitives;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -25,6 +26,13 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
private static readonly InputClient _animalClient = new("animal", "AnimalClient description", [], [], TestClientName);
|
||||
private static readonly InputClient _dogClient = new("dog", "DogClient description", [], [], _animalClient.Name);
|
||||
private static readonly InputClient _huskyClient = new("husky", "HuskyClient description", [], [], _dogClient.Name);
|
||||
private static readonly InputModelType _spreadModel = InputFactory.Model(
|
||||
"spreadModel",
|
||||
usage: InputModelTypeUsage.Spread,
|
||||
properties:
|
||||
[
|
||||
InputFactory.Property("p1", InputPrimitiveType.String, isRequired: true),
|
||||
]);
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
|
@ -365,6 +373,33 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
Assert.AreEqual(Helpers.GetExpectedFromFile(), codeFile.Content);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(ValidateClientWithSpreadTestCases))]
|
||||
public void ValidateClientWithSpread(InputClient inputClient)
|
||||
{
|
||||
var clientProvider = new ClientProvider(inputClient);
|
||||
var methods = clientProvider.Methods;
|
||||
|
||||
Assert.AreEqual(4, methods.Count);
|
||||
|
||||
var protocolMethods = methods.Where(m => m.Signature.Parameters.Any(p => p.Type.Equals(typeof(BinaryContent)))).ToList();
|
||||
Assert.AreEqual(2, protocolMethods.Count);
|
||||
Assert.AreEqual(2, protocolMethods[0].Signature.Parameters.Count);
|
||||
Assert.AreEqual(2, protocolMethods[1].Signature.Parameters.Count);
|
||||
|
||||
Assert.AreEqual(new CSharpType(typeof(BinaryContent)), protocolMethods[0].Signature.Parameters[0].Type);
|
||||
Assert.AreEqual(new CSharpType(typeof(RequestOptions)), protocolMethods[0].Signature.Parameters[1].Type);
|
||||
Assert.AreEqual(new CSharpType(typeof(BinaryContent)), protocolMethods[1].Signature.Parameters[0].Type);
|
||||
Assert.AreEqual(new CSharpType(typeof(RequestOptions)), protocolMethods[1].Signature.Parameters[1].Type);
|
||||
|
||||
var convenienceMethods = methods.Where(m => m.Signature.Parameters.Any(p => p.Type.Equals(typeof(string)))).ToList();
|
||||
Assert.AreEqual(2, convenienceMethods.Count);
|
||||
Assert.AreEqual(1, convenienceMethods[0].Signature.Parameters.Count);
|
||||
|
||||
Assert.AreEqual(new CSharpType(typeof(string)), convenienceMethods[0].Signature.Parameters[0].Type);
|
||||
Assert.AreEqual("p1", convenienceMethods[0].Signature.Parameters[0].Name);
|
||||
|
||||
}
|
||||
|
||||
private static InputClient GetEnumQueryParamClient()
|
||||
=> InputFactory.Client(
|
||||
TestClientName,
|
||||
|
@ -386,6 +421,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
InputFactory.EnumMember.String("value1", "value1"),
|
||||
InputFactory.EnumMember.String("value2", "value2")
|
||||
]),
|
||||
isRequired: true,
|
||||
location: RequestLocation.Query)
|
||||
])
|
||||
]);
|
||||
|
@ -469,6 +505,29 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TestCaseData> ValidateClientWithSpreadTestCases
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData(InputFactory.Client(
|
||||
TestClientName,
|
||||
operations:
|
||||
[
|
||||
InputFactory.Operation(
|
||||
"CreateMessage",
|
||||
parameters:
|
||||
[
|
||||
InputFactory.Parameter(
|
||||
"spread",
|
||||
_spreadModel,
|
||||
location: RequestLocation.Body,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Spread),
|
||||
])
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TestCaseData> BuildConstructorsTestCases
|
||||
{
|
||||
get
|
||||
|
|
|
@ -4,17 +4,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.Generator.CSharp.ClientModel.Providers;
|
||||
using Microsoft.Generator.CSharp.Input;
|
||||
using Microsoft.Generator.CSharp.Primitives;
|
||||
using Microsoft.Generator.CSharp.Providers;
|
||||
using Microsoft.Generator.CSharp.Tests.Common;
|
||||
using NUnit.Framework;
|
||||
using Microsoft.Generator.CSharp.Snippets;
|
||||
|
||||
namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
||||
{
|
||||
public class RestClientProviderTests
|
||||
{
|
||||
private static readonly InputModelType _spreadModel = InputFactory.Model(
|
||||
"spreadModel",
|
||||
usage: InputModelTypeUsage.Spread,
|
||||
properties:
|
||||
[
|
||||
InputFactory.Property("p1", InputPrimitiveType.String, isRequired: true),
|
||||
InputFactory.Property("optionalProp", InputPrimitiveType.String, isRequired: false)
|
||||
]);
|
||||
|
||||
public RestClientProviderTests()
|
||||
{
|
||||
MockHelpers.LoadMockPlugin();
|
||||
|
@ -120,6 +131,58 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
p.Name.Equals("repeatabilityFirstSent", StringComparison.OrdinalIgnoreCase) &&
|
||||
p.Name.Equals("repeatabilityRequestId", StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
var spreadInputParameter = inputOperation.Parameters.FirstOrDefault(p => p.Kind == InputOperationParameterKind.Spread);
|
||||
if (spreadInputParameter != null)
|
||||
{
|
||||
Assert.AreEqual(_spreadModel.Properties.Count + 1, methodParameters.Count);
|
||||
// validate path parameter
|
||||
Assert.AreEqual(inputOperation.Parameters[1].Name, methodParameters[0].Name);
|
||||
// validate spread parameters
|
||||
Assert.AreEqual(_spreadModel.Properties[0].Name, methodParameters[1].Name);
|
||||
Assert.IsNull(methodParameters[1].DefaultValue);
|
||||
// validate optional parameter
|
||||
Assert.AreEqual(_spreadModel.Properties[1].Name, methodParameters[2].Name);
|
||||
Assert.AreEqual(Snippet.Default, methodParameters[2].DefaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestGetMethodParameters_ProperOrdering()
|
||||
{
|
||||
var methodParameters = RestClientProvider.GetMethodParameters(OperationWithMixedParamOrdering);
|
||||
|
||||
Assert.AreEqual(OperationWithMixedParamOrdering.Parameters.Count, methodParameters.Count);
|
||||
|
||||
// validate ordering
|
||||
Assert.AreEqual("requiredPath", methodParameters[0].Name);
|
||||
Assert.AreEqual("requiredQuery", methodParameters[1].Name);
|
||||
Assert.AreEqual("requiredHeader", methodParameters[2].Name);
|
||||
Assert.AreEqual("body", methodParameters[3].Name);
|
||||
Assert.AreEqual("contentType", methodParameters[4].Name);
|
||||
Assert.AreEqual("optionalQuery", methodParameters[5].Name);
|
||||
Assert.AreEqual("optionalHeader", methodParameters[6].Name);
|
||||
|
||||
var orderedPathParams = RestClientProvider.GetMethodParameters(OperationWithOnlyPathParams);
|
||||
Assert.AreEqual(OperationWithOnlyPathParams.Parameters.Count, orderedPathParams.Count);
|
||||
Assert.AreEqual("c", orderedPathParams[0].Name);
|
||||
Assert.AreEqual("a", orderedPathParams[1].Name);
|
||||
Assert.AreEqual("b", orderedPathParams[2].Name);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(GetSpreadParameterModelTestCases))]
|
||||
public void TestGetSpreadParameterModel(InputParameter inputParameter)
|
||||
{
|
||||
if (inputParameter.Kind == InputOperationParameterKind.Spread)
|
||||
{
|
||||
var model = RestClientProvider.GetSpreadParameterModel(inputParameter);
|
||||
Assert.AreEqual(_spreadModel, model);
|
||||
}
|
||||
else
|
||||
{
|
||||
// assert throws
|
||||
Assert.Throws<InvalidOperationException>(() => RestClientProvider.GetSpreadParameterModel(inputParameter));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -151,6 +214,103 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
InputFactory.Parameter("message", InputPrimitiveType.Boolean, isRequired: true)
|
||||
]);
|
||||
|
||||
private readonly static InputOperation OperationWithSpreadParam = InputFactory.Operation(
|
||||
"CreateMessageWithSpread",
|
||||
parameters:
|
||||
[
|
||||
InputFactory.Parameter(
|
||||
"spread",
|
||||
_spreadModel,
|
||||
location: RequestLocation.Body,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Spread),
|
||||
InputFactory.Parameter(
|
||||
"p2",
|
||||
InputPrimitiveType.Boolean,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method)
|
||||
]);
|
||||
|
||||
private static readonly InputOperation OperationWithMixedParamOrdering = InputFactory.Operation(
|
||||
"CreateMessage",
|
||||
parameters:
|
||||
[
|
||||
// require query param
|
||||
InputFactory.Parameter(
|
||||
"requiredQuery",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Query,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// optional query param
|
||||
InputFactory.Parameter(
|
||||
"optionalQuery",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Query,
|
||||
isRequired: false,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// required path param
|
||||
InputFactory.Parameter(
|
||||
"requiredPath",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// required header param
|
||||
InputFactory.Parameter(
|
||||
"requiredHeader",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Header,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// optional header param
|
||||
InputFactory.Parameter(
|
||||
"optionalHeader",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Header,
|
||||
isRequired: false,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// content type param
|
||||
InputFactory.Parameter(
|
||||
"contentType",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Header,
|
||||
isContentType: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
// body param
|
||||
InputFactory.Parameter(
|
||||
"body",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Body,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method)
|
||||
]);
|
||||
|
||||
private static readonly InputOperation OperationWithOnlyPathParams = InputFactory.Operation(
|
||||
"CreateMessage",
|
||||
parameters:
|
||||
[
|
||||
InputFactory.Parameter(
|
||||
"c",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
InputFactory.Parameter(
|
||||
"a",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method),
|
||||
InputFactory.Parameter(
|
||||
"b",
|
||||
InputPrimitiveType.String,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method)
|
||||
]);
|
||||
|
||||
private readonly static InputClient SingleOpInputClient = InputFactory.Client("TestClient", operations: [BasicOperation]);
|
||||
|
||||
private static IEnumerable<TestCaseData> DefaultCSharpMethodCollectionTestCases =>
|
||||
|
@ -160,7 +320,18 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders
|
|||
|
||||
private static IEnumerable<TestCaseData> GetMethodParametersTestCases =>
|
||||
[
|
||||
new TestCaseData(BasicOperation)
|
||||
new TestCaseData(OperationWithSpreadParam),
|
||||
new TestCaseData(BasicOperation),
|
||||
new TestCaseData(OperationWithMixedParamOrdering)
|
||||
];
|
||||
|
||||
private static IEnumerable<TestCaseData> GetSpreadParameterModelTestCases =>
|
||||
[
|
||||
// spread param
|
||||
new TestCaseData(InputFactory.Parameter("spread", _spreadModel, location: RequestLocation.Body, kind: InputOperationParameterKind.Spread, isRequired: true)),
|
||||
// non spread param
|
||||
new TestCaseData(InputFactory.Parameter("p1", InputPrimitiveType.Boolean, location: RequestLocation.Path, isRequired: true, kind: InputOperationParameterKind.Method))
|
||||
|
||||
];
|
||||
|
||||
private class MockClientProvider : RestClientProvider
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Generator.CSharp.ClientModel.Providers;
|
||||
using Microsoft.Generator.CSharp.Input;
|
||||
using Microsoft.Generator.CSharp.Primitives;
|
||||
using Microsoft.Generator.CSharp.Providers;
|
||||
using Microsoft.Generator.CSharp.Tests.Common;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
@ -13,6 +13,14 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers
|
|||
{
|
||||
internal class ScmMethodProviderCollectionTests
|
||||
{
|
||||
private static readonly InputModelType _spreadModel = InputFactory.Model(
|
||||
"spreadModel",
|
||||
usage: InputModelTypeUsage.Spread,
|
||||
properties:
|
||||
[
|
||||
InputFactory.Property("p2", InputPrimitiveType.String, isRequired: true),
|
||||
]);
|
||||
|
||||
// Validate that the default method collection consists of the expected method kind(s)
|
||||
[TestCaseSource(nameof(DefaultCSharpMethodCollectionTestCases))]
|
||||
public void TestDefaultCSharpMethodCollection(InputOperation inputOperation)
|
||||
|
@ -20,8 +28,7 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers
|
|||
var inputClient = InputFactory.Client("TestClient", operations: [inputOperation]);
|
||||
|
||||
MockHelpers.LoadMockPlugin(
|
||||
createCSharpTypeCore: (inputType) => new CSharpType(typeof(bool)),
|
||||
createParameterCore: (inputParameter) => new ParameterProvider("mockParam", $"mock description", typeof(bool), null));
|
||||
createCSharpTypeCore: (inputType) => new CSharpType(typeof(bool)));
|
||||
|
||||
var methodCollection = new ScmMethodProviderCollection(inputOperation, ClientModelPlugin.Instance.TypeFactory.CreateClient(inputClient));
|
||||
Assert.IsNotNull(methodCollection);
|
||||
|
@ -35,6 +42,23 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers
|
|||
var parameters = signature.Parameters;
|
||||
Assert.IsNotNull(parameters);
|
||||
Assert.AreEqual(inputOperation.Parameters.Count + 1, parameters.Count);
|
||||
|
||||
var convenienceMethod = methodCollection.FirstOrDefault(m
|
||||
=> !m.Signature.Parameters.Any(p => p.Name == "content")
|
||||
&& m.Signature.Name == $"{inputOperation.Name.ToCleanName()}");
|
||||
Assert.IsNotNull(convenienceMethod);
|
||||
|
||||
var convenienceMethodParams = convenienceMethod!.Signature.Parameters;
|
||||
Assert.IsNotNull(convenienceMethodParams);
|
||||
|
||||
var spreadInputParameter = inputOperation.Parameters.FirstOrDefault(p => p.Kind == InputOperationParameterKind.Spread);
|
||||
if (spreadInputParameter != null)
|
||||
{
|
||||
var spreadModelProperties = _spreadModel.Properties;
|
||||
Assert.AreEqual(spreadModelProperties.Count + 1, convenienceMethodParams.Count);
|
||||
Assert.AreEqual("p1", convenienceMethodParams[0].Name);
|
||||
Assert.AreEqual(spreadModelProperties[0].Name, convenienceMethodParams[1].Name);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TestCaseData> DefaultCSharpMethodCollectionTestCases
|
||||
|
@ -50,6 +74,25 @@ namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers
|
|||
InputPrimitiveType.Boolean,
|
||||
isRequired: true)
|
||||
]));
|
||||
|
||||
// Operation with spread parameter
|
||||
yield return new TestCaseData(InputFactory.Operation(
|
||||
"CreateMessage",
|
||||
parameters:
|
||||
[
|
||||
InputFactory.Parameter(
|
||||
"spread",
|
||||
_spreadModel,
|
||||
location: RequestLocation.Body,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Spread),
|
||||
InputFactory.Parameter(
|
||||
"p1",
|
||||
InputPrimitiveType.Boolean,
|
||||
location: RequestLocation.Path,
|
||||
isRequired: true,
|
||||
kind: InputOperationParameterKind.Method)
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,8 @@ namespace Microsoft.Generator.CSharp.Primitives
|
|||
Unknown,
|
||||
Body,
|
||||
Uri,
|
||||
Path,
|
||||
Query,
|
||||
Header,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
/// <summary>
|
||||
/// The default value of the parameter.
|
||||
/// </summary>
|
||||
public ValueExpression? DefaultValue { get; init; }
|
||||
public ValueExpression? DefaultValue { get; set; }
|
||||
public ValueExpression? InitializationValue { get; init; }
|
||||
public ParameterValidationType Validation { get; init; } = ParameterValidationType.None;
|
||||
public bool IsRef { get; }
|
||||
|
@ -50,8 +50,15 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
{
|
||||
Name = inputParameter.Name;
|
||||
Description = FormattableStringHelpers.FromString(inputParameter.Description) ?? FormattableStringHelpers.Empty;
|
||||
Type = CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(inputParameter.Type) ?? throw new InvalidOperationException($"Failed to create CSharpType for {inputParameter.Type}");
|
||||
Validation = inputParameter.IsRequired && !Type.IsValueType ? ParameterValidationType.AssertNotNull : ParameterValidationType.None;
|
||||
var type = CodeModelPlugin.Instance.TypeFactory.CreateCSharpType(inputParameter.Type) ?? throw new InvalidOperationException($"Failed to create CSharpType for {inputParameter.Type}");
|
||||
if (!inputParameter.IsRequired && !type.IsCollection)
|
||||
{
|
||||
type = type.WithNullable(true);
|
||||
}
|
||||
Type = type;
|
||||
Validation = inputParameter.IsRequired && !Type.IsValueType && !Type.IsNullable
|
||||
? ParameterValidationType.AssertNotNull
|
||||
: ParameterValidationType.None;
|
||||
WireInfo = new WireInformation(CodeModelPlugin.Instance.TypeFactory.GetSerializationFormat(inputParameter.Type), inputParameter.NameInRequest);
|
||||
Location = inputParameter.Location.ToParameterLocation();
|
||||
}
|
||||
|
@ -66,7 +73,8 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
IReadOnlyList<AttributeStatement>? attributes = null,
|
||||
PropertyProvider? property = null,
|
||||
FieldProvider? field = null,
|
||||
ValueExpression? initializationValue = null)
|
||||
ValueExpression? initializationValue = null,
|
||||
ParameterLocation? location = null)
|
||||
{
|
||||
Debug.Assert(!(property is not null && field is not null), "A parameter cannot be both a property and a field");
|
||||
|
||||
|
@ -82,6 +90,7 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
Validation = GetParameterValidation();
|
||||
InitializationValue = initializationValue;
|
||||
WireInfo = new WireInformation(SerializationFormat.Default, name);
|
||||
Location = location ?? ParameterLocation.Unknown;
|
||||
}
|
||||
|
||||
private ParameterProvider? _inputParameter;
|
||||
|
@ -162,6 +171,8 @@ namespace Microsoft.Generator.CSharp.Providers
|
|||
private VariableExpression? _asVariable;
|
||||
public VariableExpression AsExpression => _asVariable ??= this;
|
||||
|
||||
public TypeProvider? SpreadSource { get; set; }
|
||||
|
||||
private ParameterValidationType GetParameterValidation()
|
||||
{
|
||||
if (Field is not null && !Field.Type.IsNullable)
|
||||
|
|
|
@ -13,6 +13,9 @@ namespace Microsoft.Generator.CSharp
|
|||
{
|
||||
RequestLocation.Body => ParameterLocation.Body,
|
||||
RequestLocation.Uri => ParameterLocation.Uri,
|
||||
RequestLocation.Path => ParameterLocation.Path,
|
||||
RequestLocation.Query => ParameterLocation.Query,
|
||||
RequestLocation.Header => ParameterLocation.Header,
|
||||
_ => ParameterLocation.Unknown,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ namespace Microsoft.Generator.CSharp.Tests.Common
|
|||
bool isRequired = false,
|
||||
InputOperationParameterKind kind = InputOperationParameterKind.Method,
|
||||
bool isEndpoint = false,
|
||||
bool isResourceParameter = false)
|
||||
bool isResourceParameter = false,
|
||||
bool isContentType = false)
|
||||
{
|
||||
return new InputParameter(
|
||||
name,
|
||||
|
@ -74,7 +75,7 @@ namespace Microsoft.Generator.CSharp.Tests.Common
|
|||
isRequired,
|
||||
false,
|
||||
isResourceParameter,
|
||||
false,
|
||||
isContentType,
|
||||
isEndpoint,
|
||||
false,
|
||||
false,
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace UnbrandedTypeSpec
|
|||
return message;
|
||||
}
|
||||
|
||||
internal PipelineMessage CreateHelloAgainRequest(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
internal PipelineMessage CreateHelloAgainRequest(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
PipelineMessage message = Pipeline.CreateMessage();
|
||||
message.ResponseClassifier = PipelineMessageClassifier200;
|
||||
|
@ -61,7 +61,7 @@ namespace UnbrandedTypeSpec
|
|||
return message;
|
||||
}
|
||||
|
||||
internal PipelineMessage CreateNoContentTypeRequest(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
internal PipelineMessage CreateNoContentTypeRequest(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
PipelineMessage message = Pipeline.CreateMessage();
|
||||
message.ResponseClassifier = PipelineMessageClassifier200;
|
||||
|
@ -178,7 +178,7 @@ namespace UnbrandedTypeSpec
|
|||
return message;
|
||||
}
|
||||
|
||||
internal PipelineMessage CreateAnonymousBodyRequest(RequestOptions options)
|
||||
internal PipelineMessage CreateAnonymousBodyRequest(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
PipelineMessage message = Pipeline.CreateMessage();
|
||||
message.ResponseClassifier = PipelineMessageClassifier200;
|
||||
|
@ -190,11 +190,12 @@ namespace UnbrandedTypeSpec
|
|||
request.Uri = uri.ToUri();
|
||||
request.Headers.Set("Content-Type", "application/json");
|
||||
request.Headers.Set("Accept", "application/json");
|
||||
request.Content = content;
|
||||
message.Apply(options);
|
||||
return message;
|
||||
}
|
||||
|
||||
internal PipelineMessage CreateFriendlyModelRequest(RequestOptions options)
|
||||
internal PipelineMessage CreateFriendlyModelRequest(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
PipelineMessage message = Pipeline.CreateMessage();
|
||||
message.ResponseClassifier = PipelineMessageClassifier200;
|
||||
|
@ -206,6 +207,7 @@ namespace UnbrandedTypeSpec
|
|||
request.Uri = uri.ToUri();
|
||||
request.Headers.Set("Content-Type", "application/json");
|
||||
request.Headers.Set("Accept", "application/json");
|
||||
request.Content = content;
|
||||
message.Apply(options);
|
||||
return message;
|
||||
}
|
||||
|
@ -225,7 +227,7 @@ namespace UnbrandedTypeSpec
|
|||
return message;
|
||||
}
|
||||
|
||||
internal PipelineMessage CreateProjectedNameModelRequest(RequestOptions options)
|
||||
internal PipelineMessage CreateProjectedNameModelRequest(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
PipelineMessage message = Pipeline.CreateMessage();
|
||||
message.ResponseClassifier = PipelineMessageClassifier200;
|
||||
|
@ -237,6 +239,7 @@ namespace UnbrandedTypeSpec
|
|||
request.Uri = uri.ToUri();
|
||||
request.Headers.Set("Content-Type", "application/json");
|
||||
request.Headers.Set("Accept", "application/json");
|
||||
request.Content = content;
|
||||
message.Apply(options);
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
using System;
|
||||
using System.ClientModel;
|
||||
using System.ClientModel.Primitives;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnbrandedTypeSpec.Models;
|
||||
|
||||
|
@ -137,20 +139,20 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual ClientResult HelloAgain(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
public virtual ClientResult HelloAgain(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateHelloAgainRequest(p1, p2, content, options);
|
||||
using PipelineMessage message = CreateHelloAgainRequest(p2, p1, content, options);
|
||||
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
|
||||
}
|
||||
|
||||
|
@ -162,52 +164,52 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual async Task<ClientResult> HelloAgainAsync(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
public virtual async Task<ClientResult> HelloAgainAsync(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateHelloAgainRequest(p1, p2, content, options);
|
||||
using PipelineMessage message = CreateHelloAgainRequest(p2, p1, content, options);
|
||||
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary> Return hi again. </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual ClientResult<RoundTripModel> HelloAgain(string p1, string p2, RoundTripModel action)
|
||||
public virtual ClientResult<RoundTripModel> HelloAgain(string p2, string p1, RoundTripModel action)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(action, nameof(action));
|
||||
|
||||
ClientResult result = HelloAgain(p1, p2, action, null);
|
||||
ClientResult result = HelloAgain(p2, p1, action, null);
|
||||
return ClientResult.FromValue((RoundTripModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
/// <summary> Return hi again. </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual async Task<ClientResult<RoundTripModel>> HelloAgainAsync(string p1, string p2, RoundTripModel action)
|
||||
public virtual async Task<ClientResult<RoundTripModel>> HelloAgainAsync(string p2, string p1, RoundTripModel action)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(action, nameof(action));
|
||||
|
||||
ClientResult result = await HelloAgainAsync(p1, p2, action, null).ConfigureAwait(false);
|
||||
ClientResult result = await HelloAgainAsync(p2, p1, action, null).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((RoundTripModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
|
@ -219,20 +221,20 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual ClientResult NoContentType(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
public virtual ClientResult NoContentType(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateNoContentTypeRequest(p1, p2, content, options);
|
||||
using PipelineMessage message = CreateNoContentTypeRequest(p2, p1, content, options);
|
||||
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
|
||||
}
|
||||
|
||||
|
@ -244,52 +246,52 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual async Task<ClientResult> NoContentTypeAsync(string p1, string p2, BinaryContent content, RequestOptions options)
|
||||
public virtual async Task<ClientResult> NoContentTypeAsync(string p2, string p1, BinaryContent content, RequestOptions options)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateNoContentTypeRequest(p1, p2, content, options);
|
||||
using PipelineMessage message = CreateNoContentTypeRequest(p2, p1, content, options);
|
||||
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary> Return hi again. </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual ClientResult<RoundTripModel> NoContentType(string p1, string p2, RoundTripModel action)
|
||||
public virtual ClientResult<RoundTripModel> NoContentType(string p2, string p1, RoundTripModel action)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(action, nameof(action));
|
||||
|
||||
ClientResult result = NoContentType(p1, p2, action, null);
|
||||
ClientResult result = NoContentType(p2, p1, action, null);
|
||||
return ClientResult.FromValue((RoundTripModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
/// <summary> Return hi again. </summary>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="p2"></param>
|
||||
/// <param name="p1"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p1"/>, <paramref name="p2"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="p2"/>, <paramref name="p1"/> or <paramref name="action"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual async Task<ClientResult<RoundTripModel>> NoContentTypeAsync(string p1, string p2, RoundTripModel action)
|
||||
public virtual async Task<ClientResult<RoundTripModel>> NoContentTypeAsync(string p2, string p1, RoundTripModel action)
|
||||
{
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(p2, nameof(p2));
|
||||
Argument.AssertNotNull(p1, nameof(p1));
|
||||
Argument.AssertNotNull(action, nameof(action));
|
||||
|
||||
ClientResult result = await NoContentTypeAsync(p1, p2, action, null).ConfigureAwait(false);
|
||||
ClientResult result = await NoContentTypeAsync(p2, p1, action, null).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((RoundTripModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
|
@ -637,12 +639,16 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual ClientResult AnonymousBody(RequestOptions options)
|
||||
public virtual ClientResult AnonymousBody(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateAnonymousBodyRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateAnonymousBodyRequest(content, options);
|
||||
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
|
||||
}
|
||||
|
||||
|
@ -654,28 +660,98 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual async Task<ClientResult> AnonymousBodyAsync(RequestOptions options)
|
||||
public virtual async Task<ClientResult> AnonymousBodyAsync(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateAnonymousBodyRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateAnonymousBodyRequest(content, options);
|
||||
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary> body parameter without body decorator. </summary>
|
||||
/// <param name="name"> name of the Thing. </param>
|
||||
/// <param name="requiredUnion"> required Union. </param>
|
||||
/// <param name="requiredLiteralString"> required literal string. </param>
|
||||
/// <param name="requiredLiteralInt"> required literal int. </param>
|
||||
/// <param name="requiredLiteralFloat"> required literal float. </param>
|
||||
/// <param name="requiredLiteralBool"> required literal bool. </param>
|
||||
/// <param name="requiredBadDescription"> description with xml <|endoftext|>. </param>
|
||||
/// <param name="requiredNullableList"> required nullable collection. </param>
|
||||
/// <param name="optionalLiteralString"> optional literal string. </param>
|
||||
/// <param name="optionalLiteralInt"> optional literal int. </param>
|
||||
/// <param name="optionalLiteralFloat"> optional literal float. </param>
|
||||
/// <param name="optionalLiteralBool"> optional literal bool. </param>
|
||||
/// <param name="optionalNullableList"> optional nullable collection. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/>, <paramref name="requiredUnion"/> or <paramref name="requiredBadDescription"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual ClientResult<Thing> AnonymousBody()
|
||||
public virtual ClientResult<Thing> AnonymousBody(string name, BinaryData requiredUnion, AnonymousBodyRequestRequiredLiteralString requiredLiteralString, AnonymousBodyRequestRequiredLiteralInt requiredLiteralInt, AnonymousBodyRequestRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, string requiredBadDescription, IEnumerable<int> requiredNullableList, AnonymousBodyRequestOptionalLiteralString? optionalLiteralString = default, AnonymousBodyRequestOptionalLiteralInt? optionalLiteralInt = default, AnonymousBodyRequestOptionalLiteralFloat? optionalLiteralFloat = default, bool? optionalLiteralBool = default, IEnumerable<int> optionalNullableList = default)
|
||||
{
|
||||
ClientResult result = AnonymousBody(null);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
Argument.AssertNotNull(requiredUnion, nameof(requiredUnion));
|
||||
Argument.AssertNotNull(requiredBadDescription, nameof(requiredBadDescription));
|
||||
|
||||
AnonymousBodyRequest spreadModel = new AnonymousBodyRequest(
|
||||
name,
|
||||
requiredUnion,
|
||||
requiredLiteralString,
|
||||
requiredLiteralInt,
|
||||
requiredLiteralFloat,
|
||||
requiredLiteralBool,
|
||||
optionalLiteralString,
|
||||
optionalLiteralInt,
|
||||
optionalLiteralFloat,
|
||||
optionalLiteralBool,
|
||||
requiredBadDescription,
|
||||
optionalNullableList?.ToList() as IList<int> ?? new ChangeTrackingList<int>(),
|
||||
requiredNullableList?.ToList() as IList<int> ?? new ChangeTrackingList<int>(),
|
||||
null);
|
||||
ClientResult result = AnonymousBody(spreadModel, null);
|
||||
return ClientResult.FromValue((Thing)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
/// <summary> body parameter without body decorator. </summary>
|
||||
/// <param name="name"> name of the Thing. </param>
|
||||
/// <param name="requiredUnion"> required Union. </param>
|
||||
/// <param name="requiredLiteralString"> required literal string. </param>
|
||||
/// <param name="requiredLiteralInt"> required literal int. </param>
|
||||
/// <param name="requiredLiteralFloat"> required literal float. </param>
|
||||
/// <param name="requiredLiteralBool"> required literal bool. </param>
|
||||
/// <param name="requiredBadDescription"> description with xml <|endoftext|>. </param>
|
||||
/// <param name="requiredNullableList"> required nullable collection. </param>
|
||||
/// <param name="optionalLiteralString"> optional literal string. </param>
|
||||
/// <param name="optionalLiteralInt"> optional literal int. </param>
|
||||
/// <param name="optionalLiteralFloat"> optional literal float. </param>
|
||||
/// <param name="optionalLiteralBool"> optional literal bool. </param>
|
||||
/// <param name="optionalNullableList"> optional nullable collection. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/>, <paramref name="requiredUnion"/> or <paramref name="requiredBadDescription"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual async Task<ClientResult<Thing>> AnonymousBodyAsync()
|
||||
public virtual async Task<ClientResult<Thing>> AnonymousBodyAsync(string name, BinaryData requiredUnion, AnonymousBodyRequestRequiredLiteralString requiredLiteralString, AnonymousBodyRequestRequiredLiteralInt requiredLiteralInt, AnonymousBodyRequestRequiredLiteralFloat requiredLiteralFloat, bool requiredLiteralBool, string requiredBadDescription, IEnumerable<int> requiredNullableList, AnonymousBodyRequestOptionalLiteralString? optionalLiteralString = default, AnonymousBodyRequestOptionalLiteralInt? optionalLiteralInt = default, AnonymousBodyRequestOptionalLiteralFloat? optionalLiteralFloat = default, bool? optionalLiteralBool = default, IEnumerable<int> optionalNullableList = default)
|
||||
{
|
||||
ClientResult result = await AnonymousBodyAsync(null).ConfigureAwait(false);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
Argument.AssertNotNull(requiredUnion, nameof(requiredUnion));
|
||||
Argument.AssertNotNull(requiredBadDescription, nameof(requiredBadDescription));
|
||||
|
||||
AnonymousBodyRequest spreadModel = new AnonymousBodyRequest(
|
||||
name,
|
||||
requiredUnion,
|
||||
requiredLiteralString,
|
||||
requiredLiteralInt,
|
||||
requiredLiteralFloat,
|
||||
requiredLiteralBool,
|
||||
optionalLiteralString,
|
||||
optionalLiteralInt,
|
||||
optionalLiteralFloat,
|
||||
optionalLiteralBool,
|
||||
requiredBadDescription,
|
||||
optionalNullableList?.ToList() as IList<int> ?? new ChangeTrackingList<int>(),
|
||||
requiredNullableList?.ToList() as IList<int> ?? new ChangeTrackingList<int>(),
|
||||
null);
|
||||
ClientResult result = await AnonymousBodyAsync(spreadModel, null).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((Thing)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
|
@ -687,12 +763,16 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual ClientResult FriendlyModel(RequestOptions options)
|
||||
public virtual ClientResult FriendlyModel(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateFriendlyModelRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateFriendlyModelRequest(content, options);
|
||||
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
|
||||
}
|
||||
|
||||
|
@ -704,28 +784,42 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual async Task<ClientResult> FriendlyModelAsync(RequestOptions options)
|
||||
public virtual async Task<ClientResult> FriendlyModelAsync(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateFriendlyModelRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateFriendlyModelRequest(content, options);
|
||||
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary> Model can have its friendly name. </summary>
|
||||
/// <param name="name"> name of the NotFriend. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual ClientResult<Friend> FriendlyModel()
|
||||
public virtual ClientResult<Friend> FriendlyModel(string name)
|
||||
{
|
||||
ClientResult result = FriendlyModel(null);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
|
||||
FriendlyModelRequest spreadModel = new FriendlyModelRequest(name, null);
|
||||
ClientResult result = FriendlyModel(spreadModel, null);
|
||||
return ClientResult.FromValue((Friend)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
/// <summary> Model can have its friendly name. </summary>
|
||||
/// <param name="name"> name of the NotFriend. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual async Task<ClientResult<Friend>> FriendlyModelAsync()
|
||||
public virtual async Task<ClientResult<Friend>> FriendlyModelAsync(string name)
|
||||
{
|
||||
ClientResult result = await FriendlyModelAsync(null).ConfigureAwait(false);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
|
||||
FriendlyModelRequest spreadModel = new FriendlyModelRequest(name, null);
|
||||
ClientResult result = await FriendlyModelAsync(spreadModel, null).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((Friend)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
|
@ -785,12 +879,16 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual ClientResult ProjectedNameModel(RequestOptions options)
|
||||
public virtual ClientResult ProjectedNameModel(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateProjectedNameModelRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateProjectedNameModelRequest(content, options);
|
||||
return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
|
||||
}
|
||||
|
||||
|
@ -802,28 +900,42 @@ namespace UnbrandedTypeSpec
|
|||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <param name="content"> The content to send as the body of the request. </param>
|
||||
/// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="content"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
/// <returns> The response returned from the service. </returns>
|
||||
public virtual async Task<ClientResult> ProjectedNameModelAsync(RequestOptions options)
|
||||
public virtual async Task<ClientResult> ProjectedNameModelAsync(BinaryContent content, RequestOptions options)
|
||||
{
|
||||
using PipelineMessage message = CreateProjectedNameModelRequest(options);
|
||||
Argument.AssertNotNull(content, nameof(content));
|
||||
|
||||
using PipelineMessage message = CreateProjectedNameModelRequest(content, options);
|
||||
return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary> Model can have its projected name. </summary>
|
||||
/// <param name="name"> name of the ModelWithProjectedName. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual ClientResult<ProjectedModel> ProjectedNameModel()
|
||||
public virtual ClientResult<ProjectedModel> ProjectedNameModel(string name)
|
||||
{
|
||||
ClientResult result = ProjectedNameModel(null);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
|
||||
ProjectedNameModelRequest spreadModel = new ProjectedNameModelRequest(name, null);
|
||||
ClientResult result = ProjectedNameModel(spreadModel, null);
|
||||
return ClientResult.FromValue((ProjectedModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
/// <summary> Model can have its projected name. </summary>
|
||||
/// <param name="name"> name of the ModelWithProjectedName. </param>
|
||||
/// <exception cref="ArgumentNullException"> <paramref name="name"/> is null. </exception>
|
||||
/// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
|
||||
public virtual async Task<ClientResult<ProjectedModel>> ProjectedNameModelAsync()
|
||||
public virtual async Task<ClientResult<ProjectedModel>> ProjectedNameModelAsync(string name)
|
||||
{
|
||||
ClientResult result = await ProjectedNameModelAsync(null).ConfigureAwait(false);
|
||||
Argument.AssertNotNull(name, nameof(name));
|
||||
|
||||
ProjectedNameModelRequest spreadModel = new ProjectedNameModelRequest(name, null);
|
||||
ClientResult result = await ProjectedNameModelAsync(spreadModel, null).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((ProjectedModel)result, result.GetRawResponse());
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче