Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,13 @@ private void CleanOperationNames(InputClient inputClient)
{
foreach (var serviceMethod in inputClient.Methods)
{
var updatedOperationName = GetCleanOperationName(serviceMethod);
var updatedOperationName = GetOperationName(serviceMethod);
serviceMethod.Update(name: updatedOperationName);
serviceMethod.Operation.Update(name: updatedOperationName);
}
}

private string GetCleanOperationName(InputServiceMethod serviceMethod)
private string GetOperationName(InputServiceMethod serviceMethod, bool normalizeUrlSuffix = true)
{
if (serviceMethod.IsExactName)
{
Expand All @@ -237,6 +237,11 @@ private string GetCleanOperationName(InputServiceMethod serviceMethod)
operationName = $"Get{operationName.Substring(4)}";
}

if (!normalizeUrlSuffix)
{
return operationName;
}

var normalizedName = operationName.NormalizeCSharpUrlSuffix();
if (normalizedName == operationName)
{
Expand All @@ -254,6 +259,14 @@ private string GetCleanOperationName(InputServiceMethod serviceMethod)
return normalizedName;
}

internal string GetRestOperationName(InputServiceMethod serviceMethod)
{
// Request builders use the stable input operation identity rather than the mutable public method name.
// Preserve the original Url suffix so a projection honoring a previous GA name and a newer projection
// normalized to Uri continue to reference the same request builder.
return GetOperationName(serviceMethod, normalizeUrlSuffix: false).ToIdentifierName();
}

private string? _namespace;
// This `BuildNamespace` method has been called twice - one when building the `Type`, the other is trying to find the CustomCodeView, both of them are required.
// therefore here to avoid this being called twice because this method now reports a diagnostic, we cache the result.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ private ScmMethodProvider BuildCreateRequestMethod(InputServiceMethod serviceMet
parameters = [ScmKnownParameters.NextPage, .. parameters];
}

var operation = serviceMethod.Operation;
var operationName = ClientProvider.GetRestOperationName(serviceMethod);
var methodName = isNextLinkRequest
? $"CreateNext{operation.Name.ToIdentifierName()}Request"
: $"Create{operation.Name.ToIdentifierName()}Request";
? $"CreateNext{operationName}Request"
: $"Create{operationName}Request";
Comment thread
live1206 marked this conversation as resolved.
Resolved
var signature = new MethodSignature(
methodName,
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4708,11 +4708,12 @@ public void TestIsExactNameServiceMethodPreservesOperationNameVerbatim()
var inputOperation = InputFactory.Operation("snake_case_op", isExactName: true);
var inputServiceMethod = InputFactory.BasicServiceMethod("snake_case_op", inputOperation, isExactName: true);
var client = InputFactory.Client("TestClient", methods: [inputServiceMethod]);
_ = new ClientProvider(client);
var clientProvider = new ClientProvider(client);

// After CleanOperationNames runs in the ClientProvider constructor, names should be unchanged.
Assert.AreEqual("snake_case_op", inputServiceMethod.Name);
Assert.AreEqual("snake_case_op", inputServiceMethod.Operation.Name);
Assert.AreEqual("CreateSnakeCaseOpRequest", clientProvider.RestClient.GetCreateRequestMethod(inputOperation).Signature.Name);
}

[TestCase("GetUrl", false, "GetUri")]
Expand Down Expand Up @@ -4791,6 +4792,37 @@ public async Task TestOperationNameFallsBackToClientLastContractWhenBackCompatPr
Assert.IsTrue(methods.Any(m => m.Signature.Name == "GetUrl"));
}

[Test]
public async Task TestEarlierWrapperRequestExistsAfterLaterBackCompatProvider()
{
var inputOperation = InputFactory.Operation("GetUrl");
var inputServiceMethod = InputFactory.BasicServiceMethod("GetUrl", inputOperation);
var client = InputFactory.Client("TestClient", methods: [inputServiceMethod]);
var generator = await MockHelpers.LoadMockGeneratorAsync(
clients: () => [client],
lastContractCompilation: async () => await Helpers.GetCompilationFromDirectoryAsync());
var clientProvider = generator.Object.OutputLibrary.TypeProviders.OfType<ClientProvider>().Single();
var shippedWrapper = new BackCompatTypeProvider("MockableTestResource", "Sample");

var shippedWrapperMethods = clientProvider.GetMethodCollectionByOperation(inputOperation, shippedWrapper);
var publicMethodName = shippedWrapperMethods.Single(m =>
m.Kind == ScmMethodKind.Convenience &&
!m.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Async)).Signature.Name;
var capturedRequestMethodName = clientProvider.RestClient.GetCreateRequestMethod(inputOperation).Signature.Name;

Assert.AreEqual("GetUrl", publicMethodName);
Assert.AreEqual("CreateGetUrlRequest", capturedRequestMethodName);

var newWrapper = new BackCompatTypeProvider("MissingWrapper", "Sample");
_ = clientProvider.GetMethodCollectionByOperation(inputOperation, newWrapper);

var emittedRestClient = new TypeProviderWriter(clientProvider.RestClient).Write().Content;
StringAssert.Contains(
$"{capturedRequestMethodName}(",
emittedRestClient,
"The final REST client must emit the request method captured by an earlier wrapper projection.");
}

[Test]
public void TestIsExactNameServiceMethodSkipsListToGetRename()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ClientModel;
using System.Threading.Tasks;

namespace Sample
{
public partial class MockableTestResource
{
public virtual ClientResult GetUrl() => default!;

public virtual Task<ClientResult> GetUrlAsync() => default!;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Sample
{
public partial class TestClient
{
internal global::System.ClientModel.Primitives.PipelineMessage CreateAbortCopyFromUriRequest(string copyid, global::System.ClientModel.Primitives.RequestOptions options)
internal global::System.ClientModel.Primitives.PipelineMessage CreateAbortCopyFromUrlRequest(string copyid, global::System.ClientModel.Primitives.RequestOptions options)
Comment thread
live1206 marked this conversation as resolved.
Resolved
{
global::Sample.ClientUriBuilder uri = new global::Sample.ClientUriBuilder();
uri.Reset(_endpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Sample
{
public partial class TestClient
{
internal global::System.ClientModel.Primitives.PipelineMessage CreateAbortCopyFromUriRequest(string copyid, global::System.ClientModel.Primitives.RequestOptions options)
internal global::System.ClientModel.Primitives.PipelineMessage CreateAbortCopyFromUrlRequest(string copyid, global::System.ClientModel.Primitives.RequestOptions options)
{
global::Sample.ClientUriBuilder uri = new global::Sample.ClientUriBuilder();
uri.Reset(_endpoint);
Expand Down
Loading