Skip to content

Commit

Permalink
more cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mary-georgiou-sonarsource committed May 2, 2024
1 parent b5c309f commit 0a31d21
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 107 deletions.
69 changes: 26 additions & 43 deletions analyzers/src/SonarAnalyzer.CSharp/Helpers/CSharpSyntaxHelper.cs
Expand Up @@ -45,13 +45,13 @@ public static class CSharpSyntaxHelper
];

public static bool AnyOfKind(this IEnumerable<SyntaxNode> nodes, SyntaxKind kind) =>
nodes.Any(n => n.RawKind == (int)kind);
nodes.Any(x => x.RawKind == (int)kind);

public static bool AnyOfKind(this IEnumerable<SyntaxToken> 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)
{
Expand Down Expand Up @@ -89,11 +89,11 @@ expression switch
public static bool IsInNameOfArgument(this ExpressionSyntax expression, SemanticModel semanticModel)
{
var parentInvocation = expression.FirstAncestorOrSelf<InvocationExpressionSyntax>();
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;
Expand All @@ -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<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, params SyntaxKind[] syntaxKinds) =>
syntaxKinds.Contains((SyntaxKind)syntaxToken.RawKind);
Expand All @@ -146,28 +146,19 @@ public static bool IsStringEmpty(this ExpressionSyntax expression, SemanticModel
return childNodes
.OfType<InvocationExpressionSyntax>()
.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<IMethodSymbol>()
.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) &&
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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) =>
Expand All @@ -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).
/// </summary>
public static ImmutableArray<SyntaxNode> ArgumentValuesForParameter(SemanticModel semanticModel, ArgumentListSyntax argumentList, string parameterName) =>
argumentList != null
argumentList is not null
&& new CSharpMethodParameterLookup(argumentList, semanticModel).TryGetSyntax(parameterName, out var expressions)
? expressions
: ImmutableArray<SyntaxNode>.Empty;
Expand Down
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<SyntaxKind> collection) =>
collection.Contains((SyntaxKind)syntaxToken.RawKind);

public static bool IsAnyKind(this SyntaxNode syntaxNode, ISet<SyntaxKind> 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);
Expand All @@ -104,7 +104,7 @@ public static StatementSyntax GetSucceedingStatement(this StatementSyntax curren
syntaxKinds.Contains((SyntaxKind)syntaxTrivia.RawKind);

public static bool AnyOfKind(this IEnumerable<SyntaxNode> 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 &&
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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<ParameterSyntax>? GetParameters(this MethodBlockSyntax method)
=> method.BlockStatement?.ParameterList?.Parameters;
public static SeparatedSyntaxList<ParameterSyntax>? 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;

Expand All @@ -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).
/// </summary>
public static ImmutableArray<SyntaxNode> ArgumentValuesForParameter(SemanticModel semanticModel, ArgumentListSyntax argumentList, string parameterName) =>
argumentList != null
argumentList is not null
&& new VisualBasicMethodParameterLookup(argumentList, semanticModel).TryGetSyntax(parameterName, out var expressions)
? expressions
: ImmutableArray<SyntaxNode>.Empty;
Expand Down

0 comments on commit 0a31d21

Please sign in to comment.