Skip to content

Refactor XmlDocProvider #7904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

ArcturusZhang
Copy link
Member

@ArcturusZhang ArcturusZhang commented Jul 15, 2025

Fixes #7722

This PR only solves the prematurely determined issue for parameters since this is the most commonly changable in visitors.

Copy link
Contributor

No changes needing a change description found.

@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jul 15, 2025
@ArcturusZhang ArcturusZhang marked this pull request as ready for review July 18, 2025 06:19
private int GetHashCode([DisallowNull] ParameterProvider obj)
{
// remove type as part of the hash code generation as the type might have changes between versions
return HashCode.Combine(obj.Name);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i change this because the Name property in this class is not immutable - therefore if we use this type as key of dictionary or in hashset in a scenario that its name would change, weird behavior would happen.
For instance, if we do this:

var set = new HashSet<ParameterProvider>();
set.Add(parameter);
parameter.Update(name: "bar"); // change the name to bar
Console.WriteLine(set.Contains(parameter); // this will return false.

@@ -271,7 +265,7 @@ private static bool TryBuildMethodArgumentsForOverload(
return false;
}

var currentParameters = currentMethod.Parameters.ToHashSet();
var currentParameters = currentMethod.Parameters.ToHashSet(ParameterProvider.EqualityByNameAndType);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since in this context, we are trying to compare the parameters by their names and types, we used a comparer here to do that, and its default behavior in a dictionary is by reference equality.

Comment on lines 76 to 86
foreach (var parameter in method.Signature.Parameters)
{
if (_visitedParameters.Contains(parameter))
{
// already visited this parameter, skip
continue;
}
_visitedParameters.Add(parameter);
// modify the parameter name
parameter.Update(name: parameter.Name + "_modified");
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this is the correct usage - I want to use this visitor to change the parameter names by appending a _modified.
But it turns out, some parameter instances are shared between different methods, for instance, between the sync version and async version.
Therefore without this _visitedParameters cache, this modification will be apply to the same parameter instance multiple times giving us multiple _modified suffix.

To make things right, I have to add this visitedParameters mechanism to ensure we only change each parameter once.

Is this the expected behavior?
Also because of this, I have to change the GetHashCode implementation in ParameterProvider to ensure we could get the reference equality comparison.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt there are realistic scenarios where need to blindly append something to a parameter. The more realistic scenario is that we want to find parameters with a certain name, and update them to a new name. Given that, there should be no need to have a hashset of visited parameters.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to "if the parameter name is foo, change it to foo_modified"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[http-client-csharp] The content in XmlDocProvider is determined prematurely
2 participants