diff --git a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs index 90dacc5f699..59b9c53e346 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs @@ -45,13 +45,13 @@ public static class CSharpSyntaxHelper ]; public static bool AnyOfKind(this IEnumerable nodes, SyntaxKind kind) => - nodes.Any(n => n.RawKind == (int)kind); + nodes.Any(x => x.RawKind == (int)kind); public static bool AnyOfKind(this IEnumerable tokens, SyntaxKind kind) => - tokens.Any(n => n.RawKind == (int)kind); + tokens.Any(x => x.RawKind == (int)kind); public static SyntaxNode GetTopMostContainingMethod(this SyntaxNode node) => - node.AncestorsAndSelf().LastOrDefault(ancestor => ancestor is BaseMethodDeclarationSyntax || ancestor is PropertyDeclarationSyntax); + node.AncestorsAndSelf().LastOrDefault(x => x is BaseMethodDeclarationSyntax || x is PropertyDeclarationSyntax); public static SyntaxNode GetSelfOrTopParenthesizedExpression(this SyntaxNode node) { @@ -89,11 +89,11 @@ expression switch public static bool IsInNameOfArgument(this ExpressionSyntax expression, SemanticModel semanticModel) { var parentInvocation = expression.FirstAncestorOrSelf(); - return parentInvocation != null && parentInvocation.IsNameof(semanticModel); + return parentInvocation is not null && parentInvocation.IsNameof(semanticModel); } public static bool IsNameof(this InvocationExpressionSyntax expression, SemanticModel semanticModel) => - expression != null && + expression is not null && expression.Expression is IdentifierNameSyntax identifierNameSyntax && identifierNameSyntax.Identifier.ValueText == NameOfKeywordText && semanticModel.GetSymbolInfo(expression).Symbol?.Kind != SymbolKind.Method; @@ -108,19 +108,19 @@ public static bool IsStringEmpty(this ExpressionSyntax expression, SemanticModel var nameSymbolInfo = semanticModel.GetSymbolInfo(((MemberAccessExpressionSyntax)expression).Name); - return nameSymbolInfo.Symbol != null && + return nameSymbolInfo.Symbol is not null && nameSymbolInfo.Symbol.IsInType(KnownType.System_String) && nameSymbolInfo.Symbol.Name == nameof(string.Empty); } public static bool IsNullLiteral(this SyntaxNode syntaxNode) => - syntaxNode != null && syntaxNode.IsKind(SyntaxKind.NullLiteralExpression); + syntaxNode is not null && syntaxNode.IsKind(SyntaxKind.NullLiteralExpression); public static bool IsAnyKind(this SyntaxNode syntaxNode, params SyntaxKind[] syntaxKinds) => - syntaxNode != null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); + syntaxNode is not null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); public static bool IsAnyKind(this SyntaxNode syntaxNode, ISet syntaxKinds) => - syntaxNode != null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); + syntaxNode is not null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); public static bool IsAnyKind(this SyntaxToken syntaxToken, params SyntaxKind[] syntaxKinds) => syntaxKinds.Contains((SyntaxKind)syntaxToken.RawKind); @@ -146,28 +146,19 @@ public static bool IsStringEmpty(this ExpressionSyntax expression, SemanticModel return childNodes .OfType() .Where(syntaxPredicate) - .Select(e => e.Expression.SyntaxTree.GetSemanticModelOrDefault(semanticModel)?.GetSymbolInfo(e.Expression).Symbol) + .Select(x => x.Expression.SyntaxTree.GetSemanticModelOrDefault(semanticModel)?.GetSymbolInfo(x.Expression).Symbol) .OfType() .Any(symbolPredicate); } - public static SyntaxToken? GetIdentifierOrDefault(this BaseMethodDeclarationSyntax methodDeclaration) - { - switch (methodDeclaration?.Kind()) + public static SyntaxToken? GetIdentifierOrDefault(this BaseMethodDeclarationSyntax methodDeclaration) => + methodDeclaration switch { - case SyntaxKind.ConstructorDeclaration: - return ((ConstructorDeclarationSyntax)methodDeclaration).Identifier; - - case SyntaxKind.DestructorDeclaration: - return ((DestructorDeclarationSyntax)methodDeclaration).Identifier; - - case SyntaxKind.MethodDeclaration: - return ((MethodDeclarationSyntax)methodDeclaration).Identifier; - - default: - return null; - } - } + ConstructorDeclarationSyntax constructor => (SyntaxToken?)constructor.Identifier, + DestructorDeclarationSyntax destructor => (SyntaxToken?)destructor.Identifier, + MethodDeclarationSyntax method => (SyntaxToken?)method.Identifier, + _ => null, + }; public static bool IsMethodInvocation(this InvocationExpressionSyntax invocation, KnownType type, string methodName, SemanticModel semanticModel) => invocation.Expression.NameIs(methodName) && @@ -194,7 +185,7 @@ public static bool IsStringEmpty(this ExpressionSyntax expression, SemanticModel node.Sections.IndexOf(section => section.Labels.AnyOfKind(SyntaxKind.DefaultSwitchLabel)); public static bool HasBodyOrExpressionBody(this AccessorDeclarationSyntax node) => - node.Body != null || node.ExpressionBody() != null; + node.Body is not null || node.ExpressionBody() is not null; public static string GetName(this SyntaxNode node) => node.GetIdentifier()?.ValueText ?? string.Empty; @@ -208,7 +199,7 @@ public static bool IsStringEmpty(this ExpressionSyntax expression, SemanticModel || Array.Exists(orNames, x => nodeName.Equals(x, StringComparison.Ordinal))); public static bool HasConstantValue(this ExpressionSyntax expression, SemanticModel semanticModel) => - expression.RemoveParentheses().IsAnyKind(LiteralSyntaxKinds) || expression.FindConstantValue(semanticModel) != null; + expression.RemoveParentheses().IsAnyKind(LiteralSyntaxKinds) || expression.FindConstantValue(semanticModel) is not null; public static string StringValue(this SyntaxNode node, SemanticModel semanticModel) => node switch @@ -226,20 +217,12 @@ public static bool IsLeftSideOfAssignment(this ExpressionSyntax expression) && assignment.Left == topParenthesizedExpression; } - public static bool IsComment(this SyntaxTrivia trivia) - { - switch (trivia.Kind()) - { - case SyntaxKind.SingleLineCommentTrivia: - case SyntaxKind.MultiLineCommentTrivia: - case SyntaxKind.SingleLineDocumentationCommentTrivia: - case SyntaxKind.MultiLineDocumentationCommentTrivia: - return true; - - default: - return false; - } - } + public static bool IsComment(this SyntaxTrivia trivia) => + trivia.IsAnyKind( + SyntaxKind.SingleLineCommentTrivia, + SyntaxKind.MultiLineCommentTrivia, + SyntaxKind.SingleLineDocumentationCommentTrivia, + SyntaxKind.MultiLineDocumentationCommentTrivia); // creates a QualifiedNameSyntax "a.b" public static QualifiedNameSyntax BuildQualifiedNameSyntax(string a, string b) => @@ -261,7 +244,7 @@ public static bool IsComment(this SyntaxTrivia trivia) /// There can be zero, one or more results based on parameter type (Optional or ParamArray/params). /// public static ImmutableArray ArgumentValuesForParameter(SemanticModel semanticModel, ArgumentListSyntax argumentList, string parameterName) => - argumentList != null + argumentList is not null && new CSharpMethodParameterLookup(argumentList, semanticModel).TryGetSyntax(parameterName, out var expressions) ? expressions : ImmutableArray.Empty; diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/Helpers/VisualBasicSyntaxHelper.cs b/analyzers/src/SonarAnalyzer.VisualBasic/Helpers/VisualBasicSyntaxHelper.cs index b7291bed21d..3ef36f19e19 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/Helpers/VisualBasicSyntaxHelper.cs +++ b/analyzers/src/SonarAnalyzer.VisualBasic/Helpers/VisualBasicSyntaxHelper.cs @@ -33,7 +33,7 @@ internal static class VisualBasicSyntaxHelper ]; public static SyntaxNode GetTopMostContainingMethod(this SyntaxNode node) => - node.AncestorsAndSelf().LastOrDefault(ancestor => ancestor is MethodBaseSyntax || ancestor is PropertyBlockSyntax); + node.AncestorsAndSelf().LastOrDefault(x => x is MethodBaseSyntax || x is PropertyBlockSyntax); public static SyntaxNode RemoveParentheses(this SyntaxNode expression) { @@ -86,16 +86,16 @@ public static StatementSyntax GetSucceedingStatement(this StatementSyntax curren syntaxNode.Ancestors().Any(x => x.IsAnyKind(syntaxKinds)); public static bool IsNothingLiteral(this SyntaxNode syntaxNode) => - syntaxNode != null && syntaxNode.IsKind(SyntaxKind.NothingLiteralExpression); + syntaxNode is not null && syntaxNode.IsKind(SyntaxKind.NothingLiteralExpression); public static bool IsAnyKind(this SyntaxNode syntaxNode, params SyntaxKind[] syntaxKinds) => - syntaxNode != null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); + syntaxNode is not null && syntaxKinds.Contains((SyntaxKind)syntaxNode.RawKind); public static bool IsAnyKind(this SyntaxToken syntaxToken, ISet collection) => collection.Contains((SyntaxKind)syntaxToken.RawKind); public static bool IsAnyKind(this SyntaxNode syntaxNode, ISet collection) => - syntaxNode != null && collection.Contains((SyntaxKind)syntaxNode.RawKind); + syntaxNode is not null && collection.Contains((SyntaxKind)syntaxNode.RawKind); public static bool IsAnyKind(this SyntaxToken syntaxToken, params SyntaxKind[] syntaxKinds) => syntaxKinds.Contains((SyntaxKind)syntaxToken.RawKind); @@ -104,7 +104,7 @@ public static StatementSyntax GetSucceedingStatement(this StatementSyntax curren syntaxKinds.Contains((SyntaxKind)syntaxTrivia.RawKind); public static bool AnyOfKind(this IEnumerable nodes, SyntaxKind kind) => - nodes.Any(n => n.RawKind == (int)kind); + nodes.Any(x => x.RawKind == (int)kind); public static bool IsMethodInvocation(this InvocationExpressionSyntax expression, KnownType type, string methodName, SemanticModel semanticModel) => semanticModel.GetSymbolInfo(expression).Symbol is IMethodSymbol methodSymbol && @@ -115,30 +115,17 @@ public static StatementSyntax GetSucceedingStatement(this StatementSyntax curren public static bool IsOnBase(this ExpressionSyntax expression) => IsOn(expression, SyntaxKind.MyBaseExpression); - private static bool IsOn(this ExpressionSyntax expression, SyntaxKind onKind) - { - switch (expression?.Kind()) + private static bool IsOn(this ExpressionSyntax expression, SyntaxKind onKind) => + expression switch { - case SyntaxKind.InvocationExpression: - return IsOn(((InvocationExpressionSyntax)expression).Expression, onKind); - - case SyntaxKind.GlobalName: - case SyntaxKind.GenericName: - case SyntaxKind.IdentifierName: - case SyntaxKind.QualifiedName: - // This is a simplification as we don't check where the method is defined (so this could be this or base) - return true; - - case SyntaxKind.SimpleMemberAccessExpression: - return ((MemberAccessExpressionSyntax)expression).Expression.RemoveParentheses().IsKind(onKind); - - case SyntaxKind.ConditionalAccessExpression: - return ((ConditionalAccessExpressionSyntax)expression).Expression.RemoveParentheses().IsKind(onKind); - - default: - return false; - } - } + InvocationExpressionSyntax invocation => IsOn(invocation.Expression, onKind), + // This is a simplification as we don't check where the method is defined (so this could be this or base) + GlobalNameSyntax or GenericNameSyntax or IdentifierNameSyntax or QualifiedNameSyntax => true, + MemberAccessExpressionSyntax memberAccessExpression when memberAccessExpression.IsKind(SyntaxKind.SimpleMemberAccessExpression) => + memberAccessExpression.Expression.RemoveParentheses().IsKind(onKind), + ConditionalAccessExpressionSyntax conditionalAccess => conditionalAccess.Expression.RemoveParentheses().IsKind(onKind), + _ => false, + }; public static string GetName(this SyntaxNode expression) => expression.GetIdentifier()?.ValueText ?? string.Empty; @@ -147,7 +134,7 @@ private static bool IsOn(this ExpressionSyntax expression, SyntaxKind onKind) expression.GetName().Equals(name, StringComparison.InvariantCultureIgnoreCase); public static bool HasConstantValue(this ExpressionSyntax expression, SemanticModel semanticModel) => - expression.RemoveParentheses().IsAnyKind(LiteralSyntaxKinds) || expression.FindConstantValue(semanticModel) != null; + expression.RemoveParentheses().IsAnyKind(LiteralSyntaxKinds) || expression.FindConstantValue(semanticModel) is not null; public static string StringValue(this SyntaxNode node, SemanticModel semanticModel) => node switch @@ -165,49 +152,31 @@ public static bool IsLeftSideOfAssignment(this ExpressionSyntax expression) assignment.Left == topParenthesizedExpression; } - public static bool IsComment(this SyntaxTrivia trivia) - { - switch (trivia.Kind()) - { - case SyntaxKind.CommentTrivia: - case SyntaxKind.DocumentationCommentExteriorTrivia: - case SyntaxKind.DocumentationCommentTrivia: - return true; - - default: - return false; - } - } + public static bool IsComment(this SyntaxTrivia trivia) => + trivia.IsAnyKind( + SyntaxKind.CommentTrivia, + SyntaxKind.DocumentationCommentExteriorTrivia, + SyntaxKind.DocumentationCommentTrivia); public static Location FindIdentifierLocation(this MethodBlockBaseSyntax methodBlockBase) => GetIdentifierOrDefault(methodBlockBase)?.GetLocation(); - public static SyntaxToken? GetIdentifierOrDefault(this MethodBlockBaseSyntax methodBlockBase) - { - var blockStatement = methodBlockBase?.BlockStatement; - - switch (blockStatement?.Kind()) + public static SyntaxToken? GetIdentifierOrDefault(this MethodBlockBaseSyntax methodBlockBase) => + methodBlockBase?.BlockStatement switch { - case SyntaxKind.SubNewStatement: - return (blockStatement as SubNewStatementSyntax)?.NewKeyword; - - case SyntaxKind.FunctionStatement: - case SyntaxKind.SubStatement: - return (blockStatement as MethodStatementSyntax)?.Identifier; - - default: - return null; - } - } + SubNewStatementSyntax subNewStatement => subNewStatement.NewKeyword, + MethodStatementSyntax methodStatement => methodStatement.Identifier, + _ => null, + }; - public static string GetIdentifierText(this MethodBlockSyntax method) - => method.SubOrFunctionStatement.Identifier.ValueText; + public static string GetIdentifierText(this MethodBlockSyntax method) => + method.SubOrFunctionStatement.Identifier.ValueText; - public static SeparatedSyntaxList? GetParameters(this MethodBlockSyntax method) - => method.BlockStatement?.ParameterList?.Parameters; + public static SeparatedSyntaxList? GetParameters(this MethodBlockSyntax method) => + method.BlockStatement?.ParameterList?.Parameters; public static ExpressionSyntax Get(this ArgumentListSyntax argumentList, int index) => - argumentList != null && argumentList.Arguments.Count > index + argumentList is not null && argumentList.Arguments.Count > index ? argumentList.Arguments[index].GetExpression().RemoveParentheses() : null; @@ -217,7 +186,7 @@ public static string GetIdentifierText(this MethodBlockSyntax method) /// There can be zero, one or more results based on parameter type (Optional or ParamArray/params). /// public static ImmutableArray ArgumentValuesForParameter(SemanticModel semanticModel, ArgumentListSyntax argumentList, string parameterName) => - argumentList != null + argumentList is not null && new VisualBasicMethodParameterLookup(argumentList, semanticModel).TryGetSyntax(parameterName, out var expressions) ? expressions : ImmutableArray.Empty;