-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Introduce using statement #30106
Introduce using statement #30106
Conversation
d1dd366
to
08c88b5
Compare
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...arp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
08c88b5
to
391c2f4
Compare
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.
request changes.
src/EditorFeatures/CSharpTest/IntroduceUsingStatement/IntroduceUsingStatementTests.cs
Outdated
Show resolved
Hide resolved
CancellationToken cancellationToken) | ||
|
||
where TStatementSyntax : SyntaxNode | ||
{ |
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.
an alternative approach that might would would be to get the parent, walk backward to find the last reference. That itself could be a generic helper elsewhere.
Then, when you have the node for the last reference, you simply ask for it's ancestor node that shares your parent. that would be your sibling node.
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.
The granularity of the search is at the sibling statement level, so this wouldn't provide any additional performance boost overall. It doesn't matter within each sibling statement whether we walk forwards or backwards. In fact, perf would probably go down due to the extra bookkeeping.
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.
It was not about a performance boost. it was about building this out of more general helpers with a simple and clear algorithm.
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.
Specifically, all you'd need was a helper to find the last-ref of a local in a specified node. That seems generally useful and sane to have as a general helper.
Then you could simply use the result of that with exsiting code we have to give the specific answer of "last sibling statement".
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.
Okay. I'm not ready to generalize yet. Can I keep this PR more concrete?
49f24a9
to
5ed48b3
Compare
Pushed all interesting logic into the abstract class and got all pre-existing tests passing. Next up: writing more test cases. |
...arp/Portable/IntroduceUsingStatement/CSharpIntroduceUsingStatementCodeRefactoringProvider.cs
Show resolved
Hide resolved
protected override BlockSyntax WithStatements(BlockSyntax blockSyntax, SyntaxList<StatementSyntax> statements) | ||
{ | ||
return blockSyntax.WithStatements(statements); | ||
} |
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: CSharpIntroduceVariableService_IntroduceLocal has helpers for these (which also do the right thing for switch-cases). We should likely put those somewhere and use for both of these.
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: SyntaxGenerator would be a good place for this as it already handles getting/adding statements to members.
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.
@CyrusNajmabadi Ready to do this, but where would IsBlockLike go? SyntaxGenerator? C# SyntaxFacts is public API and internal members aren't accessible to this assembly. I looked at doing it on the syntax facts language service, but VB doesn't have standalone blocks so I'd have to do a ton of work to get statements from every kind of syntax.
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.
I'm fine with SyntaxGenerator being used for this.
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.
this does'nt seem to have been done.
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.
this doesn't seem to have been done.
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.
@CyrusNajmabadi I'm actually worried that my current methods aren't general enough for this. However, maybe this is the key.
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
...e/Portable/IntroduceUsingStatement/AbstractIntroduceUsingStatementCodeRefactoringProvider.cs
Outdated
Show resolved
Hide resolved
5b7b166
to
c19f07d
Compare
@jinujoseph @JoeRobich I resolved the merge conflicts. Let me know if there's anything else you'd like me to do! |
@jnm2 After looking at the integration failures, it seems that the xlf files weren't rebuilt after making some resx changes. This is pretty common if you were fixing merge conflicts in the resx. Could you rebuild the solution and commit the rebuilt xlf files? Thanks! |
c19f07d
to
039ac27
Compare
Oops, fixed! |
@jnm2 Thanks! Assuming everything ends up green I will merge this in the morning. While playing with it some more, a separate enhancement PR might be to remove the final usage of the disposable variable, if it is an invocation of |
@JoeRobich Yes, I thought about that! I couldn't imagine running into the scenario myself, so I thought I'd wait and see if people wanted it. (I wouldn't get as far as deciding to type I think if we did this, we should place the ending brace where the .Dispose() call previously was and move any declarations that became surrounded before the using (while leaving their initialization where it was). So that could be a generally enhancement even before detecting an existing .Dispose() statement: separate declarations from initializers that became surrounded but are used outside the new |
The integration test failure was the IPC Error - #29001 - Build logs |
Thanks @jnm2! As for future enhancements, when deciding whether to move a declaration out, could we use a similar find last usage and check if it is going to fall within the using body? Even if not, I agree that would help ensure we don't break working code. |
@JoeRobich Yes, we would want to do that. |
…zyT-and-delegates * dotnet/dev16.0-preview2: (117 commits) Do not warn for double nullable supression (dotnet#30936) Add -shared and -keepalive compiler options (dotnet#30818) Introduce using statement (dotnet#30106) Skip BinaryFileErrorTest Skip ParseFileOnBinaryFile Merge fixup Add missing binding redirects to csc.exe.config Add comments for default namespace in workspace Fix variable name Merge fixups Add support for default namespace to workspace Addressing feedback from Cyrus Embed optimization data to external compiler dependencies Skip optimizing System.Threading.Tasks.Extensions Skip optimizing System.Threading.Tasks.Extensions Add cert for PKT=b03f5f7f11d50a3a RoslynTools 18526.1 Fix VS dependency deployment Fix msbuild test Deploy System.Runtime.CompilerServices.Unsafe ...
/cc @CyrusNajmabadi