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

Implement FAR for GetAwaiter methods #28230

Merged
merged 2 commits into from
Jul 3, 2018
Merged

Conversation

jcouv
Copy link
Member

@jcouv jcouv commented Jun 30, 2018

The parts of the change:

  • store information about which documents have await expressions into the syntax tree index (and update the SerializationFormat for the index),
  • AbstractReferenceFinder and OrdinaryMethodReferenceFinder inspect await expressions when looking for references to a GetAwaiter method,
  • CSharpRenameConflictLanguageService produces a conflict if you try to rename a GetAwaiter method that is used in an await expression.

Customer scenario

Invoked FindAllReferences on a GetAwaiter method. You'd expect the await expressions that implicitly involve that method to be identified as references.

Bugs this fixes

Fixes #25714

Workarounds, if any

N/A

Risk

Performance impact

Low. This is following a well-established template (see similar change for FAR to handle Deconstruct methods).

Is this a regression from a previous update?

No

How was the bug found?

Reported by customer

@@ -231,6 +231,18 @@ public ForEachSymbols GetForEachSymbols(SemanticModel semanticModel, SyntaxNode
}
}

public IMethodSymbol GetAwaitExpressionMethod(SemanticModel semanticModel, SyntaxNode node)
Copy link
Member

Choose a reason for hiding this comment

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

as weird as it sounds, i think this should be: GetGetAwaiterMethod, or if hat sounds awful: GetInvokedGetAwaiterMethod.

Copy link
Member

Choose a reason for hiding this comment

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

Is AwaitExpressionInfo shared across languages? If so, this could also be: GetAwaitExpressionInfo.

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, there are two AwaitExpressionInfo types (one for VB and one for C#).

Copy link
Member

Choose a reason for hiding this comment

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

Ughhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

can we have a CommonAwaitExpressionInfo? (seriously...)?

Copy link
Member Author

@jcouv jcouv Jul 1, 2018

Choose a reason for hiding this comment

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

Both AwaitExpressionInfo types are structs :-(
So if we want a common experience for callers, we'd have to use some interface.

Copy link
Member

Choose a reason for hiding this comment

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

Or a Common-Struct. we do that for some other APIs.

{
if (node is AwaitExpressionSyntax awaitExpression)
{
var builder = ArrayBuilder<IMethodSymbol>.GetInstance();
Copy link
Member

Choose a reason for hiding this comment

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

builder unneeded.

public bool IsAwaitExpression(SyntaxNode node)
{
return node.IsKind(SyntaxKind.AwaitExpression);
}
Copy link
Member

Choose a reason for hiding this comment

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

nit: =>

var info = await SyntaxTreeIndex.GetIndexAsync(d, c).ConfigureAwait(false);
return info.ContainsAwait;
}, cancellationToken);
}
Copy link
Member

Choose a reason for hiding this comment

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

note: we're starting to have a bunch of duplication with the above methods. consider having a single helper here that takes a Func<SyntaxTreeIndex, bool> and does all the common work.

}

return locations.ToImmutableAndFree();
}
Copy link
Member

Choose a reason for hiding this comment

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

these methods feel like there's a lot of duplication (in the overall logic, even though individual bits seem different). I'm on the fence if we should extract out a common helper...

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I think the factorings you suggested are worth it, as I'll probably add support for Dispose in using and Add in collection initializers next.

End If

Return Nothing
End Function
Copy link
Member

Choose a reason for hiding this comment

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

ok. it feels lke we don't need this method. We already have IsAwaitExpression. So all we need to do is call model.GetAwaitExpressionInfo() if we ahve an await expression. The rest of the code can all be shared by the caller.

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 left this method as-is, due to the problem with AwaitExpressionInfo.

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

Nice! I would def like a better story around AwaitExpressionInfo. However, given the current compiler API, this is the best we can do currently :)

@jcouv
Copy link
Member Author

jcouv commented Jul 2, 2018

Thanks @heejaechang and @CyrusNajmabadi for the review.

@jinujoseph for ask-mode approval for 15.8. Thanks

@jinujoseph
Copy link
Contributor

Approve to merge for 15.8.Preview5

@jcouv jcouv merged commit 2ccd656 into dotnet:master Jul 3, 2018
@jcouv jcouv deleted the far-getawaiter branch July 3, 2018 07:39
333fred added a commit to 333fred/roslyn that referenced this pull request Jul 11, 2018
…atures/compiler

* dotnet/features/compiler: (137 commits)
  Actually fix tabs.
  Added back breaking changes doc.
  Addressed PR feedback.
  Track enclosing symbol in data flow analysis, which might be a field or property. (dotnet#28252)
  Change text from 'Spell check' to 'Fix typo'.
  Implement FAR for GetAwaiter methods (dotnet#28230)
  Fix typo
  Fix typo
  Fix import.
  Address PR feedback and fix failing test.
  Lower expressions of in arguments to correct temp locals (dotnet#28181)
  Move to 2.0.7 runtime
  Produce errors on ref-assignment to non-ref parameters
  Fix spelling.
  Preserve left-to-right evaluation order for dynamic compound addition and subtraction.
  inline.
  Provide a spellchecking suggestion when someone mispells a constructor.
  Typo (dotnet#28177)
  PR Comments
  Fix regression in bitness of Interactive Window host (dotnet#28006)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No reference when awaiting custom GetAwaiter method
4 participants