-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Fix crash in sighelp #74510
Fix crash in sighelp #74510
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,8 +101,8 @@ private async Task<Model> ComputeModelInBackgroundAsync( | |
currentModel.Provider == provider && | ||
currentModel.GetCurrentSpanInSubjectBuffer(disconnectedBufferGraph.SubjectBufferSnapshot).Span.Start == items.ApplicableSpan.Start && | ||
currentModel.Items.IndexOf(currentModel.SelectedItem) == items.SelectedItemIndex && | ||
currentModel.ArgumentIndex == items.ArgumentIndex && | ||
currentModel.ArgumentCount == items.ArgumentCount && | ||
currentModel.SemanticParameterIndex == items.SemanticParameterIndex && | ||
currentModel.SyntacticArgumentCount == items.SyntacticArgumentCount && | ||
currentModel.ArgumentName == items.ArgumentName) | ||
{ | ||
// The new model is the same as the current model. Return the currentModel | ||
|
@@ -112,14 +112,28 @@ private async Task<Model> ComputeModelInBackgroundAsync( | |
|
||
var selectedItem = GetSelectedItem(currentModel, items, provider, out var userSelected); | ||
|
||
var model = new Model(disconnectedBufferGraph, items.ApplicableSpan, provider, | ||
items.Items, selectedItem, items.ArgumentIndex, items.ArgumentCount, items.ArgumentName, | ||
selectedParameter: 0, userSelected); | ||
var model = new Model( | ||
disconnectedBufferGraph, | ||
items.ApplicableSpan, | ||
provider, | ||
items.Items, | ||
selectedItem, | ||
items.SemanticParameterIndex, | ||
items.SyntacticArgumentCount, | ||
items.ArgumentName, | ||
selectedParameter: 0, | ||
userSelected); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just renames + wrapping. no other change. |
||
|
||
var syntaxFactsService = document.GetLanguageService<ISyntaxFactsService>(); | ||
var isCaseSensitive = syntaxFactsService == null || syntaxFactsService.IsCaseSensitive; | ||
var selection = DefaultSignatureHelpSelector.GetSelection(model.Items, | ||
model.SelectedItem, model.UserSelected, model.ArgumentIndex, model.ArgumentCount, model.ArgumentName, isCaseSensitive); | ||
var selection = DefaultSignatureHelpSelector.GetSelection( | ||
model.Items, | ||
model.SelectedItem, | ||
model.UserSelected, | ||
model.SemanticParameterIndex, | ||
model.SyntacticArgumentCount, | ||
model.ArgumentName, | ||
isCaseSensitive); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just renames + wrapping. no other change. |
||
|
||
return model.WithSelectedItem(selection.SelectedItem, selection.UserSelected) | ||
.WithSelectedParameter(selection.SelectedParameter); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,13 +42,13 @@ public static SignatureHelpSelection GetSelection( | |
IList<SignatureHelpItem> items, | ||
SignatureHelpItem selectedItem, | ||
bool userSelected, | ||
int argumentIndex, | ||
int argumentCount, | ||
int semanticParameterIndex, | ||
int syntacticArgumentCount, | ||
string argumentName, | ||
bool isCaseSensitive) | ||
{ | ||
SelectBestItem(ref selectedItem, ref userSelected, items, argumentIndex, argumentCount, argumentName, isCaseSensitive); | ||
var selectedParameter = GetSelectedParameter(selectedItem, argumentIndex, argumentName, isCaseSensitive); | ||
SelectBestItem(ref selectedItem, ref userSelected, items, semanticParameterIndex, syntacticArgumentCount, argumentName, isCaseSensitive); | ||
var selectedParameter = GetSelectedParameter(selectedItem, semanticParameterIndex, argumentName, isCaseSensitive); | ||
return new SignatureHelpSelection(selectedItem, userSelected, selectedParameter); | ||
} | ||
|
||
|
@@ -67,12 +67,18 @@ private static int GetSelectedParameter(SignatureHelpItem bestItem, int paramete | |
return parameterIndex; | ||
} | ||
|
||
private static void SelectBestItem(ref SignatureHelpItem currentItem, ref bool userSelected, | ||
IList<SignatureHelpItem> filteredItems, int selectedParameter, int argumentCount, string name, bool isCaseSensitive) | ||
private static void SelectBestItem( | ||
ref SignatureHelpItem currentItem, | ||
ref bool userSelected, | ||
IList<SignatureHelpItem> filteredItems, | ||
int semanticParameterIndex, | ||
int syntacticArgumentCount, | ||
string name, | ||
bool isCaseSensitive) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just renames + wrapping. no other change. |
||
{ | ||
// If the current item is still applicable, then just keep it. | ||
if (filteredItems.Contains(currentItem) && | ||
IsApplicable(currentItem, argumentCount, name, isCaseSensitive)) | ||
IsApplicable(currentItem, syntacticArgumentCount, name, isCaseSensitive)) | ||
{ | ||
// If the current item was user-selected, we keep it as such. | ||
return; | ||
|
@@ -86,7 +92,7 @@ private static void SelectBestItem(ref SignatureHelpItem currentItem, ref bool u | |
// selected parameter was outside the bounds of all methods. i.e. all methods only | ||
// went up to 3 parameters, and selected parameter is 3 or higher. In that case, | ||
// just pick the very last item as it is closest in parameter count. | ||
var result = filteredItems.FirstOrDefault(i => IsApplicable(i, argumentCount, name, isCaseSensitive)); | ||
var result = filteredItems.FirstOrDefault(i => IsApplicable(i, semanticParameterIndex, name, isCaseSensitive)); | ||
if (result != null) | ||
{ | ||
currentItem = result; | ||
|
@@ -97,7 +103,7 @@ private static void SelectBestItem(ref SignatureHelpItem currentItem, ref bool u | |
// a name. | ||
if (name != null) | ||
{ | ||
SelectBestItem(ref currentItem, ref userSelected, filteredItems, selectedParameter, argumentCount, null, isCaseSensitive); | ||
SelectBestItem(ref currentItem, ref userSelected, filteredItems, semanticParameterIndex, syntacticArgumentCount, null, isCaseSensitive); | ||
return; | ||
} | ||
|
||
|
@@ -112,7 +118,7 @@ private static void SelectBestItem(ref SignatureHelpItem currentItem, ref bool u | |
currentItem = lastItem; | ||
} | ||
|
||
private static bool IsApplicable(SignatureHelpItem item, int argumentCount, string name, bool isCaseSensitive) | ||
private static bool IsApplicable(SignatureHelpItem item, int syntacticArgumentCount, string name, bool isCaseSensitive) | ||
{ | ||
// If they provided a name, then the item is only valid if it has a parameter that | ||
// matches that name. | ||
|
@@ -126,7 +132,7 @@ private static bool IsApplicable(SignatureHelpItem item, int argumentCount, stri | |
// parameter index. i.e. if it has 2 parameters and we're at index 0 or 1 then it's | ||
// applicable. However, if it has 2 parameters and we're at index 2, then it's not | ||
// applicable. | ||
if (item.Parameters.Length >= argumentCount) | ||
if (item.Parameters.Length >= syntacticArgumentCount) | ||
{ | ||
return true; | ||
} | ||
|
@@ -141,7 +147,7 @@ private static bool IsApplicable(SignatureHelpItem item, int argumentCount, stri | |
// Also, we special case 0. that's because if the user has "Goo(" and goo takes no | ||
// arguments, then we'll see that it's arg count is 0. We still want to consider | ||
// any item applicable here though. | ||
return argumentCount == 0; | ||
return syntacticArgumentCount == 0; | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,8 +23,12 @@ internal class Model | |
|
||
/// <summary>UserSelected is true if the SelectedItem is the result of a user selection (up/down arrows).</summary> | ||
public bool UserSelected { get; } | ||
public int ArgumentIndex { get; } | ||
public int ArgumentCount { get; } | ||
|
||
/// <inheritdoc cref="SignatureHelpItems.SemanticParameterIndex"/> | ||
public int SemanticParameterIndex { get; } | ||
|
||
/// <inheritdoc cref="SignatureHelpItems.SyntacticArgumentCount"/> | ||
public int SyntacticArgumentCount { get; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just renames. |
||
public string ArgumentName { get; } | ||
public int? SelectedParameter { get; } | ||
public ISignatureHelpProvider Provider { get; } | ||
|
@@ -35,8 +39,8 @@ public Model( | |
ISignatureHelpProvider provider, | ||
IList<SignatureHelpItem> items, | ||
SignatureHelpItem selectedItem, | ||
int argumentIndex, | ||
int argumentCount, | ||
int semanticParameterIndex, | ||
int syntacticArgumentCount, | ||
string argumentName, | ||
int? selectedParameter, | ||
bool userSelected) | ||
|
@@ -51,8 +55,8 @@ public Model( | |
this.Provider = provider; | ||
this.SelectedItem = selectedItem; | ||
this.UserSelected = userSelected; | ||
this.ArgumentIndex = argumentIndex; | ||
this.ArgumentCount = argumentCount; | ||
this.SemanticParameterIndex = semanticParameterIndex; | ||
this.SyntacticArgumentCount = syntacticArgumentCount; | ||
this.ArgumentName = argumentName; | ||
this.SelectedParameter = selectedParameter; | ||
} | ||
|
@@ -61,14 +65,14 @@ public Model WithSelectedItem(SignatureHelpItem selectedItem, bool userSelected) | |
{ | ||
return selectedItem == this.SelectedItem && userSelected == this.UserSelected | ||
? this | ||
: new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, selectedItem, ArgumentIndex, ArgumentCount, ArgumentName, SelectedParameter, userSelected); | ||
: new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, selectedItem, SemanticParameterIndex, SyntacticArgumentCount, ArgumentName, SelectedParameter, userSelected); | ||
} | ||
|
||
public Model WithSelectedParameter(int? selectedParameter) | ||
{ | ||
return selectedParameter == this.SelectedParameter | ||
? this | ||
: new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, SelectedItem, ArgumentIndex, ArgumentCount, ArgumentName, selectedParameter, UserSelected); | ||
: new Model(_disconnectedBufferGraph, TextSpan, Provider, Items, SelectedItem, SemanticParameterIndex, SyntacticArgumentCount, ArgumentName, selectedParameter, UserSelected); | ||
} | ||
|
||
public SnapshotSpan GetCurrentSpanInSubjectBuffer(ITextSnapshot bufferSnapshot) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renamed these to make the distinction clear. 'argument count' refferred to how many explicit argument syntax nodes are present in the code. 'argument index' was very badly named. It indicated 'this is the parameter in the actual symcol we think the user is currently on'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: the pr is almost entirely this rename. i call out anything that isn't just that.