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

#20630 Cast is redundant on attribute with params fix #20743

Merged

Conversation

MaStr11
Copy link
Contributor

@MaStr11 MaStr11 commented Jul 10, 2017

Customer scenario

False positive on IDE0004 "Cast is redundant" analyzer

Bugs this fixes:

Fixes #20630

Workarounds, if any

Disable IDE0004

Risk

Code fix changes behavior.

Performance impact

Low.

Is this a regression from a previous update?

Variation of: #18978
Related: #20741 #20742

Root cause analysis:

Analyzer misses test for prams in attribute constructor calls.

How was the bug found?

Customer reported

@sharwell sharwell requested a review from a team July 10, 2017 22:39
@Pilchie Pilchie added this to the 15.5 milestone Jul 12, 2017
@Pilchie Pilchie added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jul 12, 2017
{
return false;
}
private static bool CheckConversionOfParamToParamArray(IParameterSymbol parameter, ITypeSymbol castType, SemanticModel semanticModel)
Copy link
Member

Choose a reason for hiding this comment

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

Check what? Is there a name that describes what is true if this method returns true?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe ParameterTypeMatchesParamsElementType or something?

}
private static bool CheckConversionOfParamToParamArray(IParameterSymbol parameter, ITypeSymbol castType, SemanticModel semanticModel)
{
if (parameter != null && parameter.IsParams)
Copy link
Member

Choose a reason for hiding this comment

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

Could just use parameter?.IsParams

{
return true;
}
var parameterType = (IArrayTypeSymbol)parameter.Type;
Copy link
Member

Choose a reason for hiding this comment

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

Is this correct in broken code? What if I type a method that says M(params int something) Does the symbol still report IsParams?

Copy link
Member

Choose a reason for hiding this comment

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

I see this is just moved code, so I assume so, but worth double checking.

@Pilchie Pilchie requested a review from a team July 16, 2017 18:39
@Pilchie
Copy link
Member

Pilchie commented Jul 16, 2017

retest windows_debug_vs-integration_prtest please

@Pilchie
Copy link
Member

Pilchie commented Jul 16, 2017

retest windows_release_vs-integration_prtest please

@Pilchie
Copy link
Member

Pilchie commented Jul 16, 2017

Test results were gone :(

@Pilchie
Copy link
Member

Pilchie commented Jul 16, 2017

@dotnet/roslyn-ide can we get a second review here?

@MaStr11
Copy link
Contributor Author

MaStr11 commented Jul 17, 2017

@Pilchie

Is this correct in broken code? What if I type a method that says M(params int something) Does the symbol still report IsParams?

This wasn't covered before by tests. I added tests for method calls and for attributes and it turned out, that both were failing with an InvalidCastException. I don't know what is the correct behavior in such a case but I decided to assume that in such cases we return true to cancel the analyzer. Unfortunately in this case the return true does not reflect what the method name ParameterTypeMatchesParamsElementType suggests.

@Pilchie
Copy link
Member

Pilchie commented Jul 17, 2017

Thanks! This looks good to me. Anyone else from @dotnet/roslyn-ide want to review?

@Pilchie
Copy link
Member

Pilchie commented Jul 25, 2017

Ping @dotnet/roslyn-ide for a second review.

@MaStr11 MaStr11 closed this Aug 11, 2017
@sharwell
Copy link
Member

@MaStr11 Were you closing this because we were slow or because it was fixed in some other manner?

@MaStr11
Copy link
Contributor Author

MaStr11 commented Aug 11, 2017

Closing the issue was a mistake on my side. I don't know how this could happen. I'm sorry for the inconvenience.

@sharwell
Copy link
Member

@MaStr11 No problem! Just wanted to make sure I didn't miss something.

@sharwell sharwell self-assigned this Aug 31, 2017
@sharwell sharwell requested a review from chborl October 5, 2017 15:29
@sharwell sharwell modified the milestones: 15.5, 15.7, 15.6 Oct 30, 2017
@sharwell sharwell changed the base branch from master to post-dev15.5-contrib November 1, 2017 12:30
@shyamnamboodiripad shyamnamboodiripad changed the base branch from post-dev15.5-contrib to master November 17, 2017 20:17
@sharwell sharwell changed the base branch from master to dev15.6.x January 23, 2018 02:04
@sharwell sharwell removed the request for review from chborl January 23, 2018 02:04
@sharwell sharwell changed the base branch from dev15.6.x to dev15.7.x January 23, 2018 02:06
@sharwell sharwell modified the milestones: 15.6, 15.7 Jan 23, 2018
@jinujoseph
Copy link
Contributor

test windows_release_vs-integration_prtest

@jinujoseph
Copy link
Contributor

test windows_coreclr_debug_prtest

Debug.Assert(parameter.Type is IArrayTypeSymbol);
// We don't check the position of the argument because in attributes it is allowed that
// params parameter are positioned in between if named arguments are used.
// The *single* argument check above is also broken: https://github.com/dotnet/roslyn/issues/20742
Copy link
Member

Choose a reason for hiding this comment

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

❓ Can you not just check that the next AttributeArgumentSyntax has a null NameEquals property?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At this position we need to find the parameter that fits to the argument (DetermineParameter). We pass this information to ParameterTypeMatchesParamsElementType which is only interested in params parameters. We could avoid the call to DetermineParameter if we are sure that looking at the attributeArgumentList and the attributeArgument in it we can be sure that it

  1. can't be a params parameter or
  2. if it might be a params parameter the argument would be a single element array passed to the parameter.

I don't think it is possible to determine either of that conditions by only looking at the attributeArgumentList and the attributeArgument.

Copy link
Member

Choose a reason for hiding this comment

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

I was specifically referring to how this:

If there are any arguments to the right, we can assume that this is not a single argument passed to a params parameter.

Relates to this:

The single argument check above is also broken

It seems that you could identify a single argument as an argument meeting both of the following conditions:

  1. The argument appears first in the list
  2. The next argument, if any, has a non-null NameEquals property, indicating that it sets a named property instead of a parameter

Copy link
Member

Choose a reason for hiding this comment

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

➡️ Filed #25790 as a follow-up

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The single argument comment is misleading. It's really asking for a single argument passed to a params parameter.

@jinujoseph
Copy link
Contributor

@Pilchie for ask mode approval for 15.7 Preview 4

/// is true, the last parameter will be returned if it is params parameter and the index of
/// the specified argument is greater than the number of parameters.
/// </summary>
public static IParameterSymbol DetermineParameter(
Copy link
Contributor

Choose a reason for hiding this comment

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

@AlekseyTs @333fred I can't seem to recall: does GetOperation(AttributeArgumentSyntax) return an IArgumentOperation? If so, we can replace this method with IArgumentOperation.Parameter. If not, it would be good to file a tracking issue.

Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like we have any tests in this area. We should give it a try and see if it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method is a copy of ArgumentSyntaxExtensions.DetermineParameter. If we change the logic here, we should also change it there.

It doesn't look like we have any tests in this area. We should give it a try and see if it works.

That's a confusing statement. I really don't know what I'm supposed to do here, especially given that this PR got approved to merge already.

return parameters.FirstOrDefault(p => p.Name == name);
}

// Handle positional argument
Copy link
Member

Choose a reason for hiding this comment

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

what if it is a "Name =" argument? That would not map to a parameter at all, regardless of position.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's right. I addressed this in 514e4fd:

  • Added a test for a cast in a named argument
  • added a section explaining the handling of named arguments
  • Added an return at the top of the method for named arguments.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

@Pilchie
Copy link
Member

Pilchie commented Mar 28, 2018

Approved - thanks @MaStr11 and sorry this took so long to get in. It's embarrassing! 😊

…arguments. Added test for cast in named argument.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved to merge Area-IDE cla-already-signed 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.

8 participants