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

Adjust implement interface service to work with static abstract operators #53941

Merged
merged 16 commits into from
Jun 29, 2021

Conversation

Youssef1313
Copy link
Member

@Youssef1313 Youssef1313 commented Jun 8, 2021

Fixes #53927
Fixes #53925
Fixes #54328
Fixes #54327

@Youssef1313 Youssef1313 requested a review from a team as a code owner June 8, 2021 11:41
@Youssef1313 Youssef1313 marked this pull request as draft June 8, 2021 11:51
Youssef1313 and others added 2 commits June 8, 2021 16:08
…tInterfaceService.CodeAction_Method.cs

Co-authored-by: CyrusNajmabadi <cyrus.najmabadi@gmail.com>
@Youssef1313 Youssef1313 marked this pull request as ready for review June 9, 2021 14:01
@Youssef1313
Copy link
Member Author

@CyrusNajmabadi This is ready for another look :)

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public async Task TestStaticAbstractInterfaceOperator_OnlyExplicitlyImplementable()
{
await TestInRegularAndScriptAsync(@"
Copy link
Member

Choose a reason for hiding this comment

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

in the future, if your'e interested, it would be good to update these to be sdk style tests. that way we can validate if our fix produces errors :)

Copy link
Member

Choose a reason for hiding this comment

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

📝 I'm working on this change for ImplementInterfaceTests in a separate branch.


abstract class C : ITest<C>
{
public abstract static int operator -(C x);
Copy link
Member

Choose a reason for hiding this comment

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

i'm curious. is this legal?

Copy link
Contributor

Choose a reason for hiding this comment

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

Abstract statics are allowed only in interfaces

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 for noting @CyrusNajmabadi @AlekseyTs
I'm curious whether the "Implement interface abstractly" should do nothing for the operator, or generate it without the "abstract" keyword?

Copy link
Member

Choose a reason for hiding this comment

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

implement abstractly needs to take the code from uncompilable state to compilable, attempting for each member it needs to generate to make that abstract. If the member doesn't need to be generated, we should not generate it.

Copy link
Member Author

Choose a reason for hiding this comment

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

@CyrusNajmabadi The member needs to be generated to be in a compilable state, but it cannot be generated abstractly.

Copy link
Contributor

Choose a reason for hiding this comment

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

I do not believe there is away to implement a static member abstractly. So, if there are static abstract members in the interface, the option probably shouldn't be offered.

Copy link
Member

Choose a reason for hiding this comment

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

The member needs to be generated to be in a compilable state, but it cannot be generated abstractly.

'GEnerate abstractly' means 'generate abstractly if possible'. If not possible, generate legally. This already occurs today where normal instance methods might cause errors if generated abstractly. In that case i believe we normally just generate explicitly.

End goal of this feature is always compilable code. The different user facing choices are about how we should generate when we have such flexibility while still ensuring compilable. If we are constrained, then we generate in whatever manner the constraints force.

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.

Overall this looks good. Just some tiny questions/cleanup/requests.

@jinujoseph jinujoseph added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jun 9, 2021
@Youssef1313 Youssef1313 marked this pull request as draft June 17, 2021 12:09
@Youssef1313 Youssef1313 marked this pull request as ready for review June 17, 2021 12:14
@AlekseyTs
Copy link
Contributor

Note that https://github.com/dotnet/roslyn/tree/features/StaticAbstractMembersInInterfaces has been merged to main, all related PRs should target main at this point.

@@ -309,7 +309,7 @@ private string DetermineMemberName(ISymbol member, ArrayBuilder<ISymbol> impleme
var generateInvisibleMember = GenerateInvisibleMember(member, memberName);
memberName = generateInvisibleMember ? member.Name : memberName;

var generateAbstractly = !generateInvisibleMember && Abstractly;
var generateAbstractly = !member.IsStatic && !generateInvisibleMember && Abstractly;
Copy link
Member

Choose a reason for hiding this comment

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

possibly explicitly comment that the language doesn't allow static abstract impls of interface methods.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added comment.

return SyntaxFactory.TokenList(
SyntaxFactory.Token(SyntaxKind.PublicKeyword),
SyntaxFactory.Token(SyntaxKind.StaticKeyword));
var tokens = ArrayBuilder<SyntaxToken>.GetInstance();
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
var tokens = ArrayBuilder<SyntaxToken>.GetInstance();
using var tokens = TemporaryArray<SyntaxToken>.Empty;

Copy link
Member

Choose a reason for hiding this comment

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

TemporaryArray is nice when we expect 4 or less items commonly :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice to know about TemporaryArray! Thanks. I applied the change.

@Youssef1313
Copy link
Member Author

CI failure is unrelated and was fixed in main. Closing and reopening for new build.

@CyrusNajmabadi CyrusNajmabadi merged commit f881f21 into dotnet:main Jun 29, 2021
@ghost ghost added this to the Next milestone Jun 29, 2021
@CyrusNajmabadi
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee.
Projects
None yet
6 participants