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

IDE0054: Fix compound assignment increment in expression context #54324

Conversation

MaStr11
Copy link
Contributor

@MaStr11 MaStr11 commented Jun 23, 2021

Fix #53969

Comment on lines 84 to 89
return Increment((TExpressionSyntax)leftOfAssign.WithoutTrailingTrivia(), postfix: syntaxFacts.IsStatement(currentAssignment.Parent));
}

if (diagnostic.Properties.ContainsKey(UseCompoundAssignmentUtilities.Decrement))
{
return Decrement((TExpressionSyntax)leftOfAssign);
return Decrement((TExpressionSyntax)leftOfAssign.WithoutTrailingTrivia(), postfix: syntaxFacts.IsStatement(currentAssignment.Parent));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

syntaxFacts.IsStatement seems legit to address #53969 (comment), but maybe there is a better way to detect

if the result of the assignment is used

There is also a lot of repetition, but I don't see a simple way to avoid that.

Copy link
Member

Choose a reason for hiding this comment

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

What about switch (x = x + 1)? The assignment parent is a statement, but it should be prefix. Am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are right. Maybe IsSimpleAssignmentStatement is better.

public bool IsSimpleAssignmentStatement([NotNullWhen(true)] SyntaxNode? statement)
=> statement.IsKind(SyntaxKind.ExpressionStatement, out ExpressionStatementSyntax? exprStatement) &&
exprStatement.Expression.IsKind(SyntaxKind.SimpleAssignmentExpression);

Copy link
Member

@Youssef1313 Youssef1313 Jun 23, 2021

Choose a reason for hiding this comment

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

I'm not sure. But things I'd make sure they are not broken:

  • switch(...)
  • return ...
  • yield return ...
  • while (...)
  • var x = ...
  • var x = (...)
  • bool_expr ? ... : ...
  • MethodCall(...)

Copy link
Member

Choose a reason for hiding this comment

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

Instead of doing syntax analysis here, could we do that by data flow analysis?

{
return SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, left);
}
protected override ExpressionSyntax Increment(ExpressionSyntax left, bool postfix)
Copy link
Member

Choose a reason for hiding this comment

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

nit: I'd call the parameter "operand" instead of left.

@@ -1087,11 +1087,85 @@ void M()
{
void M()
{
for (int i = 0; i < 10; i++)
for (int i = 0; i < 10; ++i)
Copy link
Member

Choose a reason for hiding this comment

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

would prefer this not change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 8b0e657

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.

tentatively requesting changes.

  1. if we can make it so we don't change the for loop incrementor, that would be nice.
  2. insteaf of .WithoutTrivia just do .WithTriviaFrom to preserve leading/trailing trivia.

@MaStr11 MaStr11 requested a review from a team as a code owner June 23, 2021 19:36
@CyrusNajmabadi
Copy link
Member

Are you ok with me pushing a couple of changes here? Tahnks!

/// <param name="startValue">C#: null | VB: 0</param>
/// <param name="endCondition">C#: i &lt; 10 | VB: 10</param>
/// <param name="increments">C#: i++ | VB: Step 1</param>
void GetPartsOfForStatement(SyntaxNode? node, out SyntaxNode? variableDeclaration, out SyntaxNode? startValue, out SyntaxNode? endCondition, out ImmutableArray<SyntaxNode> increments);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought the for loops of VB and C# are close enough for a "GetPartsOf" attempt, but they turned out to be quite different. Maybe it's better to create something like IsPartOfForLoopIncrementor in AbstractUseCompoundAssignmentCodeFixProvider or ISyntaxFacts.

@MaStr11
Copy link
Contributor Author

MaStr11 commented Jun 23, 2021

Are you ok with me pushing a couple of changes here? Tahnks!

Sure.

@CyrusNajmabadi
Copy link
Member

thanks!

@CyrusNajmabadi CyrusNajmabadi merged commit 047ee59 into dotnet:main Jun 23, 2021
@ghost ghost added this to the Next milestone Jun 23, 2021
@jinujoseph jinujoseph added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jun 24, 2021
@RikkiGibson RikkiGibson modified the milestones: Next, 17.0.P2 Jun 29, 2021
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
Development

Successfully merging this pull request may close these issues.

Intellisense compoud assignment suggestion incorrect
5 participants