-
Notifications
You must be signed in to change notification settings - Fork 231
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
Fix S2234 FN: primary constructors for records, classes and structs #8238
Conversation
a08d121
to
373274e
Compare
&& Language.Syntax.NodeExpression(argument) is { } argumentExpression | ||
&& c.Context.SemanticModel.GetTypeInfo(argumentExpression).ConvertedType is { } argumentType | ||
// is there another parameter that seems to be a better fit (name and type match): p_x | ||
&& methodParameterLookup.MethodSymbol.Parameters.FirstOrDefault(p => MatchingNames(p, argumentName) && argumentType.DerivesOrImplements(p.Type)) is { IsParams: false } |
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.
DerivesOrImplements
misses a whole lot of conversions:
Identity conversions
Implicit numeric conversions
Implicit enumeration conversions
Implicit interpolated string conversions
Implicit reference conversions
Boxing conversions
Implicit dynamic conversions
Implicit type parameter conversions
Implicit constant expression conversions
User-defined implicit conversions
Anonymous function conversions
Method group conversions
Null literal conversions
Implicit nullable conversions
Implicit tuple conversions
Lifted user-defined implicit conversions
Default literal conversions
Implicit throw conversion
The best way to handle this is by using ClassifyConversion(SemanticModel, ExpressionSyntax, ITypeSymbol, Boolean) but this requires even more changes. I would propose to create an issue about adding something like ILanguageFace.IsAssignableTo(SyntaxNode expression, ITypeSymbol destination)
to the facade, bring it under test, and use it here. We also should have a look at how Roslyn handles this.
=> node.GetLocation(); | ||
|
||
private static bool MatchingNames(IParameterSymbol parameter, string argumentName) => | ||
parameter.Name == argumentName; |
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.
ArgumentName()
already returns names for all kinds of expressions:
M(A.B)
-> BM(A?.B)
-> BM(A())
-> AM(A)
-> A (this might be unsupported at the moment)
and more could be added when this is fixed: #8241
Given that, the comparison should be replaced by StringComparison.OrdinalIgnoreCase
for all languages.
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.
That's a lot better!
analyzers/src/SonarAnalyzer.VisualBasic/Facade/VisualBasicFacade.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.VisualBasic/Facade/VisualBasicSyntaxFacade.cs
Show resolved
Hide resolved
&& Language.Syntax.NodeExpression(argument) is { } argumentExpression | ||
&& c.Context.SemanticModel.GetTypeInfo(argumentExpression).ConvertedType is { } argumentType | ||
// is there another parameter that seems to be a better fit (name and type match): p_x | ||
&& methodParameterLookup.MethodSymbol.Parameters.FirstOrDefault(p => MatchingNames(p, argumentName) && argumentType.DerivesOrImplements(p.Type)) is { IsParams: false } |
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.
&& methodParameterLookup.MethodSymbol.Parameters.FirstOrDefault(p => MatchingNames(p, argumentName) && argumentType.DerivesOrImplements(p.Type)) is { IsParams: false } | |
&& methodParameterLookup.MethodSymbol.Parameters.FirstOrDefault(p => MatchingNames(p, argumentName) | |
&& argumentType.DerivesOrImplements(p.Type)) is { IsParams: false } |
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.
Why?
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.
you inlined that AND condition, all the others are listed one after the other
analyzers/tests/SonarAnalyzer.UnitTest/Extensions/SyntaxNodeExtensionsTest.cs
Show resolved
Hide resolved
40175d3
to
cf4817a
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.
LGTM! Please fix the last unresolved comment before merging
cf4817a
to
9870e05
Compare
Kudos, SonarCloud Quality Gate passed! |
Kudos, SonarCloud Quality Gate passed! |
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.
Looks good! I think you can merge this one
Peach validation: Lost one issue, which was an invocation of Three new issues: Both examples are identical (copy/paste). TP: TP: |
Fixes #8070
Fixes #8071
The original implementation was rewritten from scratch. The reasons are
SonarDiagnosticAnalyzer<TSyntaxKind>
LanguageFacade
wasn't usedabstract
methods (e.g.,GetArgumentTypeSymbolInfo
) and passed delegates (e.g.,getLocationToReport
parameter inReportIncorrectlyOrderedParameters
) which are both used as language-specific holes for the language-neutral implementationArgumentIdentifier
private class and derived classes are not neededThe current implementation follows our standards more closely and moves a lot of logic to the facade.