Skip to content

Commit

Permalink
Add support for ConstructorInitializer and PrimaryConstructorBaseType
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-strecker-sonarsource committed Oct 23, 2023
1 parent 67344dc commit de5f27a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
34 changes: 25 additions & 9 deletions analyzers/src/SonarAnalyzer.CSharp/Rules/RedundantArgument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using SonarAnalyzer.Helpers;

namespace SonarAnalyzer.Rules.CSharp
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
Expand All @@ -36,24 +34,42 @@ protected override void Initialize(SonarAnalysisContext context) =>
context.RegisterNodeAction(
c =>
{
if (!c.IsInExpressionTree() // Can't use optional arguments in expression trees (CS0584), so skip those
&& ArgumentList(c) is { Arguments.Count: > 0 } argumentList
&& new CSharpMethodParameterLookup(argumentList, c.SemanticModel) is { MethodSymbol: { } } methodParameterLookup)
if (ArgumentList(c.Node) is { Arguments.Count: > 0 } argumentList
&& !IsRedundantPrimaryConstructorBaseTypeContext(c) // FIXME: Use extension method from #8238
&& !c.IsInExpressionTree() // Can't use optional arguments in expression trees (CS0584), so skip those
&& new CSharpMethodParameterLookup(argumentList, c.SemanticModel) is { MethodSymbol: { } } methodParameterLookup) // FIXME: Replace argumentList with c.Node after #8238
{
foreach (var argumentMapping in methodParameterLookup.GetAllArgumentParameterMappings().Reverse().Where(x => ArgumentHasDefaultValue(x, c.SemanticModel)))
{
c.ReportIssue(Diagnostic.Create(Rule, argumentMapping.Node.GetLocation(), argumentMapping.Symbol.Name));
}
}
},
SyntaxKind.InvocationExpression, SyntaxKind.ObjectCreationExpression, SyntaxKindEx.ImplicitObjectCreationExpression);
SyntaxKind.InvocationExpression,
SyntaxKind.ObjectCreationExpression,
SyntaxKindEx.ImplicitObjectCreationExpression,
SyntaxKind.BaseConstructorInitializer,
SyntaxKind.ThisConstructorInitializer,
SyntaxKindEx.PrimaryConstructorBaseType);

// // FIXME: Copy of https://github.com/SonarSource/sonar-dotnet/pull/8238/files#diff-260dcbe170483d6f19c1ccbd5a4159c909e032540194c6621fd94a2461b5f530R57 and should be deleted after #8238
private static bool IsRedundantPrimaryConstructorBaseTypeContext(SonarSyntaxNodeReportingContext context) =>
context is
{
Node.RawKind: (int)SyntaxKindEx.PrimaryConstructorBaseType,
Compilation.Language: LanguageNames.CSharp,
ContainingSymbol.Kind: SymbolKind.NamedType,
};

private static ArgumentListSyntax ArgumentList(SonarSyntaxNodeReportingContext c) =>
c.Node switch
// FIXME: Should be deleted after #8238
private static ArgumentListSyntax ArgumentList(SyntaxNode node) =>
node switch
{
InvocationExpressionSyntax invocationExpression => invocationExpression.ArgumentList,
ObjectCreationExpressionSyntax objectCreationExpression => objectCreationExpression.ArgumentList,
{ RawKind: (int)SyntaxKindEx.ImplicitObjectCreationExpression } => ((ImplicitObjectCreationExpressionSyntaxWrapper)c.Node).ArgumentList,
ConstructorInitializerSyntax constructorInitializer => constructorInitializer.ArgumentList,
{ RawKind: (int)SyntaxKindEx.PrimaryConstructorBaseType } => ((PrimaryConstructorBaseTypeSyntaxWrapper)node).ArgumentList,
{ RawKind: (int)SyntaxKindEx.ImplicitObjectCreationExpression } => ((ImplicitObjectCreationExpressionSyntaxWrapper)node).ArgumentList,
_ => null,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,17 @@ void NamedArguments()

class C1(int i = 42);
class C2(int i = 41, int j = 42);
class C3() : C1(42); // Noncompliant
}

class ConstructorInitializerBase
{
public ConstructorInitializerBase(int i = 42) { }
public ConstructorInitializerBase(bool _) : this(42) { } // Noncompliant

class Derived : ConstructorInitializerBase
{
public Derived() : base(42) { } // Noncompliant
}
}
}

0 comments on commit de5f27a

Please sign in to comment.