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

Optimize helper we use to determine the relevant node of a particular kind the user is on. #73812

Merged
merged 16 commits into from
Jun 3, 2024

Conversation

CyrusNajmabadi
Copy link
Member

Drops us from:

image

to

image

@CyrusNajmabadi CyrusNajmabadi requested review from a team as code owners May 31, 2024 20:05
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels May 31, 2024
return relevantNodesBuilder.ToImmutableAndClear();

using var _2 = ArrayBuilder<TSyntaxNode>.GetInstance(out var nonEmptyNodes);
foreach (var node in relevantNodesBuilder)
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 loop went away, since we're only adding the nodes if they respect the allowEmptyNodes flag.

private async Task AddRelevantNodesAsync<TSyntaxNode>(
Document document, TextSpan selectionRaw, ArrayBuilder<TSyntaxNode> relevantNodes, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode
public void AddRelevantNodes<TSyntaxNode>(
ParsedDocument document, TextSpan selectionRaw, bool allowEmptyNodes, bool stopOnFirst, ref TemporaryArray<TSyntaxNode> result, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode
Copy link
Member Author

Choose a reason for hiding this comment

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

passing in PArsedDocument allows this to all be synchronous. which also allows passing in TempArray to add results into.

AddNonHiddenCorrectTypeNodes(ExtractNodesInHeader(root, location, headerFacts), relevantNodes, cancellationToken);
AddNonHiddenCorrectTypeNodes(ExtractNodesInHeader(root, location, headerFacts), stopOnFirst, ref result, cancellationToken);
if (stopOnFirst && result.Count > 0)
return;
Copy link
Member Author

Choose a reason for hiding this comment

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

ugly repetition. dont' have a better solution.

{
var correctTypeNonHiddenNodes = nodes.OfType<TSyntaxNode>().Where(n => !n.OverlapsHiddenPosition(cancellationToken));
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 linq.

return potentialNodes.FirstOrDefault();
using var result = TemporaryArray<TSyntaxNode>.Empty;
AddRelevantNodes(document, span, allowEmptyNode, stopOnFirst: true, ref result.AsRef(), cancellationToken);
return result.FirstOrDefault();
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 helper (used in a ton of places) can now stop on the first result, and not do more work walking the tree.

@@ -40,32 +40,67 @@ internal static class CodeRefactoringContextExtensions
public static Task<TSyntaxNode?> TryGetRelevantNodeAsync<TSyntaxNode>(this CodeRefactoringContext context) where TSyntaxNode : SyntaxNode
=> TryGetRelevantNodeAsync<TSyntaxNode>(context, allowEmptyNode: false);

public static Task<TSyntaxNode?> TryGetRelevantNodeAsync<TSyntaxNode>(this CodeRefactoringContext context, bool allowEmptyNode) where TSyntaxNode : SyntaxNode
=> TryGetRelevantNodeAsync<TSyntaxNode>(context.Document, context.Span, allowEmptyNode, context.CancellationToken);
public static async Task<TSyntaxNode?> TryGetRelevantNodeAsync<TSyntaxNode>(this CodeRefactoringContext context, bool allowEmptyNode) where TSyntaxNode : SyntaxNode
Copy link
Member Author

Choose a reason for hiding this comment

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

lots of bridge methods (still async) to the new sync paths.

Copy link
Member

@cston cston left a comment

Choose a reason for hiding this comment

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

Compiler change LGTM.

private async Task AddRelevantNodesAsync<TSyntaxNode>(
Document document, TextSpan selectionRaw, ArrayBuilder<TSyntaxNode> relevantNodes, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode
public void AddRelevantNodes<TSyntaxNode>(
ParsedDocument document, TextSpan selectionRaw, bool allowEmptyNodes, bool stopOnFirst, ref TemporaryArray<TSyntaxNode> result, CancellationToken cancellationToken) where TSyntaxNode : SyntaxNode
Copy link
Contributor

Choose a reason for hiding this comment

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

bool stopOnFirst

Would it make it a bit nicer if this was passed in an int (defaulted to IntMax) and then the code could just detect to see if the size exceeded that threshold instead of checking both the bool and the current size?

Copy link
Member Author

Choose a reason for hiding this comment

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

Likely about the same. But I'll change to that as a slightly more flexible pattern!

Copy link
Member Author

Choose a reason for hiding this comment

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

done.

var hostServices = document.Project.Solution.Services
.GetLanguageServices(document.Project.Language).HostLanguageServices;
#pragma warning restore CS0618 // Type or member is obsolete
var parsedDocument = new ParsedDocument(document.Id, text, root, hostServices);
Copy link
Member Author

@CyrusNajmabadi CyrusNajmabadi Jun 3, 2024

Choose a reason for hiding this comment

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

workaround for a problem i'm having using PArsedDocument in OOP. Talking to Tomas about this now.

Copy link
Contributor

@ToddGrun ToddGrun left a comment

Choose a reason for hiding this comment

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

:shipit:

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.

4 participants