Skip to content
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

Cleanup overload resolution code used in signature help #71329

Merged
merged 17 commits into from
Dec 18, 2023

Conversation

CyrusNajmabadi
Copy link
Member

We've seen some crashes here, so i rewrote things to simplify and remove certain issues.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner December 18, 2023 20:55
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Dec 18, 2023
@@ -5,297 +5,252 @@
using System;
Copy link
Member Author

Choose a reason for hiding this comment

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

View with whitespace off.

protected readonly struct LightweightOverloadResolution(
SemanticModel semanticModel,
int position,
SeparatedSyntaxList<ArgumentSyntax> arguments)
Copy link
Member Author

Choose a reason for hiding this comment

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

made this a helper struct. moved up common, readonly, state to the primary constructor.

{
internal static class LightweightOverloadResolution
public (IMethodSymbol? method, int parameterIndex) RefineOverloadAndPickParameter(SymbolInfo symbolInfo, ImmutableArray<IMethodSymbol> candidates)
Copy link
Member Author

Choose a reason for hiding this comment

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

made this method take a symbolinfo + candidates. taht way we could move common caller method into it.

{
// map the arguments to their corresponding parameters
var argumentCount = arguments.Count;
using var _ = ArrayBuilder<int>.GetInstance(argumentCount, fillWithValue: -1, out var argToParamMap);
Copy link
Member Author

Choose a reason for hiding this comment

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

a common problem was using fillWithValue, but then not ensuring the Count of hte array matches the count requested. unless .Add is actually called the right number of times, that won't be the case. I changed this to just get empty arrays and add hte number of fill-with-value values manually.

// parameter, we will highlight the first unspecified parameter.
static int FirstUnspecifiedParameter(ArrayBuilder<int> argToParamMap, int argumentCount)
{
using var _ = ArrayBuilder<bool>.GetInstance(argumentCount, false, out var specified);
Copy link
Member Author

Choose a reason for hiding this comment

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

this logic was very suspect. it made an array filled with 'false', but which had a count of 0. so this would only work properly if the argToParameterIndex happened to be in order. if, say, there was an out of order arg/param, this would index improperly.

var type = parameter.Type;
if (parameter.IsParams
&& type is IArrayTypeSymbol arrayType
&& semanticModel.ClassifyConversion(argument.Expression, arrayType.ElementType).IsImplicit)
Copy link
Member Author

Choose a reason for hiding this comment

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

inlined this method.

}
// A by-value argument matches an `in` parameter
if (parameterRefKind == RefKind.In && argumentRefKind == RefKind.None)
return true;
Copy link
Member Author

Choose a reason for hiding this comment

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

swapped order for clarity.

}
// We count the empty argument as a used position
if (!seenOutOfPositionArgument)
AddArgumentToParameterMapping(argumentIndex, currentParameterIndex, ref argumentToParameterMap);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

always used with AddArgToParamMapping. so just inlined there.

// `$$,` points to the argument before the separator
// but `,$$` points to the argument following the separator
if (position <= arguments.GetSeparator(i).Span.Start)
return i;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

inlined to single callsite.

var arguments = constructorInitializer.ArgumentList.Arguments;
var candidates = semanticModel.GetSymbolInfo(constructorInitializer, cancellationToken).Symbol is IMethodSymbol exactSymbol
? ImmutableArray.Create(exactSymbol)
: constructors;
Copy link
Member Author

Choose a reason for hiding this comment

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

pushed this into RefineOverloadAndPickParameter.

/// </summary>
private bool TryPrepareArgumentToParameterMap(IMethodSymbol method, ref TemporaryArray<int> argumentToParameterMap)
{
Contract.ThrowIfTrue(argumentToParameterMap.Count != arguments.Count);
Copy link
Member

Choose a reason for hiding this comment

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

Instead of passing in the array as a ref, could it be initialized here and returned as an out parameter?

Copy link
Member Author

Choose a reason for hiding this comment

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

not while using it in a using scope properly.

Debug.Assert(parameterIndex >= 0);
Debug.Assert(parameterIndex < method.Parameters.Length);

inParams |= method.Parameters[parameterIndex].IsParams;
Copy link
Member

Choose a reason for hiding this comment

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

should this be isParams?

Copy link
Member Author

Choose a reason for hiding this comment

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

no, i think this means "user is currently in the params parameters).

@CyrusNajmabadi CyrusNajmabadi merged commit 95f4a35 into dotnet:main Dec 18, 2023
26 of 28 checks passed
@ghost ghost added this to the Next milestone Dec 18, 2023
@CyrusNajmabadi CyrusNajmabadi deleted the overloadResolution branch December 19, 2023 17:29
@Cosifne Cosifne modified the milestones: Next, 17.9 P3 Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants